tcpdump基本使用

基本用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
监听lo网卡的所有跟7777端口有关的tcp网络请求
tcpdump -i lo tcp port 7777
监听lo网卡的所有跟7777端口有关的tcp网络请求 -X 显示包头和包数据 -s 设定显示截断长度 0表示不截断
tcpdump -i lo -X -s 0 tcp port 7777
查看可用网卡
tcpdump -D
抓取指定网卡的数据包
tcpdump -i eth0
抓取指定数量的包
tcpdump -i eth0 -c 10
保存抓取的的数据包(该文件可以直接被wireshark分析)
tcpdump -w save.file -i eth0
显示ip地址和端口号
tcpdump -n -i eth0 显示ip
tcpdump -nn -i eth0 显示ip+端口
默认情况下抓包结果显示域名+协议名
显示时间戳
tcpdump -tttt -i eth0
抓取指定协议的数据包
tcpdump -i eth0 -p udp
-p也可以省略
抓取指定端口的数据包
tcpdump -i eth0 tcp port 7777
以ASCII值显示抓到的包(WEB经常用到)
tcpdump -A -i eth0
抓取目的ip是8.8.8.8的包
tcpdump -i eth0 -nn dst host 8.8.8.8
抓取源ip是8.8.8.8的包
tcpdump -i eth0 -nn src host 8.8.8.8
抓取包含8.8.8.8的包
tcpdump -i eth0 -nn host 8.8.8.8
抓取源端口是22的包
tcpdump -i eth0 -nn src port 22
抓取源ip是8.8.8.8且端口是22的数据包
tcpdump -i eth0 -nn src host 8.8.8.8 and dst port 22
抓取源ip是8.8.8.8或者端口是22的数据包
tcpdump -i eth0 -nn src host 8.8.8.8 or dst port 22
抓取源ip是8.8.8.8且端口不是22的数据包
tcpdump -i eth0 -nn src host 8.8.8.8 and not port 22
抓取源ip是8.88.8且目的端口是22或源ip是4.4.4.4且目的端口是80的数据包
tcpdump -i eth0 -nn \(src host 8.8.8.8 and dst port 22 \) or \(src host 4.4.4.4 and dst port 80 \)
抓取源ip是172.16.1.59且目的端口是22,或源是172.16.1.68且目的端口是80的数据包
tcpdump -i eth0 -nn 'src host 172.16.1.59 and dst port 22' or 'src host 172.16.1.68 and dst port 80'
tcpdump -nn udp port 53 or host 35.190.27.188
#使用ASCII的方式打印各个包 通常用于查看web信息
tcpdump -i 1 port 8888 -A
-s 截取的包字节长度,默认tcpdump展示96字节的长度,要获取完整的长度可以用-s0或-s1600
-nn 不展示主机名和端口名

分析

20190624156130766736541.png

Flags[P.]:tcp包header部分的第14个字节的P位。

seq 1:54: tcp包的seq号,1是起始值,54是结束值。tcp之所以被认为是流,是因为tcp包锁携带的每一个字节都有标号(seq号)。1:54表明总共有54个字节被接受,其中一个字节是三次握手阶段所使用,所以一共发送的长度是53字节

ack 10: tcp包的ack号,ack101表明seq号为100的字节已被确认收到,下一个期望接收的seq号从101开始

win 255: win表示的是tcp包发送方,作为接受方还可以接手的字节数,这里win255表明ip为17.143.164.37的主机还可以接受255个字节

Options[nop,nop,…]: optins[…]表明的是该tcp包的options区域,nop是no operation的缩写,没什么实际用途,主要用来做padding,以为options区域按协议规定必须是4字节倍数

Options[… TS val 2381386761]: ts val这个值是tcp包的时间戳,不过这个时间戳和设备的系统时间没啥关系,刚开始是随机值,后面随着系统时钟自增长。这个时间戳主要用处是seq序列号越界从0重新开始后,可以确认包的顺序。

Options[… ecr 427050796] ts ecr这个值主要用来计算RTT。比如A发送一个tcp包给B,A会在包里带上TS val,B收到之后再ack包里再把这个值原样返回,A收到B的ack之后再根据本地时钟就可以计算出RTT了。这个值只在ack包里有效,非ack包ecr的值就为0

length 53: 这个length是应用层传来的数据大小,不包括tcp的header。这个值和上面seq 1:54中分析的是一致的。

TCP Flags:

CWR,ECE两个flag是用来配合做congestion control的,一般情况与应用层关系不大。发送方的ECE(ECN-Echo)为0的时候表示出现congestion,接收方回的包里CWR(congestion window reduced)为1表明收到congestion信息并做了处理。我们一般重点看其他6个flag

