梭梭教你来抓包

Top

网络抓包利器——tcpdump命令


	用简单的话来定义tcpdump,就是:`dump the traffic on a network`,根据使用者的定义对网络上的数据包进行截获的包分析工具。 tcpdump可以将网络中传送的数据包的“头”完全截获下来提供分析。它支持针对`网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句`来帮助你去掉无用的信息。

# Linux抓包原理
    Linux抓包是通过注册一种虚拟的底层网络协议来完成对网络报文(准确的说是网络设备)消息的处理权。当网卡接收到一个网络报文之后,它会遍历系统中所有已经注册的网络协议,例如以太网协议、x25协议处理模块来尝试进行报文的解析处理,这一点和一些文件系统的挂载相似,就是让系统中所有的已经注册的文件系统来进行尝试挂载,如果哪一个认为自己可以处理,那么就完成挂载。
当抓包模块把自己伪装成一个网络协议的时候,系统在收到报文的时候就会给这个伪协议一次机会,让它来对网卡收到的报文进行一次处理,此时该模块就会趁机对报文进行窥探,也就是把这个报文完完整整的复制一份,假装是自己接收到的报文,汇报给抓包模块。

# 注意,
    1. tcpdump只能抓取流经本机的数据包
    2. linux 网卡若开启了 TSO(TCP Segmentation Offload)后,会导致数据包重组分片卸载到了网卡上。所以抓到的大数据包都会超过1500(超过网卡设备的MTU值),意思则是TCPDUMP抓到的是分片之前的数据包;
    3. 开启 TSO 后,tcpdump 会忽略了mss值协商的过程
    4. TCP和UDP校验和是根据有效载荷和IPv4或IPv6报头(称为伪报头)中的选定元素计算的。Linux和Windows在卸载校验和时,将计算来自伪报头的贡献,并将其放在校验和字段中。Wireshark 4.2及以上版本可以检测到这种部分校验和,并将其标记为部分校验和,而不是标记为无效。
    5. 

1. Linux/UNIX的标准I/O提供了全缓冲、行缓冲和无缓冲三种缓冲方式。标准错误是不带缓冲的,终端设备常为行缓冲,而其他情况默认都是全缓冲的
2. 通过 -w 选项将流量都存储在cp.pcap(二进制格式)文件中了. 可以通过 –r 读取raw packets文件 cp.pcap. 
3. 查看

过滤表达式

	过滤表达式大体可以分成三种过滤条件,"协议" 、"类型" 和 "方向",这三种条件的搭配组合就构成了我们的过滤表达式
可通过 `man pcap-filter` 命令查看
# 协议 --- 若未给定协议类型,则匹配所有可能的类型
	tcp/udp/arp/rarp/ip/ether/icmp/ 
# 方向 --- 默认为src or dst
	src/dst/src or dst/src and dst
# 类型 --- 默认 type 为 host  
	host/net/port/portrange
	
# 表达式单元之间常使用连接操作符
	" and / && / or / || / not / ! "
# 协议类型域
	" ICMP : cmp-echoreply, icmp-unreach, icmp-sourcequench, icmp-redirect,icmp-echo, icmp-routeradvert, icmp-routersolicit, icmp-timxceed, icmp-paramprob,icmp-tstamp, icmp-tstampreply, icmp-ireq, icmp-ireqreply, icmp-maskreq,icmp-maskreply "
	"TCP : tcp-fin, tcp-syn, tcp-rst, tcp-push, tcp-ack, tcp-urg"

# 规则
  1、共四个类型的修饰符:host(需要获取报文的主机或IP地址)、net(需要捕获报文的子网)、port(端口)、portrange(端口范围)
  2、传输方向修饰符:src和dst
  3、协议修饰:特定协议:IP、ARP、RARP、ICMP、TCP、UDP and(&&)、or(||)、not(!)

过滤表达式

选项及含义

