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代码文件和其他资源(例如图像,样式表等)捆绑到一个归档文件中来实现应用程序和库的分发。

  1. Wikihttps://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中一些常见的流包装器如下:

  1. file://-访问本地文件系统,在用文件系统函数时默认就使用该包装器
  2. http://-访问HTTP(s)网址
  3. ftp://-访问FTP(s)URLs
  4. php://-访问各个输入/输出流(I/O streams)
  5. zlib://-压缩流
  6. data://-数据(RFC 2397)
  7. glob://-查找匹配的文件路径模式phar://-PHP 归档
  8. ssh2//-Secure Shell 2
  9. rar://-RARogg://-音频流
  10. expect://-处理交互式的流

phar文件的结构

Phar文件都包含以下几个部分

  1. 1.stub
  2. phar文件的标志,必须以xxx_HALT_COMPILER();?>,结尾,否则无法识别。xxx可以为自定义内容。
  3. 2.manifest
  4. phar文件本质上是一种压缩文件,其中每个被压缩文件的权限、属性等信息都放在这部分。这部分还会以序列化的形式存储用户自定义的meta-data,这是漏洞利用最核心的地方。
  5. 3.content
  6. 被压缩文件的内容
  7. 4.signature(可空)
  8. 签名,放在末尾。

生成一个phar文件:

  1. <?php
  2. // phar.php
  3. class TestObject{
  4. }
  5. @unlink("phar.phar");
  6. $phar= new Phar("phar.phar");//后缀名必须为phar
  7. $phar->startBuffering();
  8. $phar->setStub("<?php __HALT_COMPILER();?>");//设置Stub
  9. $o = new TestObject();
  10. $phar->setMetadata($o);//将自定义的meta-data存入manifest
  11. $phar->addFromString("text.txt","test");//添加要压缩的文件
  12. //签名自动计算
  13. $phar->stopBuffering();
  14. ?>

案例

  1. <?php
  2. class TestObject{
  3. }
  4. function __destruct(){
  5. echo $this->name;
  6. }
  7. if($_GET['file']){
  8. file_exists($_GET['file']);
  9. }
  10. ?>

Phar反序列化漏洞的利用条件:

  1. phar文件要能够上传到服务器端。
  2. 要有可用的魔术方法作为“跳板”。
  3. 文件操作函数的参数可控,且:、/、phar等特殊字符没有被过滤。

    受影响的文件操作函数:

    反序列化漏洞(二) - 图1
    在跟踪了受影响函数的调用情况后发现,除了所有文件函数,只要是函数的实现过程直接或间接调用了php_stream_open_wrapper。都可能触发phar反序列化漏洞。
    1. exif
    2. exif_thumbnail
    3. exif_imagetype
    4. gd
    5. imageloadfont
    6. imagecreatefrom***
    7. hash
    8. hash_hmac_file
    9. hash_file
    10. hash_update_file
    11. md5_file
    12. shal_file
    13. file /url
    14. get_meta_tags
    15. get_headers
    16. standard
    17. getimagesize
    18. getimagesizefromstring
    19. zip
    20. $zip = new ZipArchive();
    21. $res = $zip->open('c. zip');
    22. $zip->extractTo(' phar://test. phar/test');
    23. Bzip /Gzip
    24. $z = ' compress. bzip2://phar:///home/sx/test. phar/test. txt';
    25. $z = ' compress. zlib://phar:///home/sx/test. phar/test. txt';

    绕过文件格式限制的例子:

    1. 上传html页面:upload.html
    2. 后端校验页面:upload.php
    3. 一个漏洞页面:index.php(存在file_exits(),eval()函数)
    4. 一个上传目录:upload_file/
    image.png

    原生类序列化

    原生类同名函数
    SessionHandler::open()
    当$flag=ZipArchive::OVERWRITE时,就会将Sfilename的文件删除
    image.png
    原生类魔法函数
    public SoapClient::SoapClient(mixed $wsdl[,array Soptions])
    第一个参数是用来指明是否是wsdl模式,如果为null,那就是非wsdl模式,反序列化的时候会对第二个参数指明的url进行soap请求。
    image.png
    image.png
    image.png

    session反序列化

    PHP中的session保存
    PHP.ini有以下配置项用于控制session有关的设置:
    image.png
    设置session为$_SESSION[“name”]=”Threezh1”;时。不同的引擎保存的session文件内容如下:
    image.png
    image.png
    image.png

    Session反序列化的特殊利用

    当PHP中’session.upload_progress.enabled’打开时,php会记录上传文件的进度,在上传时会将其信息保存在$_SESSION中。
    image.png
    上传文件进度的报告就会以写入到session文件中,所以我们可以设置一个与session.upload_progress.name同名的变量(默认名为PHP_SESSION_UPLOAD_PROGRESS),PHP检测到这种同名请求会在$_SESSION’中添加一条数据。我们就可以控制这个数据内容为我们的恶意payload。
    image.png