TCP網絡流量回放工具TCPReplay使用說明

[摘要]: 本文總結了tcpreplay的安裝使用經驗. 我是在cygwin上試驗的.
[目錄]:(Created by TxtBrowser)
    1. 什麼是tcpreplay
    2. 安裝指南
    3. 使用指南
    .   3.1 tcpprep(pcap pre-processor)
    .       3.1.1 根據報文源IP確定client/server報文
    .       3.1.2 使用自動模式確定client/server報文
    .   3.2 tcprewrite
    .       3.2.1 tcprewrite的一個例子
    .       3.2.2 修改2層頭
    .       3.2.3 修改3層頭
    .       3.2.4 修改4層頭
    .       3.2.5 修改5-7層數據
    .   3.3 tcpreplay


1. 什麼是tcpreplay

引用一段tcpreplay官方網站(http://tcpreplay.synfin.net/trac/)的話來解釋什麼是
tcpreplay[1]:

#摘自tcpreplay官方網站(http://tcpreplay.synfin.net/trac/):
|Tcpreplay is a suite of BSD licensed tools written by Aaron Turner for UNIX
|(and Win32 under Cygwin) operating systems which gives you the ability to use
|previously captured traffic in libpcap format to test a variety of network
|devices. It allows you to classify traffic as client or server, rewrite Layer
|2, 3 and 4 headers and finally replay the traffic back onto the network and
|through other devices such as switches, routers, firewalls, NIDS and IPS's.
|Tcpreplay supports both single and dual NIC modes for testing both sniffing
|and inline devices. 

簡單的說, tcpreplay是一種pcap包的重放工具, 它可以將用ethreal, wireshark工具抓
下來的包原樣或經過任意修改後重放回去. 它允許你對報文做任意的修改(主要是指對2層
, 3層, 4層報文頭), 指定重放報文的速度等, 這樣tcpreplay就可以用來複現抓包的情景
以定位bug, 以極快的速度重放從而實現壓力測試.

tcpreplay本身包含了幾個輔助工具, 用於準備發包的cache, 重寫報文等:

    * tcpprep - 簡單的說就是劃分哪些包是client的, 哪些是server的, 一會發包的
    時候client的包從一個網卡發, server的包可能從另一個網卡發.
    * tcprewrite - 簡單的說就是修改2層, 3層, 4層報文頭部. 
    * tcpreplay - 真正發包, 可以選擇主、從網卡, 發包速度等.
    * tcpbridge - bridge two network segments with the power of tcprewrite 

2. 安裝指南

tcpreplay官方提供的下載地址爲: http://tcpreplay.synfin.net/trac/wiki/Download,
由於tcpreplay依賴libpcap庫,
所以安裝tcpreplay之前必須先安裝libpcap(在windows下爲winpcap), 否則
./configure的時候你會得到提示說libpcap庫沒有安裝.

linux下的依賴庫libpcap由tcpdump工程組開發, 好像也是個開源工程, 可以到
http://www.tcpdump.org/下載到, 可以用源碼安裝, 貌似比較簡單. 

windows(包括cygwin) 下的依賴庫winpcap則必須到 winpcap的官方網站上去下載:
http://www.winpcap.org/install/default.htm. winpcap是libpcap在windows上的移植,
這個貌似不是開源的, 所以你只能得到一個靜態庫和編程接口"WpdPack_4_1_2.zip",
解壓縮後可以得到文件夾"WpdPack", 將該文件夾拷貝到cygwin的根目錄,
即可完成winpcap的安裝, 在 "./configure"
的時候選上參數--with-libpcap=/wpdpack(我自己試驗過,
貌似沒有這個參數也可以成功, 不過還是建議加上這個參數)[2]:

#winpcap的安裝過程:
|$ unzip WpdPack_4_1_2.zip
|$ cp -r WpdPack/ / (安裝tcpreplay的依賴winpcap, 即把WpdPack拷貝到根目錄下.)

#tcpreplay的安裝過程:
|$ ./autogen.sh (Subversion checkouts only) 
|$ ./configure --with-libpcap=/wpdpack
|$ make 
|# make test (Note: tcprewrite tests are currently broken on Cygwin/Win32) 
|# make install 


3. 使用指南

到此爲止, 你機器上的tcpreplay已經可以使用了, 具體怎麼用, 網上的攻略也很多, 但
最權威的使用指南當然是官網的Online Manual:
http://tcpreplay.synfin.net/trac/wiki/manual, 前面簡單地介紹了tcpreplay內嵌的
幾個工具的用途, 下面給出一個我用過的一個例子, 僅供更好的理解Online Manual:

以前的版本貌似可以用一個命令把pcap包直接經過修改發出去, 但是3.0以後的
tcpreplay不支持這樣了, 發包前先得用tcpgrep建立一個cache, 再用tcprewite修改包的
信息, 最後用tcpreplay發出去:

建立cache文件的作用解釋,主要是加速報文的發送,cache文件中存放着pcap文件中每個
幀的編號和時間戳等信息,以達到tcpreplay回放時可以更加快速的發送報文的目的。

3.1 tcpprep(pcap pre-processor)

tcpprep工具會生成一個cache文件, 裏面保存着哪些包將從主網口發出去, 哪些包將從從
網口發出去. 舉個例子, 如果你用wireshark抓了一個pcap文件, 裏面可能既有A地址發給
B地址的包, 也有B地址發給A址的包, 用tcpprep工具可以指定從A到B的包從主網卡發出, 
從B到A的包從次網卡發出.

3.1.1 根據報文源IP確定client/server報文

#tcpprep的用法舉例, 根據源IP:
|$ tcpprep -c 172.22.64.2/24 -i mgcp.pcap -o mgcp.cach

上面的命令指定所有源IP爲172.22.64.2/24的包, 都將從主網卡發出, 其它的從次網卡發
出. 輸入文件是mgcp.pcap, 輸出文件爲mgcp.cach.

3.1.2 使用自動模式確定client/server報文

#tcpprep的用法舉例, 自動模式:
|$ tcpprep -a client -i mgcp.pcap -o mgcp.cach

上面的命令採用自動/client模式指定分包模式. 自動模式這裏按我的理解解釋一下:
tcpprep在自動模式下認爲有下面行爲的IP爲client端: 1.發TCP SYN包的一方, 2.發DNS 
包的一方, 3. 收入到 ICMP-Port Unreachable的一方. 認爲有下面行爲的一方爲server 
端: 1.發TCP Syn/Ack的一方, 2.發DNS應答的一方, 3.發ICMP-Port Unreachable的一方.
而被認定爲server的那一方發的那些包, 將從主網卡發出, 被認定爲client的包則從次網
卡發出. 而自動/client模式將所有沒有認出的包都歸爲client, 同理自動/server模式將
沒有認出的包都歸爲server.這種模式貌似不如按IP地址分類的方式好用.

tcpprep還有很多其它指定發送方向的方式, 詳情請閱Online Manual或man手冊.

3.2 tcprewrite

簡單地說, tcprewrite就是改寫pcap包裏的報文頭部, 包括2層, 3層, 4層, 5-7層. 從3.0
版本以後, 所有改寫pcap報文頭的操作都從tcpreplay中移到了tcprewrite裏了.

使用tcprewrite對packet進行修改可以有兩個方法, 一種方法是一次修改一項, 生成一個
文件, 再拿這個文件作爲輸入文件..., 直到完成最後的修改, 如:

tcprewrite --option1=xxx -c input.cach -i input.pcap -o 1.pcap
tcprewrite --option2=xxx -c input.cach -i 1.pcap -o 2.pcap
...
tcprewrite --optionN=xxx -c input.cach -i N-1.pcap -o N.pcap

還有一種方法是一古腦的把所有的選項放到一個命令裏完成, 如:

tcprewrite --option1=xxx --option2=xxx ... --optionN=xxx -i input.pcap -c input.cach -o out.pcap

兩種方法都是可行的, 也各有利弊. 第一方法明瞭, 但是複雜, 第二種方法簡單但不容易
理解. 我的建議是先用第一種方法做試驗, 容易調試, 等修改成功了以後再把所有的選項
合到一起, 在實際使用的時候用第二種方法. 下面我先給出一個例子, 然後再逐個分析一
下用tcprewrite是如何修改二層, 三層, 四層, 5-7層頭的, 以便理解tcprewrite的工作原
理.

3.2.1 tcprewrite的一個例子

tcpreplay只保證能把包送出去, 至於包真正能到達的地址, 我認爲還是根據原來的包的
IP和mac. 如果是在同一網段, 可能需要把mac地址改成測試設備的mac, 如果需要經過網
關, 就得將IP地址改爲測試設備的IP以及端口號.

tcprewrite的基本格式是(請注意命令中是沒有換行符的, 只爲了閱讀的方便添加了換行
符): 詳請可以用tcprewrite ?命令查詢詳情.

#tcprewrite的格式:
|$ tcprewrite --enet-smac=host_src_mac,client_src_mac   \
|              --enet-dmac=host_dst_mac, client_dst_mac \
|              --endpoints=host_dst_ip:client_dst_ip    \
|              --portmap=old_port1:new_port1,old_port2, new_port2 \
|              -i input.pcap -c input.cach -o out.pcap

解釋一下, 該命令的輸入參數是input.pcap和input.cach文件, 結果將另存爲out.pcap文
件. 該命令將所有input.pcap包裏的主機包(由input.cach文件指定哪些包是主機包, 哪些
包是客戶端包)的源mac地址, 目的mac地址, 目的IP地址分別改爲 :host_src_mac,
host_dst_mac和host_dst_ip, 客戶端包源mac地址, 目的mac地址, 目的IP地址分別改爲
:client_src_mac, client_dst_mac和client_dst_ip, 將端口號由old_port1改爲
new_port1, 將端口號由old_port2改爲new_port2.

#tcprewrite的用法舉例:
|$ tcprewrite --enet-smac=11:22:22:22:22:22,22:22:22:22:22:22   \
|             --enet-dmac=11:11: 11:11:11:11,22:11:11:11:11:11  \
|             --endpoints=192.168.0.1:192.168.0.11              \
|             --portmap=5070:5061,9060:5060                     \
|             -i success.pcap -o out.pcap -c success.cach

該命令將修改後的包, 主機包的二層, 三層, 四層頭分別爲: 11:22:22:22:22:22,
192.168.0.1, 5061, 客戶端包的二層, 三層, 四層頭分別爲: 22:22:22:22:22:22,
192.168.0.11, 5060.

3.2.2 修改2層頭

1) 修改MAC地址