选项 含义
-i 指定网卡, 一旦找到第一个符合条件的接口,搜寻马上结束。可以使用'any'关键字表示所有网络接口
-n 不解析 IP地址, 显示 主机 IP 和 端口号
-nn 除了-n的作用外,还把端口显示为数值,否则显示端口服务名
-p 不让网络界面进入混杂模式, 可指定特定的协议
-P 指定要抓取的包是流入还是流出的包。可以给定的值为"in"、"out"和"inout",默认为"inout"。
-I 将 tcpdump 的输出变为 "行缓冲" 方式, 便于后续解析
-s 抓取数据包时默认抓取长度为68字节。参数 0 代表完整的数据包,默认将会是65535字节, 设置每个数据包的大小。 防止包截断
-t 不显示时间戳记
-c 抓取指定数目个数据包
-e 输出的每行中都将包括数据链路层头部信息,例如源MAC和目标MAC
快速打印输出。即打印很少的协议相关信息,从而输出行都比较简短
-w 将抓包数据写入指定的文件【原始文件----二进制】,使用 重定向 > 则只是保存显示的结果,而不是原始文件
-r "流量回放", 解析某一时间段的流量, 用于流量分析,从给定的数据包文件中读取数据。使用"-"表示从标准输入中读取
-v 详细显示指令执行过程
-vv 更详细显示指令执行过程
指定与某一主机通信的数据包
-X 将协议头和包内容都原原本本的显示出来,默认以16进制和ASCII的形式显示, 协议分析的利器
-XX 输出包的头部数据,会以16进制和ASCII两种方式同时输出,更详细
-F 从文件中读取抓包的表达式。若使用该选项,则命令行中给定的其他表达式都将失效
-D 显示所有可用网络接口列表
-G 每隔指定的时间,将捕获的报文循环保存为新文件
# 端口号默认标识符,存在于 /etc/services 文件 
# 时间格式
    %d:每月中的第几天,十进制数字从01-31
    %H:当前小时时间,00-23
    %M:当前分钟时间,00-59
    %S:当前秒时间,00-60

协议类型记录

网络协议与编号

....

命令示例

默认启动

tcpdump
# 默认情况下,直接启动tcpdump将默认监视第一个网络接口上所有流过的数据包。
# 默认抓取长度为68字节。
# 默认为全缓冲
# 
# 打印所有可用网络接口列表
tcpdump -D   # 其中 "any" 接口表示捕获所有接口

抓取指定网卡的数据包

tcpdump -i eth0

抓取指定主机的数据包

tcpdump host localhost      # 打印所有进入或离开localhost的数据包
tcpdump host 192.168.43.77  # 截获所有192.168.12.94 的主机收到的和发出的所有的数据包

抓取指定协议数据包

# 抓 ping 包
tcpdump -c 5 -nn -i eth0 icmp and src 192.168.100.62
" 注意不能直接写icmp src 192.168.100.70,因为icmp协议不支持直接应用 host 这个 type "
tcpdump -XXnnvvv -i ens1np0 -e icmp and src net 16.16.16.0/24
# 获取使用ftp端口和ftp数据端口的网络包
sudo tcpdump -s 0 -nn -vvv -XX 'port ftp or ftp-data'
# 抓取 DHCP 数据包
tcpdump -i eth0 -c 8 -s 0 -w /mnt/sdcard/dhcp.pcap 'udp and port 67 and port 68' 

抓取 TCP三次握手中带有 SYN 标记位的网络包

tcpdump -i eth0 'host 172.16.0.11 and host google.com and tcp[tcpflags]&tcp-syn!=0' -c 3 -nn 
" icmptype表示ICMP协议的类型域、icmpcode表示ICMP的code域,tcpflags 则表示TCP协议的标志字段域
# 抓取 SYN 报文 
tcpdump -vxn -i enp129s0f0  'tcp[tcpflags] = tcp-syn'
# 抓取 ACK 报文 
sudo tcpdump -i any 'tcp[tcpflags] & (tcp-syn|tcp-ack) != 0'

提取指定包中的 指定字段

# 需要使用 -I 参数 将默认的全缓冲 转变为 行缓冲
tcpdump -i eth0 port 1111 -l | awk '{print $1}'

PXE 抓包

tcpdump -vv -w ffff.pcap -i eth4 host 172.16.54.80 -AnnSs0
tcpdump -XXnnvvv -w lijingmiao.pcap -i eth4 host 172.16.44.125 and 'port ftp or ftp-data or 67 or 68 or 80' -AnnSs0
# windows 
netsh trace start capture=yes tracefile=c:\computername.etl
netsh trace stop
# 有待验证
tcpdump -i eth4 -XXnnvvv -w lijingmiao.pcap -e 'udp and port 67 or port 68 or port 20 or port 21' and host 172.16.44.125

读取 pcap 文件

tcpdump -r ffff.pcap

抓取 DHCP 数据包

tcpdump -i eth4 -c 10 -XXnnvvv -e 'udp and port 67 and port 68'
tcpdump -i eth0 -c 8 -s 0 -w /mnt/sdcard/dhcp.pcap 'udp and port 67 and port 68' &

抓取 SSH 连接过程数据包

