偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

CVE-2019-0230:Apache Struts OGNL遠(yuǎn)程代碼執(zhí)行漏洞詳解

安全 漏洞
在本文中,我們將為讀者詳細(xì)介紹在Apache Struts 中曝出的遠(yuǎn)程代碼執(zhí)行漏洞。

[[347959]]

在Trend Micro Vulnerability Research Service近期公布的一份漏洞報(bào)告中,Trend Micro研究團(tuán)隊(duì)成員Kc Udonsi和John Simpson詳細(xì)介紹了Apache Struts框架中最近曝出的一個(gè)代碼執(zhí)行漏洞。這個(gè)安全漏洞最初是由蘋果信息安全部的Matthias Kaiser發(fā)現(xiàn)并報(bào)告的。下文節(jié)選自他們撰寫的CVE-2019-0230報(bào)告,其中做了部分修改。

最近,Apache Struts框架被曝出了一個(gè)遠(yuǎn)程代碼執(zhí)行漏洞。該漏洞是由于輸入驗(yàn)證不足導(dǎo)致在計(jì)算原始用戶輸入時(shí)強(qiáng)制進(jìn)行兩次Object Graph Navigation Library(OGNL)計(jì)算所致。攻擊者可以通過向目標(biāo)服務(wù)器發(fā)送精心制作的請求來利用該漏洞。一旦攻擊得手,他們就能夠以服務(wù)器的權(quán)限執(zhí)行任意代碼。

漏洞詳情

Apache Struts是一個(gè)用于構(gòu)建基于Java的web應(yīng)用程序的模型-視圖-控制器(MVC)框架。該MVC框架用于將信息的表示與用戶與信息的交互隔離開來。其中,模型由負(fù)責(zé)與數(shù)據(jù)庫通信等后端工作的業(yè)務(wù)和應(yīng)用程序邏輯組成。視圖是提供給用戶的數(shù)據(jù)的表示形式,而控制器負(fù)責(zé)協(xié)調(diào)模型和視圖之間的通信。

Apache Struts將通過Java Servlet API提供一個(gè)名為ActionServlet的控制器。而來自客戶端的請求則以XML配置文件中定義的“Action(操作)”形式發(fā)送到控制器。這時(shí),控制器會調(diào)用模型代碼中相應(yīng)的Action類,這些類會使用內(nèi)部邏輯來驗(yàn)證和執(zhí)行這些操作,并以新視圖的形式返回結(jié)果,而控制器則負(fù)責(zé)更新這些結(jié)果。Apache Struts允許通過Java ServerPages(JSP)對視圖進(jìn)行編碼,這些視圖將編譯成HTML頁面,以便通過瀏覽器進(jìn)行查看。

我們可以使用如下所示的URI來訪問相關(guān)的操作:

  1. action name >.action 

其中< action name >被替換為操作名。后綴“.action”只是一個(gè)慣例?;赟truts的Web應(yīng)用程序可以使用任何后綴,如“.do”。

HTTP是RFC 7230-7237和其他RFC中描述的請求/響應(yīng)協(xié)議??蛻舳藢⒄埱蟀l(fā)送到服務(wù)器,經(jīng)過相應(yīng)的處理后,服務(wù)器會再將響應(yīng)發(fā)送回客戶端。通常情況下,HTTP請求是由一個(gè)請求行、各種標(biāo)頭、一個(gè)空行和一個(gè)可選的消息正文組成的,具體如下所示:

 

 其中,CRLF表示回車換行符(CR),后跟換行符(LF),而SP則表示空格字符。參數(shù)可以在請求URI或消息正文中作為“名稱-值”對從客戶端傳遞到服務(wù)器端,具體取決于所使用的方法和Content-Type標(biāo)頭。例如,當(dāng)使用GET方法傳送值為“1”、名為“param”的參數(shù)時(shí),相應(yīng)的HTTP請求將如下所示:

 CVE-2019-0230:Apache Struts OGNL遠(yuǎn)程代碼執(zhí)行漏洞詳解

 如果使用POST方法的話,則相應(yīng)HTTP請求將如下所示:

 CVE-2019-0230:Apache Struts OGNL遠(yuǎn)程代碼執(zhí)行漏洞詳解

 如果有多個(gè)參數(shù)/值對的話,它們將被編碼為以&為分隔符的“名稱=值”對,具體如下所示:

  1. var1=value1&var2=value2... 