如果不指定cache文件, 將把所有包的源mac地址和目的mac地址都改寫成
00:44:66:FC:29:AF和00:55:22:AF:C6:37:

    $ tcprewrite --enet-dmac=00:55:22:AF:C6:37 --enet-smac=00:44:66:FC:29:AF --infile=input.pcap --outfile=output.pcap

指定cache文件後, 將server包的目的/源mac地址改寫成
00:44:66:FC:29:AF/00:66:AA:D1:32:C2, 將client的目的/源mac地址改成:
00:55:22:AF:C6:37/00:22:55:AC:DE:AC, 注意是server地址在前.

    $ tcprewrite --enet-dmac=00:44:66:FC:29:AF,00:55:22:AF:C6:37 --enet-smac=00:66:AA:D1:32:C2,00:22:55:AC:DE:AC --cachefile=input.cache --infile=input.pcap --outfile=output.pcap

2) 修改802.1q VLAN

經常客戶的抓包帶有VLAN頭域, 這些包如果不去掉VLAN頭是沒有辦法在自己的交換機上
replay的, tcprewrite提了去掉或添加VLAN的方法:

去掉vlan很簡單:

    $ tcprewrite --enet-vlan=del --infile=input.pcap --outfile=output.pcap

添加vlan也很簡單, 下面的命令將VLAN tag設成40, CFI設成1, VLAN priority設成4. 

    $ tcprewrite --enet-vlan=add --enet-vlan-tag=40 --enet-vlan-cfi=1 --enet-vlan-pri=4 --infile=input.pcap --outfile=output.pcap

