IPv6 attack toolkit
THC-IPV6-ATTACK-TOOLKIT (c) 2005-2022 [email protected] https://github.com/vanhauser-thc/thc-ipv6
Licensed under AGPLv3 (see LICENSE file)
This code was inspired when I got into touch with IPv6, learned more and more about it - and then found no tools to play (read: "hack") around with. First I tried to implement things with libnet, but then found out that the IPv6 implementation is only partial - and sucks. I tried to add the missing code, but well, it was not so easy, hence I saved my time and quickly wrote my own library.
This code currently only runs on:
You must have libpcap-dev installed to be able to build the tools. Additionally libssl-dev and libnetfilter-queue-dev are recommended as well.
These can be installed by (Kali, Debian, Ubuntu): sudo apt-get install libpcap-dev libssl-dev libnetfilter-queue-dev
You can build the tools by running: make all
You can install the tools and existing manual pages by running: make install
The THC IPV6 ATTACK TOOLKIT comes already with lots of effective attacking tools:
Just run the tools without options and they will give you help and show the command line options.
The library thc-ipv6-lib.c is the heart and soul of all tools - and those you may want to write. Implementation is so simple, its usually just 2-4 lines to create a complete IPv6/ICMPv6 packet with the content of your choice.
Your basic structure you use is (thc_ipv6_hdr *) e.g. thc_ipv6_hdr *my_ipv6_packet; int my_ipv6_packet_len; and you will never have to play with its options/fields.
Whenever you want to build an IPv6 packet, you just write: my_ipv6_packet = thc_create_ipv6_extended(interface, prefer, &my_ipv6_packet_len, src6, dst6, ttl, length, label, class, version); if something fails, it returns NULL (only if my_ipv6_packet_len or dst6 do not exist or malloc fails). The options to thc_create_ipv6_extended are: (char*) interface - the interface on which you want to send out the packet (int) prefer - either PREFER_LINK (to use the link local address) or PREFER_HOST to use a host IPv6 address, and PREFER_GLOBAL to use a public (internet) IP6 address (default) (int ) &my_ipv6_packet_len - the size of the packet which will be created (unsigned char) src6 - the source IP6 (OPTIONAL - will be selected if NULL) (unsigned char*) dst6 - the destination IP6 (in network format, 16 bytes long) usually the result of thc_resolve6("ipv6.google.com"); (int) ttl - the ttl of the packet (OPTIONAL - 0 will set this to 255) (int) length - the length which will be set in the header (OPTIONAL - 0 = real length) (int) label - the flow label (0 is fine) (int) class - the class of the packet (0 is fine) (int) version - the IP6 version (OPTIONAL - 0 will set this to version 6) It returns NULL on errors or a malloc'ed structure on success. free() it once you are done with it.
Now you can set extension headers on top of it: thc_add_hdr_route(my_ipv6_packet, &my_ipv6_packet_len, routers, routerptr); thc_add_hdr_fragment(my_ipv6_packet, &my_ipv6_packet_len, offset, more_frags, id); thc_add_hdr_dst(my_ipv6_packet, &my_ipv6_packet_len, buf, buflen); thc_add_hdr_hopbyhop(my_ipv6_packet, &my_ipv6_packet_len, buf, buflen); thc_add_hdr_nonxt(my_ipv6_packet, &my_ipv6_packet_len, hdropt); thc_add_hdr_misc(my_ipv6_packet, &my_ipv6_packet_len, type, len, buf, buflen); The functions explained: _route: Add a Routing Forwarding Header (like IP Source Routing) (int) routers - the number of routers in routerptr (char**) routerptr - a char[routers + 1] struct with router destinations in network format. See alive6.c for an example. _fragment: Add a Fragment Header (int) offset - the offset on which to the data should be written (note: put the offset location in bytes here, not in byte octets) (int) more_frags - set to 0 if it is the fragement, 1 on all others (int) id - an ID for the packet (same for all fragments) _dst: Add a Destination Options Header (char) buf - a char buffer. you have to control this buffer yourself with but you want to write into it. (int) buflen - the length of buf _hopbyhop: Add a Hop-By-Hop Header (char*) buf - a char buffer. you have to control this buffer yourself with but you want to write into it. (int) buflen - the length of buf _nonxt: Specify that there will be no following headers whatsoever (int) hdropt - this options is currently ignored _misc: Specify a miscelleanous header. Use this if you want to design an invalid or non-existing extension header. (int) type - The type ID to specify the header as (int) len - The length to advertise the header as (OPTIONAL - -1 sets this to the correct value) (char*) buf - a char buffer. you have to control this buffer yourself with but you want to write into it. (int) buflen - the length of buf These functions return (int) 0 on success and -1 on error.
Finally you can add the stream or dgram headers. thc_add_icmp6(my_ipv6_packet, &my_ipv6_packet_len, type, code, flags, buf, buflen, checksum); thc_add_tcp(my_ipv6_packet, &my_ipv6_packet_len, source_port, destination_port, sequence_number, ack_number, flags, window_size urgent_pointer, options, optione_length, data, data_length); thc_add_udp(my_ipv6_packet, &my_ipv6_packet_len, source_port, destination_port, checksum, data, data_length); thc_add_data6(my_ipv6_packet, &my_ipv6_packet_len, type, buf, buflen); _icmp6: Add an ICMP6 packet header (int) type: the ICMP6 type (int) code: the ICMP6 code (int) flags: the ICMP6 flags (char*) buf - a char buffer. you have to control this buffer yourself with but you want to write into it. (int) buflen - the length of buf _tcp|_udp: Add an TCP or UDP header (ushort) source_port: source port (ushort) destination_port: destination port (uint) sequence_number: TCP sequence number (uint) ack_number: TCP acknowledgement number (ushort) checksum: UDP checksum, 0 = generate checksum (for TCP the checksum is always calculated) (uchar) flags: TCP flags: TCP_SYN, TCP_ACK, TCP_FIN, TCP_RST, TCP_PSH, ... (uint) window_size: TCP window size (uint) urgent_pointer: TCP urgent pointer (usually 0) (char*) options: TCP options buffer, can be NULL (uint) options_length: the length of the TCP options buffer (char*) data: the data the protocol carries (uint) data_length: the length of the data buffer _data6: Add a miscellaneous header (int) type: the protocol ID (char*) buf - a char buffer. you have to control this buffer yourself with but you want to write into it. (int) buflen - the length of buf These functions return (int) 0 on success and -1 on error.
Once you are done, you create and send the packet. thc_generate_pkt(interface, srcmac, dstmac, my_ipv6_packet, &my_ipv6_packet_len); thc_send_pkt(interface, my_ipv6_packet, &my_ipv6_packet_len); or combined into one function: thc_generate_and_send_pkt(interface, srcmac, dstmac, my_ipv6_packet, &my_ipv6_packet_len);
thc_generate_and_send_pkt: This generates the real and final IPv6 packet and then sends it. (char*) interface - the interface to send the packet on (unsigned char*) srcmac - the source mac to use (in network format) (OPTIONAL, the real mac is used if NULL) (unsigned char*) dstmac - the destination mac to use (in network format) (OPTIONAL, the real mac is looked up if NULL) The thc_generate_pkt and thc_send_pkt together provide the same functionality. You usually use these only if you do something like thc_generate_pkt(...); while(1) thc_send_pkt(...); These functions return (int) 0 on success and -1 on error.
When you are done, free the memory with: thc_destroy_packet(my_ipv6_packet);
There are some important helper functions you will need: thc_resolve6(destinationstring); This resolves the IPv6 address or DNS name to an IPv6 network address. Use this for dst6 in thc_create_ipv6_extended(). The result has to be free'd when not needed anymore. thc_inverse_packet(my_ipv6_packet, &my_ipv6_packet_len); This clever functions switches source and destination address, exchanges the ICMP header type (ECHO REQUEST -> ECHO REPLY etc.) and recalculates the checksum. If you dont have an idea what this might be useful for, go and play with your xbox :-)
If you just want to do it very fast, there are some predefined ICMPv6 creator functions which sends impc6 packets in just one line of code: thc_ping6(interface, src, dst, size, count); thc_neighboradv6(interface, src, dst, srcmac, dstmac, flags, target); thc_neighborsol6(interface, src, dst, target, srcmac, dstmac); thc_routeradv6(interface, src, dst, srcmac, default_ttl, managed, prefix, prefixlen, mtu, lifetime); thc_routersol6(interface, src, dst, srcmac, dstmac); thc_toobig6(interface, src, srcmac, dstmac, mtu, my_ipv6_packet, my_ipv6_packet_len); thc_paramprob6(interface, src, srcmac, dstmac, code, pointer, my_ipv6_packet, my_ipv6_packet_len); thc_unreach6(interface, src, srcmac, dstmac, icmpcode, my_ipv6_packet, my_ipv6_packet_len); thc_redir6(interface, src, srcmac, dstmac, newrouter, newroutermac, my_ipv6_packet, my_ipv6_pa
No open issues yet, or sync has not completed.