Java程式碼審計篇 - ofcms系統審計思路講解 - 篇3 - 檔案上傳漏洞審計

leyilea發表於2024-09-23

Java程式碼審計篇 | ofcms系統審計思路講解 - 篇3 | 檔案上傳漏洞審計

1 檔案上傳程式碼審計【有1處】

檔案上傳漏洞我們需要著重關注的是檔案在被java程式碼解析到儲存下來之間有無驗證過濾,因此什麼樣的上傳方式,什麼樣的儲存方式都不重要,大家著重關注程式碼對檔案的驗證過濾手段即可。

檔案上傳程式碼審計常搜尋的關鍵字如下:

file
upload
write
fileName
filePath
getPart
FileOutputStream
transferTo
getRealPath
FileItem
ServletFileUpload
DiskFileItemFactory
....

1.1 可疑點1【無漏洞】

1.1.1 直接搜尋upload關鍵字

1.1.2 選擇第一個,點進去分析一下

類名為UeditorAction

可以在當前頁面搜尋upload關鍵字,也可以同時參考該類的所有方法名稱。

大概看一下,四個方法的寫法是差不多的:

  • getFile()方法的第2個引數不太相同,透過引數名稱uploadPath可以大概判斷出來,這個參數列示的是檔案上傳路徑,也就是說呼叫不同的方法會儲存到不同的目錄。

透過下方的msg.put("url", "/upload/image/" + file.getFileName())也可以大體確定這一點;

當然msg.put不是用來儲存檔案用的,只是返回的資訊而已。

uploadImage()方法為例進行分析,可以看到,這個方法內部與儲存檔案相關的程式碼就前面兩行(後面的都是關於返回的訊息相關了),即

  UploadFile file = this.getFile("file", "image");
  file.getFile().createNewFile();

我們先分析下this.getFile()方法

1.1.3 分析this.getFile()方法

點選進入看一下:

getFile()方法,首先呼叫了getFiles(uploadPath),跟進之下:就在上面

可以看到這裡先做了個判斷,判斷request物件是否是MultipartRequest型別的物件,如果不是則建立一個新的MultipartRequest型別的物件,總之就是保證request物件是MultipartRequest型別的物件。

然後呼叫.getFiles()方法。

額外的:其中request物件就是HttpServletRequest,相關程式碼如下:

這裡目前來看,需要有兩個點需要分析:

  • 1)new MultipartRequest(request, uploadPath)
  • 2)request.getFiles()

接下來先分析new MultipartRequest(request, uploadPath)

1.1.4 分析new MultipartRequest(request, uploadPath)

點選進入:

一個構造方法,先呼叫了父類,然後呼叫了wrapMultipartRequest()

  • 父類可以點選去看看,其實沒啥
  • 著重看下wrapMultipartRequest()

點選進入wrapMultipartRequest(),程式碼比較長,大概意思已標註:

其中我們需要關注的是檔案的過濾程式碼,也就是圖中紅框位置:

if (isSafeFile(uploadFile)) {
            uploadFiles.add(uploadFile);
}

這裡面呼叫了一個isSafeFile()方法,進去看一看:

1.1.5 分析isSafeFile()方法

發現這裡有了驗證過濾:

  • 首先是對檔名去空白字元,然後轉成小寫
  • 其次是檔名如果是.jsp或者.jspx結尾則刪除,返回false

師傅們可以想一下有無繞過手段

如果沒有問題,則將檔案add進入uploadFiles列表中。

1.1.6 分析request.getFiles()方法

然後接下來點進2.1.3步驟中的this.getFile()方法中的getFiles()方法進行分析

進來之後,發現方法中沒有太多語句,只是直接返回了uploadFiles,也就是上一步所說的uploadFiles列表,這裡面存放的是經過過濾的檔案。

到此為止,其實已經差不多了,已經找到了檔案的過濾方式:

  • 首先是對檔名去空白字元,然後轉成小寫
  • 其次是檔名如果是.jsp或者.jspx結尾則刪除,返回false

剛開始所說的uploadImage()方法中的第2條語句 file.getFile().createNewFile();這裡沒什麼,就是透過返回的經過過濾的file物件來建立一個新的檔案。

那麼接下來可以驗證一下:

1.1.7 驗證檔案的過濾方式,並嘗試找到繞過之法(畢竟是黑名單[\偷笑])

根據前面所說的路由機制,可以確定此uploadImage()方法的呼叫需要訪問admin/ueditor/uploadImage.json

