一種新的攻擊方法——Java-Web-Expression-Language-Injection

wyzsk發表於2020-08-19
作者: 綠盟科技 · 2014/07/03 13:10

Nsfocus-TRC

title: “一種新的攻擊方法——Java-Web-Expression-Language-Injection”
date: 2014-06-24 16:36:56 +0800
comments: true
categories: “安全技術”
author: “申軍利”

tags: [Java Web,Expression Language]

0×00 引言


[email protected]

enter image description here

連結的內容是一個名為Jenkins的服務,可以在沒有password的情況下受到攻擊。而攻擊方法比較有趣,Jenkins提供了一個Script Console功能,可以執行Groovy 指令碼語言。下面我們來看下維基百科對於這個指令碼語言的解釋:

Groovy是Java平臺上設計的物件導向程式語言。這門動態語言擁有類似Python、Ruby和Smalltalk中的一些特性,可以作為Java平臺的指令碼語言使用。 Groovy的語法與Java非常相似,以至於多數的Java程式碼也是正確的Groovy程式碼。Groovy程式碼動態的被編譯器轉換成Java位元組碼。由於其執行在JVM上的特性,Groovy可以使用其他Java語言編寫的庫。

比較巧的是,我前一段時間因為在關注表示式注入這個攻擊方向,也研究了下Groovy這個語言。這個語言簡單而強大,我可以直接用一個字串來執行系統命令。下面是一個demo:

java
class demo {
static void main(args){
def cmd = "calc";
println "${cmd.execute()}";
}
}

enter image description here

如果單純的看Jenkins的這個問題,可能只是覺得這是一個比較有趣的攻擊手法。但如果我們再聯想一下之前的一些漏洞,就會發現這些個體之間是存在某種聯絡的。

2014年5月:CVE-2014-3120,ELASTICSEARCH遠端程式碼程式碼漏洞 2013年5、6、7月:Struts2多個OGNL導致的遠端命令執行漏洞 2012年12月:[email protected]guage-Injection》一文

這些事件的串聯導致了我打算寫下這篇文章,來向各位介紹這種新的攻擊方法(雖然實際上,它已經存在了很久),我們可能會在未來很長的一段時間內和它打交道,就像我們當初和SQL隱碼攻擊、程式碼執行、命令執行這些一樣。

它的名字叫做Java Web Expression Language Injection——Java Web 表示式注入

0×01 表示式注入概述


2013年4月15日Expression Language Injection詞條在OWASP上被建立,而這個詞的最早出現可以追溯到2012年12月的《Remote-Code-with-Expression-Language-Injection》一文,在這個paper中第一次提到了這個名詞。

而這個時期,我們其實也一直在響應這個新型的漏洞,只不過我們還只是把它叫做遠端程式碼執行漏洞、遠端命令執行漏洞或者上下文操控漏洞。像Struts2系列的s2-003、s2-009、s2-016等,這種由OGNL表示式引起的命令執行漏洞。

而隨著Expression Language越來越廣泛的使用,它的受攻擊面也隨著展開,所以我們覺得有必要開始針對這種型別的漏洞進行一些研究,Expression Language Injection在將來甚至有可能成為SQL隱碼攻擊一樣的存在。

而且從OWASP中定義的表示式注入以及《Remote-Code-with-Expression-Language-Injection》這篇paper所提到的表示式注入所面向的服務,可以看出這種漏洞,在目前的web現狀中,只存在於Java Web服務。而在未來的web發展中,其他的Web方向也有可能出現表示式的存在,所以我們為了謹慎起見,將這個稱為Java Web Expression Language Injection。

從以往的這種形式的漏洞來看,這種漏洞的威力往往都非常大,最典型的就像Struts2的OGNL系列漏洞。而漏洞的形成原因,一般是功能濫用或者過濾不嚴這兩種,比較代表性的例子是Struts2的s2-16(功能濫用)和s2-009(過濾不嚴)。

0×02 一些流行的表示式語言


我們在去年的時候做過一個關於Java Web的研究課題,對於一些Java Web框架和程式進行過比較深入的研究。而且對於Java Web 表示式注入(後面簡稱JWEI)也做了一點積累,在這小節中我覺得有必要向各位介紹一下它們,以方便日後研究工作的開始。

下面我將用盡量簡單的語言來向各位介紹幾種簡單的流行表示式語言和它們的基本用法(攻擊相關),以及它們曾經導致的漏洞。

Struts2——OGNL

實至名歸的“漏洞之王”,目前被攻防雙方理解得足夠透徹的唯一表示式語言。

