溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么突破JFinal黑名單機制實現(xiàn)任意文件上傳

發(fā)布時間:2021-12-18 14:45:48 來源:億速云 閱讀:137 作者:柒染 欄目:安全技術

今天就跟大家聊聊有關怎么突破JFinal黑名單機制實現(xiàn)任意文件上傳,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據(jù)這篇文章可以有所收獲。

JFinal是國產優(yōu)秀的web框架,短小精悍強大,易于使用。近期團隊內一名小伙伴(LuoKe)在安全測試的時候報了一個很玄學的任意文件上傳,筆者本著知其然必知其所以然的態(tài)度去跟進了一下問題代碼,發(fā)現(xiàn)問題系統(tǒng)在處理上傳文件功能的時候使用了JFinal框架,于是去對該框架上傳文件處的代碼做了一下審計,發(fā)現(xiàn)了JFinal上傳文件的黑名單機制的存在被繞過的風險。目前該漏洞已上報至廠商并修復,下面意在和各位分享一下該漏洞的原理和發(fā)現(xiàn)過程。

關鍵函數(shù)

isSafeFile(UploadFileuploadFile) //jfinal黑名單檢測函數(shù),負責對jsp與jspx類型文件進行過濾

com.oreilly.servlet.MultipartRequest(request, uploadPath, maxPostSize, encoding,fileRenamePolicy) //jfinal處理上傳文件請求類,負責處理上傳請求中的文件與參數(shù)

漏洞發(fā)現(xiàn)

注:漏洞發(fā)現(xiàn)場景由我這邊搭建的測試環(huán)境模擬,并非當時爆出漏洞的實際場景,如有疏漏,還請見諒。

某日下午,團隊內的安全測試組的LuoKe同學分享了一個很有意思的任意文件上傳大體情況如下

1、上傳txt類型文件,提示上傳成功。

怎么突破JFinal黑名單機制實現(xiàn)任意文件上傳

2、上傳jsp文件,顯示上傳失敗。

怎么突破JFinal黑名單機制實現(xiàn)任意文件上傳

3、提交如下數(shù)據(jù)包,顯示上傳失敗,但是給上傳目錄下,可以發(fā)現(xiàn)上傳成功。

怎么突破JFinal黑名單機制實現(xiàn)任意文件上傳

剛看到這種情況,還是比較懵,因為但是比對了一下3個數(shù)據(jù)包,立馬可以明白一個問題,第三個數(shù)據(jù)包是不完整的,它的最末行缺少分割的boundary,為了驗證這個想法,我試了一下如下形式的數(shù)據(jù)包,

怎么突破JFinal黑名單機制實現(xiàn)任意文件上傳

果然是上傳失敗,那就說明一個道理,此次繞過黑名單一定是和程序報錯有關系的。那接下來就是去跟進一下系統(tǒng)代碼,確認一下我們的猜想。

漏洞分析

跟進代碼的時候發(fā)現(xiàn),系統(tǒng)中處理上傳文件的代碼是如下形式:

UploadFile file = getFile("file", "test");

看了一下lib,發(fā)現(xiàn)這個函數(shù)是JFinal框架處理上傳文件的函數(shù),那是不是代表這種利用方式是在JFinal框架中是具有通用性的,所以直接在本地搭了一個JFinal框架去看一下上傳文件的代碼。

首先去看一下黑名單處理函數(shù)

Upload/MultipartRequest.class 100-107

isSafeFile(UploadFile uploadFile) {
     String fileName = uploadFile.getFileName().trim().toLowerCase();
     (!fileName.endsWith() && !fileName.endsWith()) {
         ;
     } {
         uploadFile.getFile().delete();
         ;
     }
 }

可以發(fā)現(xiàn)在處理后綴為jsp和jspx類型的文件的時候,會做一步刪除操作“uploadFile.getFile().delete(); “,看到這一步的時候我就基本心如明鏡了,在這個地方做了刪除操作是不是就代表了,代碼在處理上傳文件的時候先是什么都不管的,上傳完成后再對有問題的文件做刪除。

