tcpdump命令最初设计用于观察TCP/IP性能问题,它是一个用于截取网络分组
,并输出分组内容的工具。tcpdump可以将网络中传送的数据包的报文头完全截获下来提供分析,它支持针对网络层、协议、主机、网络或端口的过滤,并提供and, or, not等逻辑语句来帮助用户去掉无用的信息。抓包还是偏向于非HTTP协议,常用于服务器端,客户端可以使用wireshark,也可以使用tcpdump抓包保存数据文件,使用wireshark分析。
tcpdump常用选项
tcpdump [ -AdDefIKlLnNOpqRStuUvxX ] [ -B buffer_size ] [ -c count ]
[ -C file_size ] [ -G rotate_seconds ] [ -F file ]
[ -i interface ] [ -m module ] [ -M secret ]
[ -r file ] [ -s snaplen ] [ -T type ] [ -w file ]
[ -W filecount ]
[ -E spi@ipaddr algo:secret,... ]
[ -y datalinktype ] [ -z postrotate-command ] [ -Z user ] [ expression ]
选项 | 说明 |
---|---|
-i | 指定抓取的网络接口-i interface ,-i any 可以抓取所有网络接口 |
-D | 列出机器所有的网络接口 |
-w | 将捕获的包数据写入到文件中,后面再进行分析;-w - 可以进行标准输出,会出现一大串的乱码,也可以使用重定向或tee |
-r | 从文件中读取包数据,回放场景 |
-c size | 指定要捕获报文数量,使用 -w 写入文件时,使用-C ,限制文件的最大大小,超出时新开一个文件(单位是 1,000,000 bytes) |
-p | 将网卡接口设置为非混杂模式 |
-s | 控制数据的截取长度,一般tcpdump默认为一最大字节数量并只会从单一报文中截取到该数量长度, 为 0 时表示让 tcpdump 自动选择合适的长度来抓取数据包. |
-S | 打印绝对序列号,一般分析数据还是使用相对的 |
-a | 强制将网络地址显示为名称,默认的选项 |
-n | 不要将主机地址转换为名称。这可用于避免DNS查找 |
-nn | 不要将协议和端口号等转换为名称 |
-N | 阻止将域名转换FQDN |
-f | 阻止远端名称解析 |
-t | 不显示时间 |
-tt | 输出时间戳 |
-tttt | 00:00:00.000000 详细输出时间信息 |
-v | 显示详细信息,-v 会显示ttl信息,使用-vv,-vvv 抓包时输出包的更多附加信息 |
-q | 显示更少的输出信息 |
-e | 显示链路层头信息 |
-x | 将报文以十六进制形式dump出来,排除了链路层报文头,-xx 增加以太网header的显示 |
-A | 以 ASCII 码方式显示每一个数据包(不会显示数据包中链路层头部信息). 在抓取包含网页数据的数据包时, 可方便查看数据 |
-X | :以hex和ASCII两种形式显示包的内容,-XX 增加以太网header的显示 |
混杂模式就是接收所有经过网卡的数据包,包括不是发给本机的包,即不验证MAC地址。普通模式下网卡只接收发给本机的包(包括广播包)传递给上层程序,其它的包一律丢弃。
一般来说,混杂模式不会影响网卡的正常工作,多在网络监听工具上使用。
网卡具有如下的几种工作模式:
1) 广播模式(Broad Cast Model):它的物理地址(MAC)地址是 0Xffffff 的帧为广播帧,工作在广播模式的网卡接收广播帧。
2)多播传送(MultiCast Model):多播传送地址作为目的物理地址的帧可以被组内的其它主机同时接收,而组外主机却接收不到。但是,如果将网卡设置为多播传送模式,它可以接收所有的多播传送帧,而不论它是不是组内成员。
3)直接模式(Direct Model):工作在直接模式下的网卡只接收目地址是自己 Mac地址的帧。
4)混杂模式(Promiscuous Model):工作在混杂模式下的网卡接收所有的流过网卡的帧,信包捕获程序就是在这种模式下运行的。
网卡的缺省工作模式包含广播模式和直接模式,即它只接收广播帧和发给自己的帧。如果采用混杂模式,一个站点的网卡将接受同一网络内所有站点所发送的数据包这样就可以到达对于网络信息监视捕获的目的。
过滤数据包
过滤规则表达式
过滤规则一般包含三种修饰符的组合:
- type: 指定id 所代表的对象类型, id可以是名字也可以是数字. 可选的对象类型有: host, net, port 以及portrange,默认是
host
- dir: 描述id 所对应的传输方向, 即发往id 还是从id 接收(而id 到底指什么需要看其前面的type 修饰符).可取的方向为: src, dst, src or dst, src and dst
- proto: 描述id 所属的协议. 可选的协议有: ether, fddi, tr, wlan, ip, ip6, arp, rarp, decnet, tcp以及udp
通过括号(\( xxx \))
和 bool 操作符可以组合多种过滤规则,一对括号是一组:
- 否定操作: ! 或 not
- 与操作: && 或 and
- 或操作: || 或 or
常用过滤规则
过滤地址ip/域名
过滤目标是www.baidu.com的域名:
sudo tcpdump -i any -Avvv dst host www.baidu.com
过滤源ip或目标ip是172.27.0.14:
sudo tcpdump -i any -Avvv host 172.27.0.14
过滤源ip是172.27.0.14:
sudo tcpdump -i any -Avvv src 172.27.0.14
过滤目标ip是172.27.0.14:
sudo tcpdump -i any -Avvv dst host 172.27.0.14
过滤网段,ip段:
sudo tcpdump -i any net 172.17.16.0/24
sudo tcpdump -i any net 172.17.16.0 mask 255.255.255.0
过滤端口
过滤指定端口:
sudo tcpdump -i eth0 -Avvv port 8888 -c 10
过滤源和目的端口:
sudo tcpdump -i eth0 -nvvv 'port 22 && port 62644' -c 3
排除指定端口:
sudo tcpdump -i eth0 not port 22
sudo tcpdump -i eth0 not \(port 443 or port 80 or port 22\)
过滤端口范围:
sudo tcpdump -i eth0 portrange 79-81
过滤协议
限制抓取指定协议,tcpdump可识别的关键字包括ip
,ip6
,arp
,igmp
,tcp
,udp
,icmp
有很多传输层服务没有可以识别的关键字。在这种情况下,可以使用关键字proto
或ip proto加上/etc/protocols能够找到的协议名或相应的协议编号
sudo tcpdump -i macvlan0 arp
过滤协议头
常用的 tcp 标记:tcp-fin
, tcp-syn
, tcp-rst
, tcp-push
, tcp-ack
, tcp-urg
, tcp-ece
, tcp-cwr
过滤 tcp SYN
消息包:
sudo tcpdump -i eth0 'tcp[tcpflags] & (tcp-syn) != 0' -c 1
13:52:32.070747 IP 125.226.39.220.54500 > bestsre.microsoft-ds: Flags [S], seq 3744066256, win 8192, options [mss 1200,nop,wscale 2,sackOK,TS val 1380022 ecr 0], length 0
过滤 tcp SYN/ACK
消息包:
sudo tcpdump -i eth0 'tcp[tcpflags] & (tcp-syn|tcp-ack) != 0' -c 1
13:54:47.889653 IP bestsre.ssh > YZ.62644: Flags [P.], seq 4178293879:4178294067, ack 3163427986, win 314, options [nop,nop,TS val 3890058229 ecr 558951371], length 188
过滤HTTP
过滤 GET 请求:
sudo tcpdump -i eth0 -Anvvv 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420 and port 8888'
0x47455420
为GET的16进制表示
>>> list(map(hex, [ord(x) for x in 'GET ']))
['0x47', '0x45', '0x54', '0x20']
过滤 POST 请求:
sudo tcpdump -i eth0 -Anvvv 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354 && tcp[((tcp[12:1] & 0xf0) >> 2) + 4:1] = 0x20'
过滤PUT请求:
sudo tcpdump -i eth0 -Anvvv 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x50555420'
过滤 PATCH 请求:
sudo tcpdump -i eth0 -Anvvv 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x50415443 && tcp[((tcp[12:1] & 0xf0) >> 2) + 4:2] = 0x4820'
过滤 DELETE 请求:
sudo tcpdump -i eth0 -Anvvv 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x44454c45 && tcp[((tcp[12:1] & 0xf0) >> 2) + 4:2] = 0x5445 && tcp[((tcp[12:1] & 0xf0) >> 2) + 6:1] = 0x20'
过滤 HEAD 请求:
sudo tcpdump -i eth0 -Anvvv 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x48454144 && tcp[((tcp[12:1] & 0xf0) >> 2) + 4:1] = 0x20'
过滤 OPTIONS 请求:
sudo tcpdump -i eth0 -Anvvv 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x4f505449 && tcp[((tcp[12:1] & 0xf0) >> 2) + 4:4] = 0x4f4e5320'
过滤 HTTP 响应 (HTTP/1.):
sudo tcpdump -i eth0 -Anvvv 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x48545450 && tcp[((tcp[12:1] & 0xf0) >> 2) + 4:2] = 0x2f31 && tcp[((tcp[12:1] & 0xf0) >> 2) + 6:1] = 0x2e'
根据包大小过滤
数据报大小,单位是字节
tcpdump less 32
tcpdump greater 128
tcpdump > 32
tcpdump <= 128
过滤器的更多详细信息,请访问 tcpdump 官方 map page 的 PCAP-FILTER 部分。
怎么看输出的报文信息
tcpdump 能够抓取并解码多种协议类型的数据报文,如 TCP、UDP、ICMP 等等。虽然这里我们不可能介绍所有的数据报文类型,但可以分析下 TCP 类型的数据报文,来帮助你入门。
tcpdump 抓取的 TCP 报文看起来如下:
sudo tcpdump -i eth0 -SXttttvvvnn -c 3
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
2019-01-23 14:24:11.889635 IP (tos 0x10, ttl 64, id 58162, offset 0, flags [DF], proto TCP (6), length 176)
172.27.0.14.22 > 125.226.39.220.63970: Flags [P.], cksum 0x488a (incorrect -> 0xdcc4), seq 2687384271:2687384395, ack 2449155490, win 314, options [nop,nop,TS val 4064622229 ecr 643829509], length 124
0x0000: 4510 00b0 e332 4000 4006 0f1e ac1b 000e E....2@.@.......
0x0010: 73ec 27d2 0016 f9e2 a02e 3acf 91fb 25a2 s.'.......:...%.
0x0020: 8018 013a 488a 0000 0101 080a f245 3695 ...:H........E6.
0x0030: 2660 0f05 86a8 9dad 926d 03c7 f118 6a29 &`.......m....j)
0x0040: 28f2 03e9 aa82 00e2 7b89 3f8f ac0e 32eb (.......{.?...2.
0x0050: 7b56 9ce3 245f bef7 82a1 56b6 9793 3fa2 {V..$_....V...?.
0x0060: f04c bbd7 396a 8774 fb66 2683 9195 efe3 .L..9j.t.f&.....
0x0070: 70e1 e295 c712 0b93 c168 c348 51cd 66e6 p........h.HQ.f.
0x0080: 9336 20b0 d304 d754 3ed4 6f45 20a0 b574 .6.....T>.oE...t
0x0090: 29c4 9ac0 9d00 166a b9dd 369f 465e fc7b )......j..6.F^.{
0x00a0: 1f11 4795 826f 4cbb 045f 00c5 d908 1ba3 ..G..oL.._......
- 2019-01-23 14:24:11.889635: 详细的可读时间
- IP: ip协议,默认ipv4,如果ipv6则显示ip6
- tos: 表示服务类型,4bit的tos分别表示最小时延,最大吞吐量,最高可靠性,最小费用。这里都是0,表示一般服务,其余4bit废用,置0
- ttl: 数据报的生存时间,每经过一个路由器减1
- id: 对应IP报文头的Identification,用于IP分片重组
- offset: 用于IP分片重组,表示相对于原始未分片的报文的位置
- flags: MF表示有更多分片,DF表示不分片,这里是DF,未使用分片,所以id和offset的值都可以忽略
- proto: 表示协议,可以是TCP,UDP等
- length: 总长度字段,是指整个IP数据报的长度
- 172.27.0.14.22 > 125.226.39.220.63970: 表示数据是从IP为172.27.0.14端口为22发送的IP为115.236.39.210端口为63970,分别对应ip报文头的源地址、目的地址,源端口、目标端口
Flags: tcp报文标记段
值 标志类型 描述 S SYN Connection Start F FIN Connection Finish P PUSH Data push R RST Connection reset . ACK Acknowledgment - chksum: IP首部检验和和TCP报文段(包括TCP首部和数据)检验和
- seq: 代表该数据包包含该数据流的第 2687384271 到 2687384395 字节 这里使用的是绝对序列号
- ack: TCP是可靠连接,所以收到发送方的数据,接受方就会发送ack确认,告诉发送方,接受方已经接收到数据,否则,发送方认为数据没有发送成功,重复发送数据;如果该数据包是数据发送方,ack 值为 1,在数据接收方,该字段代表数据流上的下一个预期字节数据。
- win: 接收窗口大小,它表示接收缓冲区中可用的字节数,后跟 TCP 选项如 MSS(最大段大小)或者窗口比例值
length: 代表数据包有效载荷字节长度。这个长度和 seq 序列号中字节数值长度是不一样的
参考文档
https://www.tcpdump.org/manpages/tcpdump.1.html
https://blog.wains.be/2007/2007-10-01-tcpdump-advanced-filters/
https://linuxwiki.github.io/NetTools/tcpdump.html
https://www.iana.org/assignments/tcp-parameters/tcp-parameters.xhtml