天天看點

網絡抓包工具

<a href="http://blog.csdn.net/wangxg_7520/article/details/2795229">http://blog.csdn.net/wangxg_7520/article/details/2795229</a>

看了太多的“自己動手”,這次咱也“自己動手”一下,寫個簡單的網絡抓包工具吧。要寫出像tcpdump和wireshark(ethereal)這樣的大牛程式來,咱也沒那能耐,呵呵。是以這個工具隻能抓取本地IP資料報,同時它還使用了BPF,目的是了解如何進行簡單有效的網絡抓包。

當打開一個标準SOCKET套接口時,我們比較熟悉的協定往往是用AF_INET來建立基于TCP(SOCK_STREAM)或UDP(SOCK_DGRAM)的連結。但是這些隻用于IP層以上,要想從更底層抓包,我們需要使用AF_PACKET來建立套接字,它支援SOCK_RAW和SOCK_DGRAM,它們都能從底層抓包,不同的是後者得到的資料不包括以太網幀頭(最開始的14個位元組)。好了,現在我們就知道該怎樣建立SOCKET套接口了:

sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP));

最後一個參數 ETH_P_IP 指出,我們隻對IP包感興趣,而不是ARP,RARP等。之後就可以用recvfrom從套接口讀取資料了。

現在我們可以抓到發往本地的所有IP資料報了,那麼有沒有辦法抓到那些“流經”本地的資料呢?呵呵,當然可以了,這種技術叫網絡嗅探(sniff),它很能威脅網絡安全,也非常有用,尤其是當你對網内其他使用者的隐私感興趣時:(  由于以太網資料包是對整個網段廣播的,是以網内所有使用者都能收到其他使用者發出的資料,隻是預設的,網卡隻接收目的位址是自己或廣播位址的資料,而把不是發往自己的資料包丢棄。但是多數網卡驅動會提供一種混雜模式(promiscous mode),工作在這種模式下的網卡會接收網絡内的所有資料,不管它是發給誰的。下面的方法可以把網卡設成混雜模式:

<code>// set NIC to promiscous mode, so we can recieve all packets of the network</code>

<code>strncpy</code><code>(ethreq.ifr_name,</code><code>"eth0"</code><code>, IFNAMSIZ);</code>

<code>ioctl(sock, SIOCGIFFLAGS, &amp;ethreq);</code>

<code>ethreq.ifr_flags |= IFF_PROMISC;</code>

<code>ioctl(sock, SIOCSIFFLAGS, &amp;ethreq);</code>

  通過ifconfig可以很容易的檢視目前網卡是否工作在混雜模式(PROMISC)。但是請注意,程式退出後,網卡的工作模式不會改變,是以别忘了關閉網卡的混雜模式:

<code>// turn off promiscous mode</code>

<code>ethreq.ifr_flags &amp;= ~IFF_PROMISC;</code>

  現在我們可以抓到本網段的所有IP資料包了,但是問題也來了:那麼多的資料,怎麼處理?CPU可能會被嚴重占用,而且絕大多數的資料我們可能根本就不敢興趣!那怎麼辦呢?用if語句?可能要n多個,而且絲毫不會降低核心的繁忙程度。最好的辦法就是告訴核心,把不感興趣的資料過濾掉,不要往應用層送。BPF就為此而生。

BPF(Berkeley Packet Filter)是一種類是彙編的僞代碼語言,它也有指令代碼和操作數。例如,如果我們隻對使用者192.168.1.4的資料感興趣,可以用tcpdump的-d選項生成BPF代碼如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<code>$tcpdump -d host 192.168.1.4</code>

<code>(000) ldh      [12]</code>

<code>(001) jeq      #0x800           jt 2 jf 6</code>

<code>(002) ld       [26]</code>

<code>(003) jeq      #0xc0a80104      jt 12 jf 4</code>

<code>(004) ld       [30]</code>

<code>(005) jeq      #0xc0a80104      jt 12 jf 13</code>

<code>(006) jeq      #0x806           jt 8 jf 7</code>

<code>(007) jeq      #0x8035          jt 8 jf 13</code>

<code>(008) ld       [28]</code>

<code>(009) jeq      #0xc0a80104      jt 12 jf 10</code>

<code>(010) ld       [38]</code>

繼續閱讀