科技

用來組流的網路資料包嗅探器:Streamdump

前言

在平時需要對資料包進行分析和統計,亦或是進行抓包時,通常會使用 Wireshark 或者 tcpdump 等工具。這兩個工具以及 tshark(wireshark 的命令列),基本上已經涵蓋了絕大部分的需求場景,但是如果需要大規模地拆分單個流,進行分析、特徵提取時,似乎這些工具都沒有能夠提供很方便的切流解決方案。

更常見的做法是,通過一個比較抽象的過濾規則,將符合該規則的所有資料包通通記錄在一個 pcap 包裡,接著再編寫一個 Python 指令碼或者通過 tshark 與 shell 指令碼來實現切流的操作。這似乎沒有是麼難度,而且也已經解決了問題,應該現成的方案也不少。

Wireshark 與 Tshark 切流的方案

在 Wireshark 中,我們通常是在過濾條件中,輸入tcp.stream == ?,?表示某個流在整個包中的編號,而 Wireshark 會根據該編號的 packet 的四元組找出所有符合條件的流進行組裝。

但是使用這樣需要一個個手動地操作,效率不得不說實在是太低下了,而使用 tshark 來進行切流會快得多,命令:

>tshark -r $LINE -T fields -e tcp.stream|sort -n | uniq -c | awk -F ' ' '{if (>=0)print }' >tcp_stream_number.txt

$LINE 代表 pcap 檔名,-T 和 -e 組合使用表示列印 Wireshark 中相應的欄位,本例中表示輸出 tcp.stream 欄位,即流號。因為是針對每一個報文都要輸出該報文對應的流號,因此需要做排序,去重的工作。將最後的所有的流號按照大小順序輸入到 tcp_stream_number.txt 檔案中。

最後,再將輸入的流提取出來:

tshark -r $LINE -Y "tcp.stream == $(($tcpnumber)) " -w $filedic/$streamname.pcap

$LINE 代表pcap檔名,$tcpnumber 表示從 tcp_stream_number.txt 檔案中讀出的每一行的內容,$(($tcpnumber))轉換成數字,$filedic,$streamname 分別表示檔案目錄和檔名,上述的命令表示從 $LINE 報文中提取流。

如此,就可以進行切流操作了。但是總的來說,雖然 tshark 比起 Wireshark 手動單個操作的方式效率高得多,但是,tshark 是一次性將整個資料包讀入記憶體,分析好後再統一輸出的,針對超大檔案進行分析時,對資源的需求十分巨大。

換句話說,如果你不是有龐大的記憶體資源,使用 tshark 來對大檔案進行切流操作,是很難進行下去的!另外值得注意的是,當流檔案個數過多的時候,由於產生的檔案控制代碼過多,會出現錯誤,沒法繼續進行下去。

更重要的一點,切分單個流,我們通常通過四元組進行確定,這隻能確定單個方向的流,而更多情況下,我們需要對雙向的流進行分析。

StreamDump

所以為了滿足前文說的大規模的單個流的組裝與分析,本次要介紹的是一個我們小組裡一直在使用的一個小工具 —— StreamDump,根據 TCP 流的四元組來將每個 TCP 重新組裝還原,並分別儲存成一個單獨的 pcap 檔案。為了執行效率和編譯方便,程式使用 Golang 來實現。

程式的幾個特點:

支援 BPF 過濾規則,可根據需求來進行自定義過濾

支援捕獲雙向資料流,儲存的檔案根據四元組來進行命名:IP[Port]-IP[Port].pcap,在儲存雙向資料流的情況下,以捕獲到的第一個 packet 中的四元組引數進行命名

不僅支援從網絡卡中實時捕獲流量,還支援從 pcap 檔案中讀取分析,過濾出自己需要的單個的流檔案

功能雖然不多,但是卻可以做很多的事情!特別當需要解析一個 10G 或者 20G pcap 檔案的時候,使用 Python 來解析是效率十分低下的!

分拆出來的 TCP 流有什麼用?如果你需要對某個特定的流,或者某組,或者某個特定應用的流進行分析,我想這個工具對你一定十分有用,會讓你節省很多時間!

廢話少說,下面簡單說說如何使用這個小工具:

編譯

編譯就十分輕鬆了,go 自帶了編譯工具,只需要將包裡的依賴庫取回本地,直接編譯就可以了

>go get github.com/google/gopacket

>go build -o streamdump streamdump.go

用例

Usage: streamdump [-hv] [-i interface]

Options:

-b Capture bidirectional data flow

-d string

The domain name of the packet to be captured

-f string

BPF filter rules for pcap (default "tcp")

-h print this help message and exit

-i string

Interface to get packets from (default "en0")

-l int

SnapLen for pcap packet capture (default 1600)

-promisc

Set promiscuous mode (default true)

-r string

Filename to read from, overrides -i

-s string

Filepath to save pcap files (default "./pcap_s")

-v Logs every packet in great detail

程式會將兩分鐘內沒有資料傳輸的連線視為無效

從預設網絡卡(en0)捕獲 baidu.com 對應 ip 以及 443 埠的 tcp 流量:

命令:./streamdump -f 'tcp and port 443' -s './stream/' -d '[www.baidu.com](http://www.baidu.com)'

程式會主動查詢[www.baidu.com](http://www.baidu.com)這個域名對應的 ip,並根據過濾條件進行過濾,將符合這個過濾條件的 TCP 流儲存下來,如圖:

從 pcap 檔案中過濾出單個 TCP 流量:

命令:./streamdump -r './file.pcap' -f 'tcp' -s './stream/'

還有很多自定義的組合,需要大家自己動手操作了!比如使用-b選項進行雙向資料儲存!

好了,簡要的介紹就到這裡了,希望這個小工具能夠為大家稍稍提升一些效率!

重要地方來了!!!我們已經對程式進行了開源,更詳細的用例在 Github 上已有說明,需要的同學自行閱讀!

開源地址

可執行程式下載地址

*本文作者:scu-igroup,轉載自FreeBuf.COM

Reference:科技日報

看更多!請加入我們的粉絲團

轉載請附文章網址

不可錯過的話題