tcpdump
tcpdump
tcpdump 须在管理员权限下运行。
#tcpdump
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
- 输出结果表明 tcpdump 的监听网卡为
ens33
。 - 默认截断大小为 262144 字节(随版本而改变),超过该数字报文会被截断。
使用 ifconfig
查看其他网卡:
#ifconfig
ens33 Link encap:Ethernet HWaddr 00:0c:29:48:09:a9
inet addr:192.168.248.128 Bcast:192.168.248.255 Mask:255.255.255.0
inet6 addr: fe80::555a:9e00:3f14:e7f/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:12058 errors:0 dropped:0 overruns:0 frame:0
TX packets:4911 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:9115911 (9.1 MB) TX bytes:577567 (577.5 KB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:1110 errors:0 dropped:0 overruns:0 frame:0
TX packets:1110 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1022006 (1.0 MB) TX bytes:1022006 (1.0 MB)
-i 指定网卡
上面默认监听网卡是 ens33
,我们也可以指定为 lo
:
tcpdump -i lo
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
-i any
可以监听所有网卡。
-nn 直接显示IP和端口号
#tcpdump -i lo
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
01:12:54.640796 IP localhost.44438 > localhost.12345: Flags [S], seq 1028792545, win 65495, options [mss 65495,sackOK,TS val 1381449987 ecr 0,nop,wscale 7], length 0
01:12:54.640834 IP localhost.12345 > localhost.44438: Flags [S.], seq 3925511357, ack 1028792546, win 65483, options [mss 65495,sackOK,TS val 1381449987 ecr 1381449987,nop,wscale 7], length 0
01:12:54.640870 IP localhost.44438 > localhost.12345: Flags [.], ack 1, win 512, options [nop,nop,TS val 1381449987 ecr 1381449987], length 0
监听环回网卡时,我们运行自己编写的简易 TCP 服务器端和客户端的回射程序,结果输出以上三次握手内容。其中主机地址为 localhost
,由于 server 和 client 都在一台主机,所以都为 localhost
。如果服务器的端口为著名端口(如 ssh 为 22 号端口),那么 22 也会显示为 ssh。若想直接显示 IP 和端口号,则使用 -nn
命令:
#tcpdump -i lo -nn
01:14:54.615811 IP 127.0.0.1.44438 > 127.0.0.1.12345: Flags [P.], seq 1028792546:1028792548, ack 3925511358, win 512, options [nop,nop,TS val 1381569983 ecr 1381449987], length 2
-n 不将IP转换为域名
不讲 IP 转为域名,则可以省去 DNS 查询,输出速度会快很多。
过滤主机
- 抓取所有经过 eth1,目的或源地址是 192.168.1.1 的网络数据
#tcpdump -i eth1 host 192.168.1.1
- 指定源地址
#tcpdump -i eth1 src host 192.168.1.1
- 指定目的地址
#tcpdump -i eth1 dst host 192.168.1.1
- 也可直接指定域名:
#tcpdump -i eth1 dest host "baidu.com"
过滤端口
- 抓取所有经过 eth1,目的或源端口是 25 的网络数据
#tcpdump -i eth1 port 25
- 指定源端口
#tcpdump -i eth1 src port 25
- 指定目的端口
#tcpdump -i eth1 dst port 25
-
指定端口范围:portrange
# tcpdump -i lo portrange 10000-20000
-
对于著名端口,可直接用应用层协议替代,相当于宏:
# tcpdump port http
网段过滤
#tcpdump -i eth1 net 192.168
#tcpdump -i eth1 src net 192.168
#tcpdump -i eth1 dst net 192.168.0.0/16
协议过滤
#tcpdump arp
#tcpdump ip
#tcpdump tcp
不能直接过滤协议,如下
#tcpdump http
而应该
#tcpdump port http
常用表达式
非 : ! 或 not
且 : && 或 and
或 : || 或 or
#tcpdump -i lo -nn tcp && dst port 12345 && src host 127.0.0.1
#tcpdump -i lo -nn tcp and dst port 12345 and src host 127.0.0.1
有时条件比较复杂的需要用括号:
#tcpdump -i eth1 '((tcp) and (! port 80) and ((dst host 192.168.1.254) or (dst host 192.168.1.200)))'
抓取所有经过eth1,目的地址是192.168.1.254或192.168.1.200,并且端口不是80的TCP数据
如果使用括号,则整个表达式需要用 ''
或 ""
包住。
包头过滤
proto[x:y] : 过滤从x字节开始的y字节数。比如ip[2:2]过滤出3、4字节(从第0字节开始)
proto[x:y] & z = 0 : proto[x:y]和z的与操作为0
proto[x:y] & z !=0 : proto[x:y]和z的与操作不为0
IP报头格式:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 \bit
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0 |Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4 | Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
12 | Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16 | Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20 | Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24 | Options | Padding | <-- optional
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
28 | DATA ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\byte
TCP报头格式:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 \bit
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0 | Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4 | Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8 | Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |C|E|U|A|P|R|S|F| |
12 | Offset| Res. |W|C|R|C|S|S|Y|I| Window |
| | |R|E|G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16 | Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20 | Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24 | data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\byte
# tcpdump -i lo "tcp[2:2]=12345"
只显示目的端口号为12345的报文
TCP标记定义在TCP头的第 13 个字节:
# tcpdump -i lo "src port 12345 && tcp[13]&1 = 1"
只显示目的端口号为12345的FIN报文
TCP标记宏可以替代数值:
tcpflags
, tcp-fin
, tcp-syn
, tcp-rst
, tcp-push
, tcp-push
, tcp-ack
, tcp-urg
# tcpdump -i lo "dst port 12345 && tcp[tcpflags]&tcp-fin=tcp-fin"
-w 输出到文件、-r 读取文件
# tcpdump tcp -w test.cap
把信息输出到 test.cap 文件。将文件保存为 cap
或 pcap
类型就能方便地使用 wireshark 打开并分析:
# tcpdump tcp -r test.cap
读取 test.cap
文件并打印在终端,同时也可以使用过滤规则:
# tcpdump tcp -r test.cap port 12345
输出时间
-t
:在每行的输出中不输出时间-tt
:在每行的输出中会输出时间戳-ttt
:输出每两行打印的时间间隔(以毫秒为单位)-tttt
:在每行打印的时间戳之前添加日期的打印
# tcpdump -t dst "baidu.com"
IP 192.168.248.128 > 39.156.66.10: ICMP echo request, id 11930, seq 1650, length 64
# tcpdump -tt dst "baidu.com"
1680352032.093467 IP 192.168.248.128 > 39.156.66.10: ICMP echo request, id 11930, seq 1662, length 64
# tcpdump -ttt dst "baidu.com"
00:00:00.000000 IP 192.168.248.128 > 39.156.66.10: ICMP echo request, id 11930, seq 1672, length 64
00:00:01.002438 IP 192.168.248.128 > 39.156.66.10: ICMP echo request, id 11930, seq 1673, length 64
# tcpdump -tttt dst "baidu.com"
2023-04-01 05:27:30.131073 IP 192.168.248.128 > 39.156.66.10: ICMP echo request, id 11930, seq 1680, length 64
-v 展示详细信息
-v
:产生详细的输出。比如包的TTL,id标识,数据包长度,以及IP包的一些选项:
root@ubuntu:/home/butcher/Documents# tcpdump -v dst "baidu.com"
tcpdump: listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
05:36:46.543701 IP (tos 0x0, ttl 64, id 44013, offset 0, flags [DF], proto ICMP (1), length 84)
192.168.248.128 > 39.156.66.10: ICMP echo request, id 12115, seq 7, length 64
-c 指定接收报文个数
# tcpdump -v -c 3
05:46:32.275269 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 192.168.248.2 tell 192.168.248.1, length 46
05:46:32.276545 IP (tos 0x0, ttl 64, id 50690, offset 0, flags [DF], proto UDP (17), length 72)
192.168.248.128.34566 > 192.168.248.2.domain: 39118+ PTR? 2.248.168.192.in-addr.arpa. (44)
05:46:32.280758 IP (tos 0x0, ttl 128, id 35219, offset 0, flags [none], proto UDP (17), length 127)
192.168.248.2.domain > 192.168.248.128.34566: 39118 NXDomain 0/1/0 (99)
3 packets captured
抓满指定数量的报文后自动停止。
-C -W 分文件写入
#tcpdump -C 1 -W 4 -w test
-C 和 -w 配套使用,后者将抓包情况写入文件,前者指定每个文件的最大大小,单位为 1MB(小文件利于分析)。
-C 1
:指定单个文件最大为 1MB-W
:指定最多写 4 个文件-w
:写入文件
每个文件会依次添加后缀:test1、test2、test3、test4 。注意,如果写满这 4 个文件后,数据还在持续,那么会重新覆盖这 4 个文件并继续写入,而不会新建文件。
-Q 指定方向
- -Q in :只显示收到的数据
- -Q out :只显示发出的数据
# tcpdump -Q in
06:04:34.157713 IP 192.168.248.1.50277 > 239.255.255.250.1900: UDP, length 175
06:04:34.163603 IP 192.168.248.2.domain > 192.168.248.128.34566: 27092 NXDomain 0/1/0 (103)
06:04:35.003369 IP 180.101.49.186.https > 192.168.248.128.33644: Flags [.], ack 769671203, win 64240, length 0
-s 指定截取大小
-s
指定每个包捕获的长度、单位是 byte,而不是默认的 262144 字节;如果超过了设定的大小限制,包就会被截断,并在打印行出现[|proto]这种标识,这个proto就是被截断的报文的协议名字。但是抓取越长,包的处理时间越长,并且会减少 tcpdump 可缓存的数据包的数量,从而会导致数据包的丢失,所以在能抓取我们想要的包的前提下,抓取长度越小越好,一般只抓报头 ,抓 80 个字节一般就能包含 TCP 层、IP 层、链路层。
-s 0
使用默认长度 262144。
-e 显示链路层信息
# tcpdump -e
06:49:36.315000 00:0c:29:48:09:a9 (oui Unknown) > 00:50:56:fb:6d:e0 (oui Unknown), ethertype IPv4 (0x0800), length 54: 192.168.248.128.33644 > 180.101.49.186.https: Flags [.], ack 565954419, win 65535, length 0
-F 指定过滤过滤表达式文件
有些过滤表达式经常用,但又很冗长,每次输入都很麻烦。所以可以保存为文件,每次 tcpdump 时指定该文件为过滤规则:
#tcpdump -F filter_file
该命令行中的其他命令会被忽略。
less,greater 指定大小
#tcpdump less 100
-X 打印数据内容
-X
除了打印每个数据包的头之外,还可以用十六进制和ASCII打印每个数据包的数据(不包括链路级头,-XX
可包含):