理解网络层次
OSI 五层协议
物理层:一般是基于电信号进行 bit 流传输
数据链路层: 定义 bit 信号分组方式,常见的协议是 以太网协议 (Ethernet)
Ethernet 数据帧 [帧头,数据,帧尾]
网络层: 划分广播域 / 子网, 一般网络层都是 IP 协议
IP 数据帧 [报头,数据]
传输层: 建立端口到端口的通信, 常见传输层协议有 TCP/UDP
TCP 基于连接,提供可靠传输,面向字节流,三次握手 / 四次挥手 (创建 / 断开连接), 粘包 / 拆包,timewait, 报文头长,总体传输慢,窗口, 拥塞控制
UDP 无连接,尽可能快,不可靠传输,面向报文,过长报文会被分片
应用层

使用 Wireshark 分析数据包时,一般关注的是后面三层, 每层的报文头中都包含了特定信息,在数据层存放更上层的数据
实际报文分析
我们看一个实际的 TCP 报文
1 | ###[ Ethernet ]### |
以太网层 (Ethernet) 中最重要的信息
- 源 MAC 地址
- 目的 MAC 地址
- 上层协议类型
网络层 (IP)
- 源 IP 地址
- 目的 IP 地址
- 版本,长度,标志位,上层协议类型 等
传输层 (TCP)
- 源端口
- 目的端口
- 长度,标志位,序列号 / 应答号 等
用户数据 (示例中的传输层数据不是像 HTTP 一样普通的传输层协议报文, 可能是自定义的协议报文)
选择正确的网口
使用 Wireshark 抓包,首先需要选择正确的网络接口, 如果目的数据包的源 IP 或者目的 IP 在某个网络接口上,就选择该网络接口
一般来说,名称中包含 "以太网" 的接口是通过网线连接的网口; 包含 "WLAN" 的是无线网络的网口
Windows 上可以使用 ipconfig /all
来查看网口信息,
确定要使用的网口
或者鼠标指向对应的网口,在 Tooltip 中查看网口配置的 IP 信息
网络包过滤
开始捕获后一般会发现一个网口上的报文数量非常庞大, 不过滤根本看不清楚
此时我们就需要用到上述网络层次相关知识
网络层过滤 (IP 协议信息过滤)
IP 协议包含了源 IP 地址和目的 IP 地址, 这也是我们在 IP 层上一般需要过滤的内容
1
2
3
4
5
6
7ip // 协议过滤, 非ip协议的报文过滤掉
ip.src == 192.168.10.121 // 源地址过滤
ip.dst == 192.168.10.225 // 目标地址过滤
ip.addr == 192.168.10.66 // 源或者目的地址过滤
ip.dst [not] in {192.168.10.121, 192.168.10.225} // (不)在某几个值中
ip.version == 4 // ip协议过滤
ip.len > 100 // 如果需要, ip协议的其它信息也可以用于过滤传输层过滤 (TCP/UDP 协议信息过滤)
1
2
3
4
5
6
7tcp // 协议过滤, 非tcp协议报文过滤掉
tcp or udp // 协议过滤, 仅保留tcp或者udp报文
tcp.srcport == 8788 // tcp源端口过滤
udp.dstport != 8888 // udp目的端口过滤
udp.dstport not in {8888, 8889}
udp.dstport >= 2000 and udp.dstport <= 9000
udp.port == 12345 // 源或者目的端口过滤应用层 / 用户数据过滤 (可以根据数据帧的特性, 快速过滤出特定协议的数据包)
数据内容过滤时,中括号第一个数字是字节起始位置, 第二个数字是字节长度
1
2
3
4
5
6
7
8
9
10
11
12
13data.data[4:2] == 0300 // tcp/udp负载数据部分第字节开始的两字节为0300的包
tcp.segment_data[0:2] == 4d15
tcp.payload[0:2] == 6f72 // tcp负载数据过滤
udp.payload[0:4] == 6f726179 // udp负载数据过滤
data.len > 0 // 负载数据长度过滤
data.data[0:1] == 6f // tcp/udp负载数据过滤
data.data == 6f:72:61:79 // 整端数据匹配, 十六进制数据可以按照字节用:分开
http.request.method == GET
dns.qry.name == "www.baidu.com"
http.request.uri contains "User" // contains 区分大小写
http.host contains "baidu"
http.request.uri matches "user" // matches 不区分大小写
条件组合
以上的过滤条件都可以自由组合,使用 and
or
not
来连接多个判断条件
1 | tcp.dstport in {12345, 12315} and http and ip.version == 6 |
捕获数据导出
- 直接保存 (Save), 将保存指定时间内所有捕获的数据包, 数据量一般非常大
- 导出特定分组 (Export Specified Packets), 可以选择只保存选中的包, 或者已过滤的包 (Displayed), Range 参数可以选择保存第 xxx 包 - 第 yyy 包
- 导出分组解析结果 (Export Packet Dissections), 选择纯文本 (As Plain Text), 可以过滤导出哪些包,同时可以在 Packet Format 中仅勾选 Packet Bytes, 导出指定包的 hexdump
一般来说为了便于分析,先初步过滤一下,比如 ip 过滤,
然后将原始数据保存 (导出特定分组), 存储为.pcapng
之后再使用 scapy 来进一步分析,重播, 使用 scapy 重播可以取出特定层的原始数据,按照新的源 IP / 目标 IP 发送, 或者发送到特定的 Socket