此外,Apache Struts還支持使用對象圖導(dǎo)航語言(Object Graph Navigational Language,OGNL)表達(dá)式通過模板.jsp文件動(dòng)態(tài)生成網(wǎng)頁內(nèi)容。OGNL是一種具有簡潔語法的動(dòng)態(tài)表達(dá)式語言(EL),用于獲取和設(shè)置Java對象、lambda表達(dá)式等屬性。OGNL表達(dá)式可以包含組成導(dǎo)航鏈的字符串。這些字符串可以是屬性名、方法調(diào)用、數(shù)組索引等。OGNL表達(dá)式是根據(jù)以O(shè)GNL上下文形式提供給求值器的初始或根上下文對象進(jìn)行計(jì)算的。

Apache Struts使用名為ActionContext的線程本地容器對象來存儲執(zhí)行Action所需的各種對象。這些對象通常會包括會話標(biāo)識符、請求參數(shù)、區(qū)域設(shè)置等。此外,ActionContext還公開了一個(gè)ValueStack接口,用于推送和存儲處理動(dòng)態(tài)表達(dá)式語言(EL)所需的對象。當(dāng)EL編譯器需要解析表達(dá)式時(shí),它會從推送到堆棧中的最新對象開始向下搜索堆棧。OGNL是Struts使用的主要EL,它具有以下特殊語法:

  •  --objectName:ValueStack中的對象(OGNL上下文中的默認(rèn)/根對象),如Action屬性。
  •  --#objectName:位于ActionContext之內(nèi),同時(shí)位于ValueStack之外的對象。例如,#parameters.objectName用于請求參數(shù),#session.objectName用于會話作用域?qū)傩裕鹊取?/li>
  •  --%{ognlexp}:強(qiáng)制對通常為字符串的屬性進(jìn)行OGNL評估。
  •  --@full.class.name@Static_Field:用于表示類的靜態(tài)字段(變量和方法)。

與此報(bào)告相關(guān)的功能是強(qiáng)制使用語法%{ognlexp}對通常為字符串的屬性進(jìn)行OGNL計(jì)算。該語法稱為alt語法,是默認(rèn)啟用的。如果ognlexp是從用戶輸入中獲得的,且沒有進(jìn)行任何消毒處理,那么很可能會發(fā)生雙重計(jì)算。如果在標(biāo)簽屬性中進(jìn)行強(qiáng)制求值的話,這種情況就非??赡馨l(fā)生。例如(以錨點(diǎn)標(biāo)簽為例):

如果用戶提供的fileNam,使得原始OGNL表達(dá)式未經(jīng)進(jìn)一步驗(yàn)證即進(jìn)行了傳遞,則當(dāng)該標(biāo)簽作為請求的結(jié)果渲染時(shí),將會計(jì)算走私的OGNL表達(dá)式。也就是說,如果filename是OGNL表達(dá)式,如%{2+2},則渲染的標(biāo)簽為:

在渲染響應(yīng)時(shí),對于每個(gè)要渲染的標(biāo)簽,都會調(diào)用在org.apache.struts2.views.jsp.ComponentTagSupport類中定義的doStartTag()方法。然后,這個(gè)方法會進(jìn)一步調(diào)用populateParams()方法。然而,這個(gè)方法的實(shí)際調(diào)用版本,則取決于被處理的標(biāo)簽。對于錨標(biāo)簽來說,對應(yīng)的方法被定義為org.apache.struts2.views.jsp.ui.AnchorTag類中的populateParams()方法。實(shí)際上,id屬性的第一次計(jì)算發(fā)生在populateParams()的基類實(shí)現(xiàn)中,即調(diào)用在org.apache.struts2.component.UIBean類中定義的setId()。

