Phar反序列化
Phar 反序列化概要
除了unserialize()来利用反序列化漏洞之外,还可以利用phar文件以序列化的形式存储用户自定义的meta-data这一特性,扩大php反序列化漏洞的攻击面。该方法在文件系统函数(file_exists()、is_dir()等)参数可控的情况下,配合phar://伪协议,可以不依赖unserialize()直接进行反序列化操作。
来自Secarma的安全研究员Sam Thomas发现了一种新的漏洞利用方式,可以在不使用php函数unserialize()的前提下,引起严重的php对象注入漏洞。
这个新的攻击方式被他公开在了美国的BlackHat会议演讲上,演讲主题为:”不为人所知的php反序列化漏洞”。它可以使攻击者将相关漏洞的严重程度升级为远程代码执行。我们在RIPS代码分析引擎中添加了对这种新型攻击的检测。
什么是Phar文件?
在软件中,PHAR(PHP归档)文件是一种打包格式,通过将许多PHP代码文件和其他资源(例如图像,样式表等)捆绑到一个归档文件中来实现应用程序和库的分发。
Wiki:https://zh.wikipedia.org/wiki/PHAR_(%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F
php通过用户定义和内置的“流包装器”实现复杂的文件处理功能。内置包装器可用于文件系统函数,如(fopen(),copy(),file_exists()和filesize()。phar://就是一种内置的流包装器。
php中一些常见的流包装器如下:
file://-访问本地文件系统,在用文件系统函数时默认就使用该包装器
http://-访问HTTP(s)网址
ftp://-访问FTP(s)URLs
php://-访问各个输入/输出流(I/O streams)
zlib://-压缩流
data://-数据(RFC 2397)
glob://-查找匹配的文件路径模式phar://-PHP 归档
ssh2://-Secure Shell 2
rar://-RARogg://-音频流
expect://-处理交互式的流
phar文件的结构
Phar文件都包含以下几个部分
1.stub
phar文件的标志,必须以xxx_HALT_COMPILER();?>,结尾,否则无法识别。xxx可以为自定义内容。
2.manifest
phar文件本质上是一种压缩文件,其中每个被压缩文件的权限、属性等信息都放在这部分。这部分还会以序列化的形式存储用户自定义的meta-data,这是漏洞利用最核心的地方。
3.content
被压缩文件的内容
4.signature(可空)
签名,放在末尾。
生成一个phar文件:
<?php
// phar.php
class TestObject{
}
@unlink("phar.phar");
$phar= new Phar("phar.phar");//后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER();?>");//设置Stub
$o = new TestObject();
$phar->setMetadata($o);//将自定义的meta-data存入manifest
$phar->addFromString("text.txt","test");//添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>
案例
<?php
class TestObject{
}
function __destruct(){
echo $this->name;
}
if($_GET['file']){
file_exists($_GET['file']);
}
?>
Phar反序列化漏洞的利用条件:
- phar文件要能够上传到服务器端。
- 要有可用的魔术方法作为“跳板”。
- 文件操作函数的参数可控,且:、/、phar等特殊字符没有被过滤。
受影响的文件操作函数:
在跟踪了受影响函数的调用情况后发现,除了所有文件函数,只要是函数的实现过程直接或间接调用了php_stream_open_wrapper。都可能触发phar反序列化漏洞。exif
exif_thumbnail
exif_imagetype
gd
imageloadfont
imagecreatefrom***
hash
hash_hmac_file
hash_file
hash_update_file
md5_file
shal_file
file /url
get_meta_tags
get_headers
standard
getimagesize
getimagesizefromstring
zip
$zip = new ZipArchive();
$res = $zip->open('c. zip');
$zip->extractTo(' phar://test. phar/test');
Bzip /Gzip
$z = ' compress. bzip2://phar:///home/sx/test. phar/test. txt';
$z = ' compress. zlib://phar:///home/sx/test. phar/test. txt';
绕过文件格式限制的例子:
上传html页面:upload.html
后端校验页面:upload.php
一个漏洞页面:index.php(存在file_exits(),eval()函数)
一个上传目录:upload_file/
原生类序列化
原生类同名函数
SessionHandler::open()
当$flag=ZipArchive::OVERWRITE时,就会将Sfilename的文件删除
原生类魔法函数
public SoapClient::SoapClient(mixed $wsdl[,array Soptions])
第一个参数是用来指明是否是wsdl模式,如果为null,那就是非wsdl模式,反序列化的时候会对第二个参数指明的url进行soap请求。
session反序列化
PHP中的session保存
PHP.ini有以下配置项用于控制session有关的设置:
设置session为$_SESSION[“name”]=”Threezh1”;时。不同的引擎保存的session文件内容如下:
Session反序列化的特殊利用
当PHP中’session.upload_progress.enabled’打开时,php会记录上传文件的进度,在上传时会将其信息保存在$_SESSION
中。
上传文件进度的报告就会以写入到session文件中,所以我们可以设置一个与session.upload_progress.name同名的变量(默认名为PHP_SESSION_UPLOAD_PROGRESS),PHP检测到这种同名请求会在$_SESSION’中添加一条数据。我们就可以控制这个数据内容为我们的恶意payload。