前端找一下唄。怎麼找?搜唄...哎真麻煩,說實話好難找啊

根據路徑大致判斷範圍:ueditor,貌似在哪見過這個詞?

原來是個富文字編輯器,還好我“見多識廣”哈哈

那就在前端找一下哪裡有富文字,同時在控制檯搜尋著ueditor:

經過了九九八十一天,終於找到了。

admin/ueditor/uploadImage.json應該就是在富文字上傳圖片時觸發的吧:嘗試一下

uploadImage()方法打上斷點,yakit也開啟抓包攔截

先來個普通圖片試一試

大事不妙!之前分析的路由機制不太對,這裡怎麼是/admin/ueditor/handler.html?action=uploadImage

  • 這裡我懶得分析了,懂的師傅可以留個言~麼麼噠

不過沒關係,放包!uploadImage()方法觸發了。也就是功能和方法對上了!

在下面也可以看到上傳路徑在:D:\Program Files\tomcat\apache-tomcat-8.0.17\webapps\ofcms_admin_war\upload\image

當然在返回包中,也可以看到上傳路徑

訪問一下,可以訪問到。

接下來嘗試繞過一下,已知檔案過濾方式

  • 首先是對檔名去空白字元,然後轉成小寫
  • 其次是檔名如果是.jsp或者.jspx結尾則刪除,返回false

絞盡腦汁~貌似只有一個方式:檔名後面加.繞過,但是這種好像只適用於windows。

來都來了,試一下吧,誰讓我現在用的電腦是windows。

這裡我直接修改了資料包,將檔名改成了.jsp.,檔案內容用的是冰蠍生成的jsp馬子。

這裡idea就先不debug了,直接放包,上傳成功。

可以到目錄中看一下,有沒有上傳成功:

嘿嘿,成功,同時字尾是.jsp。

接下來就是看看能不能連線了...

測試了下,不太行,雖然能上傳,但是不能解析。

這裡為了避免中文問題,我改成了webshell.jsp

怎麼辦?目錄穿越試一試,哈哈哈

經過三天三夜的除錯,找到了檔名處理的原始碼(這裡過程就不粘出來了,自己可以調一下,如果想看過程,評論區留個言,給兄弟們安排上[\狗頭])

  • 先計算/的位置
  • 然後進行原始檔名的擷取

即檔名為../../../webshell.jsp.,最終檔名也將變為webshell.jsp.

1.1.8 這裡,這個點就到此結束,總結一下:

  • 該位置的檔案上傳可以任意上傳除.jsp.jspx的檔案,但是沒什麼luan用。
  • 當然如果是windows是可以透過加.繞過的,不過解析不了。
  • 嘗試目錄穿越,有程式碼會將路徑接取掉。

成果:0day無,分析經驗+1

1.2 可疑點2【無漏洞】

分析第二個ComnController類中的:

進來之後發現,寫法和之前是差不多的,同樣使用了getFile()方法,怎麼辦?放棄!

後面使用了getFile()方法的,直接放棄就好了。

換目標!

這裡多說一下,其實我們搜的這些,都是jfinal元件中的upload,漏洞基本沒有,如果有,那就是元件0Day了。不過分析分析原始碼也是好的,贊同請點贊。

1.3 可疑點3【跑偏的漏洞-路徑遍歷讀取.xml檔案】

透過upload搜尋的,翻了一圈,不是UeditorAction類,就是ComnController類,沒有別的可疑的了。換關鍵字搜尋。

1.3.1 搜尋file關鍵字

找到一個TemplateController類中匯入了File。進入看看

檔案中搜尋下file,85個,真不少

進來之後,大概瀏覽一遍,該類中其中兩個方法getTemplates() save()方法中存在檔案相關的功能程式碼,所以這裡分開來分析下。先分析getTemplates()

【其實這裡不需要分析的,因為它是獲取檔案用的,沒有寫入檔案儲存檔案的功能,和檔案上傳無關】。
既然來都來了,看一下吧~

1.3.2 分析getTemplates()方法

方法程式碼如下:

首先看前面三行,getPara()方法獲取引數值,獲取不到,會有預設值:

點進getPara()方法,進來一看:欣喜若狂啊

直接透過request.getParameter(name)獲取引數值,也就是說,目錄可控啊~

繼續往下分析

