目錄
第18關 滲透實戰
1.打開靶場
2.構造php腳本
3.源碼分析
(1)客戶端源碼
(2)服務的源碼
4.Nginx解析法滲透
(1)缺陷原因
(2)缺陷條件
(3)構造腳本
(4)上傳腳本
(5)訪問腳本
5.生僻字繞過滲透實戰
(1)制作腳本
(2)上傳圖片并bp抓包
(3)生僻字繞過
(4)訪問腳本
本文通過《webug4.0靶場第18文件上傳之前端攔截》來進行滲透實戰。Nginx解析缺陷是指在 Nginx 服務器配置或解析過程中存在的一些安全缺陷,可能導致服務器受到攻擊,本文通過2種不同的方法實現滲透測試。
第18關 滲透實戰
1.打開靶場
打開webug4.0靶場的第18關卡文件上傳之解析關卡,具體如下所示。
http://192.168.71.1/webug4/control/upload_file/upload_file_2.php
2.構造php腳本
構造info.php目的是獲取服務器的php信息,具體如下所示。
<?php phpinfo();?>
隨手上傳php腳本,提示不允許上傳該格式類型,說明第18關卡同樣有文件類型檢查。
3.源碼分析
(1)客戶端源碼
如下客戶端存在js前端驗證的問題,而且使用的白名單繞過要求文件的格式屬于圖片,具體如下所示。
(2)服務的源碼
接下來我們來查看服務端是否進行文件格式過濾,打開upload_file_2.php文件,分析可知存在后綴的白名單過濾,僅允許上傳jpg和png以及gif的文件,注釋后的源代碼如下所示。
<?php
// 引入公共配置文件,通常這里面包含一些全局的函數、常量、配置信息等
// 路徑是相對于當前文件上兩級目錄下的 common 文件夾中的 common.php 文件
require_once "../../common/common.php";// 檢查會話中是否存在 'user' 變量,如果不存在,意味著用戶未登錄
// 使用 header 函數將用戶重定向到登錄頁面
if (!isset($_SESSION['user'])) {header("Location:../login.php");
}// 定義一個允許上傳的文件擴展名數組,這里只允許上傳 .jpg、.png 和 .gif 格式的圖片文件
$filter = array(".jpg", '.png', '.gif');// 檢查上傳文件是否出現錯誤,$_FILES['file']['error'] 會返回上傳文件的錯誤碼
// 如果存在錯誤,直接終止腳本執行
if ($_FILES['file']['error']) {die();
}// 檢查是否有文件被上傳
if ($_FILES['file']) {// 將上傳文件的相關信息(如文件名、臨時文件路徑、錯誤碼等)賦值給變量 $arr$arr = $_FILES['file'];// 獲取上傳文件的擴展名,步驟如下:// strrchr($arr['name'], ".") 從文件名中找到最后一個 '.' 及其后面的部分,即擴展名// strtolower() 將擴展名轉換為小寫,以忽略大小寫的影響// trim() 去除擴展名前后可能存在的空格$file_ext = trim(strtolower(strrchr($arr['name'], ".")));// 檢查獲取到的文件擴展名是否不在允許的擴展名數組 $filter 中// 如果不在,意味著文件類型不被允許if (!in_array($file_ext, $filter)){// 彈出一個警告框提示用戶 "error"echo "<script>alert('error')</script>";// 終止腳本執行die();}// 檢查目標上傳目錄中是否已經存在同名文件// TPMELATE 應該是一個預先定義好的常量,表示上傳目錄的路徑if (file_exists(TPMELATE."/upload/".$arr['name'])){// 如果文件已存在,彈出警告框提示用戶echo "<script>alert('該文件已經存在')</script>";} else {// 將文件名從 UTF - 8 編碼轉換為 gb2312 編碼,可能是為了適應服務器文件系統的編碼要求$filename = iconv("UTF-8","gb2312",TPMELATE."/upload/".$arr['name']);// 將臨時上傳的文件從臨時目錄移動到目標上傳目錄move_uploaded_file($arr["tmp_name"],$filename);// 輸出文件的完整路徑,并終止腳本執行echo $filename;die();}
}// 引入上傳文件頁面的 HTML 文件,通常該文件包含文件上傳表單
require_once TPMELATE."/upload_file_1.html";
這段 PHP 代碼實現了一個帶有登錄驗證和文件類型過濾的文件上傳功能。首先檢查用戶是否登錄,若未登錄則重定向到登錄頁面。接著定義了允許上傳的文件擴展名數組,當有文件上傳時,會檢查文件是否有上傳錯誤,若有則終止腳本。然后獲取文件擴展名,檢查其是否在允許的擴展名列表中,若不在則提示錯誤并終止。之后檢查目標目錄是否已存在同名文件,若不存在則將文件從臨時目錄移動到目標上傳目錄,并輸出文件完整路徑;若存在則提示用戶。最后引入文件上傳頁面的 HTML 文件。?
4.Nginx解析法滲透
(1)Nginx解析缺陷原理
本文利用Nginx文件擴展名解析缺陷來進行滲透,原理是Nginx 在處理文件請求時,可能會根據文件擴展名來確定如何解析和處理該文件。如果配置不當,可能會導致 Nginx 將某些本應被視為靜態文件的文件,按照腳本文件的方式進行解析,從而執行惡意代碼。
當php.ini中 cgi.fix_pathinfo = 1配置開啟時,會產生解析缺陷。
當訪問http://x.x.x.x:8000/parse/index.jpg/x.php時,如果x.php不存在,PHP會遞歸向前解析,如果index.jpg存在就會把index.jpg當做PHP解析,造成了解析缺陷。
(2)缺陷條件
1) cgi.fix_pathinfo = 1
2)IIS 7.0/IIS 7.5/Nginx <0.8.03
3) phpStudy <= 8.1.0.7 (Windows版)
這里要強調,滲透環境要使用較低版本的phpstudy才可以復現此bug,其他版本的未必有此缺陷。
(3)構造腳本
?將info.php復制一份,并重命名為info18.jpg。
(4)上傳腳本
搭建好Nginx滲透環境后,上傳info18.jpg,如下所示。
如上所示點擊上傳按鈕后,可知圖片上傳成功,上傳后的腳本路徑如下所示。
http://192.168.71.1/webug4/template/upload/info18.jpg
(5)訪問腳本
接下來利用Nginx解析法構造腳本的訪問路徑,具體如下所示。
http://192.168.71.1/webug4/template/upload/info18.jpg/x.php
由于x.php不存在,PHP會遞歸向前解析,如果info18.jpg存在就會把info18.jpg當做PHP解析,造成了解析缺陷,從而成功獲取到服務器的php相關信息,具體如下所示。
5.生僻字繞過滲透實戰
(1)制作腳本
將info.php復制一份,并重命名為info18.jpg。
(2)上傳圖片并bp抓包
將info18.jpg上傳,并使用bp抓包,同時將報文發送給repeater。
(3)生僻字繞過
使用生僻字來繞過,具體如下所示。
龘
將文件名進行修改,添加生僻字后文件名如下所示。
info18.php龘.jpg
?修改完畢后點擊發送,如下所示,滲透成功。
(4)訪問腳本
根據上一步中的腳本上傳地址來訪問腳本地址,如下所示滲透成功。