在2014年6月18日@終極修煉師曾發(fā)布這樣一條微博:
新攻擊方法–Java Web Expression Language Injection
鏈接的內(nèi)容是一個名為Jenkins的服務(wù),可以在沒有password的情況下受到攻擊。而攻擊方法比較有趣,Jenkins提供了一個Script Console功能,可以執(zhí)行Groovy 腳本語言。下面我們來看下維基百科對于這個腳本語言的解釋: Groovy是Java平臺上設(shè)計的面向?qū)ο缶幊陶Z言。這門動態(tài)語言擁有類似Python、Ruby和Smalltalk中的一些特性,可以作為Java平臺的腳本語言使用。
Groovy的語法與Java非常相似,以至于多數(shù)的Java代碼也是正確的Groovy代碼。Groovy代碼動態(tài)的被編譯器轉(zhuǎn)換成Java字節(jié)碼。由于其運行在JVM上的特性,Groovy可以使用其他Java語言編寫的庫。
比較巧的是,我前一段時間因為在關(guān)注表達式注入這個攻擊方向,也研究了下Groovy這個語言。這個語言簡單而強大,我可以直接用一個字符串來執(zhí)行系統(tǒng)命令。下面是一個demo:
java class demo { static void main(args){ def cmd = "calc"; println "${cmd.execute()}"; } } 新攻擊方法–Java Web Expression Language Injection
如果單純的看Jenkins的這個問題,可能只是覺得這是一個比較有趣的攻擊手法。但如果我們再聯(lián)想一下之前的一些漏洞,就會發(fā)現(xiàn)這些個體之間是存在某種聯(lián)系的。
2014年5月:CVE-2014-3120,ELASTICSEARCH遠程代碼代碼漏洞
2013年5、6、7月:Struts2多個OGNL導(dǎo)致的遠程命令執(zhí)行漏洞
2012年12月:國外研究者@DanAmodio發(fā)布《Remote-Code-with-Expression-Language-Injection》一文
這些事件的串聯(lián)導(dǎo)致了我打算寫下這篇文章,來向各位介紹這種新的攻擊方法(雖然實際上,它已經(jīng)存在了很久),我們可能會在未來很長的一段時間內(nèi)和它打交道,就像我們當(dāng)初和SQL注入、代碼執(zhí)行、命令執(zhí)行這些一樣。
它的名字叫做Java Web Expression Language Injection——Java Web 表達式注入
表達式注入概述
2013年4月15日Expression Language Injection詞條在OWASP上被創(chuàng)建,而這個詞的最早出現(xiàn)可以追溯到2012年12月的《Remote-Code-with-Expression-Language-Injection》一文,在這個paper中第一次提到了這個名詞。
而這個時期,我們其實也一直在響應(yīng)這個新型的漏洞,只不過我們還只是把它叫做遠程代碼執(zhí)行漏洞、遠程命令執(zhí)行漏洞或者上下文操控漏洞。像Struts2系列的s2-003、s2-009、s2-016等,這種由OGNL表達式引起的命令執(zhí)行漏洞。
而隨著Expression Language越來越廣泛的使用,它的受攻擊面也隨著展開,所以我們覺得有必要開始針對這種類型的漏洞進行一些研究,Expression Language Injection在將來甚至有可能成為SQL注入一樣的存在。
而且從OWASP中定義的表達式注入以及《Remote-Code-with-Expression-Language-Injection》這篇paper所提到的表達式注入所面向的服務(wù),可以看出這種漏洞,在目前的web現(xiàn)狀中,只存在于Java Web服務(wù)。而在未來的web發(fā)展中,其他的Web方向也有可能出現(xiàn)表達式的存在,所以我們?yōu)榱酥斏髌鹨姡瑢⑦@個稱為Java Web Expression Language Injection。
從以往的這種形式的漏洞來看,這種漏洞的威力往往都非常大,最典型的就像Struts2的OGNL系列漏洞。而漏洞的形成原因,一般是功能濫用或者過濾不嚴(yán)這兩種,比較代表性的例子是Struts2的s2-16(功能濫用)和s2-009(過濾不嚴(yán))。
一些流行的表達式語言
我們在去年的時候做過一個關(guān)于Java Web的研究課題,對于一些Java Web框架和程序進行過比較深入的研究。而且對于Java Web 表達式注入(后面簡稱JWEI)也做了一點積累,在這小節(jié)中我覺得有必要向各位介紹一下它們,以方便日后研究工作的開始。
下面我將用盡量簡單的語言來向各位介紹幾種簡單的流行表達式語言和它們的基本用法(攻擊相關(guān)),以及它們曾經(jīng)導(dǎo)致的漏洞。
Struts2——OGNL
實至名歸的“漏洞之王”,目前被攻防雙方理解得足夠透徹的唯一表達式語言。
基本用法:
java
ActionContext AC = ActionContext.getContext();
Map Parameters = (Map)AC.getParameters();
String expression = "${(new java.lang.ProcessBuilder('calc')).start()}";
AC.getValueStack().findValue(expression));相關(guān)漏洞:
s2-009、s2-012、s2-013、s2-014、s2-015、s2-016,s2-017Spring——SPEL
SPEL即Spring EL,故名思議是Spring框架專有的EL表達式。相對于其他幾種表達式語言,使用面相對較窄,但是從Spring框架被使用的廣泛性來看,還是有值得研究的價值的。而且有一個Spring漏洞的命令執(zhí)行利用,讓漏洞發(fā)現(xiàn)者想得腦袋撞墻撞得梆梆響都沒想出來,而我卻用SPEL解決了,大家來猜下是哪個漏洞呢^_^。
基本用法:
java
String expression = "T(java.lang.Runtime).getRuntime().exec(/"calc/")";
String result = parser.parseExpression(expression).getValue().toString();相關(guān)漏洞:
暫無公開漏洞JSP——JSTL_EL
這種表達式是JSP語言自帶的表達式,也就是說所有的Java Web服務(wù)都必然會支持這種表達式。但是由于各家對其實現(xiàn)的不同,也導(dǎo)致某些漏洞可以在一些Java Web服務(wù)中成功利用,而在有的服務(wù)中則是無法利用。
例如:《Remote-Code-with-Expression-Language-Injection》一文中所提到的問題,在glassfish和resin環(huán)境下是可以成功實現(xiàn)命令執(zhí)行的,而在tomcat的環(huán)境下是沒有辦法實現(xiàn)的。
而且JSTL_EL被作為關(guān)注的對象,也是由于它的2.0版本出現(xiàn)之后,為滿足需求,這個版本在原有功能的基礎(chǔ)之上,增加了很多更為強大的功能。
從這點中我們不難看出,隨著未來的發(fā)展,對于表達式語言能實現(xiàn)比較強大的功能的需求越來越強烈,主流的表達式語言都會擴展這些功能。而在擴展之后,原來一些不是問題的問題,卻成了問題。
基本用法:
jsp <spring:message text="${/"/".getClass().forName(/"java.lang.Runtime/").getMethod(/"getRuntime/",null).invoke(null,null).exec(/"calc/",null).toString()}"></spring:message>
相關(guān)漏洞:
CVE-2011-2730Elasticsearch——MVEL
首先要感謝下Elasticsearch的CVE-2014-3120這個漏洞,因為跟蹤這個漏洞時,讓我開始重新關(guān)注到Java Web表達式研究的價值,并決定開始向這個方向作深入的研究。
MVEL是同OGNL和SPEL一樣,具有通過表達式執(zhí)行Java代碼的強大功能。
基本用法:
java import org.mvel.MVEL; public class MVELTest { public static void main(String[] args) { String expression = "new java.lang.ProcessBuilder(/"calc/").start();"; Boolean result = (Boolean) MVEL.eval(expression, vars); } } 相關(guān)漏洞:
CVE-2014-31200×03 總結(jié)
在未來針對表達式語言開展的研究中,我準(zhǔn)備將研究表達式語言定位為和SQL語法一樣的利用方法研究。從我們上面對于表達式語言分析的結(jié)果來看,JWEI攻擊和SQL注入攻擊很像。
多種平臺風(fēng)格,但是基本的語法一定 多數(shù)情況下是由于拼接問題,或用戶直接操控表達式,從而造成的攻擊 由此我們未來的研究,會將Java Web表達式語言作為一種利用方法來研究。
而JWEI漏洞的研究,我們會通過研究程序員在編程中如何使用表達式語言來進行。具體的操作方法,會是閱讀研究的表達式語言所對應(yīng)的框架代碼。試圖從中找到一些規(guī)律和習(xí)慣。最終總結(jié)出一些針對表達式注入漏洞挖掘和利用方法。
擴展延伸
在研究表達式語言時,翻閱以往Java Web資料的過程中,我還發(fā)現(xiàn)了一些Java Web漏洞的小細節(jié)。這些細節(jié)可能沒有表達式語言這么通用,但也是Java Web中不可忽略的潛在漏洞點。
反序列化代碼執(zhí)行
序列化是Java的一個特性,在Web服務(wù)中也經(jīng)常用來傳輸信息,這就導(dǎo)致攻擊者有可能通過出傳遞帶有惡意序列化內(nèi)容的代碼實現(xiàn)攻擊。典型的漏洞有Spring的CVE-2011-2894和JBoss的CVE-2010-0738。
利用Java反射觸發(fā)命令執(zhí)行
反射是Java的一個大特性,如果在開發(fā)過程中沒有針對對象的行為進行嚴(yán)格的限制的話,用戶就有可能通過操控一些可控對象,利用反射機制觸發(fā)命令執(zhí)行攻擊。典型的漏洞有CVE-2014-0112。
利用框架某些特性實現(xiàn)代碼執(zhí)行
這種形式的攻擊,根據(jù)框架的某些特性才能進行,而大部分框架的功能實現(xiàn)是有很大的不同的,所以此類攻擊定制性很強。不過,框架之間還是有一些共同性的,譬如自定義標(biāo)簽庫的實現(xiàn)和調(diào)用,都是大同小異的。典型漏洞有CVE-2010-1622。