前言

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

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

Wireshark 與 Tshark 切流的方案

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

用來組流的網絡數據包嗅探器:Streamdump

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

>tshark -r $LINE -T fields -e tcp.stream|sort -n | uniq -c | awk -F ' ' '{if ($2>=0)print $2 }' >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 流保存下來,如圖:

用來組流的網絡數據包嗅探器:Streamdump

從 pcap 文件中過濾出單個 TCP 流量:

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

用來組流的網絡數據包嗅探器:Streamdump

用來組流的網絡數據包嗅探器:Streamdump

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

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

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

開源地址

可執行程序下載地址

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

相關文章