[目錄]:(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