抓包工具

抓包工具

在排查网络问题的时候,我们最常见的需求就是判断从一个机器到另一个机器能否正常通信,这个时候,我们就需要一个工具来帮助我们判断机器是否发出了数据包,发出的网络包发经过了哪些机器,这些机器有没有正常转发,在哪一步中断了,确定了在哪中断的,我们就能对症下药解决问题。

目前市面上有很多好用的抓包工具,比如

这里,我们要将抓包工具和包分析工具区分开,抓包工具和包分析工具都可以获取并输出整个数据包,不过抓包工具主要分析包头,包分析工具主要分析包体,如果问题发生在链路层,则需要抓包工具判断包是否成功发送,是否成功接收。如果问题发生在网络层,也就是 TCP/IP 层面,则需要 TCP 报文的捕获和分析工具。比较常见的网络层问题包括 SSL 握手失败和 TCP 链接中断、重发等。

ngreptcpdumptshark -f 使用的都是 pcap-filter 语法,用于抓取网络包时,对抓到的网络包进行过滤,pcap-filter 官网文档,而 Wireshark 界面上的显示过滤器,以及 tshark -Y 使用的都是 wireshark-filter 语法,用于对已抓取的数据包进行进一步过滤分析,具体请参考 DisplayFilters

tcpdump

参考:tcpdump 工具使用说明 - 雪山飞猪 - 博客园网络/命令行抓包工具 tcpdump 详解

tcpdump 采用命令行方式对本机的网络接口(一般是网卡、交换机)的收到和发送的数据包进行筛选,然后输出到前台,其原理主要是通过对数据包的 header 部分进行分析,然后过滤(tcpdump 也可以输出数据包的包体,但是一般不这样做),tcpdump 的强大主要体现在强大的筛选命令表达式上。这也是我们学习的重点。不带任何选项的 tcpdump,默认会抓取第一个网络接口,且 tcpdump 命令会一直输出日志,只有将 tcpdump 进程终止才会停止抓包。

命令格式:

tcpdump [options] [expression]

具体参数如下,以下 option 不全,完整的 option 列表,请看在安装了 tcpdump 的主机中通过 man tcpdump 查看,或者直接查看 官方文档