tcpdump -i eth4 -XXnnvvv -e -c 1000 -w shiwei.pacp tcp and host 172.16.44.44 and port 22
# ssh是应用层协议,它的传输层协议是tcp,所以在ssh登录之前必定会有tcp连接。其ssh协议建立连接过程如下:
1、tcp三次握手;
2、ssh协议版本协商;
3、服务器端把公钥发给客户端;
4、加密算法协商;
5、客户端使用公钥对服务器端的密码加密并发送给服务器端;
6、服务器端收到后用自己的私钥解密后得到用户名密码和本地密码对比,验证成功允许登录,否则需要客户端再次输入密码验证

抓取 LLDP 数据包

# 指定协议编号 
tcpdump -XXnnvvv -i ens5f0np0 -e ether  proto 0x88cc
tcpdump  -XXnnvvv   -i  <网口名>   -nev ether proto 0x88cc -w shiwei.pacp

tcpdump -nv -i bond2 -e '((ether  proto 0x0806) or (ether  proto 0x88cc))' 
tcpdump -nv -i ens26f0  '((arp) or (ether  proto 0x88cc))'
# icmp6 + arp + lldp 
tcpdump -n -i bond2  '((icmp6) or (arp) or (ether  proto 0x88cc))'

抓取 LACP 数据包

tcpdump -Xvvnn -i ens26f0np0 -e ether  proto 0x8809
tcpdump -Xvvnn -i ens26f0np0 -e ether  proto 0x8809 -w bond4.pacp

抓取 ARP/ND 数据包

tcpdump -i bond2 icmp6
# 主要看驱动是如何设计的, 一般 bond 接口是双发双收的,bond 子接口是单收的;
# 在抓包时若经过了交换机,要特别注意交换机端口下的 hash 配置,有可能都被 hash 到了同一个子接口;

抓取 ICMP数据包

tcpdump -Xvvnn -i ens26f0np0 -e icmp
# 同时抓取 arp 和 icmp 报文
tcpdump -nv -i vxlan1 arp or icmp

# 抓取 icmp6 报文; ipv6 下的 icmp 报文
tcpdump -i bond2 icmp6

抓取 ARP 数据包

tcpdump -XXnnvvv -i enp0s20f0u4 -e ether  proto 0x0806
or
tcpdump -XXnnvvv -i enp0s20f0u4 -e arp

抓取 RDMA 建链和拆链的交互数据包

# tcpdump -XXnnvvv -i ens5f0np0 -e ether  proto 0x0800
# 添加限速
ib_send_bw -d mlx5_0  -i 1 --report_gbits -D 2 -F -R --burst_size=1000 --rate_limit_type=SW --rate_limit=0.1
# 指定 IB 设备网口名
tcpdump -XXnnvvv -i mlx5_0 -w ens5f0np0_mlx5_0.pacp

抓取 TCP 协议数据包

tcpdump -i eth4  -XXnnvvv -e ether proto 0x0800  -w 0x0800.pcap

自动切割 pcap 文件

# 抓取大量数据并写入文件时,可以自动切割为多个大小相同的文件。例如,下面的命令表示每 3600 秒创建一个新文件 capture-(hour).pcap,每个文件大小不超过 200*1000000 字节
tcpdump  -w /tmp/capture-%H.pcap -G 3600 -C 200
这些文件的命名为 capture-{1-24}.pcap,24 小时之后,之前的文件就会被覆盖。

找出发包数最多的 IP

[root@chongqing ~]# tcpdump -nnn -i ens1f0 -t -c 200 | cut -f 1,2,3,4 -d '.' | sort | uniq -c | sort -nr | head -n 20
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens1f0, link-type EN10MB (Ethernet), capture size 262144 bytes
200 packets captured
224 packets received by filter
0 packets dropped by kernel
    102 IP 33.33.33.22 > 33
     98 IP 33.33.33.33 > 33

常见问题

1. 抓取到的报文长度超过了网卡的MTU

    网卡可能开启了分片卸载功能,例如 TSO, GSO ;
# 查看网卡 offloading 配置
ethtool --show-offload  ethX  或是 ethtool -k  ethX
# 关闭网卡 offloading 配置
ethtool --offload  ethX  rx off  tx off

参考网址

Linux系统诊断必备技能之二:tcpdump抓包工具详解

关于 tcpdump 的抓包总结

抓包神器TCPDUMP的分析总结-涵盖各大使用场景、高级用法

posted @ 2023-11-28 19:58  梭梭666  阅读(97)  评论(0编辑  收藏  举报
返回顶部