-r参数是sqlmap最可靠的注入检测方式,因其能完整复现含cookie、多header及post体的真实请求,避免手动构造遗漏关键字段导致漏测。

直接用 sqlmap -r 读取完整 HTTP 请求文件是最可靠的方式。只靠 --cookie 参数硬编码值,90% 的场景会漏掉注入点——因为 Cookie 往往只是整个认证上下文的一部分,Header 中的 X-Forwarded-For、User-Agent、Referer 都可能参与后端拼接逻辑。
为什么 --cookie 单独用大概率失效
很多教程教你在命令里写 sqlmap -u "http://x.com" --cookie="uid=1; role=admin",这看似简单,实则埋雷:
- 服务器可能校验
Authorization或X-CSRF-Token,缺一不可,否则返回 302 跳转或 403 拒绝 - Cookie 值本身被 Base64 或 URL 编码过(比如
uname=RHVtYiIgb3JkZXIgYnkgNCM=),--cookie不会自动解码再注入 - 某些框架把多个 Header 合并进日志或 SQL 查询(例如用
User-Agent记录“操作来源”,却未过滤单引号) -
--level=2并不自动覆盖所有 Cookie 字段;它只对--cookie显式指定的键做基础探测,不会枚举uid、sessionid、tracking_id等潜在字段
用 -r 读请求文件:必须满足的三个格式条件
从 Burp Suite 或浏览器 DevTools 复制的原始请求,粘贴进文本文件后,必须满足以下三点,否则 sqlmap 会报 invalid format:
- 第一行必须是完整的请求行,如
GET /user/profile?uid=123 HTTP/1.1,不能只写路径 - Host 头必须存在且正确(
Host: example.com),sqlmap不会自动补全 - 空行分隔请求头与 body:Header 块结束后必须有一个**空行**,哪怕没有 body;若含 POST 数据,空行后紧跟 JSON 或表单内容
错误示例:GET /api/data?id=1\nUser-Agent: sqlmap/1.0(缺 Host、无空行)→ 直接退出;正确写法应为:
GET /api/data?id=1 HTTP/1.1 Host: example.com User-Agent: sqlmap/1.0 Cookie: uid=1; token=abc123
扫描全部 Header 字段:绕过 --level 限制的实操方法
--level 和 --risk 控制的是 payload 覆盖范围,但默认不主动测试 User-Agent、Referer 这类 Header。要强制扫描,必须显式指定:
- 加
-p "User-Agent,Referer,Cookie,X-Forwarded-For":明确告诉sqlmap这些字段可测 - 配合
--skip-static:跳过明显静态值(如Accept: */*),避免浪费时间 - 若目标用 JWT,加
--headers="Authorization: Bearer xxxxx"替代--cookie,否则 Token 会被忽略 - 遇到
400 Bad Request频发,先用--skip="User-Agent"排查是否 UA 字符串过长触发 WAF 截断
从 access_log 反向验证 Header 注入是否真实发生
光靠 sqlmap 扫描不够,攻击载荷是否真进了数据库?看日志最准:
- 用
awk -F'"' '{for(i=2;i 扫所有双引号内字段(UA/Referer/Cookie) - 重点匹配组合:同一
$remote_addr在 60 秒内,$http_user_agent含sqlmap且$request含id=1'→ 高概率已成功 - 如果
$http_referer出现javascript:且响应状态码是200,别急着定性 XSS,先查后端是否把 Referer 写进了 SQL(比如“来源统计”功能)
Header 注入最难察觉的地方在于:它不改变 URL,也不依赖表单提交,只要后端代码里有类似 query("SELECT * FROM logs WHERE ua = '" + req.headers['user-agent'] + "'") 这种写法,就成立。而这种代码,在监控埋点、审计日志、反爬识别模块里太常见了。










