文章目录
1,tcpdump
tcpdump采用命令行方式对接口的数据包进行筛选抓取,其丰富特性表现在灵活的表达式上。
不带任何选项的tcpdump,默认会抓取第一个网络接口,且只有将tcpdump进程终止才会停止抓包
1.1, tcpdump基本选项
它的命令格式为:
tcpdump [ -DenNqvX ] [ -c count ] [ -F file ] [ -i interface ] [ -r file ]
[ -s snaplen ] [ -w file ] [ expression ]
抓包选项:
-c:指定要抓取的包数量。注意,是最终要获取这么多个包。例如,指定"-c 10"将获取10个包,但可能已经处理了100个包,只不过只有10个包是满足条件的包。
-i interface:指定tcpdump需要监听的接口。若未指定该选项,将从系统接口列表中搜寻编号最小的已配置好的接口(不包括loopback接口,要抓取loopback接口使用tcpdump -i lo),
:一旦找到第一个符合条件的接口,搜寻马上结束。可以使用'any'关键字表示所有网络接口。
-n:对地址以数字方式显式,否则显式为主机名,也就是说-n选项不做主机名解析。
-nn:除了-n的作用外,还把端口显示为数值,否则显示端口服务名。
-N:不打印出host的域名部分。例如tcpdump将会打印'nic'而不是'nic.ddn.mil'。
-P:指定要抓取的包是流入还是流出的包。可以给定的值为"in"、"out"和"inout",默认为"inout"。
-s len:设置tcpdump的数据包抓取长度为len,如果不设置默认将会是65535字节。对于要抓取的数据包较大时,长度设置不够可能会产生包截断,若出现包截断,
:输出行中会出现"[|proto]"的标志(proto实际会显示为协议名)。但是抓取len越长,包的处理时间越长,并且会减少tcpdump可缓存的数据包的数量,
:从而会导致数据包的丢失,所以在能抓取我们想要的包的前提下,抓取长度越小越好。
输出选项:
-e:输出的每行中都将包括数据链路层头部信息,例如源MAC和目标MAC。
-q:快速打印输出。即打印很少的协议相关信息,从而输出行都比较简短。
-X:输出包的头部数据,会以16进制和ASCII两种方式同时输出。
-XX:输出包的头部数据,会以16进制和ASCII两种方式同时输出,更详细。
-v:当分析和打印的时候,产生详细的输出。
-vv:产生比-v更详细的输出。
-vvv:产生比-vv更详细的输出。
其他功能性选项:
-D:列出可用于抓包的接口。将会列出接口的数值编号和接口名,它们都可以用于"-i"后。
-F:从文件中读取抓包的表达式。若使用该选项,则命令行中给定的其他表达式都将失效。
-w:将抓包数据输出到文件中而不是标准输出。可以同时配合"-G time"选项使得输出文件每time秒就自动切换到另一个文件。可通过"-r"选项载入这些文件以进行分析和打印。
-r:从给定的数据包文件中读取数据。使用"-"表示从标准输入中读取。
所以常用的选项也就这几个:
tcpdump -D
tcpdump -c num -i eth -nn -XX -vvv
1.2, tcpdump过滤条件
1:过滤主机
// 抓取所有经过enp0s3,目的或源地址是 192.168.1.101 的网络数据
tcpdump -i enp0s3 host 192.168.1.101
// 指定源地址
tcpdump -i enp0s3 src host 192.168.1.101
// 指定目的地址
tcpdump -i enp0s3 dst host 192.168.1.101
//如果想要获取主机192.168.1.101除了和主机192.168.1.102之外所有主机通信的ip包
tcpdump ip host 192.168.1.101 and !192.168.1.102
2:过滤端口
// 抓取所有经过 enp0s3,目的或源端口是22的网络数据
tcpdump -i enp0s3 port 22
// 指定源端口
tcpdump -i enp0s3 src port 22
// 指定目的端口
tcpdump -i enp0s3 dst port 22
3:网络过滤
tcpdump -i enp0s3 net 192.168
tcpdump -i enp0s3 src net 192.168
tcpdump -i enp0s3 dst net 192.168
4:协议过滤
tcpdump -i enp0s3 arp
tcpdump -i enp0s3 ip
tcpdump -i enp0s3 tcp
tcpdump -i enp0s3 udp
tcpdump -i enp0s3 icmp
5:常用表达式
非 : ! or "not" (without the quotes)
且 : && or "and"
或 : || or "or"
// 抓取目的地址是192.168.1.254或192.168.1.200端口是80的TCP数据
tcpdump -i enp0s3 '((tcp) and (port 80) and ((dst host 192.168.1.254) or (dst host 192.168.1.200)))'
// 抓取目标MAC地址是00:01:02:03:04:05的ICMP数据
tcpdump '((icmp) and ((ether dst host 00:01:02:03:04:05)))'
// 抓取目的网络是192.168,但目的主机不是192.168.1.200的TCP数据
tcpdump '((tcp) and ((dst net 192.168) and (not dst host 192.168.1.200)))'
1.3, tcpdump抓包示例
[root@server2 ~]# tcpdump -c 2 -q -XX -vvv -nn -i eth0 tcp dst port 22
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
12:15:54.788812 IP (tos 0x0, ttl 64, id 19303, offset 0, flags [DF], proto TCP (6), length 40)
192.168.100.1.5788 > 192.168.100.62.22: tcp 0
0x0000: 000c 2908 9234 0050 56c0 0008 0800 4500 ..)..4.PV.....E.
0x0010: 0028 4b67 4000 4006 a5d8 c0a8 6401 c0a8 .(Kg@[email protected]...
0x0020: 643e 169c 0016 2426 5fd6 1fec 2b62 5010 d>....$&_...+bP.
0x0030: 0803 7844 0000 0000 0000 0000 ..xD........
12:15:54.842641 IP (tos 0x0, ttl 64, id 19304, offset 0, flags [DF], proto TCP (6), length 40)
192.168.100.1.5788 > 192.168.100.62.22: tcp 0
0x0000: 000c 2908 9234 0050 56c0 0008 0800 4500 ..)..4.PV.....E.
0x0010: 0028 4b68 4000 4006 a5d7 c0a8 6401 c0a8 .(Kh@[email protected]...
0x0020: 643e 169c 0016 2426 5fd6 1fec 2d62 5010 d>....$&_...-bP.
0x0030: 0801 7646 0000 0000 0000 0000 ..vF........
2 packets captured
2 packets received by filter
0 packets dropped by kernel
MAC包头占有14字节,即:
000c 2908 9234 :目的mac
0050 56c0 0008 :源mac
0800:type是ipv4
IP包头占有20个字节,即:
4500:4代表ipv4,5说明IP头长20字节,00为服务类型
0028 :IP数据报文总长40字节,包含头部以及数据
4b68 :唯一地标识主机发送的每一份数据报
4000 :第2,3个bit是两个标志DF和MF,后5个是Fragment Offset
4006 :40代表TTL=64,06为tcp协议
a5d7 :checksum
c0a8 6401 :源ip是192.168.100.1
c0a8 643e:目的ip是192.168.100.62
TCP包头占有20个字节,即:
169c :本地端口号5788
0016:目的端口号22
2426 5fd6 :顺序号(Sequence Number),简写为SEQ
1fec 2d62 :确认号(Acknowledgment Number),简写为ACKNUM
5010:5代表tcp头长20字节,最后6bit分别是URG,ACK, PSH,RST,SYN,FIN
0801 :窗口值,用来控制实现流量控制
7646:检验和,TCP的检验和是强制的
0000:紧急指针
1.4, tcpdump高级过滤包头
proto[x:y] : 过滤从x字节开始的y字节数。比如ip[2:2]过滤出3、4字节(第一字节从0开始)
当然,前提是必须了解tcp/ip包头的头部信息。TCP/IP协议栈中各层包头的介绍:
https://blog.csdn.net/qq_15437629/article/details/79560742
1,一般的IP头是20字节,但IP头有选项设置,不能直接从偏移21字节处读取数据。IP头有个长度字段可以知道头长度是否大于20字节。通常第一个字节的二进制值是:01000101,分成两个部分:
0100 = 4 表示IP版本; 0101 = 5 表示IP头32 bit的块数,5 x 32 bits = 160 bits or 20 bytes。如果第一字节第二部分的值大于5,那么表示头有IP选项:
tcpdump 'ip[0] & 0x0f > 5'
2,分片标记 -Exercise: Is DF bit (don’t fragment) set?
当发送端的MTU大于到目的路径链路上的MTU时就会被分片,分片信息在IP头的第七和第八字节:
Bit 0: 保留,必须是0
Bit 1: (DF) 0 = 可能分片, 1 = 不分片
Bit 2: (MF) 0 = 最后的分片, 1 = 还有分片
Fragment Offset字段只有在分片的时候才使用。
要抓带DF位标记的不分片的包,第七字节的值应该是: 64
tcpdump 'ip[6] = 64'
// 匹配分片(包括最后分片)
tcpdump '((ip[6:2] > 0) and (not ip[6] = 64))'
3,匹配TCP数据包的特殊标记
TCP标记定义在TCP头的第十四个字节
+-+-+-+-+-+-+-+-+
|C|E|U|A|P|R|S|F|
|W|C|R|C|S|S|Y|I|
|R|E|G|K|H|T|N|N|
+-+-+-+-+-+-+-+-+
TCP 3次握手中过程如下:
1、源端发送 SYN
2、目标端口应答 SYN,ACK
3、源端发送 ACK
// 只抓取SYN包,第十四字节是二进制的00000010,也就是十进制的2
tcpdump 'tcp[13] = 2'
// 抓取 SYN,ACK (00010010 or 18)
tcpdump 'tcp[13] = 18'
// 抓取SYN或者SYN-ACK
tcpdump 'tcp[13] & 2 = 2'
2,wireshark分析数据包
Wireshark是一款最流行和强大的开源数据包抓包与分析工具,使用tcpdump命令抓包保存pcap文件即可用wireshark打开分析。
上图中标出三块区域,红色框内,是用来显示简单的数据包信息,我们用tcpdump抓包如时候,默认情况是显示成这样的;深蓝框内,是用来显示选中的数据包的详细信息,是按照TCP/IP四层结构显示的,第一行是数据链路层的信息,第二行是网络层信息(IP协议),第三行是传输层信息(TCP协议),第四层是应用层信息(HTTP协议),可以展开第一行用来观察具体的内容;最后一个区域淡蓝色框中,是用来显示此数据包的真实面目。
下面列举一些常用的过滤规则:
过滤IP
ip.src==192.168.1.102 or ip.dst==192.168.1.102
过滤端口
tcp.dstport == 80 // 只显tcp协议的目标端口80
tcp.srcport == 80 // 只显tcp协议的来源端口80
也可以写成tcp.port eq 80 or udp.port eq 80 这样的模式
过滤协议
单独写上tcp、udp、xml、http就可以过滤出具体协议的报文。你也可以用tcp or xml这样格式来过滤。
我们还可以更加具体过滤协议的内容,如tcp.flags.syn == 0x02 表示显示包含TCP SYN标志的封包。
过滤mac地址
eth.src eq A0:00:00:04:C5:84 // 过滤来源mac地址
eth.dst==A0:00:00:04:C5:84 // 过滤目的mac地址
http模式过滤
http.request.method == “GET”
http.request.method == “POST”
http.request.uri == “/img/logo-edu.gif”
http contains “GET”
http contains “HTTP/1.”
// GET包
http.request.method == “GET” && http contains “Host: ”
http.request.method == “GET” && http contains “User-Agent: ”
// POST包
http.request.method == “POST” && http contains “Host: ”
http.request.method == “POST” && http contains “User-Agent: ”
// 响应包
http contains “HTTP/1.1 200 OK” && http contains “Content-Type: ”
http contains “HTTP/1.0 200 OK” && http contains “Content-Type: “
过滤内容
contains:包含某字符串
ip.src==192.168.1.107 and udp contains 02:12:21:00:22
ip.src==192.168.1.107 and tcp contains “GET”
下面介绍一些常见的场景:
2.1,tcp三次握手
从图可知,连接建立伊始,客户机发了3个SYN报文,这也许是为了更快建立连接(假设有个请求报文段丢失,也不至于要等一段时间,重发报文)。接下来分析TCP连接建立过程:
- 客户端通过TCP首部发送一个SYN包请求,seq =0
- 服务器发送ACK(=SYN+1)包确认应答,并发送SYN包请求连接,seq=0,ack=1
- 客户端针对SYN包发送ACK包确认应答,ack=1