tcpdump [ -AbdDefhHIJKlLnNOpqStuUvxX# ] [ -B buffer_size ]
        [ -c count ]
        [ -C file_size ] [ -G rotate_seconds ] [ -F file ]
        [ -i interface ] [ -j tstamp_type ] [ -m module ] [ -M secret ]
        [ --number ] [ -Q|-P in|out|inout ]
        [ -r file ] [ -V file ] [ -s snaplen ] [ -T type ] [ -w file ]
        [ -W filecount ]
        [ -E spi@ipaddr algo:secret,...  ]
        [ -y datalinktype ] [ -z postrotate-command ] [ -Z user ]
        [ --time-stamp-precision=tstamp_precision ]
        [ --immediate-mode ] [ --version ]
        [ expression ]

常用配置项:

输出配置选项:

其他功能性选项:

常用选项也就:

tcpdump -Dtcpdump -i int -nn -e -XX -vvv

筛选命令表达式

pcap-filter 官网文档

表达式用于筛选输出哪些类型的数据包,如果没有给定表达式,所有的数据包都将输出,否则只输出表达式为 true 的包。在表达式中出现的 shell 元字符建议使用单引号包围。

pcap_compile(3PCAP) 用于将字符串编译成过滤器程序。由此产生的过滤器程序可以应用于一些数据包流,以确定哪些数据包将被提供给 pcap_loop(3PCAP), pcap_dispatch(3PCAP), pcap_next(3PCAP), 或者 pcap_next_ex(3PCAP)。

过滤器表达式由一个或多个单元组成。单元通常由 id(名称或数字) 和 id 前的一个或多个限定词组成。一个单元的表达式的格式为

[proto] [dir] [type] ID

三种不同的限定词:

除此之外,还有一些特殊的单元关键字不遵循以上描述的格式:gateway、broadcast、less、greater 和算术表达式。所有的合法的单元都可以在 官网文档Allowable primitives 小节中找到。

更复杂的过滤器表达式是通过使用 and, or 和 not(或等价的:&&||! 来组合单元。例如,host foo and not port ftp and not port ftp-data,表示筛选的数据包要满足 " 主机为 foo 且端口不是 ftp(端口 21) 和 ftp-data(端口 20) 的包 "。为了节省输入,可以省略相同的限定词列表。例如,tcp dst port ftp or ftp-data or domaintcp dst port ftp or tcp dst port ftp-data or tcp dst port domain 意思完全相同,表示包的协议为 tcp 且目的端口为 ftp 或 ftp-data 或 domain(端口 53)。

常用端口和名字的对应关系可在 Linux 系统中的 /etc/service 文件中找到

使用括号 () 可以改变表达式的优先级,但需要注意的是括号会被 shell 解释,所以应该使用反斜线 \ 转义,在需要的时候,还需要将整个表达式包围在引号中。

举个简单的例子:

host foo, host 127.0.0.1 :针对单个主机来进行过滤

net 192.168 :针对某个网段的包来进行过滤;

src host 127.0.0.1dst net 192.168:同时加上来源 (src) 或目标 (dst) 限制

tcp port 21:还可以针对通讯协定侦测,如 tcp, udp, arp, ether 等

host helios and \( hot or ace \):打印 helios<--> hothelios<-->ace 之间通信的数据包,因为没有指定 dir,因此默认是 src or dst,因此直接写 host 会会默认配置入和出两个方向的包。

简单实践

打印 helios<-->hot 或 helios<-->ace 之间通信的数据包,因为没有指定 dir,因此默认是 src or dst,因此直接写 host 会会默认配置入和出两个方向的包。

tcpdump host helios and \( hot or ace \)

打印 ace 与任何其他主机之间通信的 IP 数据包,但不包括与 helios 之间的数据包。

tcpdump ip host ace and not helios

截获主机 hostname 发送的所有数据

tcpdump src host hostname

监视所有发送到主机 hostname 的数据包

tcpdump dst host hostname

监视指定主机和端口的数据包

tcpdump tcp port 22 and host hostname

对本机的 udp 123 端口进行监视

tcpdump udp port 123

监视指定网络的数据包,如本机与 192.168 网段通信的数据包,"-c 10" 表示只抓取 10 个包

tcpdump -c 10 net 192.168

打印所有通过网关 snup 的 ftp 数据包 (注意,表达式被单引号括起来了,这可以防止 shell 对其中的括号进行错误解析)

tcpdump 'gateway snup and (port ftp or ftp-data)'

抓取 ping 包

tcpdump -c 5 -nn -i eth0 icmp

如果明确要抓取主机为 192.168.100.70 对本机的 ping,则使用 and 操作符。

tcpdump -c 5 -nn -i eth0 icmp and src 192.168.100.62

注意不能直接写 icmp src 192.168.100.70,因为 icmp 协议不支持直接应用 host 这个 type。

抓取到本机 22 端口包

tcpdump -c 10 -nn -i eth0 tcp dst port 22

解析包数据

tcpdump -c 2 -q -XX -vvv -nn -i eth0 tcp dst port 22

Wireshark

GitHub 地址:GitHub - wireshark/wireshark:

下载地址:Download Wireshark

官方教程:Wireshark User’s Guide

一个写的非常好的 Wireshark 教程:Wireshark 抓包,带你快速入门 - 农码一生 - 博客园

在 Windows 操作系统下,Wireshark 真的很好用。具体的初步上手的教程,请参考 Wireshark 抓包,带你快速入门 - 农码一生 - 博客园,珠玉在前,我就不写重复的入门教程了。

观察包结构

选择一个封包列表中的一个包,然后查看网络包的内容,工具已经帮我们分好层了。

Frame 层表示的是物理层的数据帧概况,表示整个网络包,其他层从下往上,从 7 层网络协议的高层到低层:从应用层 (HTTP) 到传输层 (TCP) 再到网络层 (IP) 到链路层(MAC 协议,以太网),其对应的数据包也在对应的往前移。这跟我们《用电信号传输 TCP/IP 数据 —— 探索协议栈和网卡》中的 包的基本知识 小节学习到的网络包的结构是一致的。

右侧有两列数据,16 进制数字表示的是报文,字符列表示的是 16 进制的二进制表示的 ASCII 编码的字符。

过滤器

包列表内容刷新的到非常快,根本没法找到自己想要分析的内容。这里我们可以使用显示过滤器,只显示我们想要看的内容。

注意,Wireshark 有两种过滤语言:抓包过滤器(capture filters)和显示过滤器(display filters)

显示过滤器

语法规则::wireshark-filter(4)

显示过滤器允许您将报文中指定协议中的指定字段与特定值进行比较,或者将报文中指定协议中的指定字段与另一个字段进行比较,并检查指定字段或协议的存在性。通过这个来筛选网络包。

比较符

eq, ==    Equal
ne, !=    Not Equal
gt, >     Greater Than
lt, <     Less Than
ge, >=    Greater than or Equal to
le, <=    Less than or Equal to

查找符:

contains     Does the protocol, field or slice contain a value
matches, ~   Does the string match the given case-insensitive
             Perl-compatible regular expression

过滤器支持的方法

upper(string-field) - converts a string field to uppercase
lower(string-field) - converts a string field to lowercase
len(field)          - returns the byte length of a string or bytes field
count(field)        - returns the number of field occurrences in a frame
string(field)       - converts a non-string field to string
max(f1,...,fn)      - return the maximum value
min(f1,...,fn)      - return the minimum value
abs(field)          - return the absolute value of numeric fields

wireshark 将报文中每个协议的每一个字段都确定成了一个 key,字段对应的值都确定为了一个 value,我们编写的过滤规则,实际上就是对 value 进行过滤,value 也是有类型的

ASN.1 object identifier, plain or relative
AX.25 address
Boolean
Byte sequence
Character string
Character, 1 byte
Date and time
Ethernet or other MAC address
EUI64 address
Fibre Channel WWN
Floating point, single or double precision
Frame number
Globally Unique Identifier
IEEE-11073 floating point, 16 or 32 bits
IPv4 address
IPv6 address
IPX network number
Label
OSI System-ID
Protocol
Signed integer, 1, 2, 3, 4, or 8 bytes
Time offset
Unsigned integer, 1, 2, 3, 4, or 8 bytes
VINES address

逻辑表达式

not, !    Logical NOT   (right-associative)
and, &&   Logical AND   (left-associative)
xor, ^^   Logical XOR   (left-associative)
or,  ||   Logical OR    (left-associative)

现在有一个问题,当我们写显示表达式的时候,我们需要知道 Wireshark 支不支持我们想要过滤的协议的字段,此时我们可以查看手册:Wireshark · Display Filter Reference: Index,以下是一些常见协议支持的字段的列表

Wireshark 还提供了一个新手帮助器帮助我们快速编写显示过滤器,菜单地址为:分析->显示过滤器表达式

文档:6.5. The “Display Filter Expression” Dialog Box

有了这个工具,我们就可以不用去查手册了。

常见的显示过滤器表达式:

针对 ip 的过滤

针对协议的过滤

针对端口的过滤(视传输协议而定)

针对长度和内容的过滤

针对 http 请求的一些过滤实例。

我们还可以根据现有的包,直接将其协议字段值作为过滤条件:

抓包过滤器

显示过滤器是指捕获了所有经过网卡的封包,然后在显示的时候进行过滤显示。明显,如果流量过大会导致捕获的内容过多,筛选变得卡顿。所以,我们可以在抓包阶段的时候就过滤掉无用的流量。

抓包过滤器使用的是 libpcap 过滤语言,完整文档在 pcap-filter man page,我们可以发现,跟 tcpdump 的 筛选命令表达式 小节中描述的语法规则是一样的,本质上使用的是同一个模块 pcap-filter

常见抓包场景

我们选中包列表中的一个包,然后右键选择追踪流 -> TCP Stream 这样包列表中就会只展示这一个 TCP 连接中的数据包,方便我们只观察特定的连接,非常方便。

TCP 三次握手

TCP 四次挥手

HTTPS 抓包

配置的方式很简单,参考教程:如何使用 wireshark 抓取 HTTPS 数据包?-CSDN 博客

然后我们抓包就可以直接看到 HTTP 请求的内容了。

tcpdump 配合 Wireshark

看看 tcpdump抓包结合wireshark进行分析_tcpdump+wireshark-CSDN博客tcpdump抓包与wireshark分析 小节