URG: URG代表Urgent,表明包的优先级高,需要优先传送给对方并处理。像我们平时用的terminal的时候常用ctrl+c来结束某个人物,这种命令产生的网络数据包就需要urgent

ACK: 也就是我们所熟悉的ack包,用来告诉对方上一个数据包已经成功收到。不过一般不会为了ack单独发一个包,都是在下一个要发送的pacet里设置ack位,这属于tcp的优化机制,详见delayed ack

PSH: 接收方接收到P位的flag包后需要马上将包交给应用层处理,一般我们在http request的最后一个包里都能看到P位被设置。

RST: Reset位,表明packet的发送方马上就要断开当前连接了。在http请求结束的时候一般可以看到一个数据包设置了RST位

FIN: Finish位设置了就表示发送方没有更多的数据要发送了,之后就要单向关闭连接了,接收方一般会回一个ack包。接收方再同理发送一个FIN就可以双向关闭连接了。

这8个flag首字母分别是CEUAPRSF,我们常见[S][P][R][F][.],其中[.]是个占位符,没有其他flag被设置的时候就显示这个占位符,一般表示ack

示例

抓取本地

终端1

1
2
3
4
5
6
7
8
$ redis-cli
127.0.0.1:6379> set a 111111
OK
127.0.0.1:6379> get a
"111111"
127.0.0.1:6379> set a
(error) ERR wrong number of arguments for 'set' command

终端2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ tcpdump -i lo0 -ttt -nn port 6379
00:01:16.053308 IP 127.0.0.1.61240 > 127.0.0.1.6379: Flags [P.], seq 20:52, ack 19, win 12436, options [nop,nop,TS val 1687525441 ecr 1687450086], length 32: RESP "set" "a" "111111"
00:00:00.000040 IP 127.0.0.1.6379 > 127.0.0.1.61240: Flags [.], ack 52, win 12749, options [nop,nop,TS val 1687525441 ecr 1687525441], length 0
00:00:00.000062 IP 127.0.0.1.6379 > 127.0.0.1.61240: Flags [P.], seq 19:24, ack 52, win 12749, options [nop,nop,TS val 1687525441 ecr 1687525441], length 5: RESP "OK"
00:00:00.000026 IP 127.0.0.1.61240 > 127.0.0.1.6379: Flags [.], ack 24, win 12436, options [nop,nop,TS val 1687525441 ecr 1687525441], length 0
00:00:07.295898 IP 127.0.0.1.61240 > 127.0.0.1.6379: Flags [P.], seq 52:72, ack 24, win 12436, options [nop,nop,TS val 1687532675 ecr 1687525441], length 20: RESP "get" "a"
00:00:00.000038 IP 127.0.0.1.6379 > 127.0.0.1.61240: Flags [.], ack 72, win 12748, options [nop,nop,TS val 1687532675 ecr 1687532675], length 0
00:00:00.000063 IP 127.0.0.1.6379 > 127.0.0.1.61240: Flags [P.], seq 24:36, ack 72, win 12748, options [nop,nop,TS val 1687532675 ecr 1687532675], length 12: RESP "111111"
00:00:00.000025 IP 127.0.0.1.61240 > 127.0.0.1.6379: Flags [.], ack 36, win 12436, options [nop,nop,TS val 1687532675 ecr 1687532675], length 0
00:00:04.541925 IP 127.0.0.1.61240 > 127.0.0.1.6379: Flags [P.], seq 72:92, ack 36, win 12436, options [nop,nop,TS val 1687537183 ecr 1687532675], length 20: RESP "set" "a"
00:00:00.000054 IP 127.0.0.1.6379 > 127.0.0.1.61240: Flags [.], ack 92, win 12747, options [nop,nop,TS val 1687537183 ecr 1687537183], length 0
00:00:00.000057 IP 127.0.0.1.6379 > 127.0.0.1.61240: Flags [P.], seq 36:86, ack 92, win 12747, options [nop,nop,TS val 1687537183 ecr 1687537183], length 50: RESP "ERR wrong number of arguments for 'set' command"
00:00:00.000028 IP 127.0.0.1.61240 > 127.0.0.1.6379: Flags [.], ack 86, win 12434, options [nop,nop,TS val 1687537183 ecr 1687537183], length 0

FAQ

1.tcpdump: ‘udp’ modifier applied to host

1
2
3
4
5
6
$ tcpdump udp -i eth0 dst host 10.13.80.202 and port 8333 -A
tcpdump: 'udp' modifier applied to host
解决方法:
多个过滤关系间添加逻辑运算符and
tcpdump udp -i eth0 and dst host 10.13.80.202 and port 8333 -A

参考

tcpdump使用

使用tcpdump抓包
Tcpdump的详细用法
Linux tcpdump命令详解