传统的文件读漏洞
传统的漏洞模型可以抽象为如下代码
<?php
$filename = $_GET['name'];
file_get_contents($filename);
而常见的文件读写漏洞往往没办法造成很严重的漏洞,在这里提供一种崭新的攻击方式,配合以列目录,可以造成反序列化。
临时文件
当我们使用compress.zlib://
这个php的Wrapper时php会生成临时文件。如图:
// test.php
<?php
putenv("TMPDIR=xxxxx"); // 设置临时文件夹
file_get_contents("compress.zlib://http://www.baidu.com");
除此之外,我们还可以使用上传文件
,PHP_SESSION_UPLOAD_PROGRESS
等功能产生的临时文件。
反序列化
我们知道,当我们使用phar://的Wrapper
时会产生反序列化,我们可以通过如下代码生成。
<?php
class TestObject {
}
@unlink("phar.phar");
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>"); //设置stub,增加gif文件头
$o = new TestObject();
$phar->setMetadata($o); //将自定义meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>
反序列化临时文件
通过上述分析,如果我们可以获得临时文件的地址,我们便可以使用phar包含达到反序列化的目的。这里我们便需要利用两者的时间差进行利用。
时间差的制造
制造时间差,我们有两种主要的方法
大文件
利用协议
Phar协议
Phar协议定义在ext/phar/phar.c
中,其会对文件名称,路径进行一系列的检查,如下图
由于phar协议使用方法形如phar://dir1/dir2/phar.phar/file1.txt
,为了有效判别其对应的phar文件,因为相关文件地址可以为
dir1/dir2/phar.phar
dir1/dir2/phar.phar/file1.txt 其中phar.phar为目录名
Phar协议进行了如下处理
检查是否开头为phar://
然后根据文件中的.,/穷举判断后缀名
最终根据第一次匹配结果进行解析
在上述步骤中我们发现,如果我们生成的文件名没有后缀名是无法利用的,这里用两种方案
在Windows上使用Windows相关特性
使用可以产生文件名带有后缀名Wrapper
Windows相关特性
我们知道在Windows中会忽略文件末尾的.以及空格,所以我们可以使用.假装为文件的后缀名,实际解析时并不会有影响
使用可以产生临时文件的Wrapper
事实上,这个Wrapper并不存在。
类似情况参见Pwnhub比赛中的imageConvent题目
综上我们可以利用这个Windows特征进行利用
文件格式
我们发现,使用compress.zlib://构造临时文件时,其临时文件中的内容与原内容是相同的,这给我们的利用提供了极大的方便。
综合利用
这里我们可以描绘出在Windows环境下一个具体的攻击流程
使用compress.zlib协议产生临时文件,并保留临时文件
通过某种列目录方式列举出该临时文件名
使用phar协议加上WindowsTrick使用该临时文件