那我們先去跟一下上傳文件的代碼

Servlet/MultipartRequest.class 84-108

((part = parser.readNextPart()) != ) {
     String name = part.getName();
     (name == ) {
         IOException();
     }
     String fileName;
     (part.isParam()) {
         ParamPart paramPart = (ParamPart)part;
         fileName = paramPart.getStringValue();
         existingValues = (Vector).parameters.get(name);
         (existingValues == ) {
             existingValues = Vector();
             .parameters.put(name, existingValues);
         }
         existingValues.addElement(fileName);
     } (part.isFile()) {
         FilePart filePart = (FilePart)part;
         fileName = filePart.getFileName();
         (fileName != ) {
             filePart.setRenamePolicy(policy);
             filePart.writeTo(dir);
             .files.put(name, UploadedFile(dir.toString(), filePart.getFileName(), fileName, filePart.getContentType()));
         }

可以看到代碼會去輪詢上傳時候傳的每個參數(shù),一旦是文件,就會直接上傳到給定的dir。

現(xiàn)在我們已經(jīng)明確了,無論什么類型的文件都會上傳,但是在抵達黑名單函數(shù)后就會對jsp和jspx文件進行刪除,所以我們接下來要思考的問題就是:

如何讓代碼執(zhí)行到上傳文件后,而又不去執(zhí)行黑名單處理代碼。

總結剛剛我們在測試階段的分析,比較良好的做法就是想辦法讓程序執(zhí)行到黑名單函數(shù)之前報錯,這樣代碼就會停止執(zhí)行到黑名單函數(shù)。那我們去看一下代碼,

Upload/MultipartRequest.class 76-87

.multipartRequest = com.oreilly.servlet.MultipartRequest(request, uploadPath, maxPostSize, encoding, fileRenamePolicy);
 Enumeration files = .multipartRequest.getFileNames();(files.hasMoreElements()) {
     String name = (String)files.nextElement();
     String filesystemName = .multipartRequest.getFilesystemName(name);
     (filesystemName != ) {
         String originalFileName = .multipartRequest.getOriginalFileName(name);
         String contentType = .multipartRequest.getContentType(name);
         UploadFile uploadFile = UploadFile(name, uploadPath, filesystemName, originalFileName, contentType);
         (.isSafeFile(uploadFile)) {
             .uploadFiles.add(uploadFile);
         }
     }
 }

從上傳文件

this.multipartRequest = new com.oreilly.servlet.MultipartRequest(request,uploadPath, maxPostSize, encoding, fileRenamePolicy);

到刪除黑名單文件

this.isSafeFile(uploadFile)

這段代碼之間我們還是有很多操作可以去做的。

我這邊的思路就是,首先保證上傳文件的參數(shù)正常,再在文件參數(shù)后去給一個該接口不存在的參數(shù),于是在輪詢上傳參數(shù)的時候,第一個參數(shù)是文件,直接會被上傳到服務器,而去輪詢第二個參數(shù)的時候,系統(tǒng)就會“報參數(shù)不存在“的異常,從而停止程序的執(zhí)行,繞過黑名單機制。

看到這些代碼也可以明白,第一版的時候LuoKe同學繞過黑名單成功的原因是因為提交的第二個參數(shù)缺少分割boundary導致的報錯,思路同樣可行。

下圖給出poc:

怎么突破JFinal黑名單機制實現(xiàn)任意文件上傳

看一下后臺拋的異常:

怎么突破JFinal黑名單機制實現(xiàn)任意文件上傳

1、 其實我猜測這個漏洞也還有其他可能的利用方式,比如我們常提到的資源競爭(寫一個寫木馬文件的jsp,在上傳的同事瘋狂訪問該上傳路徑,這樣就有可能在刪除文件之前訪問到jsp文件,并寫入木馬成功)。

2、 該漏洞歸根到底還是開發(fā)意識的問題,無論如何,處理上傳文件的時候還是應該牢記先校驗,再上傳。

看完上述內容,你們對怎么突破JFinal黑名單機制實現(xiàn)任意文件上傳有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI