关于phar反序列化漏洞挖掘
反序列化
说到PHP反序列化,大概就是围绕serialize(),unserialize()这两个函数
序列化说通俗点就是把一个对象变成可以传输的字符串
那反序列化不就是颠转过来吗
反序列化漏洞造成原因
服务器能够接收我们反序列化过的字符串、并且未经过滤的把其中的变量直接放进这些魔术方法里面的话,就容易造成很严重的漏洞了
phar反序列化漏洞
phar文件会以序列化的形式存储用户自定义的meta-data;该方法在文件系统函数(file_exists()、is_dir()等)参数可控的情况下,配合phar://伪协议,可以不依赖unserialize()直接进行反序列化操作
phar文件结构
简单来说phar
就是php
压缩文档。它可以把多个文件归档到同一个文件中,而且不经过解压就能被 php 访问并执行,与file://
php://
等类似,也是一种流包装器。
phar
结构由 4 部分组成
stub
phar 文件标识,格式为xxx<?php xxx; __HALT_COMPILER();?>;
manifest
压缩文件的属性等信息,以序列化存储,是主要的攻击点。contents
压缩文件的内容;signature
签名,放在文件末尾;
这里有两个关键点,一是文件标识,必须以__HALT_COMPILER();?>
结尾,但前面的内容没有限制,也就是说我们可以轻易伪造一个图片文件或者pdf
文件来绕过一些上传限制;二是反序列化,phar
存储的meta-data
信息以序列化方式存储,当文件操作函数通过phar://
伪协议解析phar
文件时就会将数据反序列化,而这样的文件操作函数有很多。
受影响函数列表 | |||
---|---|---|---|
fileatime | filectime | file_exists | file_get_contents |
file_put_contents | file | filegroup | fopen |
fileinode | filemtime | fileowner | fileperms |
is_dir | is_executable | is_file | is_link |
is_readable | is_writable | is_writeable | parse_ini_file |
copy | unlink | stat | readfile |
造成原因
phar反序列化可以不用unserialize函数的可控,只需要满足上面的危险函数可控,就可以造成反序列化的攻击,大大增加了反序列化漏洞的挖掘。这里,利用以下代码生成phar文件
漏洞复现
1 | <?php |
发现函数file_exists,存在危险函数可控
1 | <?php |
phar文件是通过stub来标识的,是通过xxx来判断的,所以对后缀并没有要求,修改成gif,通过图片的上传点,上传到目标服务器,在利用phar://协议执行pahr文件。
修复方法
在php.ini中需要设置phar.readonly为off,不是无法生成phar文件
phar.readonly = off