Linux command - tcpdump
Dump the traffic on a network.
1 | tcpdump [options] [expression] |
常用 options:
-c count
: Exit after receivingcount
packets. 指定抓取的包的数量。-D, --list-interfaces
: 打印出系统中可以被 tcpdump 抓包的网络接口。列出的网络接口包括相应的序号和网络接口名,可以用tcpdump -i
指定相应的网络接口或相应的序号来抓取特定网络接口的数据包。其中名为any
的网络接口表示可以抓取所有网络接口的数据包 (tcpdump -i any
)。-F file
: 从指定的file
中读取expression
(tcpdump [options] [expression]
)。-i interface, --interface=interface
: 指定抓包的网络接口。如果没有指定tcpdump
会监听tcpdump -D
中第一个网络接口。当指定interface
为any
则表示监听所有网络接口。-l
: Make stdout line buffered. 将抓包记录从标准输出变为行缓冲形式。当抓包的时候,你可以将抓包记录存到文件,边抓包边分析。-n
: Don not convert address (i.e., host address, port numbers, etc) to names. 即直接显示数字形式的地址端口号等,而不进行解析。-#, --number
: 给每行抓包的输出结果添加行号。-q
: 简短快速输出。只打印较少的协议信息。-t
: 每行抓包记录不打印时间。-tt
: 将每行抓包记录的时间代替为时间戳形式。-ttt
: 将每行记录的时间替换为和上一行的时间差。-tttt
: 在每行记录的时间前添加日期 (默认只显示时分秒)。-v
,-vv
,-vvv
: 打印其它详细信息,详细程度依次递增。-w file
, 不打印抓取的数据包,而是将数据保存到file
文件中,文件后缀一般为.pcap
,.cap
,.dmp
。保存的数据是没有解码的十六进制数据,可以使用 wirekshark 等工具进行分析。-x
: 以十六进制形式打印数据包的头部信息。-xx
: 比-x
更加详细。-X
: 以十六进制和 ASCII 的形式打印数据包的头部信息。-XX
: 比-X
更加详细。
1 | # 查看系统中可以被 tcpdump 抓包的网络接口 |
expression
expression 可以用来过滤抓取的数据包。
The filter expression consists of one or more primitives. Primitives usually consist of an id (name or number) preceded by one or more qualifiers. There are three different kinds of qualifier: type, dir, proto.
过滤表达式可以由 type, dir, proto 中的一个或多个组成。
type: type qualifiers say what kind of thing the id name or number refers to. Possible type are:
host
,net
,port
andportrange
. E.g.host lizs.cc
,net 127.0
,port 80
,portrange 6000-6008
, etc.1
2
3
4# 监听地址以 127. 开头的数据包,如`127.0.0.1`, `127.0.1.1`等
sudo tcpdump -c 3 -i any -n# net 127
# 监听 lizs.cc
sudo tcpdump -c 3 -i any -n# host lizs.ccdir: dir qualifiers specify a particular transfer direction to
and/or
from id. Possible directions aresrc
,dst
,src or dst
,src and dst
,ra
,ta
,addr1
,addr2
,addr3
, andaddr4
. E.g.,src foo
,dst net 128.3
,src or dst port ftp-data
. Thera
,ta
,addr1
,addr2
,addr3
, andaddr4
qualifiers are only valid for IEEE 802.11 Wireless LAN link layers.1
2
3
4# 监听源地址为 127.0.0.1 的数据包
sudo tcpdump -c3 -i any -n# src net 127.0.0.1
# 监听源地址或目的地址为 lizs.cc 的数据包
sudo tcpdump -c3 -i any -n#tttt src or dst host lizs.cc
- proto: proto qualifiers restrict the match to a particular protocol. Possible protos are:
ether
,fddi
,tr
,wlan
,ip
,ip6
,arp
,rarp
,decnet
,tcp
andudp
. E.g.,ether src foo
,arp net 128.3
,tcp port 21
,udp portrange 7000-7009
,wlan addr2 0:2:3:4:5:6
.1
2
3
4# 监听 TCP 的数据包
sudo tcpdump -c 3 -i any -n#qtttt tcp
# 监听所有网络接口的 ICMP 数据包
sudo tcpdump -c3 -i any -n#qtttt icmp
除了以上 primitive,还有其它 primitive,如:gateway
, broadcast
, less
, greater
以及算术表达式,等等。
多个修饰语 (qualifier) 可以用and
, or
, not
, !
等连接组合起来,也可以用括号()
指定优先级,不过要用反斜杠转义\(\)
或 expression 用单引号或双引号括起来。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16# 监听源端口为 80 或 443 的 TCP 数据包
sudo tcpdump -n#qtttt tcp src port 80 or 443 # 或者 sudo tcpdump -n#qtttt src port 80 or 443 and tcp
# 监听 lizs.cc 的 TCP 数据包,不过过滤掉和 github.com 通信的数据包
sudo tcpdump -i any tcp host lizs.cc and not github.com
# 监听端口不为 1080 的非 TCP 数据包
sudo tcpdump ! tcp port ! 1080
# 监听目的端口不为 1080 的 tcp 或 arp 包
sudo tcpdump dst port ! 1080 and \(tcp or arp\) # 或
sudo tcpdump 'dst port ! 1080 and (tcp or arp)' # 或
sudo tcpdump tcp or arp dst port ! 1080
# 监听 ftp 端口或 telnet 端口的数据包
sudo tcpdump -i any port ftp or telnet
# 监听所有通过网关 snup 的 ftp 数据包
sudo tcpdump -i any 'gateway snup and (port ftp or ftp-data)'
# 抓取数据包长度小于或等于 65 的 tcp 数据包。
sudo tcpdump -i any tcp and less 65
更多端口信息可以查看/etc/services
。
表达式中的切片
proto[x]
,表示协议中的第 x
个字节的内容。proto
为相应的协议名称,如tcp
, ip
。proto[x:y]
,表示协议中从 x
位置开始的 y
个字节内容。proto
为相应的协议名称,如tcp
, ip
。1
2
3
4
5
6
7
8
9
10# 过滤掉源端口小于 1024 的 TCP 连接
sudo tcpdump -i any -n#qtttt 'tcp[0:2] < 1024'
# 打印目的端口为 443 的 TCP 连接数据包
sudo tcpdump -i any -n#qtttt 'tcp[2:2] = 443'
# 打印源端口不是 443 的 TCP 连接
sudo tcpdump -i any -n#qtttt 'tcp[0:2] != 443'
# 抓取 SYN 包并保存到 syn_packets.pcap 文件中
sudo tcpdump -i any -w syn_pckets.pcap 'tcp[13] == 2'
# 抓取 HTTP 协议的 GET 方法请求的数据包
sudo tcpdump -i any -n#qtttt 'tcp[20] = 0x47 and tcp[21] = 0x45 and tcp[22] = 0x54'
TCP 首部共 20 字节: 16 位 (2 字节) 的源端口和 16 位的目的端口;32 位系列号;32 位确认序列号;4 位首部长度;6位保留位;6 位标志位 (URG, ACK, PSH, RST, SYN, FIN,各占一位);等等。
下标从 0 开始,所以,源端口为tcp[0:2]
,目的端口为tcp[2:2]
,SYN 标志位在第 14 字节 (即 13),值为 000010 == 2
。
因为,要计算各协议的标志位很麻烦,所以,提供了部分别名:
proto[icmptype]
,ICMP 类型。同时 ICMP 类型有: icmp-echoreply, icmp-unreach, icmp-sourcequench, icmp-redirect, icmp-echo 等等。proto[icmpcode]
,ICMP 符号。proto[tcpflags]
,TCP 标志位。标志值有:tcp-urg, tcp-ack, tcp-psh, tcp-syn, tcp-fin。1
2# 抓取 SYN 包
sudo tcpdump -i any 'tcp[tcpflags] = tcp-syn'
更多 expression 的详细语法可以通过 man pcap-filter
查看。