字节匹配抓 HTTP 请求在做什么
HTTP 请求行以方法名开头,因此可以在 TCP 载荷的前四个字节上做精确匹配:GET 加一个空格对应十六进制 47 45 54 20。难点在于 TCP 头部长度可变,必须先用头部长度字段算出载荷起始位置,再取四个字节比较。这样写出来的过滤器能精确抓取请求报文,比只按端口过滤干净得多。它只适用于明文 HTTP/1.x,加密流量与 HTTP/2 无法用这种方法匹配。
基本信息
| 匹配原理 | TCP 头长度高四位乘四得到载荷偏移,再比较前四字节 |
|---|---|
| GET 请求 | 偏移处四字节等于 47 45 54 20 |
| POST 请求 | 等于 50 4f 53 54 |
| HEAD 请求 | 等于 48 45 41 44 |
| 适用范围 | 仅明文 HTTP/1.x,加密与 HTTP/2 无效 |
典型使用场景
- 在高流量口精确筛出请求,数据量比只看端口小一个量级
- 统计请求数量:配合计数命令得到真实的调用频次
- 排查是否真的发出了某类请求:结合目的地址确认调用方向
- 与响应端口条件配合:请求与响应分开统计,定位单向缺失
- 取证与合规场景:确认明文中是否传输了特定方法或参数
常用示例
常用示例
tcpdump -i eth0 -nn -s 0 -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420' # 抓 GET
tcpdump -i eth0 -nn -s 0 'dst port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354' # 抓 POST
tcpdump -i eth0 -nn -s 0 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x48454144' # 抓 HEAD
tcpdump -i eth0 -nn -s 0 -c 20 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420 and host 10.0.0.9' # 限定来源
tcpdump -nn -r a.pcap -s 0 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420' | wc -l # 离线统计方法名与字节值
| 方法 | 十六进制 | 说明 |
|---|---|---|
| GET | 47 45 54 20 | 最常见的读取请求,容易验证表达式 |
| POST | 50 4f 53 54 | 提交类请求,常用于确认数据上报方向 |
| HEAD | 48 45 41 44 | 只取头部,响应无正文 |
| PUT | 50 55 54 20 | 上传或替换资源 |
| DELETE | 44 45 4c 45 | 删除请求,通常与鉴权一起观察 |
| OPTIONS | 4f 50 54 49 | 跨域预检常出现的探测请求 |
表达式依赖 TCP 头部长度字段计算偏移,因此对带选项的报文同样有效。写错偏移会静默匹配不到,先用一条已知的请求验证表达式再挂到长时间抓包上。
该写法只对明文 HTTP/1.x 有效。加密流量、HTTP/2 与 HTTP/3 的载荷结构完全不同,用字节匹配会得不到任何结果,此时应改用端口级过滤或先解密。
验证与统计
验证与统计
tcpdump -i eth0 -nn -s 0 -A -c 3 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420' # 先看三条验证
tcpdump -i eth0 -nn -s 0 -c 100 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420' | wc -l # 统计样本量
tshark -r a.pcap -Y 'http.request.method == "GET"' | wc -l # 落盘后用协议解析统计判读要点
- 命中数量为零时先在已知请求上验证表达式,再怀疑环境是否全部加密
- 抓到的报文只有请求没有响应,说明响应方向需要用源端口条件另外统计
- 分片报文里只有首片带请求行,后续分片没有方法名,统计时不会重复计数
- 把偏移写死成固定值会在带选项的报文上失效,必须用头部长度字段动态计算