在調(diào)用populateParams()方法之后,doStartTag()方法將開始計(jì)算標(biāo)簽并渲染模板。在org.apache.struts2.component.ClosingUIBean類中定義的start()方法中,將會執(zhí)行函數(shù)evaluateParams(),而這個(gè)函數(shù)會利用populateComponentHtmlId()函數(shù)來填充標(biāo)簽的id屬性。至于這個(gè)方法的調(diào)用版本,具體取決于被渲染的標(biāo)簽。對于一個(gè)錨標(biāo)簽來說,將調(diào)用org.apache.struts2.component.UIBean類中定義的populateComponentHtmlId()方法。這個(gè)實(shí)現(xiàn)會在findStringIfAltSyntax()函數(shù)中再次將id屬性作為OGNL表達(dá)式進(jìn)行處理。

在Apache Struts 2框架存在一個(gè)遠(yuǎn)程代碼執(zhí)行漏洞。該漏洞是由于對OGNL表達(dá)式可用的類和包限制不足所致,特別是java.io.、java.nio.、java.net.、sun.misc.包。雖然Apache Struts團(tuán)隊(duì)多次指出重復(fù)的OGNL計(jì)算是一個(gè)潛在的安全風(fēng)險(xiǎn),并指出開發(fā)人員應(yīng)該只使用強(qiáng)制計(jì)算功能來處理受信任的數(shù)據(jù),并已經(jīng)添加了相應(yīng)緩解控制措施,以最大限度地降低被利用的可能性。這些緩解控制措施包括:

  •  -- struts.excludedClasses:以逗號分隔的由排除的類組成的列表。
  •  -- struts.excludedPackageNamePatterns:用于根據(jù)Regex來排除包的模式。
  •  -- struts.excludedPackageNames: 用逗號分隔的由被排除的包組成的列表。

此外,Struts默認(rèn)限制了對Class構(gòu)造函數(shù)以及靜態(tài)方法的訪問。SetOgnlUtil()方法會修改ValueStack的SecurityMemberAccess屬性,以包含上述列表中的排除項(xiàng)。但是,如果遇到不在排除項(xiàng)中的類或包,則仍然允許其執(zhí)行不安全操作,因?yàn)镾ecurityMemberAccess.isAccessible()方法允許對那些訪問或操作這些包中定義的對象的表達(dá)式進(jìn)行計(jì)算。

Apache Struts所使用的FreeMarker Java模板引擎在包freemarker.ext.jsp中提供了一組實(shí)用工具類,以方便FreeMarker-JSP的雙向集成。在這些類中,有一個(gè)名為TaglibFactory的類。這個(gè)類提供了一個(gè)與servlet上下文相關(guān)聯(lián)的哈希模型,可以加載相關(guān)的JSP標(biāo)簽庫。類TaglibFactory能夠通過ObjectWrapper類的實(shí)例將Java對象映射到FreeMarker模板語言的類型系統(tǒng)。ObjectWrapper類決定了Java對象的哪些部分可以從模板中訪問,以及如何訪問。此外,類TaglibFactory還公開了一個(gè)獲取支持ObjectWrapper實(shí)例的getter。同時(shí),這個(gè)ObjectWrapper實(shí)例還提供了一種創(chuàng)建任意Java對象的方法,以便在需要時(shí)分別使用newInstance()和wrap()兩個(gè)公共方法對其進(jìn)行封裝。因此,攻擊者可以通過首先使用wrap()方法對參數(shù)進(jìn)行封裝,然后調(diào)用newInstance()指定要實(shí)例化的類和封裝的構(gòu)造函數(shù)參數(shù)來創(chuàng)建一個(gè)具有公共構(gòu)造函數(shù)的任意類實(shí)例。這個(gè)gadget有效地幫助Struts擺脫了對Class構(gòu)造函數(shù)的默認(rèn)限制。因此,TaglibFactory的實(shí)例可用于OGNL ValueStack中的OGNL表達(dá)式。

Guice輕量級依賴注入容器在包c(diǎn)om.openymphony.xwork2.inject中提供了一組實(shí)用工具類,用于提供構(gòu)造函數(shù)、方法、靜態(tài)方法、字段和靜態(tài)字段注入。其中,有一個(gè)名為ContainerBuilder的類。這個(gè)類提供了構(gòu)建依賴注入容器的工廠方法。更重要的是,它還提供了一個(gè)公共方法,可以用來創(chuàng)建Container實(shí)例。而Container實(shí)例不僅存有依賴關(guān)系映射,而且還提供了一個(gè)公共方法injection(),該方法可用于創(chuàng)建任意實(shí)例并將其注入依賴項(xiàng)映射中。容器實(shí)例有效地提供了一種檢索靜態(tài)工廠方法保護(hù)的實(shí)例的方法,否則OGNL表達(dá)式將無法使用這些方法。通過調(diào)用inject()并指定所需的類,我們就可以獲得沒有公共構(gòu)造函數(shù),只有返回單例實(shí)例的靜態(tài)工廠方法的任意類實(shí)例。我們可以使用前述的FreeMarker TagLibFactory小工具來獲得ContainerBuilder類的實(shí)例,因?yàn)樗鼘?shí)現(xiàn)了一個(gè)公共構(gòu)造函數(shù)。