這一塊就沒啥了,就是將String型別的路徑,封裝一下,變成物件。順便還做了一下驗證處理。

  • 其中畫紅框位置表示:pathFile.listFiles表示目錄下的檔案或目錄,然後透過FileFilter做了一下驗證,判斷是否是目錄,是目錄的放入dirs列表中。

  • 其中的setAttr()方法,是將目錄物件儲存到request物件中。

繼續向下分析:這裡和之前的差不多,只不過是透過FileFilter限制了白名單檔案,即將.html.xml.css.js的檔案放入到了files列表中。

繼續向下分析:這段程式碼作用就是頁面上預設顯示的模版檔案,傳入的檔名如果沒有則顯示files列表中的第一個(所以沒有任意檔案讀取~哈哈哈)

最後返回resource.html或者是index.html

沒有檔案上漏洞!

1.3.3 柳暗花明又一村

但是別急,回想下,最開始說該方法獲取的前端引數可控,即目錄可控,那我們能不能不去獲取預設路徑下的.html.xml.css.js檔案。

直接驗證了,前端找到對應功能點,還是那個熟悉的模版~

隨便點個模版,yakit攔截下~

預設引數是這樣的:

  • file_name=contact.html
  • dir=/
  • dir_name=/

對照下原始碼,dir是當前目錄,file_name是檢視的檔案

那麼修改一下,讀取網站下的web.xml試一試

而預設讀取的根目錄是webapps\ofcms_admin_war\WEB-INF\page\default

所以我們構造dir=../../../../ROOT/WEB-INFfile_name=web.xml

成功讀取!經驗+1

1.3.4 多點腦洞

既然這裡可以讀取web.xml,並且下方可以儲存,那我們是不是就可以修改web.xml檔案了呢?

嘗試修改儲存一下,出現請求異常~

直接除錯下,在save()方法處打個斷點,發現是因為dirs引數值即dirName中存在../因此被拒絕了。

這裡其實很好繞過,聰明的你一點發現了,前面還有個引數:res_path

我們可以修改res_path的值和dirs引數的值,來達到修改web.xml的目的。

這裡師傅們可以自己嘗試下,因為這裡和下面的save()方法的分析是一樣的,就放一起說了。

1.4 可疑點4【有漏洞】

從上一個分析,發現save()方法其實是有問題的,接下來著重分析一下。

1.4.1 分析save()方法

程式碼就這麼長:

首先看:

這裡從前端獲取“res_path”的引數值,前面也說過,getPara()獲取的值是可控的。

然後透過res_path的值決定pathFile是什麼內容,這裡其實不用管,因為不管res_path是什麼,pathFile都是固定的,不是SystemUtile.getSiteTemplateResourcePath()就是SystemUtile.getSiteTemplatePath(),沒有可變的地方。

接下來是這段,也是核心:

首先從前端獲取“dirs”引數的值,不過這個值中不能存在../,也就是說這個引數不能是利用點了。

然後從前端獲取“file_name”引數的值,沒有任何限制。

最後從前端獲取“file_content”引數的值,僅僅對<>做了轉義。

然後就是新建檔案,呼叫FileUtils.writeString(file, fileContent)寫入內容。

writeString方法如下:直接呼叫FileOutputStream.write()寫的,沒有別的過濾。

分析下來之後,可以利用的點為:file_name和file_content。

檔名和檔案內容都可控,這不就是妥妥的任意檔案寫入(可以理解為任意檔案上傳)。

1.4.2 利用漏洞寫入jsp馬

那直接寫個jsp馬進去!當然,可能解析不了。

file_name和file_content都替換掉,最後別忘了file_content的值使用URL編碼一下

  • 這裡我用的是冰蠍jsp馬

成功寫入:

訪問連線:但是會發現連線失敗,看來當前目錄下不能直接訪問,或者是jsp不解析

繼續嘗試別的目錄:file_name=../../../webshell.jsp

也是失敗。

這裡嘗試在static目錄,是可以的。file_name=../../../static/webshell.jsp

小tips:static目錄是靜態目錄,一般檔案是可以直接訪問。

命令成功執行!撒花~

1.5 最後結尾

最後搜尋了其他的類和關鍵字,沒有可以分析利用的點了。師傅們看看就好。

1.5.1 例1:SystemUtile類下

1.5.2 例2:GenUtils類下,都是建立固定名稱的檔案,並非檔案上傳

1.5.3 例3:換關鍵字write搜尋,基本都是分析過的,要不就是無用的

檔案上傳漏洞程式碼審計到此為止,希望師傅們有所收穫,如有問題,評論區留言~
也可掃碼加好友,一起進步~

相關文章