1. 使用指南
具體怎麼用, 網上的攻略也很多, 但最權威的使用指南當然是官網的Online Manual:
http://tcpreplay.synfin.net/trac/wiki/manual, 前面簡單地介紹了tcpreplay內嵌的
幾個工具的用途, 下面給出一個我用過的一個例子, 僅供更好的理解Online Manual:
以前的版本貌似可以用一個命令把pcap包直接經過修改發出去, 但是3.0以後的
tcpreplay不支持這樣了, 發包前先得用tcpgrep建立一個cache, 再用tcprewite修改包的
信息, 最後用tcpreplay發出去:
建立cache文件的作用解釋,主要是加速報文的發送,cache文件中存放着pcap文件中每個
幀的編號和時間戳等信息,以達到tcpreplay回放時可以更加快速的發送報文的目的。
1.1 tcpprep(pcap pre-processor)
tcpprep工具會生成一個cache文件, 裏面保存着哪些包將從主網口發出去, 哪些包將從從
網口發出去. 舉個例子, 如果你用wireshark抓了一個pcap文件, 裏面可能既有A地址發給
B地址的包, 也有B地址發給A址的包, 用tcpprep工具可以指定從A到B的包從主網卡發出,
從B到A的包從次網卡發出.
1.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.
1.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手冊.
1.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的工作原
理.
1.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.
1.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].
1.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
1.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
1.2.5 修改5-7層數據
tcpwrite對5-7層的修改非常有限, 頂多也就是抓包沒有抓全, 中間的應用層數據丟了.
tcpwrite將沒有抓到的數據補成全0, 或者修改tcp/udp的長度字節, 或者將該包丟棄. 有
需要的直接參考官方資料吧.[2]
1.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發出去.