每日一博 - tcpdump小技巧
Posted 小小工匠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日一博 - tcpdump小技巧相关的知识,希望对你有一定的参考价值。
文章目录
- what
- 网络包接收过程
- 网络包发送过程
- 工作原理
- 基础用法
- 不加任何参数,默认情况下将抓取第一个非 lo 网卡上所有的数据包
- 抓取 eth0 网卡上的所有数据包
- 抓包时指定 -n 选项,不解析主机和端口名。
- 抓取指定主机 192.168.1.100 的所有数据包
- 抓取指定主机 10.1.1.2 发送的数据包
- 抓取发送给 10.1.1.2 的所有数据包
- 抓取 eth0 网卡上发往指定主机的数据包,抓到 10 个包就停止
- 抓取 eth0 网卡上所有 SSH 请求数据包,SSH 默认端口是 22
- 抓取 eth0 网卡上 5 个 ping 数据包
- 抓取 eth0 网卡上所有的 arp 数据包
- 使用十六进制输出,当你想检查数据包内容是否有问题时,十六进制输出会很有帮助。
- 只抓取 eth0 网卡上 IPv6 的流量
- 抓取指定端口范围的流量
- 抓取指定网段的流量
- 高级进阶
- 抓取指定客户端访问 ssh 的数据包
- 抓取从某个网段来,到某个网段去的流量
- 抓取来自某个主机,发往非 ssh 端口的流量
- 当构建复杂查询的时候,你可能需要使用引号,单引号告诉 tcpdump 忽略特定的特殊字符,这里的 () 就是特殊符号,如果不用引号的话,就需要使用转义字符
- 基于包大小进行筛选,如果你正在查看特定的包大小,可以使用这个参数
- 过滤 TCP 特殊标记的数据包
- 抓取所有非 ping 类型的 ICMP 包
- 抓取端口是 80,网络层协议为 IPv4, 并且含有数据,而不是 SYN、FIN 以及 ACK 等不含数据的数据包
- 抓取 HTTP 报文,0x4754 是 GET 前两字符的值,0x4854 是 HTTP 前两个字符的值
- 常用选项
- 过滤表达式
- netfilter 过滤的包 tcpdump是否可以抓的到
what
tcpdump 网络工具, 通常用于故障诊断、网络分析 ,甩锅必备, 那还等什么
网络包接收过程
在接收包的过程中,数据包是先经过网络设备层然后才到协议层的。
假如我们设置了 netfilter 规则,在接收包的过程中,工作在网络设备层的 tcpdump 先开始工作。还没等 netfilter 过滤,tcpdump 就抓到包了!
所以,在接收包的过程中,netfilter 过滤并不会影响 tcpdump 的抓包!
网络包发送过程
在网络包的发送过程中,和接收过程恰好相反,是协议层先处理、网络设备层后处理。
如果 netfilter 设置了过滤规则,那么在协议层就直接过滤掉了。在下层网络设备层工作的 tcpdump 将无法再捕获到该网络包。
工作原理
tcpdump 是 Linux 系统中非常有用的网络工具,运行在用户态,本质上是通过调用 libpcap 库的各种 api 来实现数据包的抓取功能.
用户态 tcpdump 命令是通过 socket 系统调用,在内核源码中用到的 ptype_all 中挂载了函数钩子上去。无论是在网络包接收过程中,还是在发送过程中,都会在网络设备层遍历 ptype_all 中的协议,并执行其中的回调。tcpdump 命令就是基于这个底层原理来工作的。
通过上图我们可以发现当数据包到达网卡后,经过数据包过滤器(BPF)筛选后,拷贝至用户态的 tcpdump 程序,以供 tcpdump 工具进行后续的处理工作,输出或保存到 pcap 文件。
数据包过滤器(BPF)主要作用,就是根据用户输入的过滤规则,只将用户关心的数据包拷贝至 tcpdump,这样能够减少不必要的数据包拷贝,降低抓包带来的性能损耗。
基础用法
不加任何参数,默认情况下将抓取第一个非 lo 网卡上所有的数据包
[root@VM-0-7-centos ~]# tcpdump
抓取 eth0 网卡上的所有数据包
[root@VM-0-7-centos ~]# tcpdump -i eth0
抓包时指定 -n 选项,不解析主机和端口名。
这个参数很关键,会影响抓包的性能,一般抓包时都需要指定该选项。
[root@VM-0-7-centos ~]# tcpdump -n -i eth0
抓取指定主机 192.168.1.100 的所有数据包
[root@VM-0-7-centos ~]# tcpdump -ni eth0 host 192.168.1.100
抓取指定主机 10.1.1.2 发送的数据包
[root@VM-0-7-centos ~]# tcpdump -ni eth0 src host 10.1.1.2
抓取发送给 10.1.1.2 的所有数据包
[root@VM-0-7-centos ~]# tcpdump -ni eth0 dst host 10.1.1.2
抓取 eth0 网卡上发往指定主机的数据包,抓到 10 个包就停止
这个参数也比较常用
[root@VM-0-7-centos ~]# tcpdump -ni eth0 -c 10 dst host 192.168.1.200
抓取 eth0 网卡上所有 SSH 请求数据包,SSH 默认端口是 22
[root@VM-0-7-centos ~]# tcpdump -ni eth0 dst port 22
抓取 eth0 网卡上 5 个 ping 数据包
[root@VM-0-7-centos ~]# tcpdump -ni eth0 -c 5 icmp
抓取 eth0 网卡上所有的 arp 数据包
[root@VM-0-7-centos ~]# tcpdump -ni eth0 arp
使用十六进制输出,当你想检查数据包内容是否有问题时,十六进制输出会很有帮助。
[root@VM-0-7-centos ~]# tcpdump -ni eth0 -c 1 arp -X
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
12:13:31.602995 ARP, Request who-has 172.17.92.133 tell 172.17.95.253, length 28
0x0000: 0001 0800 0604 0001 eeff ffff ffff ac11 ................
0x0010: 5ffd 0000 0000 0000 ac11 5c85 _.........\\.
只抓取 eth0 网卡上 IPv6 的流量
[root@VM-0-7-centos ~]# tcpdump -ni eth0 ip6
抓取指定端口范围的流量
[root@VM-0-7-centos ~]# tcpdump -ni eth0 portrange 80-9000
抓取指定网段的流量
[root@VM-0-7-centos ~]# tcpdump -ni eth0 net 192.168.1.0/24
高级进阶
tcpdump 强大的功能和灵活的策略,主要体现在过滤器(BPF)强大的表达式组合能力。
抓取指定客户端访问 ssh 的数据包
$ tcpdump -ni eth0 src 192.168.1.100 and dst port 22
抓取从某个网段来,到某个网段去的流量
$ tcpdump -ni eth0 src net 192.168.1.0/16 and dst net 10.0.0.0/8 or 172.16.0.0/16
抓取来自某个主机,发往非 ssh 端口的流量
$ tcpdump -ni eth0 src 10.0.2.4 and not dst port 22
当构建复杂查询的时候,你可能需要使用引号,单引号告诉 tcpdump 忽略特定的特殊字符,这里的 () 就是特殊符号,如果不用引号的话,就需要使用转义字符
$ tcpdump -ni eth0 'src 10.0.2.4 and (dst port 3389 or 22)'
基于包大小进行筛选,如果你正在查看特定的包大小,可以使用这个参数
小于等于 64 字节:
$ tcpdump -ni less 64
大于等于 64 字节:
$ tcpdump -ni eth0 greater 64
等于 64 字节:
$ tcpdump -ni eth0 length == 64
过滤 TCP 特殊标记的数据包
抓取某主机发送的 RST 数据包:
$ tcpdump -ni eth0 src host 192.168.1.100 and 'tcp[tcpflags] & (tcp-rst) != 0'
抓取某主机发送的 SYN 数据包:
$ tcpdump -ni eth0 src host 192.168.1.100 and 'tcp[tcpflags] & (tcp-syn) != 0'
抓取某主机发送的 FIN 数据包:
$ tcpdump -ni eth0 src host 192.168.1.100 and 'tcp[tcpflags] & (tcp-fin) != 0'
抓取 TCP 连接中的 SYN 或 FIN 包
$ tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0'
抓取所有非 ping 类型的 ICMP 包
$ tcpdump 'icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply'
抓取端口是 80,网络层协议为 IPv4, 并且含有数据,而不是 SYN、FIN 以及 ACK 等不含数据的数据包
$ tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
解释一下这个复杂的表达式,具体含义就是,整个 IP 数据包长度减去 IP 头长度,再减去 TCP 头的长度,结果不为 0,就表示数据包有 data,如果还不是很理解,需要自行补一下 tcp/ip 协议
抓取 HTTP 报文,0x4754 是 GET 前两字符的值,0x4854 是 HTTP 前两个字符的值
$ tcpdump -ni eth0 'tcp[20:2]=0x4745 or tcp[20:2]=0x4854'
常用选项
(一)基础选项
-i:指定接口
-D:列出可用于抓包的接口
-s:指定数据包抓取的长度
-c:指定要抓取的数据包的数量
-w:将抓包数据保存在文件中
-r:从文件中读取数据
-C:指定文件大小,与 -w 配合使用
-F:从文件中读取抓包的表达式
-n:不解析主机和端口号,这个参数很重要,一般都需要加上
-P:指定要抓取的包是流入还是流出的包,可以指定的值 in、out、inout
(二)输出选项
-e:输出信息中包含数据链路层头部信息
-t:显示时间戳,tttt 显示更详细的时间
-X:显示十六进制格式
-v:显示详细的报文信息,尝试 -vvv,v 越多显示越详细
过滤表达式
tcpdump 强大的功能和灵活的策略,主要体现在过滤器(BPF)强大的表达式组合能力。
(一)操作对象
表达式中可以操作的对象有如下几种:
- type,表示对象的类型,比如:host、net、port、portrange,如果不指定 type 的话,默认是 host
- dir:表示传输的方向,可取的方式为:src、dst。
- proto:表示协议,可选的协议有:ether、ip、ip6、arp、icmp、tcp、udp。
(二)条件组合
表达对象之间还可以通过关键字 and、or、not 进行连接,组成功能更强大的表达式。
- or:表示或操作
- and:表示与操作
- not:表示非操作
netfilter 过滤的包 tcpdump是否可以抓的到
关于这个问题,得分接收和发送过程分别来看。
在网络包接收的过程中,由于 tcpdump 近水楼台,所以完全可以捕获到命中 netfilter 过滤规则的包。
但是在发送的过程中,恰恰相反。网络包先经过协议层,这时候被 netfilter 过滤掉的话,底层工作的 tcpdump 还没等看见就啥也没了。
以上是关于每日一博 - tcpdump小技巧的主要内容,如果未能解决你的问题,请参考以下文章