sqlmap仅检测和利用SQL注入,不修复漏洞;确认注入点需先验证基础可注入性,检查WAF拦截、参数转义或查询未执行等问题,再通过-v 3观察payload、-r导入请求、--level 3 --risk 2增强探测。

sqlmap 本身不修复漏洞,只检测和利用。把它当“听诊器”用可以,但指望它改代码、加参数绑定、修过滤逻辑——不行。
怎么确认一个 URL 真的有 SQL 注入点?
别一上来就 --dbs,先验证基础可注入性。很多报错是 WAF 拦截、参数被转义、或根本没进数据库查询。
常见错误现象:
-
sqlmap -u "http://x.com?id=1"跑完显示[CRITICAL] all tested parameters do not appear to be injectable—— 很可能没漏洞,也可能是被 WAF 拦了 - 返回页面内容乱码、超时、HTTP 503、或者全是空响应 —— 先检查是否能正常访问原始 URL,再看是不是需要
--cookie或-r request.txt
实操建议:
- 用
-v 3看注入 payload 是否真正发出去,响应里有没有mysql_fetch、ORA-、Microsoft SQL Server这类指纹 - 如果目标是 POST 表单,优先用
-r request.txt导入抓包内容,比手动拼-u可靠得多 - 加
--level 3 --risk 2提高探测强度(默认 level=1 risk=1),但会增加请求量,某些接口会直接封 IP
为什么 --dump 失败但 --tables 成功?
这说明注入点存在,但权限或上下文不足以读取数据。比如当前 DBMS 用户只有 SELECT 权限,没开 FILE_PRIV,或表用了视图/加密字段。
关键差异:
-
--tables依赖information_schema.tables,几乎所有 MySQL/PostgreSQL 都开放读取 -
--dump实际执行的是SELECT col1,col2 FROM table LIMIT X,受行级权限、WHERE 条件、甚至应用层逻辑限制 - Oracle 下必须指定
--schema或用--current-user确认角色,否则--dump直接跳过
实操建议:
- 先跑
--current-user --current-db,确认你“以谁的身份”在查 - 对敏感表加
--where "id>100"缩小范围,避免触发应用层风控 - 若提示
unable to retrieve the table's entries,试试--hex或--encoding=utf8绕过字符集问题
如何把 sqlmap 结果对接到修复流程?
扫描只是第一步,真正卡住开发的是:不知道哪段代码拼了 SQL、哪个参数没过滤、为什么预编译没生效。
可落地的做法:
- 用
--batch+--output-dir ./report/生成结构化 JSON 报告,重点看target和injection字段里的place(GET/POST/Cookie)和parameter(如id、username) - 把
sqlmap发出的最终 payload(-v 3输出里带GET /?id=1%27那行)复制进 Burp Repeater,对照源码找对应 Controller 参数名 - 对
--forms扫出的注入点,直接定位 HTML 表单的action和input name,比猜 URL 参数更准
注意:sqlmap 不会告诉你用的是 MyBatis 的 ${} 还是 #{},也不会标出 JDBC 的 Statement vs PreparedStatement —— 这些得靠人工翻代码。
绕过 WAF 时哪些参数最容易踩坑?
--tamper 是双刃剑。不是加得越多越有效,反而容易触发规则升级。
典型陷阱:
-
--tamper="space2comment,randomcase"在 MySQL 里可能让SELECT变成SeLeCt,但某些 WAF 会统一转小写再匹配,直接失效 -
--tamper="charunicodeencode"对 Oracle 有用,但对 PostgreSQL 可能导致UNICODE函数未定义报错 - 用
--proxy=http://127.0.0.1:8080接 Burp 时,如果 WAF 基于 User-Agent 或 Referer 拦截,sqlmap默认 UA 不在白名单里,得配--user-agent
实操建议:
- 先不用 tamper,用
-v 5看原始请求头和响应状态码,确认是 WAF 拦还是服务端 500 - 单个 tamper 测试,例如
--tamper=apostrophenullencode,比堆 5 个更易定位问题 - 企业级 WAF(如 Cloudflare、阿里云 WAF)通常对
sleep(5)类时间盲注极其敏感,优先换布尔盲注或报错注入
真正难的从来不是跑出 --dbs,而是把 sqlmap.py -u "x?id=1" --dump -T users 的结果,映射回 Spring Boot 的 UserRepository.java 里那行 @Query("SELECT * FROM users WHERE id = " + id)。这个映射过程没有自动化工具,只能靠人盯日志、对参数、翻 commit 记录。

















