Upload-Lab第六關:如何巧妙利用大小寫繞過黑名單驗證?
在第6關,我們將面對一個黑名單驗證機制,服務器通過檢測文件擴展名來拒絕上傳特定類型的文件(例如 .php 文件)。但由于驗證邏輯不完善,可以利用大小寫繞過等技巧進行繞過。如下是第六關的關鍵源碼:
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//刪除文件名末尾的點
$file_ext = strrchr($file_name, '.');
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空
if (!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上傳出錯!';
}
} else {
$msg = '此文件類型不允許上傳!';
}
} else {
$msg = UPLOAD_PATH . '文件夾不存在,請手工創建!';
}
}
?>
通過觀察上述代碼發現,同時過濾掉.htaccess和.ini。但是沒有使用strtolower()函數,可以使用大小寫繞過黑名單把.php格式改為 .Php上傳上去之后,就會自動解析為.php
解法步驟
(1) 準備webshell文件:
創建一個簡單的 PHP 文件 webshell.Php,內容如下:
<?php phpinfo(); ?>
(2) 上傳文件:
在第6關的文件上傳界面,選擇webshell.Php文件并上傳。上傳成功如下圖所示:
(3) 驗證上傳結果
如果上傳成功,你可以通過URL訪問該文件,驗證是否能夠正常執行PHP代碼。在本次復現過程中,通過訪問這個文件的URL提示如下報錯:
經過檢查也沒有發現任何問題,本關卡使用的環境如下:
- nginx-1.24.0
- php-5.3
有知道的小伙伴,麻煩評論區告訴我一聲
在windows平臺下也測試過一遍,還是不能正常解析到Php后綴的文件。如下圖:
總結
第6關通過利用黑名單驗證的缺陷和大小寫繞過技巧,可以成功繞過服務器的文件上傳限制。這一關展示了在實際開發中簡單黑名單驗證的不足之處,強調了安全驗證中細節的重要性。
推薦閱讀:
《Upload-Lab第二關:如何巧妙繞過MIME類型過濾?》
《Upload-Lab第三關:如何巧妙應對黑名單文件后綴檢測?》