close

在Windows系統中,如果保存文件的文件名是以點結尾,系統會自動將點去掉。利用這一特點在某些場景下可以繞過對應的文件後綴檢查,達到任意文件上傳的效果。

0x00 引言

一般針對文件上傳業務,主要判斷是否有檢查後綴名,同時要查看配置文件是否有設置白名單或者黑名單,如果沒有的話,那麼攻擊者利用該缺陷上傳類似webshell等惡意文件。這裡列舉JavaWeb中一些常見的思路:

利用servlet單例的特點進行繞過,此外,除了servlet以外,Spring中的controller默認也是是單例的,同樣會發生類似的安全問題。但是可以通過@Scope註解來指定對應controller的作用域

通過報錯的方式進行繞過(例如JFinal的CVE-2019-17352)

實際業務中發現了一處繞過後綴安全檢查進行文件上傳的實例,當前漏洞已經修復完畢。提取關鍵的的漏洞代碼做下復盤。

0x01 業務場景

上傳業務接口是基於SpringMCV實現的,主要用於文件的上傳,關鍵代碼如下:

簡單總結一下當前上傳接口所做的安全措施:

通過後綴白名單的方式限制類似jsp/jspx惡意文件的上傳

未返回文件名/存儲路徑等敏感信息

查看接口具體的效果:

上傳txt文件,成功上傳:

嘗試上傳惡意JSP文件,被攔截:

可以看到設置的後綴白名單「的確」起到了一定的攔截作用。

0x02 繞過過程

查看具體的上傳邏輯代碼,獲取後綴名的方式是通過substring進行字符串的切割:

在獲取到文件後綴名後(這裡的後綴名是去掉了.的),這裡有個很關鍵的地方,如果後綴名不為空,那麼進入白名單的檢查,否則通過transferTo方法完成文件的上傳:

//檢查文件後綴名 if(extName!=null&&!extName.equals("")) { if (!allowedExtList.contains(extName)){ result.put("code", \-1); result.put("msg", "illegal File Type,try again!"); return result; } }

那麼也就是說,當程序獲取不到文件名的時候,即可繞過對應黑名單後綴的檢查,但是單純上傳沒有.xxx的文件,即使內容包含惡意的jsp內容,上傳成功也無法解析造成危害。那麼有沒有辦法進行進一步的利用呢?

首先要解決的問題是要讓程序獲取不到文件名,這裡有師傅提到了一個思路,當上傳文件名為test.jsp.時,因為獲取後綴的邏輯是通過substring最後一個.的位置獲取的,這裡返回的是null,符合第一個要求。但是比較遺憾的是,直接在tomcat中訪問test.jsp.的文件是沒辦法解析的:

查閱相應的資料:

https://docs.microsoft.com/zh-cn/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN:

Windows normally requires files to have either no extension or an extension that is at least one character long. It does not like zero length extensions (i.e. file names that end with a period). Folders can have extensions too, therefore, Windows does not let their names end with a period.

發現Windows系統中,如果保存文件的文件名是以點結尾(形如test.jsp.),系統會自動將.去掉,上述文件名就會變成(test.jsp)。

這裡做一個實驗,直接在windows環境下通過代碼生成以.結尾的文件,確實無論以任意數量的.結尾,最終實際保存的文件對應自動將.去掉:

PS:與Windows不同,Linux並不關心文件的擴展名。它會查看文件內容,並自行解決。換句話說,Linux與擴展名無關。所以如果應用部署在Linux的話該姿勢並不能產生對應的效果。

結合上述內容,因為應用部署環境剛好是windows的,這裡嘗試上傳以jsp.結尾的文件,可以看到最終保存的文件是以.jsp結尾,並且可以成功解析,成功繞過了後綴檢查:

0x03 其他

最後開發人員更換了獲取後綴名的方式,通過split切割文件名獲取對應的String[]數組,然後獲取數組最後一個元素作為後綴名,此時類似test.jsp.的文件名會獲取到jsp後綴,避免了上述的繞過過程。

String[] splitName = fileName.split("\\.");String extName = splitName[splitName.length - 1];

但是在window下,如果文件名+"::$DATA"會把::$DATA之後的數據當成文件流處理,不會檢測後綴名,且保持::$DATA之前的文件名,他的目的就是不檢查後綴名,通過:$DATA這個在黑名單場景下也是可以繞過的。

在進行黑盒測試時,通過上面的方式嘗試繞過後綴安全檢查進行文件上傳也是一種不錯的思路。白盒審計中也需要額外關注。

原文鏈接:https://forum.butian.net/share/1596

侵權請私聊公眾號刪文

熱文推薦

藍隊應急響應姿勢之Linux
通過DNSLOG回顯驗證漏洞
記一次服務器被種挖礦溯源
內網滲透初探 | 小白簡單學習內網滲透
實戰|通過惡意 pdf 執行 xss 漏洞
免殺技術有一套(免殺方法大集結)(Anti-AntiVirus)
內網滲透之內網信息查看常用命令
關於漏洞的基礎知識
任意賬號密碼重置的6種方法
乾貨 | 橫向移動與域控權限維持方法總匯
手把手教你Linux提權

歡迎關注LemonSec

覺得不錯點個「贊」、「在看「
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 鑽石舞台 的頭像
    鑽石舞台

    鑽石舞台

    鑽石舞台 發表在 痞客邦 留言(0) 人氣()