PHP反序列化绕过__wakeup
题目地址:
newbugku web24
CVE-2016-7124(绕过__wakeup)
- 查看源码,在末尾发现文件所在位置:
-
访问该文件:
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
class Small_white_rabbit{
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_f1ag.php
$this->file = 'index.php';
}
}
}
if (isset($_GET['var'])) {
$var = base64_decode($_GET['var']);
@unserialize($var);
} else {
highlight_file("index.php");
}由此可知,此处考察PHP的反序列化知识:简单分析过后,需要构造指向目标文件的对象,将其序列化后,再base64编码即可。
常见方法如下:
(1) __construct():当对象创建时会自动调用(但在unserialize()时是不会自动调用的)。
(2) __wakeup() :unserialize()时会自动调用
(3) __destruct():当对象被销毁时会自动调用。
(4) __toString():当反序列化后的对象被输出在模板中的时候(转换成字符串的时候)自动调用
(5) __get() :当从不可访问的属性读取数据
(6) __call(): 在对象上下文中调用不可访问的方法时触发
-
问题所在:
__wakeup()
会在unserilize()
之前被调用,而且会修改目标文件。 -
序列化问题:
不同属性的序列化结果不同。
Public属性序列化后格式:成员名
Private属性序列化后格式:%00类名%00成员名
Protected属性序列化后的格式:%00*%00成员名
1
2
3
4
5
6
7
8
9
10
class user{
public $username = "lowbee";
protected $age = 88;
private $income = "-10000";
}
$test = new user();
print_r(serialize($test));由于显示问题,无法显示
%00
:1
O:4:"user":3:{s:8:"username";s:6:"lowbee";s:6:"