tcpreplay を使って Raw IP Pcap ファイルに任意の Ethernet Frame を追加する

「とあるインターネットトレースされた Pcap ファイルを再送してインターネットトラフィックを模す」ということをする必要が出たのですが、元の Pcap ファイルはもちろん加工されており、Ethernet Frame と Payload が削除された状態でした。

$ tcpdump -evXnnr sample.pcap
reading from file sample.pcap, link-type RAW (Raw IP)
14:12:02.795288 ip: (tos 0x10, ttl 64, id 11762, offset 0, flags [DF], proto TCP (6), length 1088)
    10.20.22.132.20222 > 10.20.22.15.62585: Flags [P.], seq 3211:4247, ack 3682, win 501, options [nop,nop,TS val 1205061784 ecr 1681210238], length 1036
        0x0000:  4510 0440 2df2 4000 4006 c7fb 0a14 1684  E..@-.@.@.......
        0x0010:  0a14 160f 4efe f479 54ed cb7f 4024 f5da  ....N..yT...@$..
        0x0020:  8018 01f5 44ed 0000 0101 080a 47d3 c898  ....D.......G...
        0x0030:  6435 3b7e 
...

これを tcpreplay で再送すると、Raw IP のまま送信されてしまいます。そこで、以下のことをしたのでその備忘録です。

  • 偽の Ethernet Frame を追加する
  • IPアドレスを任意のものに変更する
  • Header の Length フィールドに従ってパケットの末尾に Padding を追加する

tcpreplay をインストールする

まずは tcpreplay をインストールします。現時点での最新はv4.4.4ですが、このバージョンでは Ethernet Frame 追加の動作が期待通り動かなかったのでv4.3.4を使います。

$ wget https://github.com/appneta/tcpreplay/releases/download/v4.3.4/tcpreplay-4.3.4.tar.gz
$ tar xzvf tcpreplay-4.3.4.tar.gz
$ cd tcpreplay-4.3.4
$ ./configure
$ make
$ sudo make install
$ tcpreplay -V
Warning: May need to run as root to get access to all network interfaces.
tcpreplay version: 4.3.4 (build git:v4.3.4)
Copyright 2013-2018 by Fred Klassen <tcpreplay at appneta dot com> - AppNeta
Copyright 2000-2012 by Aaron Turner <aturner at synfin dot net>
The entire Tcpreplay Suite is licensed under the GPLv3
Cache file supported: 04
Not compiled with libdnet.
Compiled against libpcap: 1.9.1
64 bit packet counters: enabled
Verbose printing via tcpdump: enabled
Packet editing: disabled
Fragroute engine: disabled
Injection method: PF_PACKET send()
Not compiled with netmap

高速に Pcap を再送したい場合などは、より高度なインストールも可能だそうです。

偽の Ethernet Frame を追加する

$ sudo tcprewrite --dlt=enet --enet-smac=55:44:33:22:11:00 --enet-dmac=00:11:22:33:44:55 --infile=sample.pcap --outfile=sample_add_frame.pcap

Data Link Types: DLT が Ethernet になっており、指定した MAC アドレスを含む Ethernet Frame が追加されていることが確認できます。

$ tcpdump -er sample_add_frame.pcap
reading from file sample_add_frame.pcap, link-type EN10MB (Ethernet)
14:12:02.795288 55:44:33:22:11:00 > 00:11:22:33:44:55, ethertype IPv4 (0x0800), length 1102: (tos 0x10, ttl 64, id 11762, offset 0, flags [DF], proto TCP (6), length 1088)
    10.20.22.132.20222 > 10.20.22.15.62585: Flags [P.], seq 3211:4247, ack 3682, win 501, options [nop,nop,TS val 1205061784 ecr 1681210238], length 1036
        0x0000:  4510 0440 2df2 4000 4006 c7fb 0a14 1684  E..@-.@.@.......
        0x0010:  0a14 160f 4efe f479 54ed cb7f 4024 f5da  ....N..yT...@$..
        0x0020:  8018 01f5 44ed 0000 0101 080a 47d3 c898  ....D.......G...
        0x0030:  6435 3b7e                                d5;~
...

IPアドレスを任意のものに変更する

$ tcpprep --auto=first --pcap=sample_add_frame.pcap --cachefile=sample_add_frame.cache
$ tcprewrite --endpoints=192.0.2.254:203.0.113.254 --cachefile=sample_add_frame.cache --infile=sample_add_frame.pcap --outfile=sample_add_frame_rewrite_ip.pcap

IP アドレスが書き換わっていることが確認できます。また、チェックサムは自動で再計算してくれます。

$ tcpdump -evXnnr sample_add_frame_rewrite_ip.pcap
reading from file sample_add_frame_rewrite_ip.pcap, link-type EN10MB (Ethernet)
14:12:02.795288 55:44:33:22:11:00 > 00:11:22:33:44:55, ethertype IPv4 (0x0800), length 1102: (tos 0x10, ttl 64, id 11762, offset 0, flags [DF], proto TCP (6), length 1088)
    192.0.2.254.20222 > 203.0.113.254.62585: Flags [P.], seq 3211:4247, ack 3682, win 501, options [nop,nop,TS val 1205061784 ecr 1681210238], length 1036
        0x0000:  4510 0440 2df2 4000 4006 08b9 c000 02fe  E..@-.@.@.......
        0x0010:  cb00 71fe 4efe f479 54ed cb7f 4024 f5da  ..q.N..yT...@$..
        0x0020:  8018 01f5 85aa 0000 0101 080a 47d3 c898  ............G...
        0x0030:  6435 3b7e  
...

IPv6 の場合は、--endpoints=[2001:db8::dead:beef]:[::ffff:0:0:ac:f:0:2]のように指定することができます。

Header の Length フィールドに従ってパケットの末尾に Padding を追加する

$ tcprewrite --fixlen=pad --infile=sample_add_frame_rewrite_ip.pcap --outfile=sample_add_frame_rewrite_ip_pad.pca

0x00 の Padding が追加されていることが確認できます。

$ tcpdump -evXnnr sample_add_frame_rewrite_ip_pad.pcap
reading from file sample_add_frame_rewrite_ip_pad.pcap, link-type EN10MB (Ethernet)
14:12:02.795288 55:44:33:22:11:00 > 00:11:22:33:44:55, ethertype IPv4 (0x0800), length 1102: (tos 0x10, ttl 64, id 11762, offset 0, flags [DF], proto TCP (6), length 1088)
    192.0.2.254.20222 > 203.0.113.254.62585: Flags [P.], cksum 0x26b3 (correct), seq 3211:4247, ack 3682, win 501, options [nop,nop,TS val 1205061784 ecr 1681210238], length 1036
        0x0000:  4510 0440 2df2 4000 4006 08b9 c000 02fe  E..@-.@.@.......
        0x0010:  cb00 71fe 4efe f479 54ed cb7f 4024 f5da  ..q.N..yT...@$..
        0x0020:  8018 01f5 26b3 0000 0101 080a 47d3 c898  ....&.......G...
        0x0030:  6435 3b7e 0000 0000 0000 0000 0000 0000  d5;~............
        0x0040:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0050:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0060:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0070:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0080:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0090:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x00a0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x00b0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x00c0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x00d0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x00e0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x00f0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0100:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0110:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0120:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0130:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0140:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0150:  0000 0000 0000 0000 0000 0000 0000 0000  ................
...