iptables可通过string模块的--hex-string在TCP/UDP载荷中匹配预定义十六进制特征(如NOP指令、DNS域名编码、HTTP恶意路径),需绑定端口协议、限定偏移范围并结合tcpdump验证,但仅适用于明文流量且存在性能与绕过局限。

iptables 本身不直接解析应用层协议,但可通过 string 模块的 --hex-string 功能,在 TCP/UDP 载荷中匹配预定义的十六进制特征码,从而拦截含已知恶意代码特征的报文。关键在于特征需明确、位置可预期,且规则需部署在合适链和顺序中。
用 --hex-string 匹配固定二进制特征
这是最常用、最可靠的方式,适用于已知恶意载荷头部、shellcode 前缀、加密密钥标识、C2 协议魔数等场景:
-
语法简洁:
iptables -A INPUT -p tcp -m string --algo bm --hex-string "|90 90 90 90|" -j DROP—— 匹配连续四个 NOP 指令(0x90),常用于识别简单 shellcode -
支持混合格式:可用竖线分隔字节,明文与 hex 可混写,例如
"|www|05|baidu|03|com|"精确匹配 DNS 查询中的域名编码格式 -
注意偏移范围:默认全包扫描效率低,建议加
--from 0 --to 1024限定在 TCP payload 前段,避免误匹配或性能损耗
结合端口与协议提升准确性
单纯匹配 hex 特征易误杀,必须绑定上下文:
-
DNS 污染阻断:针对 GFW 劫持包中固定的响应结构(如伪造 A 记录后无 Additional 段),可匹配
--dport 53 -p udp --hex-string "|00 00 00 01 00 00 00 00 00 00|"(简化示例,实际需按真实响应构造) -
HTTP 恶意载荷拦截:对未加密 HTTP 流量,匹配 C2 通信特征:
-p tcp --dport 80 -m string --hex-string "|47 45 54 20 2f 6d 61 6c 77 61 72 65|" --from 0 --to 512 -j DROP(即 "GET /malware" 的 ASCII 十六进制) -
拒绝非标准端口滥用:若恶意软件改用 8080 或 4444 端口回连,需同步更新
--dport,不可只盯默认端口
验证与调试不能跳过
规则上线前必须确认是否真能捕获目标流量,否则形同虚设:
-
用 tcpdump 抓包比对:
tcpdump -i any -XX 'tcp port 80 and (tcp[20:4] = 0x47455420)'—— 抓取 TCP 头后第 20 字节起的 4 字节是否为 "GET "(0x47455420),验证 hex 位置是否正确 -
临时加 LOG 规则观察:
iptables -I INPUT -p tcp -m string --hex-string "|DE AD BE EF|" -j LOG --log-prefix "HEX-MATCH: ",再查dmesg看是否触发 - 避免规则被绕过:某些恶意载荷会加随机填充、分片传输或使用 TLS,此时 --hex-string 失效;HTTPS 流量中仅 Client Hello 的 SNI 域名可能被匹配,正文无法识别
注意事项与局限
这类过滤是静态特征防御,有明确边界:
- 依赖 root 权限:Android 设备需已 root,Linux 需有 sudo 或 CAP_NET_ADMIN 能力
- 不适用于加密流量正文:HTTPS、QUIC、TLS 加密后的 payload 不可见,--hex-string 仅能尝试匹配握手阶段的有限字段
-
性能敏感:全包扫描 + 多条 hex-string 规则会显著增加 CPU 开销,生产环境建议控制在 10 条以内,并优先用更高效的
--algo kmp替代默认 bm(尤其对长特征) - 不能替代专业检测:仅适合已知样本快速封堵,无法应对多态、混淆、零日攻击;应配合 suricata、zeek 或 EDR 工具形成纵深防御

