基本用法:

java
ActionContext AC = ActionContext.getContext();
Map Parameters = (Map)AC.getParameters();
String expression = "${(new java.lang.ProcessBuilder('calc')).start()}";
AC.getValueStack().findValue(expression));

相關漏洞:

s2-009、s2-012、s2-013、s2-014、s2-015、s2-016,s2-017

Spring——SPEL

SPEL即Spring EL,故名思議是Spring框架專有的EL表示式。相對於其他幾種表示式語言,使用面相對較窄,但是從Spring框架被使用的廣泛性來看,還是有值得研究的價值的。而且有一個Spring漏洞的命令執行利用,讓漏洞發現者想得腦袋撞牆撞得梆梆響都沒想出來,而我卻用SPEL解決了,大家來猜下是哪個漏洞呢^_^。

基本用法:

java
String expression = "T(java.lang.Runtime).getRuntime().exec(/"calc/")";
String result = parser.parseExpression(expression).getValue().toString();

相關漏洞:

暫無公開漏洞

JSP——JSTL_EL

這種表示式是JSP語言自帶的表示式,也就是說所有的Java Web服務都必然會支援這種表示式。但是由於各家對其實現的不同,也導致某些漏洞可以在一些Java Web服務中成功利用,而在有的服務中則是無法利用。

例如:《Remote-Code-with-Expression-Language-Injection》一文中所提到的問題,在glassfish和resin環境下是可以成功實現命令執行的,而在tomcat的環境下是沒有辦法實現的。

而且JSTL_EL被作為關注的物件,也是由於它的2.0版本出現之後,為滿足需求,這個版本在原有功能的基礎之上,增加了很多更為強大的功能。

從這點中我們不難看出,隨著未來的發展,對於表示式語言能實現比較強大的功能的需求越來越強烈,主流的表示式語言都會擴充套件這些功能。而在擴充套件之後,原來一些不是問題的問題,卻成了問題。

基本用法:

jsp
<spring:message text="${/"/".getClass().forName(/"java.lang.Runtime/").getMethod(/"getRuntime/",null).invoke(null,null).exec(/"calc/",null).toString()}"></spring:message>

相關漏洞:

CVE-2011-2730

Elasticsearch——MVEL

首先要感謝下Elasticsearch的CVE-2014-3120這個漏洞,因為跟蹤這個漏洞時,讓我開始重新關注到Java Web表示式研究的價值,並決定開始向這個方向作深入的研究。

MVEL是同OGNL和SPEL一樣,具有透過表示式執行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);
         }
  } 

相關漏洞:

CVE-2014-3120

0×03 總結


在未來針對表示式語言開展的研究中,我準備將研究表示式語言定位為和SQL語法一樣的利用方法研究。從我們上面對於表示式語言分析的結果來看,JWEI攻擊和SQL隱碼攻擊很像。

多種平臺風格,但是基本的語法一定 多數情況下是由於拼接問題,或使用者直接操控表示式,從而造成的攻擊 由此我們未來的研究,會將Java Web表示式語言作為一種利用方法來研究。

而JWEI漏洞的研究,我們會透過研究程式設計師在程式設計中如何使用表示式語言來進行。具體的操作方法,會是閱讀研究的表示式語言所對應的框架程式碼。試圖從中找到一些規律和習慣。最終總結出一些針對表示式注入漏洞挖掘和利用方法。

0×04 擴充套件延伸


在研究表示式語言時,翻閱以往Java Web資料的過程中,我還發現了一些Java Web漏洞的小細節。這些細節可能沒有表示式語言這麼通用,但也是Java Web中不可忽略的潛在漏洞點。

反序列化程式碼執行

序列化是Java的一個特性,在Web服務中也經常用來傳輸資訊,這就導致攻擊者有可能透過出傳遞帶有惡意序列化內容的程式碼實現攻擊。典型的漏洞有Spring的CVE-2011-2894和JBoss的CVE-2010-0738。

利用Java反射觸發命令執行

反射是Java的一個大特性,如果在開發過程中沒有針對物件的行為進行嚴格的限制的話,使用者就有可能透過操控一些可控物件,利用反射機制觸發命令執行攻擊。典型的漏洞有CVE-2014-0112。

利用框架某些特性實現程式碼執行

這種形式的攻擊,根據框架的某些特性才能進行,而大部分框架的功能實現是有很大的不同的,所以此類攻擊定製性很強。不過,框架之間還是有一些共同性的,譬如自定義標籤庫的實現和呼叫,都是大同小異的。典型漏洞有CVE-2010-1622。

本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章