如何针对特定WAF定制sqlmap的tamper脚本?
SQLMAP详细参数详解
在渗透测试中,面对部署了特定规则的WAF,直接使用sqlmap往往会被拦截。此时,编写符合目标WAF特征的tamper脚本成为突破的关键手段。本文从技术原理出发,逐步拆解如何为任意WAF量身定制tamper脚本,帮助安全工程师在实战中快速构建“隐形”payload。
了解WAF的检测机制
大多数WAF会基于正则、关键字或行为分析对请求体进行过滤。ModSecurity、Cloudflare、Imperva等产品各自拥有独特的规则集合,例如检测SQL关键字、单引号、注释符或异常的User‑Agent。要想绕过,需要先抓包确认哪些字符被“吃掉”,哪些触发了404/403响应。常见的抓包工具包括Burp Suite的拦截器或Fiddler的自动化脚本。
tamper脚本的工作原理
tamper脚本本质上是一个Python函数,接受原始payload字符串并返回经加工后的版本。sqlmap在每一次注入尝试前都会调用该函数,因而可以在不改变注入逻辑的前提下,对字符进行编码、分割或混淆,从而躲避WAF的规则检测。
定制流程
- 确认目标WAF类型:通过响应头、错误页面或公开文档定位具体产品。
- 收集拦截特征:使用Burp抓包,记录哪些payload被改写或直接返回403。
- 选择合适的加工手段:字符编码(%xx、Unicode)、空格替代(/**/)、大小写混淆等。
- 编写tamper脚本:在
tamper/目录下新建my_waf.py,实现def tamper(payload, **kwargs):。 - 本地测试:使用
sqlmap -u "http://example.com/vuln?id=1" --tamper=my_waf观察是否仍被拦截。 - 迭代优化:根据返回的错误信息继续微调字符替换,直至成功注入。
#!/usr/bin/env python
# my_waf.py – 针对ModSecurity的简单绕过
import urllib.parse
def tamper(payload, **kwargs):
# 将单引号替换为 %27,空格替换为 %20,避免关键字直接出现
payload = payload.replace("'", "%27")
payload = payload.replace(" ", "%20")
# 对常见SQL关键字进行大小写混淆
for kw in ["SELECT","UNION","AND","OR"]:
payload = payload.replace(kw, kw[0] + kw[1:].lower())
return payload
实战案例:针对ModSecurity的绕过
某金融系统使用ModSecurity默认规则集,检测到UNION SELECT时直接返回403 Forbidden。通过上述脚本,将UNION改写为UniOn、空格编码为%20后,sqlmap成功发起盲注并获取了数据库版本信息。整个过程从抓包定位拦截点到脚本迭代,仅用了两次调试,节省了大量手工尝试的时间。
调试与迭代技巧
1)在脚本内部打印payload,配合--batch模式快速查看每轮请求的实际内容。
2)利用--skip-waf选项让sqlmap先忽略自带的WAF识别,以免误判。
3)结合--level=5与--risk=3,让sqlmap生成更复杂的payload,迫使自定义脚本承担更细致的混淆工作。
掌握了上述思路后,面对市面上几乎所有商业WAF,都能在数分钟内写出对应的tamper脚本,实现“看不见、摸不着”的注入路径。只要不停观察、不断编码,WAF的防线也会在不经意间被拆穿

参与讨论
这思路挺实用的
ModSecurity的哪个规则最容易被%20空格编码绕过?