按载荷内容筛选报文
有时筛选条件不是地址端口而是报文内容,例如只想抓某个接口路径的请求,或只想抓返回特定状态码的响应。抓包工具的过滤表达式支持按字节偏移与十六进制字节比较,因此可以定位到传输层载荷的起始位置再匹配关键字。关键在于载荷起点不是固定的:传输层头长度可变,必须用表达式动态计算头部长度,否则偏移会错位,抓到一堆无关报文或者什么都抓不到。
基本信息
| 适用前提 | 明文协议,加密流量无法按内容匹配 |
|---|---|
| 偏移原理 | 从头长度字段换算出载荷起始位置 |
| 常用字节 | 请求方法(如 GET、POST)与响应状态码的十六进制编码 |
| 抓包长度 | 需要抓取完整报文,否则载荷被截断匹配失败 |
| 替代思路 | 加密场景改用域名或地址维度过滤,或在终止加密的一侧抓包 |
典型使用场景
- 只抓某个接口路径的请求:按请求行关键字筛选,减少无关流量
- 定位错误响应:按响应状态码筛选,快速找到异常回复
- 确认请求是否真正到达某台服务器:在两端用同一内容条件抓包
- 验证代理是否改写请求:对比转发前后的请求行内容
- 演示与教学:用少量样本展示明文协议的报文结构
载荷匹配
载荷匹配
# 匹配 GET 请求(按传输层头长度动态计算载荷起点):
tcpdump -nn -i eth0 -A -s 0 'tcp port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'
# 匹配 POST:
tcpdump -nn -i eth0 -A -s 0 'tcp port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354'
# 匹配响应中的 404(在状态行固定位置匹配三个字节):
tcpdump -nn -i eth0 -A -s 0 'tcp port 80 and tcp[((tcp[12:1] & 0xf0) >> 2)+9:3] = 0x343034'
# 落盘后再用字符串工具复核:
tcpdump -nn -i eth0 -s 0 -w /tmp/http.pcap 'tcp port 80'
strings /tmp/http.pcap | grep -E 'GET|POST' | head写法与要点
| 要点 | 说明 | 常见错误 |
|---|---|---|
| 载荷起点 | 由传输层头长度字段换算 | 用固定偏移导致错位 |
| 方法编码 | 请求方法的十六进制表示 | 大小写与字节顺序搞错 |
| 状态码位置 | 响应行中状态码的相对偏移 | 偏移算错抓到无关报文 |
| 抓包长度 | 需要抓全包才能匹配载荷 | 限制长度后载荷被截断 |
| 方向过滤 | 配合地址或方向条件收窄 | 只在单向抓包造成证断 |
加密流量无法按载荷匹配;这类需求要么在加密终止的一侧抓包,要么改用域名与地址维度过滤。