借助于這些小工具(gadget),我們可以通過獲取受限類sun.misc.Unsafe的實(shí)例,從java.net.包中實(shí)例化一個(gè)類,打開與遠(yuǎn)程機(jī)器的連接并從遠(yuǎn)程機(jī)器接收類字節(jié),最后使用sun.misc.Unsafe.defineAnonymousClass()方法以及從遠(yuǎn)程服務(wù)器接收到的字節(jié)來定義一個(gè)任意類,從而繞過當(dāng)前的安全限制。然后,我們就可以使用sun.misc.Unsafe.allocateInstance()方法初始化任意類了。盡管allocateInstance()方法無法調(diào)用構(gòu)造函數(shù),卻可以在創(chuàng)建的實(shí)例上調(diào)用為該類定義的其他公共方法。或者,我們也可以使用來自java.io或java.nio包的類的實(shí)例可以用來創(chuàng)建任意文件(如JSP文件),并將其寫入到任意位置(如Web應(yīng)用程序根目錄),因?yàn)槲募窂揭每捎糜贠GNL ValueStack的OGNL表達(dá)式。

遠(yuǎn)程攻擊者可以通過向受攻擊的服務(wù)器發(fā)送包含惡意參數(shù)的HTTP請求來利用該漏洞。一旦成功利用該漏洞,他們就能夠執(zhí)行具有服務(wù)器權(quán)限的任意代碼。

小結(jié)

Apache Struts團(tuán)隊(duì)已經(jīng)在2020年8月修復(fù)了這個(gè)安全漏洞。根據(jù)他們的說法,相關(guān)的補(bǔ)丁是通過確保對傳入的每個(gè)值進(jìn)行正確檢查,并驗(yàn)證其是否用于標(biāo)簽的屬性來修復(fù)該漏洞的。此外,他們還建議,除非無法避免,否則最好不要使用%{...}或${...}語法對值以外的屬性進(jìn)行強(qiáng)制求值。最后,需要補(bǔ)充一點(diǎn),Struts的2.5.22和更高版本不受該漏洞影響。

特別感謝趨勢科技研究團(tuán)隊(duì)的Kc Udonsi和John Simpson對該漏洞提供了如此詳盡的分析。有關(guān)趨勢科技研究服務(wù)的簡介,請?jiān)L問http://go.trendmicro.com/tis/。

 本文翻譯自:https://www.thezdi.com/blog/2020/10/7/cve-2019-0230-apache-struts-ognl-remote-code-execution如若轉(zhuǎn)載,請注明原文地址。

 

責(zé)任編輯:姜華 來源: 嘶吼網(wǎng)
相關(guān)推薦

2023-12-14 16:20:09

2024-12-19 13:42:48

2017-05-25 22:20:05

2020-10-08 13:44:27

漏洞

2013-05-22 10:28:19

2014-09-12 17:47:36

2021-09-23 15:20:18

微軟漏洞代碼

2017-05-27 10:22:37

2024-12-19 15:13:26

2013-07-18 10:06:54

2020-10-19 10:43:49

漏洞

2016-03-22 12:37:45

Struts2Struts2漏洞漏洞檢測

2021-01-26 10:00:45

漏洞網(wǎng)絡(luò)安全網(wǎng)絡(luò)攻擊

2017-03-08 22:23:02

2015-03-06 15:31:01

2025-10-29 09:39:48

2013-07-24 14:06:48

2021-12-29 14:47:43

Apache團(tuán)隊(duì)Log4j漏洞

2025-05-08 09:49:19

2013-11-29 15:41:08

解析漏洞ApacheApache解析漏洞
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號