/* * UDP Toolkit * * Simple utility for crafting UDP traffic of your choosing. * Allows full control over virtually every parameter you can think * of and makes spoofing traffic or poking holes in your favorite firewall * or other pieces of networking equipment a piece of cake. * * Requires: * libnet >= 1.1.x (http://www.packetfactory.net/projects/libnet/) * root * a basic understanding what this tool does * * Compile with something like: * gcc -Wall `libnet-config --defines --cflags` -o udp-tk udp-tk.c `libnet-config --libs` * * This code can be found in its original form here: * * http://spoofed.org/files/udp-tk.c * * * Jon Hart * * Copyright (c) 2002, Jon Hart * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the organization nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Changes: * 10/30/2002 * Fixed the TTL so that it is not obviously spoofed. * Use random number between 1024 and 65535 for src/dst if no port provided * * */ #include #if (SOLARIS || BSD) #include #else #include #endif #define OPT_HELP 0 #define OPT_VERBOSE 1 #define OPT_INTERFACE 2 #define OPT_SRCIP 3 #define OPT_DSTIP 4 #define OPT_SRCETHER 5 #define OPT_DSTETHER 6 #define OPT_SRCPORTS 7 #define OPT_DSTPORTS 8 #define OPT_PAYLOAD 9 #define OPT_IPID 10 #define OPT_IPTOS 11 #define OPT_IPTTL 12 struct opt { char *name; /* name of this option */ int req; /* required? */ int set; /* Does it have a value? */ }; struct opt opts[] = { {"help", 0, 0}, {"verbose", 0, 0}, {"interface", 1, 0}, {"source IP", 1, 0}, {"destination IP", 1, 0}, {"source ethernet address", 0, 0}, {"destination ethernet address", 0, 0}, {"source port(s)", 1, 0}, {"destination port(s)", 1, 0}, {"payload", 1, 0}, {"IP ID number", 1, 0}, {"TOS", 1, 0}, {"TTL", 1, 0} }; void usage() { fprintf(stderr, "\tudp-tk\n\tA simple UDP Toolkit\n\tby Jon Hart \n"); fprintf(stderr, "\thttp://spoofed.org/files/udp-tk.c\n"); fprintf(stderr, "\nUsage:\n"); fprintf(stderr, "\tRequired:\n"); fprintf(stderr, "\t-i Specify interface\n"); fprintf(stderr, "\t-d Destination IP\n"); fprintf(stderr, "\n\tOptional:\n\n"); fprintf(stderr, "\tLink Layer:\n"); fprintf(stderr, "\t-e Source ethernet address (default: auto)\n"); fprintf(stderr, "\t-E Destination ethernet address (default: auto)\n"); fprintf(stderr, "\tIP Layer:\n"); fprintf(stderr, "\t-I IP ID number (default: sane)\n"); fprintf(stderr, "\t-s Source IP (default: auto)\n"); fprintf(stderr, "\t-t IP TTL (default: sane)\n"); fprintf(stderr, "\t-T IP TOS (default: 0)\n"); fprintf(stderr, "\tUDP Layer:\n"); fprintf(stderr, "\t-c Packet payload (default: NULL)\n"); fprintf(stderr, "\t-p Source ports (default: random)\n"); fprintf(stderr, "\t-P Destination ports (default: random)\n"); fprintf(stderr, "\tOther:\n"); fprintf(stderr, "\t-h Help (this message)\n"); fprintf(stderr, "\t-v Be verbose\n"); } int main(int argc, char *argv[]) { int c; libnet_t *libnet; libnet_ptag_t udp, ipv4, ether; u_long src_ip, dst_ip; u_short src_port, dst_port; u_char ip_ttl, ip_tos; u_short ip_id; /* The source and destination MAC addresses * for the ethernet level */ struct libnet_ether_addr *src_ether; struct libnet_ether_addr *dst_ether; char *interface; struct ether_addr *ether_t; struct servent *servent; u_char *udp_payload; u_long udp_payload_l; char errbuf[LIBNET_ERRBUF_SIZE]; while ((c = getopt(argc, argv, "i:c:e:p:s:E:P:d:i:u:I:t:T:vh")) != EOF) { switch (c) { case 'h': usage(); exit(EXIT_SUCCESS); case 'v': opts[OPT_VERBOSE].set = 1; break; case 'i': interface = optarg; opts[OPT_INTERFACE].set = 1; break; case 'e': if ((ether_t = ether_aton(optarg)) == NULL) { printf("Invalid source ethernet address: %s\n", optarg); return(EXIT_FAILURE); } if ((src_ether = malloc(sizeof(struct libnet_ether_addr))) == NULL) { printf("Couldn't malloc() for src_ether\n"); return(EXIT_FAILURE); } memcpy(src_ether->ether_addr_octet, ether_t, sizeof(struct ether_addr)); opts[OPT_SRCETHER].set = 1; break; case 'E': if ((ether_t = ether_aton(optarg)) == NULL) { printf("Invalid ethernet address: %s\n", optarg); return(EXIT_FAILURE); } if ((dst_ether = malloc(sizeof(struct libnet_ether_addr))) == NULL) { printf("Couldn't malloc() for dst_ether\n"); return(EXIT_FAILURE); } memcpy(dst_ether->ether_addr_octet, ether_t, sizeof(struct ether_addr)); opts[OPT_DSTETHER].set = 1; break; case 'p': src_port = atoi(optarg); opts[OPT_SRCPORTS].set = 1; break; case 'P': dst_port = atoi(optarg); opts[OPT_DSTPORTS].set = 1; break; case 's': src_ip = libnet_name2addr4(libnet, optarg, LIBNET_RESOLVE); opts[OPT_SRCIP].set = 1; break; case 'd': dst_ip = libnet_name2addr4(libnet, optarg, LIBNET_RESOLVE); opts[OPT_DSTIP].set = 1; break; case 't': ip_ttl = atoi(optarg); opts[OPT_IPTTL].set = 1; break; case 'T': ip_tos = atoi(optarg); opts[OPT_IPTOS].set = 1; break; case 'c': udp_payload = optarg; udp_payload_l = strlen(udp_payload); opts[OPT_PAYLOAD].set = 1; break; case 'I': ip_id = atoi(optarg); opts[OPT_IPID].set = 1; break; default: usage(); goto pass; } } /* Ensure that an interface is specified or have libnet guess */ if (!opts[OPT_INTERFACE].set) { usage(); goto fail; } /* Depending on whether or not they choose to pick their own MACs, * libnet needs to be initialized differently for some reason */ if (opts[OPT_SRCETHER].set || opts[OPT_DSTETHER].set) { if ((libnet = libnet_init(LIBNET_LINK, interface, errbuf)) == NULL) { fprintf(stderr, "libnet_init() failed: %s", errbuf); goto fail; } } else { if ((libnet = libnet_init(LIBNET_RAW4, interface, errbuf)) == NULL) { fprintf(stderr, "libnet_init() failed: %s", errbuf); goto fail; } } libnet_seed_prand(libnet); /* If they didn't set a source ethernet address, figure out */ if (!opts[OPT_SRCETHER].set) { if ((src_ether = libnet_get_hwaddr(libnet)) == NULL) { fprintf(stderr, "libnet_get_hwaddr() failed: %s", errbuf); libnet_destroy(libnet); goto fail; } } /* If they didn't set a destination ethernet address, figure out */ if (!opts[OPT_DSTETHER].set) { if ((dst_ether = libnet_get_hwaddr(libnet)) == NULL) { fprintf(stderr, "libnet_get_hwaddr() failed: %s", errbuf); libnet_destroy(libnet); goto fail; } } /* If they didn't set a source IP, have libnet figure it out */ if (!opts[OPT_SRCIP].set) { src_ip = libnet_get_ipaddr4(libnet); opts[OPT_SRCIP].set = 1; } /* If no source port is given, make one up */ if (!opts[OPT_SRCPORTS].set) { src_port = 1024 + (libnet_get_prand(LIBNET_PRu16) % (65535 - 1024)); opts[OPT_SRCPORTS].set = 1; } /* If no destination port is given, make one up */ if (!opts[OPT_DSTPORTS].set) { dst_port = 1024 + (libnet_get_prand(LIBNET_PRu16) % (65535 - 1024)); opts[OPT_DSTPORTS].set = 1; } /* If no IP id is set, pick a random one */ if (!opts[OPT_IPID].set) { ip_id = libnet_get_prand(LIBNET_PRu16); opts[OPT_IPID].set = 1; } /* If no IP TOS is set, pick 0 */ if (!opts[OPT_IPTOS].set) { ip_tos = 0; opts[OPT_IPTOS].set = 1; } /* No payload? Then NULL */ if (!opts[OPT_PAYLOAD].set) { udp_payload = NULL; udp_payload_l = 0; opts[OPT_PAYLOAD].set = 1; } /* If no TTL is set, default to something sly. */ if (!opts[OPT_IPTTL].set) { /* 255 is too high, others are too low. I'll take the midground! */ ip_ttl = 200 + (libnet_get_prand(LIBNET_PR8) % 55); opts[OPT_IPTTL].set = 1; } udp = libnet_build_udp( src_port, dst_port, LIBNET_UDP_H + udp_payload_l, 0, udp_payload, udp_payload_l, libnet, 0); if (udp == -1) { fprintf(stderr, "Can't build udp: %s\n", libnet_geterror(libnet)); libnet_destroy(libnet); goto fail; } ipv4 = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_UDP_H + udp_payload_l, ip_tos, ip_id, IP_DF, ip_ttl, IPPROTO_UDP, 0, src_ip, dst_ip, NULL, 0, libnet, 0); if (ipv4 == -1) { fprintf(stderr, "Can't build ipv4: %s\n", libnet_geterror(libnet)); libnet_destroy(libnet); goto fail; } /* If they wish to set their own src/dst ethernet addresses * we need to actually build the ethernet. If they don't, * libnet does it automagically for us. */ if (opts[OPT_SRCETHER].set || opts[OPT_DSTETHER].set) { ether = libnet_build_ethernet( dst_ether->ether_addr_octet, src_ether->ether_addr_octet, ETHERTYPE_IP, NULL, 0, libnet, 0); if (ether == -1) { fprintf(stderr, "Can't build ethernet: %s\n", libnet_geterror(libnet)); libnet_destroy(libnet); goto fail; } } if ((c = libnet_write(libnet)) == -1) { fprintf(stderr, "Couldn't write packet to the wire: %s\n", libnet_geterror(libnet)); } else { if (opts[OPT_VERBOSE].set) { if (opts[OPT_SRCETHER].set || opts[OPT_DSTETHER].set) { printf("Link Layer: "); printf("%s -> ", opts[OPT_SRCETHER].set ? ether_ntoa((struct ether_addr *) src_ether->ether_addr_octet) : interface); printf("%s\n", opts[OPT_DSTETHER].set ? ether_ntoa((struct ether_addr *) dst_ether->ether_addr_octet) : "(auto)"); } printf(" IP Layer: %s -> %s\n", libnet_addr2name4(src_ip, LIBNET_DONT_RESOLVE), libnet_addr2name4(dst_ip, LIBNET_DONT_RESOLVE)); printf(" IP Layer: TTL: %d TOS: 0x%X ID: %d\n", ip_ttl, ip_tos, ip_id); printf(" UDP Layer: SrcPort: %d (%s) ", src_port, (servent = getservbyport(htons(src_port), "udp")) != NULL ? servent->s_name : "unknown"); printf("DstPort: %d (%s)\n", dst_port, (servent = getservbyport(htons(dst_port), "udp")) != NULL ? servent->s_name : "unknown"); printf(" App Layer: %ld byte payload\n", udp_payload_l); } } libnet_destroy(libnet); goto pass; fail: if (opts[OPT_SRCETHER].set) { free(src_ether); } if (opts[OPT_DSTETHER].set) { free(dst_ether); } return(EXIT_FAILURE); pass: if (opts[OPT_SRCETHER].set) { free(src_ether); } if (opts[OPT_DSTETHER].set) { free(dst_ether); } return(EXIT_SUCCESS); }