風炫安全web安全學習第三十六節課 15種上傳漏洞講解(一)
檔案上傳漏洞
0x01 漏洞描述和原理
檔案上傳漏洞可以說是日常滲透測驗用得最多的一個漏洞,因為用它獲得服務器權限最快最直接,但是想真正把這個漏洞利用好卻不那么容易,其中有很多技巧,也有很多需要掌握的知識,俗話說,知己知彼方能百戰不殆,因此想要研究怎么防護漏洞,就要了解怎么去利用,
網站web應用都有一些檔案上傳功能,比如檔案、圖片、頭像、視頻上傳,當上傳功能的實作代碼沒有嚴格校驗上傳檔案的后綴和檔案型別,此時攻擊者就可以上傳一個webshell到一個web可訪問的目錄上,并將惡意檔案傳遞給PHP解釋器去執行,之后就可以在服務器上執行惡意代碼,進行資料庫執行、服務器檔案管理,服務器命令執行等惡意操作,
根據網站使用及可決議的程式腳本不同,此處可以上傳的惡意腳本可以是PHP、ASP、JSP檔案,也可以是篡改后綴后的這幾類腳本,
WebShell 就是以 asp、php、jsp 或者 cgi 等網頁檔案形式存在的一種命令執行環境,也可以將其稱之為 一種網頁后門,攻擊者在入侵了一個網站后,通常會將這些 asp 或 php 后門檔案與網站服務器 web 目錄 下正常的網頁檔案混在一起,然后使用瀏覽器來訪問這些后門,得到一個命令執行環境,以達到控制網站服務器的目的(可以上傳下載或者修改檔案,操作資料庫,執行任意命令等),
0x02 基礎知識
php的超級全域變數 $_FILE
$_FILES['file']['name'] 客戶端檔案名稱
$_FILES['file']['type'] 檔案的MIME型別
$_FILES['file']['size'] 檔案大小 單位位元組
$_FILES['file']['tmp_name'] 檔案被上傳后再服務器端臨時檔案名,可以在php.ini中指定
要注意的是在檔案上傳結束后,默認的被儲存在臨時檔案夾中,這時必須把他從臨時目錄中洗掉或移動到其他地方,否則,腳本運行完畢后,自動洗掉臨時檔案,可以使用copy或者move_uploaded_file兩個函式
檔案頭content-type欄位校驗(服務端MIME型別檢測)
MIME型別格式: 類別/子類別;引數 Content-Type: [type]/[subtype]; parameter
MIME主類別: text:用于標準化地表示的文本資訊,文本訊息可以是多種字符集和或者多種格式的;
Multipart:用于連接訊息體的多個部分構成一個訊息,這些部分可以是不同型別的資料;
Application:用于傳輸應用程式資料或者二進制資料;
Message:用于包裝一個E-mail訊息;
Image:用于傳輸靜態圖片資料;
Audio:用于傳輸音頻或者音聲資料;
Video:用于傳輸動態影像資料,可以是與音頻編輯在一起的視頻資料格式,
0x02 校驗方式分類&總結
1、客戶端javascript校驗(一般只校驗后綴名)
2、服務端校驗
3、檔案頭content-type欄位校驗(image/gif)
4、后綴名黑名單校驗
5、檔案內容頭校驗(GIF89a)
6、后綴名白名單校驗
7、自定義正則校驗
8、WAF設備校驗(根據不同的WAF產品而定)
0x03 漏洞利用
此次我們用的靶場是:upload-labs: https://github.com/c0ny1/upload-labs
01利用HTTP PUT方式上傳檔案
這個漏洞已經過時,幾乎不會再出此類漏洞
WebDAV是一種基于 HTTP 1.1協議的通信協議.它擴展了HTTP 1.1,在GET、POST、HEAD等幾個HTTP標準方法以外添加了一些新的方法,使應用程式可直接對Web Server直接讀寫,并支持寫檔案鎖定(Locking)及解鎖(Unlock),還可以支持檔案的版本控制,當WebDAV開啟PUT,MOVE,COPY,DELETE方法時,攻擊者就可以向服務器上傳危險腳本檔案,
此時可以使用OPTIONS探測服務器支持的http方法,如果支持PUT,就進行上傳腳本檔案,在通過MOVE或COPY方法改名,當開啟DELETE時還可以洗掉檔案
02繞過前端驗證
<?php
//檔案上傳漏洞演示腳本之js驗證
$uploaddir = 'uploads/';
if (isset($_POST['submit'])) {
if (file_exists($uploaddir)) {
if (move_uploaded_file($_FILES['upfile']['tmp_name'], $uploaddir . '/' . $_FILES['upfile']['name'])) {
echo '檔案上傳成功,保存于:' . $uploaddir . $_FILES['upfile']['name'] . "\n";
}
} else {
exit($uploaddir . '檔案夾不存在,請手工創建!');
}
//print_r($_FILES);
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=gbk"/>
<meta http-equiv="content-language" content="zh-CN"/>
<title>檔案上傳漏洞演示腳本--JS驗證實體</title>
<script type="text/javascript">
function checkFile() {
var file = document.getElementsByName('upfile')[0].value;
if (file == null || file == "") {
alert("你還沒有選擇任何檔案,不能上傳!");
return false;
}
//定義允許上傳的檔案型別
var allow_ext = ".jpg|.jpeg|.png|.gif|.bmp|";
//提取上傳檔案的型別
var ext_name = file.substring(file.lastIndexOf("."));
//alert(ext_name);
//alert(ext_name + "|");
//判斷上傳檔案型別是否允許上傳
if (allow_ext.indexOf(ext_name + "|") == -1) {
var errMsg = "該檔案不允許上傳,請上傳" + allow_ext + "型別的檔案,當前檔案型別為:" + ext_name;
alert(errMsg);
return false;
}
}
</script>
<body>
<h3>檔案上傳漏洞演示腳本--JS驗證實體</h3>
<form action="" method="post" enctype="multipart/form-data" name="upload" onsubmit="return checkFile()">
<input type="hidden" name="MAX_FILE_SIZE" value="https://www.cnblogs.com/fxsec/p/204800"/>
請選擇要上傳的檔案:<input type="file" name="upfile"/>
<input type="submit" name="submit" value="https://www.cnblogs.com/fxsec/p/上傳"/>
</form>
</body>
</html>
繞過方式
去掉前端的提交時候的驗證checkFile 函式既可
演示地址:Pass-01/index.php
03修改MIME型別繞過上傳
MIME type的縮寫為(Multipurpose Internet Mail Extensions)代表互聯網媒體型別(Internet media type),MIME使用一個簡單的字串組成,最初是為了標識郵件Email附件的型別,在html檔案中可以使用content-type屬性表示,描述了檔案型別的互聯網標準,
?php
if($_FILE['userfile']['type'] != "image/gif"){ //檢測content-type
echo "sorry,we only allow uploading GIF images";
exit;
}
else
{
echo "Upload success!";
}
?>
以上是一個簡單的服務器上傳驗證代碼,只要content-type符合image/gif就允許上傳
繞過方式
使用Burp截取上傳資料包,修改Content-Type的值,改為image/gif即可成功繞過上傳webshell
演示地址:Pass-02/index.php
04后綴名黑名單校驗之上傳特殊腳本檔案后綴突破
使用黑名單,禁止上傳.asp,.aspx,.php,.jsp 結尾的檔案,
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array('.asp','.aspx','.php','.jsp');
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//洗掉檔案名末尾的點
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //轉換為小寫
$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 = '不允許上傳.asp,.aspx,.php,.jsp后綴檔案!';
}
} else {
$msg = UPLOAD_PATH . '檔案夾不存在,請手工創建!';
}
}
繞過方式
使用特殊檔案.php,.phtml、php2、php3、php5、phtml、pht,來突破上傳,在特定情況下同樣也可以決議
演示地址:Pass-03/index.php
參考
http://blog.evalshell.com/2020/12/20/風炫安全web安全學習第三十六節課-15種上傳漏洞講解/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/246765.html
標籤:其他
