对PHP中文件读漏洞利用的新方式

传统的文件读漏洞

传统的漏洞模型可以抽象为如下代码

<?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包含达到反序列化的目的。这里我们便需要利用两者的时间差进行利用。

时间差的制造

制造时间差,我们有两种主要的方法

  1. 大文件
  2. 利用协议

Phar协议

Phar协议定义在ext/phar/phar.c中,其会对文件名称,路径进行一系列的检查,如下图

由于phar协议使用方法形如phar://dir1/dir2/phar.phar/file1.txt,为了有效判别其对应的phar文件,因为相关文件地址可以为

  1. dir1/dir2/phar.phar
  2. dir1/dir2/phar.phar/file1.txt 其中phar.phar为目录名

Phar协议进行了如下处理

  1. 检查是否开头为phar://
  2. 然后根据文件中的.,/穷举判断后缀名
  3. 最终根据第一次匹配结果进行解析

在上述步骤中我们发现,如果我们生成的文件名没有后缀名是无法利用的,这里用两种方案

  1. 在Windows上使用Windows相关特性
  2. 使用可以产生文件名带有后缀名Wrapper

Windows相关特性

我们知道在Windows中会忽略文件末尾的.以及空格,所以我们可以使用.<space>假装为文件的后缀名,实际解析时并不会有影响

使用可以产生临时文件的Wrapper

事实上,这个Wrapper并不存在。
类似情况参见Pwnhub比赛中的imageConvent题目

综上我们可以利用这个Windows特征进行利用

文件格式

我们发现,使用compress.zlib://构造临时文件时,其临时文件中的内容与原内容是相同的,这给我们的利用提供了极大的方便。

综合利用

这里我们可以描绘出在Windows环境下一个具体的攻击流程

  1. 使用compress.zlib协议产生临时文件,并保留临时文件
  2. 通过某种列目录方式列举出该临时文件名
  3. 使用phar协议加上WindowsTrick使用该临时文件

点击收藏 | 1 关注 | 1
登录 后跟帖