tcpdump是Linux下的一个网络数据采集分析工具,也就是常说的抓包工具
tcpdump 核心参数
tcpdump [option] [proto] [dir] [type]
例如:
$ tcpdump -i eth0 -nn -s0 -v port 80
-
option 可选参数:
-
-i : 选择要捕获的接口,通常是以太网卡或无线网卡,也可以是 vlan 或其他特殊接口。如果该系统上只有一个网络接口,则无需指定。
-
-nn : 单个 n 表示不解析域名,直接显示 IP;两个 n 表示不解析域名和端口。这样不仅方便查看 IP 和端口号,而且在抓取大量数据时非常高效,因为域名解析会降低抓取速度。
-
-s0 : tcpdump 默认只会截取前 96 字节的内容,要想截取所有的报文内容,可以使用 -s number, number 就是你要截取的报文字节数,如果是 0 的话,表示截取报文全部内容。
-
-v : 使用 -v,-vv 和 -vvv 来显示更多的详细信息,通常会显示更多与特定协议相关的信息。
-
port 80 : 这是一个常见的端口过滤器,表示仅抓取 80 端口上的流量,通常是 HTTP。
-
-e : 显示数据链路层信息。默认情况下 tcpdump 不会显示数据链路层信息,使用 -e 选项可以显示源和目的 MAC 地址,以及 VLAN tag 信息
-
-w
参数后接一个以.pcap
后缀命令的文件名,就可以将 tcpdump 抓到的数据保存到文件中。 -
使用
-r
是从文件中读取数据。-
tcpdump icmp -w icmp.pcap tcpdump icmp -r all.pcap
-
-
-v
:产生详细的输出. 比如包的TTL,id标识,数据包长度,以及IP包的一些选项。同时它还会打开一些附加的包完整性检测,比如对IP或ICMP包头部的校验和。 -
-vv
:产生比-v更详细的输出. 比如NFS回应包中的附加域将会被打印, SMB数据包也会被完全解码。 -
-A
:以ASCII码方式显示每一个数据包(不显示链路层头部信息). 在抓取包含网页数据的数据包时, 可方便查看数据 -
-l
: 基于行的输出,便于你保存查看,或者交给其它工具分析 -
-q
: 简洁地打印输出。即打印很少的协议相关信息, 从而输出行都比较简短. -
-c
: 捕获 count 个包 tcpdump 就退出 -
-s
: tcpdump 默认只会截取前96
字节的内容,要想截取所有的报文内容,可以使用-s number
,number
就是你要截取的报文字节数,如果是 0 的话,表示截取报文全部内容。 -
-D
: 显示所有可用网络接口的列表 -
-e
: 每行的打印输出中将包括数据包的数据链路层头部信息 -
and:所有的条件都需要满足,也可以表示为
&&
-
or:只要有一个条件满足就可以,也可以表示为
||
-
not:取反,也可以使用
!
-
-
proto 类过滤器:根据协议进行过滤,可识别的关键词有: tcp, udp, icmp, ip, ip6, arp, rarp,ether,wlan, fddi, tr, decnet
-
type 类过滤器:可识别的关键词有:host, net, port, portrange,这些词后边需要再接参数。
-
direction 类过滤器:根据数据流向进行过滤,可识别的关键字有:src, dst,同时你可以使用逻辑运算符进行组合,比如 src or dst
理解tcpdump输出
内容结构
21:26:49.013621 IP 172.20.20.1.15605 > 172.20.20.2.5920: Flags [P.], seq 49:97, ack 106048, win 4723, length 48
-
第一列:时分秒毫秒 21:26:49.013621
-
第二列:网络协议 IP
-
第三列:发送方的ip地址+端口号,其中172.20.20.1是 ip,而15605 是端口号
-
第四列:箭头 >, 表示数据流向
-
第五列:接收方的ip地址+端口号,其中 172.20.20.2 是 ip,而5920 是端口号
-
第六列:冒号
-
第七列:数据包内容,包括Flags 标识符,seq 号,ack 号,win 窗口,数据长度 length,其中 [P.] 表示 PUSH 标志位为 1,更多如下:
-
[S]
: SYN(开始连接) -
[P]
: PSH(推送数据) -
[F]
: FIN (结束连接) -
[R]
: RST(重置连接) -
[.]
: 没有 Flag (意思是除上面四种类型外的其他情况,有可能是 ACK 也有可能是 URG)
-
常规过滤规则
基于IP地址过滤:host
$ tcpdump host 192.168.10.100
数据包的 ip 可以再细分为源ip和目标ip两种
# 根据源ip进行过滤
$ tcpdump -i eth2 src 192.168.9.50
# 根据目标ip进行过滤
$ tcpdump -i eth2 dst 192.168.9.100
网段同样可以再细分为源网段和目标网段
CopyCopy# 根据源网段进行过滤
$ tcpdump src net 192.168
# 根据目标网段进行过滤
$ tcpdump dst net 192.168
基于端口过滤:port
使用 port
就可以指定特定端口进行过滤
$ tcpdump port 8088
端口同样可以再细分为源端口,目标端口
# 根据源端口进行过滤
$ tcpdump src port 8088
# 根据目标端口进行过滤
$ tcpdump dst port 8088
多个端口
$ tcpdump port 80 or 8088
端口段
$ tcpdump portrange 8000-8080
$ tcpdump src portrange 8000-8080
$ tcpdump dst portrange 8000-8080
常见协议的默认端口,直接使用协议名
$ tcpdump 'ip6 proto tcp'
$ tcpdump 'ip4 proto tcp'
比如 http == 80,https == 443 等
$ tcpdump tcp port http
基于协议进行过滤:proto
$ tcpdump icmp
想查看 tcp 的包,不区分ipv4和ipv6
$ tcpdump tcp
区分:
$ tcpdump 'ip6 proto tcp'
抓包例子
提取 HTTP 的 User-Agent,即提取HTTP用户代理
$ tcpdump -nn -A -s1500 -l | grep "User-Agent:"
通过 egrep 可以同时提取用户代理和主机名(或其他头文件):
$ tcpdump -nn -A -s1500 -l | egrep -i 'User-Agent:|Host:'
抓取 HTTP GET 请求包:
$ tcpdump -vvAls0 | grep 'GET'
抓取DNS请求和响应
DNS 的默认端口是 53,因此可以通过端口进行过滤
$ tcpdump -i any -s0 port 53
提取HTTP请求中的URL
$ tcpdump -s 0 -v -n -l | egrep -i "POST /|GET /|Host:"
从HTTP post请求中提取密码和主机名
$ tcpdump -s 0 -A -n -l | egrep -i "POST /|pwd=|passwd=|password=|Host:"
提取 Set-Cookie(服务端的 Cookie)和 Cookie(客户端的 Cookie):
$ tcpdump -nn -A -s0 -l | egrep -i 'Set-Cookie|Host:|Cookie:'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlp58s0, link-type EN10MB (Ethernet), capture size 262144 bytes
Host: dev.example.com
Cookie: wordpress_86be02xxxxxxxxxxxxxxxxxxxc43=admin%7C152xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
查看网络上的所有 ICMP 数据包:
$ tcpdump -n icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp7s0, link-type EN10MB (Ethernet), capture size 262144 bytes
11:34:21.590380 IP 10.10.1.217 > 10.10.1.30: ICMP echo request, id 27948, seq 1, length 64
11:34:21.590434 IP 10.10.1.30 > 10.10.1.217: ICMP echo reply, id 27948, seq 1, length 64
11:34:27.680307 IP 10.10.1.159 > 10.10.1.1: ICMP 10.10.1.189 udp port 59619 unreachable, length 115
抓取 SMTP/POP3 协议的邮件
可以提取电子邮件的正文和其他数据。例如,只提取电子邮件的收件人:
$ tcpdump -nn -l port 25 | grep -i 'MAIL FROM\|RCPT TO'
抓取HTTP有效数据包
抓取 80 端口的 HTTP 有效数据包,排除 TCP 连接建立过程的数据包(SYN / FIN / ACK):
$ tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
抓取DHCP报文
抓取 DHCP 服务的请求和响应报文,67 为 DHCP服务机 端口,68 为DHCP客户机端口。
$ tcpdump -v -n port 67 or 68