目錄
?第19關 文件上傳(畸形文件)
1.打開靶場
2.源碼分析
(1)客戶端源碼
(2)服務器源碼
3.滲透實戰
(1)構造腳本
(2)雙寫繞過
(3)訪問腳本
本文通過《webug4.0靶場第19文件上傳之畸形文件》對客戶端前端和服務端的代碼進行審計,基于代碼審計來分析滲透思路并進行滲透實戰。
?第19關 文件上傳(畸形文件)
1.打開靶場
進入webug4.0靶場的第19關卡文件上傳(畸形文件),完整URL地址如下所示。
http://192.168.71.1/webug4/control/upload_file/upload_file_3.php
進入靶場后發現這是一個注冊賬號的頁面,包含文件上傳的功能,具體如下圖所示。?
2.源碼分析
(1)客戶端源碼
如下所示右鍵發現依舊存在客戶端繞過,在前端通過js腳本使用白名單校驗文件的后綴,具體如下所示。
(2)服務器源碼
如下所示,查看upload_file_3.php代碼,分析可知服務器端過濾了php關鍵字,可以通過雙寫法繞過。
<?php
// 引入公共配置文件,該文件可能包含了一些全局的常量、函數或配置信息
require_once "../../common/common.php";// 檢查會話中是否存在 'user' 變量
// 如果不存在,說明用戶未登錄,將用戶重定向到登錄頁面
if (!isset($_SESSION['user'])) {header("Location:../login.php");
}// 檢查上傳文件是否出現錯誤
// 如果存在錯誤,直接終止腳本執行
if ($_FILES['file']['error']) {die();
}// 檢查是否有文件上傳
if ($_FILES['file']) {// 將上傳文件的相關信息存儲在 $arr 數組中$arr = $_FILES['file'];// 獲取上傳文件的擴展名,并轉換為小寫// strrchr 函數用于返回文件名中從最后一個點開始的部分// trim 函數用于去除字符串首尾的空白字符$file_ext = trim(strtolower(strrchr($arr['name'], ".")));// 檢查擴展名中是否包含 'php'// 如果包含,則將 'php' 從擴展名中移除if (strstr($file_ext, "php")) {$file_ext = str_replace("php", "", $file_ext);}// 檢查目標上傳目錄中是否已經存在同名文件// TPMELATE 可能是一個定義在公共配置文件中的常量,表示模板目錄路徑if (file_exists(TPMELATE."/upload/".$arr['name'])) {// 如果文件已存在,彈出提示框告知用戶echo "<script>alert('該文件已經存在')</script>";} else {// 如果文件不存在,為上傳文件生成一個新的文件名// 使用 time() 函數生成一個時間戳,確保文件名的唯一性// iconv 函數用于將文件名從 UTF-8 編碼轉換為 gb2312 編碼$filename = iconv("UTF-8","gb2312",TPMELATE."/upload/".time().$file_ext);// 將上傳的臨時文件移動到指定的目標路徑move_uploaded_file($arr["tmp_name"], $filename);// 輸出上傳文件的完整路徑,并終止腳本執行echo $filename;die();}
}// 引入上傳文件的 HTML 頁面
require_once TPMELATE."/upload_file_1.html";
這段 PHP 代碼的主要功能是處理文件上傳操作,整個代碼的主要處理邏輯如下所示。
-
登錄驗證:檢查用戶是否已登錄,如果未登錄則重定向到登錄頁面。
- 錯誤檢查:檢查上傳文件是否出現錯誤,如果有錯誤則終止腳本。
- 文件擴展名處理:獲取上傳文件的擴展名,并嘗試將字符串php替換為空(刪掉文件名中的php字符串),以防止上傳 PHP 腳本文件。
- 文件存在性檢查:檢查目標上傳目錄中是否已經存在同名文件,如果存在則提示用戶。
- 文件上傳:如果文件不存在,則為上傳文件生成一個新的文件名,并將臨時文件移動到指定的目標路徑。
- 頁面引入:最后引入上傳文件的 HTML 頁面。
不過這段代碼存在文件上傳繞過的可能性,主要原因如下:
- 擴展名過濾不嚴格:代碼只是簡單地將擴展名中的?
php
?字符串移除,而沒有對擴展名進行全面的白名單驗證。攻擊者可以通過構造特殊的擴展名,如?.pphph
,在移除?php
?后仍然保留?.php,從而可能滲透成功
。 - 編碼轉換問題:使用?
iconv
?函數將文件名從 UTF-8 編碼轉換為 gb2312 編碼,可能會導致文件名被截斷或出現亂碼,攻擊者可以利用這一點繞過文件類型檢查。 - 缺乏文件內容驗證:代碼只檢查了文件的擴展名,沒有對文件的實際內容進行驗證。攻擊者可以將惡意代碼嵌入到圖片或其他允許的文件類型中,形成圖片馬,從而繞過擴展名檢查。
3.滲透實戰
由于對文件的檢查是客戶端處理,故而可以在客戶端上傳圖片,繞過客戶端的前端檢查然后在bp中修改報文并將報文后綴改為info.pphphp 發送到服務器。
(1)構造腳本
將info.php修改為info.jpg,這樣的話可以繞過前端的檢查,如下所示。
bp開啟攔截功能,firefox瀏覽器開啟代理。
(2)雙寫繞過
將info.jpg上傳,并使用bp抓包,同時將報文發送給repeater。
接下來將info.jpg改名為info.pphphp并點擊發送,如下所示。
根據上圖burpsuite工具中的response文件上傳路徑如下所示。
D:/web/phpstudy_pro/WWW/webug4/template/upload/1669881408.php
(3)訪問腳本
訪問上傳的腳本,URL地址如下所示。
http://192.168.71.1/webug4/template/upload/1669881408.php
如下所示雙寫繞過成功,獲取到了服務器的php版本信息。