3) 修改二層協議名:

好像是將Ethernet協議頭轉成Cisco HDLC或其它二層協議? 這部分沒有真正用過, 需要的
人自行參考[2].

3.2.3 修改3層頭

從版本3.4.2開始, tcprewrite開始支持ipv6協議(我寫這篇文章的時候版本號還是3.4.1呢
, tcpreplay升級蠻快哦^)^). tcprewrite修改IP地址後會自動幫你計算校驗和, 這點還是
蠻周到的^)^, 命令行傳入IPv6地址的時候要使用方括號, 例如: [2001::dead:beef]或
[2001::/16]

1) 修改目的IP

根據cache文件裏的標識, 將server的IP改爲10.10.1.1, client的IP改爲10.10.1.2:

$ tcprewrite --endpoints=10.10.1.1:10.10.1.2 --cachefile=input.cache --infile=input.pcap --outfile=output.pcap --skipbroadcast 

2) 修改IP地址的網絡部分

注: 2)和3)沒有驗證過

衆所周知, IP地址同網絡部分和主機部分組成, 下面的命令可以將子網地址爲10.0.0.0/8
或192.168.0.0/16的IP改成子網爲172.16.0.0/12:

    $ tcprewrite --pnat=10.0.0.0/8:172.16.0.0/12,192.168.0.0/16:172.16.0.0/12 --infile=input.pcap --outfile=output.pcap --skipbroadcast

