感谢https://cloud.tencent.com/developer/article/1432605的分享
1 简介
tcpdump 是一款 Linux 平台的抓包工具。它可以抓取涵盖整个 TCP/IP 协议族的数据包,支持针对网络层、协议、主机、端口的过滤,并提供 and、or、not 等逻辑语句来过滤无用的信息。
tcpdump 是一个非常复杂的工具,掌握它的方方面面实属不易,也不推荐,能够用它来解决日常工作问题才是关系。
2 tcpdump 命令选项
tcpdump 有很多命令选项,想了解所有选项可以 Linux 命令行输入 tcpdump -h,man tcpdump 查看每个选项的意思。
下面列举一些常用选项:
-A 只使用 ASCII 打印报文的全部数据,不要和 -X 一起使用,获取 http 可以用 tcpdump -nSA port 80
-b 在数据链路层上选择协议,包括 ip, arp, rarp, ipx 等
-c 指定要抓取包的数量
-D 列出操作系统所有可以用于抓包的接口
-e 输出链路层报头
-i 指定监听的网卡,-i any 显示所有网卡
-n 表示不解析主机名,直接用 IP 显示,默认是用 hostname 显示
-nn 表示不解析主机名和端口,直接用端口号显示,默认显示是端口号对应的服务名
-p 关闭接口的混杂模式
-P 指定抓取的包是流入的包还是流出的,可以指定参数 in, out, inout 等,默认是 inout
-q 快速打印输出,即只输出少量的协议相关信息
-s len 设置要抓取数据包长度为 len,默认只会截取前 96bytes 的内容,-s 0 的话,会截取全部内容。
-S 将 TCP 的序列号以绝对值形式输出,而不是相对值
-t 不要打印时间戳
-vv 输出详细信息(比如 tos、ttl、checksum等)
-X 同时用 hex 和 ascii 显示报文内容
-XX 同 -X,但同时显示以太网头部
3 过滤器
tcpdump 提供了灵活的语法可以精确获取我们关心的数据,这些语法说得专业点就是过滤器。
过滤器简单可分为三类:协议(proto)、传输方向(dir)和类型(type)。
一般的 表达式格式 为:

关于 proto:可选有 ip, arp, rarp, tcp, udp, icmp, ether 等,默认是所有协议的包
关于 dir:可选有 src, dst, src or dst, src and dst,默认为 src or dst
关于 type:可选有 host, net, port, portrange(端口范围,比如 21-42),默认为 host
4 常用操作
测试环境 IP:192.168.10.1
4.1 抓取某主机的数据包
1)抓取主机 192.168.10.1上所有收到(DST_IP)和发出(SRC_IP)的所有数据包
tcpdump host 192.168.10.1
2)抓取经过指定网口 interface ,并且 DST_IP 或 SRC_IP 是 192.168.10.1 的数据包
tcpdump -i eth0 host 192.168.10.1
3)筛选 SRC_IP,抓取经过 interface 且从 192.168.10.1 发出的包
tcpdump -i eth0 src host 192.168.10.1
4)筛选 DST_IP,抓取经过 interface 且发送到 192.168.10.1 的包
tcpdump -i eth0 dst host 192.168.10.1
5)抓取主机 200.200.200.1 和主机 200.200.200.2 或 200.200.200.3 通信的包
tcpdump host 200.200.200.1 and \(200.200.200.2 or 200.200.200.3\)
6)抓取主机 200.200.200.1 和除了主机 200.200.200.2 之外所有主机通信的包
tcpdump ip host 200.200.200.1 and ! 200.200.200.2
4.2 抓取某端口的数据包 1)抓取所有端口,显示 IP 地址
tcpdump -nS
2)抓取某端口上的包
tcpdump port 22
3)抓取经过指定 interface,并且 DST_PORT 或 SRC_PORT 是 22 的数据包
tcpdump -i eth0 port 22
4)筛选 SRC_PORT
tcpdump -i eth0 src port 22
5)筛选 DST_PORT
tcpdump -i eth0 dst port 22
6)比如希望查看发送到 host 192.168.10.1 的网口 eth0 的 22 号端口的包
tcpdump -i eth0 -nnt dst host 192.168.10.1 and port 22 -c 1 -vv
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytesIP (tos 0x14, ttl 114, id 27674, offset 0, flags [DF], proto TCP (6), length 40)
113.98.59.61.51830 > 192.168.10.1.22: Flags [.], cksum 0x7fe3 (correct), seq 19775964, ack 1564316089, win 2053, length 0
4.3 抓取某网络(网段)的数据包 1)抓取经过指定 interface,并且 DST_NET 或 SRC_NET 是 172.18.82 的包
tcpdump -i eth0 net 172.18.82
2)筛选 SRC_NET
tcpdump -i eth0 src net 172.18.82
3)筛选 DST_NET
tcpdump -i eth0 dst net 172.18.82
4.4 抓取某协议的数据包
tcpdump -i eth0 icmp
tcpdump -i eth0 ip
tcpdump -i eth0 tcp
tcpdump -i eth0 udp
tcpdump -i eth0 arp
4.5 复杂的逻辑表达式抓取过滤条件 1)抓取经过 interface eth0 发送到 host 200.200.200.1 或 200.200.200.2 的 TCP 协议 22 号端口的数据包
tcpdump -i eth0 -nntvv -c 10 '((tcp) and (port 22) and ((dst host 200.200.200.1) or (dst host 200.200.200.2)))'
PS:对于复杂的过滤器表达式,为了逻辑清晰,可以使用 (),不过默认情况下,tcpdump 会将 () 当做特殊字符,所以必须使用 '' 来消除歧义。
2)抓取经过 interface eth0, DST_MAC 或 SRC_MAC 地址是 00:16:3e:12:16:e7 的 ICMP 数据包
tcpdump -i eth0 '((icmp) and ((ether host 00:16:3e:12:16:e7)))' -nnvv
3)抓取经过 interface eth0,目标网络是 172.18 但目标主机又不是 192.168.10.1 的 TCP 且非 22 号端口号的数据包
tcpdump -i eth0 -nntvv '((dst net 172.18) and (not dst host 192.168.10.1) and (tcp) and (not port 22))'
4)抓取流入 interface eth0,host 为 192.168.10.1 且协议为 ICMP 的数据包
tcpdump -i eth0 -nntvv -P in host 192.168.10.1 and icmp
5)抓取流出 interface eth0,host 为 192.168.10.1 且协议为 ICMP 的数据包
tcpdump -i eth0 -nntvv -P out host 192.168.10.1 and icmp