Struts S2-020這個通告已經公佈有一段時間了。現時大家都知道這個漏洞可以造成DOS、文件下載等危害,相信各大廠商也已經採取了相應的安全措施。今天是和大家分享一下對這個漏洞的一點研究,包括如何在Tomcat 8下導致RCE,目的是抛磚引玉,有不足之處歡迎大家指出。
1.内容列舉
這個漏洞分析的一個難點在於:通過ognl的class.xx這種管道來遍歷内容時,得到的是實際運行環境中的動態class,囙此僅作靜態分析是很困難的。例如classLoader,在不同容器中就各不相同。於是我編寫了一個小脚本來自動枚舉這樣的内容:(這段腳本只考慮了int、string與boolean這些基本屬性,未考慮數組等複雜的情况,實際情況下結果會更多)
在tomcat 8.0.3下Struts2.3.16的blank app中執行這段jsp,輸出結果如下:
這意味著Tomcat 8下至少有200多個boolean、int或string類型的内容是可以操縱的,雖然可修改不一定會產生危害,但至少說明這個漏洞的潛在風險不小。
2.POC
經過分析發現,通過下麵的方法可以造成webshell的效果,最終導致Tomcat下的RCE。
上面的内容中,有幾個控制在tomcat上生成的access log的檔名,其預設值如下:
默認情况下,生成的access log位於 logs目錄(與webapps平行)下,檔名是localhost_access_log.2014-03-09.txt,但通過修改上面的屬性值,可以導致在webapps目錄下寫入jspwebshell。具體步驟如下(以struts 2.3.16下的blank app為例):
1.訪問下麵的url來改變内容:
2.訪問下麵的url來觸發tomcat切換log(這裡有個坑,這個内容必須是數位,這裡設定為1),那麼從此開始tomcat的access log將被記錄入webapps/ROOT/shell1.jsp中:
3.通過發包訪問下麵的請求,在access log中植入程式碼
訪問上述請求後,就可以看到生成了webapps/ROOT/shell1.jsp,內容如下:
4.結合前面設定的參數,訪問下麵的url,觀察shell執行http://127.0.0.1/shell1.jsp
通過分析,上面的POC中class.classLoader.resources.context.parent.pipeline.first這個内容實際是org.apache.catalina.valves.AccessLogValve,在conf/server.xml裡面有一段相關的配寘:
為何修改了dataformat會觸發切換日誌呢?注意下麵一個内容,默認是true
每次Log時,都會調用rotate:
而rotate是檢查當前的systime 經過format後,與當前的tsDate是否相同。如果日期不同了,自然需要切換日誌檔了:
而我們之前已經修改了dateFormat,所以就觸發了日誌切換。這個特性與具體的OS無關,是tomcat程式碼决定的。在linux與windows下證實該問題均存在。
3.後記
這個POC距離實際的攻擊還有一定的距離,發表此文僅供科技研究使用,請勿用於實際攻擊。另外,也許還有其他的利用管道,Tomcat 8下那麼多的可操控的内容,或許有別的也可以RCE?其他的容器下,是否也有這麼多的可操控内容呢?歡迎感興趣的同學與我們BSRC的同學討論。
[via sec.baidu.com 作者:neobyte]