close

1 、Sniff軟體即是網路竊聽器, 由於乙太網路是以廣播的方式來傳輸同一網路區段的資料,因此當網路

     連接方式是使用HUB而非Switch或Route,則只須將網路卡設定為混雜模式(promisscuous)來接

     收所有輸送至網路卡的資料並進行資料封包的分析即可。

2、C#使用Windows API時必須先使用DllImport來Include Library,主要使用下列14個網路相關的API:

      2-01、int WSAStartup(ushort wVersionrequested,ref WSDATA lpWSAData)

         一  使用Windows Socket必須成功的調用此函式,才可以完成其他一系列的初始化。

      2-02、int sock(int af,int type,int protocol) 一 建立一個具體傳輸服務的Socket。

      2-03、int WSAGetLastError() 一 擷取使用Windows Socket函式失敗時的錯誤訊息。

      2-04、uint GetIpAddrTable(IntPtr pIpAddrTable,ref int pdwSize,bool bOrder)

          一 取得目前主機有多少介面有IPv4 Address。

      2-05、ushort ntohs(ushort netshort) 一 將TCP/IP的網路格式轉換成Inter Processors格式

      2-06、ushort htons(ushort hostshort) 一 將Inter Processors格式轉換成TCP/IP的網路格式

                PS:big-endian - TCP/IP的網路格式   little-endian - Inter Processor格式

                     Ex.  0x1000 (big-endian) = 0x0010 (little-endian)  = 4 (Decimal)  

      2-07、uint inet_addr(Intptr cp) 一 將帶有dot的字串IP轉換成網路格式(big-endian)的uint。     

      2-08、string inet_ntoa(uint sin_addr) 一  將網路格式(big-endian)的ushort轉換成帶有dot的字串IP。

      2-09、int setsockopt(int s,int level,int optname,IntPtr optval,int optlen)

          一  設定Socket 相關選項的函式。

               Ex. send/receive timeout or 設定IP_HDRINCL 由應用程式產生IP Header。

      2-10、int bind(int s,ref SOCKADDR_IN name,int namelen) 一

      2-11、int WSAIoctl( int s,

                                  uint dwIoControlCode,

                                  IntPtr lpvInBuffer,

                                  uint cbInBuffer,

                                  IntPtr lpvOutBuffer,

                                  uint cbOutBuffer,

                                  IntPtr lpOverlapped,

                                  IntPtr lpCompletionRoutine                

                                );

         一  設定Socket 模式的函式,對於一般網路卡提供四種不同的模式:

              1. 廣播模式(broadcast):接收網路中的廣播資訊。

              2. 組播模式(multicast):接收網路中的組播資訊。

              3. 直接模式(unicast):只接收目的位址符合網路卡位址的資訊。

              4. 混雜模式(promiscuous):接收所有經過網路卡的所有資訊。

                                                (實現Sniff功能必須將Socket設為該模式)

      2-12、int recv(int s,IntPtr buf,int len,int flags) 一 接收連接的Socket或Bound未連接的Socket。

      2-13、int closesocket(int s) 一 關閉指定的Socket。

      2-14、int WSACleanup() 一 終止使用Windows Socket 2 DLL (to close WSAStartup)

3、實作Sniff功能時,在成功的調用WAStartup函式之後;由於必須讀取各種的網路封包資訊,因此必須使用

    SOCK_RAW即原始的SOCKET並設定協為PROTOCOL_IP,讓應用程式自已來對封包進行檢查及分析。

    設定方式如下:

    Ex.   openSocket = socket(AF_INET,SOCK_RAW,PROTOCOL_IP)

           AF_INET:設定使用IPv4(Inter Protocol Version 4)    PS. IPv6是使用AF_INET6

           SOCK_RAW:接收/傳送包含IP Header 和 UDP/TCP/ICMP Header

           PROTOCOL_IP:設定接收 IP 封包的傳送協定。

     PS. 由於使用SOCK_RAW程式必須有管理人權限,因此可以執行下列的步驟。

           系統將會自動詢問(Vista) 是否以管理人權限來執行。

           1. 在專案目錄下建立manifest File內容如下。

               Ex. .../PingTrace/PringTrace/PingTrace.manifest    

                <?xml version="1.0" encoding="utf-8" ?>
                <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
                <assemblyIdentity
                                      version="1.0.0.0"
                                      processorArchitecture="X86"
                                      name="someExecName"
                                      type="win32"  />
                 <description>Your Program Description</description>
                 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
                 <security>
                 <requestedPrivileges>
                          <requestedExecutionLevel level="requireAdministrator" /> <==主要在這一行
                  </requestedPrivileges>
                  </security>
                  </trustInfo>
                  </assembly>

             2. Project -> Properties

          manifest.jpg  

4、另外還必須使用WSAIoctl函式來設定Socekt模式為混雜模式(promiscuous)來接收所有同一網路區段的

    封包。設定方式如下:

    Ex.
        4.1 IntPtr dwBufferInLen = Marshal.AllocHGlobal(sizeof(int));

             Marshal.WriteInt32(dwBufferInLen, RCVALL_ON);          

             int retMessage = WSAIoctl(

                                              openSocket,

                                              WSAIO("w",IOC.IOC_VENDOR, 1),  //SIO_RCVALL

                                              dwBufferInLen,   // Set parameter value of SIO_RCVALL

                                              sizeof(int),    // The data length of the parameter value

                                              IntPtr.Zero                

                                              0,

                                              ref dwBytesReturned,

                                              IntPtr.Zero,

                                              IntPtr.Zero

                                     );        

             Marshal.FreeHGlobal(dwBufferInLen); 

        4.2 WSAIO函式是我模擬winsock2.h內 1.WSAIO 2.WSAIOR 3. WSAIOW 4.WSAIORW

              四個巨集的函式,主要用來產生socket的控制碼。

5、當電腦有兩張網路卡擁有IP位址時,則可先用GetIpAddrTable函式來取得目前擁有IP位址的網

     路卡,再依需求對特定的網路卡使用bind函式。

6、當使用recv函式接收到網路封包後則依到下列步驟進行解析。

     6.1、判斷接收到的網路封包長度是否小於IP Header的長度。

     6.2、分析IP Header取得下一層的協定類型和整個封包長度

     6.3、判斷接收封包長度與IP Header內的封包長度是否相等。

        6.3.1、 當接收封包長度小於IP Header內的封包長度則表示資料沒有接收完整必須再執行

                  recv函式並累加接收封包長度,直到等於IP Header內的封包長度。

        6.3.2、當接收封包長度大於IP Header內的封包長度則表示資料內有兩筆以上的不同封包,因此

                  必須依序以IP Header內的封包長度將接收到的封包進行分解成個獨立的封包。

        6.3.3、當接收封包長度等於IP Header內的封包長度則表示完整接收封包資料。

    6.4、依照IP Header內的協定內容將封包以ICMP、UDP or TCP Header來取得封包的資訊。

Download:    Sniff (Source Code)      Sniff(EXE)

Result:

          sniff.jpg 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 yunjuihuang 的頭像
    yunjuihuang

    瑞の資訊備忘錄

    yunjuihuang 發表在 痞客邦 留言(0) 人氣()