下面的命令是基於client包或server包修改子網地址:

    $ tcprewrite --pnat=10.0.0.0/8:192.168.0.0/24 --pnat=10.0.0.0/8:192.168.1.0/24 --cachefile=input.cache --infile=input.pcap --outfile=output.pcap --skipbroadcast

3) 修改IP頭的其它部分:

修改IPv4頭的TOS爲50

    $ tcprewrite --tos=50 --infile=input.pcap --outfile=output.pcap

將IPv6頭Traffic Class值改爲33

    $ tcprewrite --tclass=33 --infile=input.pcap --outfile=output.pcap


修改Flow Label field:

    $ tcprewrite --flowlabel=67234 --infile=input.pcap --outfile=output.pcap

3.2.4 修改4層頭

和修改IP頭一樣, 修改4層頭的時候tcpwrite會自動計算校驗和, 這個就不需要擔心了.

1) 修改端口號

將80端口號改爲8080, 22改爲8022:

    $ tcprewrite --portmap=80:8080,22:8022 --infile=input.pcap --outfile=output.pcap

2) 強制計算傳輸層校驗和:

有些應用可能不計算傳輸層的校驗和, 可以讓tcpwrite強制計算一下:

    $ tcprewrite --fixcsum --infile=input.pcap --outfile=output.pcap

3.2.5 修改5-7層數據

tcpwrite對5-7層的修改非常有限, 頂多也就是抓包沒有抓全, 中間的應用層數據丟了.
tcpwrite將沒有抓到的數據補成全0, 或者修改tcp/udp的長度字節, 或者將該包丟棄. 有
需要的直接參考官方資料吧.[2]

3.3 tcpreplay

在linux下, 用ifconfig命令可以獲得接口的名字, 但在cygwin下必須用下面的命令獲得
接口的名字:

#在cygwin下獲得接口的名字:
|$ tcpreplay --listnics

#結果可能如下所示:
|$ tcpreplay --listnics
|Available network interfaces:
|Alias   Name    Description
|%0      \Device\NPF_GenericDialupAdapter
|        Adapter for generic dialup and VPN capture
|%1      \Device\NPF_{6B508B29-B3E3-4D0B-892F-02914AC9A668}
|    Intel(R) 82566DM Gigabit Network Connection (Microsoft's Packet
|    Scheduler) 
|%2      \Device\NPF_{CBCE38CA-1FAD-4AEB-89DF-FD2D8EF861FA}
|    D-Link DFE-530TX PCI Fast Ethernet Adapter (rev.C)
|    (Microsoft's Packet Scheduler) 
|%3      \Device\NPF_{ABB813FE-3C51-49A3-8146-16CD2C4507C3}
|    D-Link DFE-530TX PCI Fast Ethernet Adapter (rev.C)
|    (Microsoft's Packet Scheduler) 

從中可以看出這臺機器有兩塊網卡, 一塊叫做%1, 另一塊叫做%2. 下面就可以指定網卡
重發包了:

#用tcpreplay發包:
|$ tcpreplay -c mgcp.cach -i %1 -I %2 out.pcap

這條命令是把out.pcap包, 按照mgcp.cach裏劃分的主機包和客戶端包的方式, 將主機包
從網卡%1發出去, 將客戶端包從網卡%2發出去.

[參考資料]

[1] tcpreplay官方網站: http://tcpreplay.synfin.net/trac/
[2] tcpreplay官方網站: http://tcpreplay.synfin.net/wiki/manual
[3] winpcap官方網站: http://www.winpcap.org
[4]巧用Tcpreplay讓攻擊流量瞞天過海,
http://news.newhua.com/news1/safe_product/2007/1116/0711169442155I34A78I25B09B5752K.html
發佈了69 篇原創文章 · 獲贊 56 · 訪問量 44萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章