struts2 漏洞分析 及解决办法
1.討論關(guān)于struts 安全問(wèn)題。
2.黑客文化。
3.如何降低安全漏洞的出現(xiàn)。
4.忠告建議。
題記:
這篇文章本來(lái)很早應(yīng)該和大家見(jiàn)面的,中間由于個(gè)人原因調(diào)整了系列文章發(fā)布時(shí)間,實(shí)屬罪過(guò)。為了不誤導(dǎo)大眾文章中間講述的經(jīng)歷想法實(shí)戰(zhàn),均屬個(gè)人看法個(gè)人行為不代表任何團(tuán)體及組織。觀看者請(qǐng)保留自己的想法觀點(diǎn)!歡迎各位熱愛(ài)編程的技術(shù)人員交流。廢話不多,開(kāi)始正文。
1.討論關(guān)于struts安全問(wèn)題。
最近各位都看到了各種關(guān)于struts安全問(wèn)題的文章,及實(shí)戰(zhàn)演練,安全問(wèn)題波及到了各種大小的互聯(lián)網(wǎng)站點(diǎn)(京東,電信,IBM,其中后兩個(gè)網(wǎng)站都是筆者請(qǐng)自嘗試,只是做友情檢測(cè),并未做任何非法過(guò)激動(dòng)作)。各個(gè)論壇相繼出現(xiàn)各種詆毀,謾罵關(guān)于struts安全的回復(fù)。
對(duì)于以上的問(wèn)題,個(gè)人奔著還原問(wèn)題的本質(zhì),通過(guò)友情檢測(cè)IBM報(bào)名網(wǎng)站做實(shí)戰(zhàn)講述+個(gè)人測(cè)試Test,講述關(guān)于我們應(yīng)該如何看待struts安全問(wèn)題。
對(duì)于IBM報(bào)名網(wǎng)站這里做必要解釋,并非刻意測(cè)試,而是今日公司安排報(bào)名培訓(xùn),上去結(jié)果發(fā)現(xiàn)該網(wǎng)站亦是struts架構(gòu),遂友情檢測(cè)。截止文章發(fā)布之時(shí)已經(jīng)郵件通知IBM運(yùn)維。如下截圖為證。
在正式解讀struts安全問(wèn)題之前我們先來(lái)了解一下struts,其實(shí)在命名的時(shí)候都不知道改用struts還是struts2?有人會(huì)問(wèn)題?為什么?看官且慢慢聽(tīng)我講,現(xiàn)在apache官方稱(chēng)謂struts2,為何筆者又命名為struts呢?因?yàn)槲覀冞@里討論 大家對(duì)struts安全的誤解和盲區(qū),struts作為apache眾多項(xiàng)目的一個(gè)頂級(jí)項(xiàng)目,而struts2的前身就是struts,漏洞也是從struts開(kāi)始暴露出來(lái)的,想必老一輩的coder應(yīng)該用過(guò)struts,開(kāi)始的時(shí)候就用struts2 了,截止前不久apache 官方對(duì)struts已經(jīng)終結(jié)其生命了。各位可以到這里觀摩(http://struts.apache.org/)
早在沒(méi)有使用struts之前,玩駭客的應(yīng)該都知道有struts漏洞檢測(cè)工具,不錯(cuò)!這個(gè)就是struts第一次出現(xiàn)安全漏洞問(wèn)題,截止目前struts已經(jīng)出現(xiàn)兩次安全漏洞!最近一次的安全描述(http://struts.apache.org/release/2.3.x/docs/s2-016.html)
看完各種網(wǎng)絡(luò)文章,評(píng)論,有人說(shuō)這個(gè)漏洞5月份就提交apache處理了,但是漏洞大面積鋪開(kāi)的時(shí)候是7月中旬,也就是apache公開(kāi)安全漏洞的不久后!而得知的是在7月14日有人在博客園閃存多次發(fā)布,而引起筆者注意,當(dāng)天下午筆者邊看到apache公開(kāi)漏洞滲透的方法。這里apache的做法確實(shí)不對(duì),因?yàn)榘凑諊?guó)際慣例,漏洞發(fā)現(xiàn)后不能公開(kāi)具體滲透方法,只能描述,等官方修復(fù)后才能!
過(guò)后幾天,各種網(wǎng)站類(lèi)似于struts2安全漏洞做各種的評(píng)論文章分析,導(dǎo)致各種的批判詆毀的爭(zhēng)論不休的評(píng)論發(fā)生!確實(shí)如此筆者得知后第一時(shí)間google測(cè)試,結(jié)果發(fā)現(xiàn)確實(shí)如此,不幸的是google出來(lái)一個(gè)電信某積分分站,確實(shí)如此,之后突然想起來(lái),交話費(fèi)用的電信官網(wǎng)也是struts架構(gòu)的,立刻友情檢測(cè),確實(shí)中招!之后想通過(guò)email通知,結(jié)果發(fā)現(xiàn)電信網(wǎng)站木有email提交,神馬在線交流都是擺設(shè),筆者隧到烏云(我朝號(hào)稱(chēng)為互聯(lián)網(wǎng)安全而戰(zhàn)的網(wǎng)站,上屬?lài)?guó)家互聯(lián)網(wǎng)安全中心,自命白帽子)不行,忘記了賬號(hào)密碼,放棄!瀏覽網(wǎng)站,確實(shí)有人提交了,故放棄,看了看,發(fā)現(xiàn)烏云很多人為了提交漏洞而提交漏洞!覺(jué)得實(shí)屬?zèng)]有意思,放棄了,本來(lái)想寫(xiě)文章后來(lái)覺(jué)網(wǎng)上各種有,放棄!后來(lái)一想該漏洞確實(shí)不是出自struts,而是XWork,想必用過(guò)struts的人都知道,XWork才是struts的核心,早起這兩個(gè)不是一家,后來(lái)apache收入麾下將XWork和struts結(jié)婚了(正所謂不是一家人不進(jìn)一家門(mén)),而XWork提供的ONGL表達(dá)式語(yǔ)言正是兩次struts漏洞的罪魁禍?zhǔn)?#xff01;
ps:當(dāng)我們發(fā)現(xiàn)安全問(wèn)題的時(shí)候,而不是批判別人為我們做的不夠,也不是推卸責(zé)任的時(shí)候,及時(shí)有效的解決問(wèn)題才是!當(dāng)然,作為商業(yè)性的要另行討論,正如我下午在閃存和某兄討論:項(xiàng)目管理之風(fēng)險(xiǎn)合理規(guī)避問(wèn)題一樣。說(shuō)俗點(diǎn)就是推卸責(zé)任(但又在合理之中)。我們謾罵框架的不夠完美也罷,維護(hù)人員維護(hù)不及時(shí)也罷,要看問(wèn)題的實(shí)質(zhì)是不是我們想的那樣,正如Xwork的核心漏洞,struts維護(hù)人員怎能及時(shí)發(fā)現(xiàn)?盡管發(fā)現(xiàn),輕而易舉的修改核心?這個(gè)看起來(lái)似乎不是那么的簡(jiǎn)單!想必大家都是程序員,寫(xiě)程序比維護(hù)程序或者修改程序難的多!不管你有多么的牛逼,網(wǎng)上后來(lái)也有人試過(guò)一些非官方推薦方法,有些失敗,因?yàn)楸砻鎸?duì)了,但是實(shí)質(zhì)聰明的駭客還可以繞過(guò)他的過(guò)濾!
直到今日IBM亦出現(xiàn)該安全漏洞!故借此一起講講個(gè)人的安全看法!廢話不講了,下面看實(shí)戰(zhàn)!
(圖1.1)
(圖1.2)
(圖1.3)
?
到此,再也沒(méi)有測(cè)試,因?yàn)闇y(cè)試也是意義不大,即使你可以遠(yuǎn)程啟動(dòng)也沒(méi)有意義,做一些遠(yuǎn)程關(guān)閉服務(wù)器的事情也沒(méi)意義!不過(guò)可以通過(guò)遠(yuǎn)程構(gòu)造上傳腳本小子提權(quán)!
下面講講三幅圖的奧秘,圖1.1中只是采用redirect中定向baidu,也算是初步判斷是不是存在struts2的漏洞,到圖1.2可以證明一點(diǎn),確實(shí)存在struts2漏洞!那么接下來(lái)就是駭客常用的手法,小馬提權(quán)再通過(guò)大馬獲取服務(wù)器(大小木馬后面講)。圖1.3就是我嘗試提交運(yùn)行遠(yuǎn)程服務(wù)器的命令(開(kāi)始calc,當(dāng)然這個(gè)是windows下命令),response給我的jsp頁(yè)面,從圖中我們可以看出我的命令執(zhí)行了,但是我們?nèi)绾未_定呢?因?yàn)槲覀兺ㄟ^(guò)這個(gè)無(wú)法判斷是否成功!由于為IBM服務(wù)器,可能涉及法律相關(guān)問(wèn)題,本人沒(méi)有進(jìn)一步滲透!
接下來(lái)通過(guò)自己的Demo來(lái)演示 上面的構(gòu)造是否成功!搭建了一個(gè)struts2的入門(mén)項(xiàng)目,struts2 core是2.1.8。為了驗(yàn)證我們前面的猜想及準(zhǔn)確性,我采用雙系統(tǒng)切換測(cè)試,一個(gè)windows 一個(gè)linux,兩個(gè)系統(tǒng)同時(shí)部署相同的項(xiàng)目,測(cè)試不同平臺(tái)下看看結(jié)果是神馬?客戶端我采用的是服務(wù)器如果是linux,我就用windows客戶端訪問(wèn),反之同理。結(jié)果如下!
游戲開(kāi)始:只需要redirectAction:%25{(new+java.lang.ProcessBuilder(new+java.lang.String[]{'calc','goes','here'})).start()} 一句話就可以構(gòu)造起來(lái)遠(yuǎn)程服務(wù)器windows。
第一:我們先測(cè)試windows服務(wù)器下的結(jié)果(下面上圖)
?
(圖2.1.1)
從上面豐富的圖中可以看出游戲的結(jié)果,圖中我們可以看出上面的那一句話確實(shí)開(kāi)啟了windows 服務(wù)器的calc(計(jì)算器)綠色框中的就是windows 下服務(wù)器控制臺(tái)爆出來(lái)的bug,為什么會(huì)出現(xiàn)bug呢?我們通過(guò)%{}構(gòu)造了一個(gè)進(jìn)程對(duì)象,而ONGL去執(zhí)行了我們構(gòu)造的進(jìn)程對(duì)象,這個(gè)時(shí)候服務(wù)器端的計(jì)算器被遠(yuǎn)程開(kāi)啟,到這里漏洞就算是暴露的無(wú)疑了!那為什么控制臺(tái)有那樣的bug呢?redirectAction我們?yōu)槭裁匆x用這個(gè)呢?見(jiàn)名知意,重定向去執(zhí)行一個(gè)action,所以構(gòu)造的進(jìn)程對(duì)象被執(zhí)行了,struts2的架構(gòu)必須返回一個(gè)字符串來(lái)跳轉(zhuǎn)到該action映射到的jsp頁(yè)面,而我們只指定了其執(zhí)行邏輯沒(méi)有返回任何字符串,這個(gè)時(shí)候在Map搜尋不到就返回一個(gè)沒(méi)有該映射(具體我們?cè)诤竺嬖敿?xì)解釋)。
總結(jié):windows 下如此構(gòu)造出來(lái)的腳本可以遠(yuǎn)程啟動(dòng)windows下的commnd。
第二:既然windows可以那我們不妨換到linux平臺(tái)再看看會(huì)發(fā)生神馬情況!
首先我們要明白windows上面的命令和linux上面的是不同的,所以我們需要切換命令執(zhí)行。
redirectAction:%25{(new+java.lang.ProcessBuilder(new+java.lang.String[]{'shutdown –h now'})).start()}(這次有點(diǎn)邪惡哦,用的關(guān)機(jī)命令,linux用不多,這個(gè)絕對(duì)記得!)
游戲開(kāi)始:看下面圖
(圖2.2.1)
(圖2.2.2)
圖2.2.1中能看出來(lái)說(shuō)明,執(zhí)行成功了,圖2.2.2中可以看出來(lái)執(zhí)行了,抱的錯(cuò)誤還是跟windows平臺(tái)同理!有人會(huì)問(wèn)了,為什么,木有關(guān)機(jī)?呵呵!確實(shí),為什么呢?
其實(shí)道理很簡(jiǎn)單,linux執(zhí)行權(quán)限規(guī)則審查比較嚴(yán)格.我們無(wú)權(quán)執(zhí)行核心命令!所以執(zhí)行無(wú)效!web正常返回!404page.那么有人就說(shuō)了,能不能讓其表現(xiàn)出我們所要看到的遠(yuǎn)控漏洞呢?這個(gè)是可以的,我們稍微修改一下檢測(cè)的代碼讓正在運(yùn)行的web服務(wù)器停機(jī)!通過(guò)啟動(dòng)虛擬機(jī)的關(guān)閉序列,終止當(dāng)前正在運(yùn)行的 Java 虛擬機(jī)。
struts2為我們提供了動(dòng)態(tài)方法執(zhí)行的模式!我們只需要開(kāi)啟,那么再加上struts2的ONGL漏洞執(zhí)行,這樣不就可以執(zhí)行了嘛!(這里說(shuō)是struts2還不如說(shuō)是XWork提供的機(jī)制)
公開(kāi)部分代碼:
?('\u0023_memberAccess[\'allowStaticMethodAccess\']')(meh)=true&(aaa)(('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003d\u0023foo')(\u0023foo\u003dnew%20java.lang.Boolean("false")))&(asdf)(('\u0023rt.exit(1)')(\u0023rt\u003d@java.lang.Runtime@getRuntime()))=1
簡(jiǎn)單解釋一下這句話,這句話的意思就是通過(guò)客戶的url地址欄修改了XWork的動(dòng)態(tài)方法執(zhí)行權(quán)限,然后借助ONGL漏洞,讓其執(zhí)行我們動(dòng)態(tài)構(gòu)造的終止當(dāng)前正在運(yùn)行的 Java 虛擬機(jī)指令。而這句話也是轉(zhuǎn)義過(guò)的,否則Map里面不會(huì)去存放我們的執(zhí)行指令(當(dāng)然XWork設(shè)計(jì)者考慮到了這一點(diǎn),就是禁止啟用這一功能,但為什么我們能執(zhí)行呢?你如果能看明白我們的代碼是通過(guò)轉(zhuǎn)義過(guò)的其實(shí)質(zhì)代碼就是:?('#_memberAccess['allowStaticMethodAccess']')(meh)=true&(aaa)(('#context['xwork.MethodAccessor.denyMethodExecution']=#foo')(#foo=new%20java.lang.Boolean("false")))&(asdf)(('#rt.exit(1)')(#rt=@java.lang.Runtime@getRuntime()))=1里面的“#”就是ONGL表達(dá)式中需通過(guò)“#+對(duì)象的名稱(chēng)”來(lái)訪問(wèn)context中的對(duì)象,里面的“@”就是調(diào)用靜態(tài)方法,需要在類(lèi)名和變量名前面加上@來(lái)調(diào)用,對(duì)于實(shí)例方法,用"."來(lái)調(diào)用。)、到時(shí)候ONGL也是無(wú)法執(zhí)行的、
官方的解析參考是如圖:這個(gè)是對(duì)動(dòng)態(tài)方法執(zhí)行的官方解釋(這個(gè)是struts2最新版的XWork里面的描述,當(dāng)然在我翻看API的時(shí)候發(fā)現(xiàn)struts2API和XWorkAPI依舊分開(kāi),雖然兩人日子過(guò)一起了,可是“錢(qián)”還是各賺各的。)、
下圖就是通過(guò)struts配置文件的形式啟動(dòng)動(dòng)態(tài)方法執(zhí)行(true就是開(kāi)啟,有些公司為了提高代碼的高可用就是通過(guò)這個(gè)表達(dá)式來(lái)映射方法及jsp來(lái)執(zhí)行的,當(dāng)然這個(gè)相當(dāng)危險(xiǎn)項(xiàng)目的檢查機(jī)制必須做好。)。看圖很明顯的解釋。
結(jié)果:
(圖3.1)
當(dāng)我接到服務(wù)器響應(yīng)給我圖3.1的效果的時(shí)候,我肯定確實(shí)服務(wù)器停止了!這個(gè)過(guò)程稍微延遲了幾秒,我心砰砰的,能感覺(jué)到服務(wù)器正在關(guān)閉!之后立刻查看服務(wù)器,結(jié)果如下圖3.2!
?
(圖3.2)
總結(jié):到這里我的謎團(tuán)打開(kāi)了,就是為神馬我檢測(cè)IBM,中國(guó)電信,網(wǎng)站的時(shí)候給我一個(gè)404的原因了,原因就是這兩家的都是linux服務(wù)器,電信的貌似是unix服務(wù)器(曾經(jīng)聽(tīng)別人提起過(guò)!)IBM是linux服務(wù)器。最起碼能斷定該服務(wù)器不是windows,有過(guò)駭客經(jīng)驗(yàn)的都應(yīng)該清楚攻擊服務(wù)器,對(duì)了解該服務(wù)器是那種平臺(tái)又很重要意義,通過(guò)實(shí)踐我們就能推理出來(lái)!而且確實(shí)執(zhí)行了我的遠(yuǎn)程指令,只不過(guò)我木有高級(jí)權(quán)限,但是即使拿到高級(jí)權(quán)限我覺(jué)得也沒(méi)多大意義,IBM服務(wù)器也不是吃素的應(yīng)該上面有防火墻,而且有殺毒軟件!執(zhí)行這些高危系統(tǒng)進(jìn)程肯定會(huì)被攔截、但是絕對(duì)有方法可以繞過(guò)去、這里就嘗試這么多。
嘗試了這么多,我們下面剖析ONGL漏洞,神馬是ONGL。這里我給出官方的解釋:OGNL is the Object Graph Navigation Language (seehttp://www.opensymphony.com/ognl?for the full documentation of OGNL).簡(jiǎn)言之就是:對(duì)象圖導(dǎo)航語(yǔ)言。下面給出官方模型圖(具體訪問(wèn):http://struts.apache.org/release/2.3.x/docs/ognl.html)
演練了這么就是OGNL對(duì)象地圖導(dǎo)航惹的禍,而且我知道的兩次struts漏洞都是出自這個(gè),對(duì)象導(dǎo)航顧名思義,構(gòu)造對(duì)象然后去找Map里面存的地圖。響應(yīng)給客戶jsp,所以struts的核心就是這個(gè),其他的攔截過(guò)濾機(jī)制都是輔助ONGL來(lái)完成對(duì)象導(dǎo)航的、這里不多講了,用過(guò)struts的都應(yīng)該明白。我用圖來(lái)給大家解讀、
看圖吧,寫(xiě)的都多了!最后總結(jié)一句話目前來(lái)看struts2將會(huì)伴隨這種機(jī)制一直修補(bǔ)下去,除非重構(gòu)這種方式,顯然很難!我想struts2官方推薦升級(jí)版,也就是過(guò)濾防止不允許執(zhí)高危構(gòu)造方式,杜絕轉(zhuǎn)碼方式滲透。
如何預(yù)防:
1.網(wǎng)上有人通過(guò)
<interceptor-ref name="params">?
<param name="excludeParams">.*\\u0023.*</param>?
</interceptor-ref>?
這個(gè)是struts提供的一種機(jī)制就是通過(guò)正則表達(dá)式過(guò)濾提交參數(shù)。
2.可以通過(guò)過(guò)濾器的方式初級(jí)過(guò)濾,然后再采用struts2提供validate來(lái)驗(yàn)證提交的參數(shù)(提高驗(yàn)證規(guī)則,比如:包括轉(zhuǎn)碼也需要考慮)。很多coder大多就是javascript蒙騙驗(yàn)證法,何謂蒙騙驗(yàn)證法?就是在頁(yè)面通過(guò)javascript驗(yàn)證,后臺(tái)從來(lái)不做規(guī)則驗(yàn)證。你要知道 駭客可是不吃這一套的。還有需要加入強(qiáng)制類(lèi)型轉(zhuǎn)換機(jī)制,這個(gè)struts2也提供了,只是很多coder也無(wú)視其存在。
3.這種是我個(gè)人推薦的五星級(jí)方法:天空一聲巨響spring security 閃亮登場(chǎng),關(guān)于安全的框架很少,但是這個(gè)東東絕對(duì)是一個(gè)好東西,可是國(guó)內(nèi)對(duì)安全的不重視,導(dǎo)致該框架用的很少。網(wǎng)上資料也是很少。這個(gè)是spring 的一個(gè)頂級(jí)項(xiàng)目,本人用過(guò)spring security2,3沒(méi)有用過(guò),基本變化不大,里面有少數(shù)class做了修改。這里不做過(guò)多介紹各位好好研究去吧,這個(gè)東西是一套權(quán)限,安全,openID,cas單點(diǎn)登錄,防止會(huì)話偽造等功能!對(duì)于未授權(quán)的action都是無(wú)法執(zhí)行的、從集成ssh2的架構(gòu)上來(lái)講,他是保護(hù)在struts2外面的一到防線、
struts2漏洞解決辦法
??????????7月17日,世界知名開(kāi)源軟件struts 2爆出了2個(gè)高危漏洞,這些漏洞可使黑客取得網(wǎng)站服務(wù)器的“最高權(quán)限”,從而使企業(yè)服務(wù)器變成黑客手中的“肉雞”。
?
詳細(xì)漏洞信息:http://struts.apache.org/release/2.3.x/docs/s2-016.html
http://struts.apache.org/release/2.3.x/docs/s2-017.html
http://struts.apache.org/release/2.3.x/docs/version-notes-23151.html
目前,官方已經(jīng)發(fā)布高危安全漏洞補(bǔ)丁升級(jí)(最新版本為:2.3.15.1,下載地址:http://struts.apache.org/download.cgi#struts23151),升級(jí)修補(bǔ)了多個(gè)安全漏洞,其中包括這個(gè)遠(yuǎn)程任意代碼的高危安全漏洞。
關(guān)于此漏洞,最好的解決方法當(dāng)然是將struts2的jar包更新到最新版本。不過(guò)對(duì)于不同struts2版本,升級(jí)會(huì)引起一些包沖突。
升級(jí)步驟:
1.下載到的更新包中主要用到以下幾個(gè)替換掉舊版本的:
commons-lang3-3.1.jar (保留原有的commons-lang.jar,因?yàn)樯?jí)后,org.apache.commons.lang.StringUtils類(lèi)被 org.apache.commons.lang3.StringUtils替換了,所有要保留原有包)
javassist-3.4.GA.jar (新加包)
ognl-3.0.6.jar (替換舊版本)
struts2-core-2.3.15.1.jar (替換舊版本)
xwork-core-2.3.15.1.jar (替換舊版本)
struts2-spring-plugin-2.3.15.1.jar(替換舊版本)
2.如果原有spring包版本太低,如2.0,還需要升級(jí)spring包到2.5版本。
struts2.1以下版本,需要檢查struts的xml配置文件,type="redirect" 改為 type="redirectAction"。
3.修改 web.xml文件
將
struts-cleanup
org.apache.struts2.dispatcher.ActionContextCleanUp
struts-cleanup
public class SqlFilter implements Filter {
public static final Logger logger = Logger.getLogger(sun.reflect.Reflection.getCallerClass(1));
//需要過(guò)濾的post字符
private static String sqlStr="',<,>,and,exec,insert,select, ,delete,update,count,*,%,chr,mid,master,truncate,char,like,declare,&,#,(,),,=,script,
總結(jié)
以上是生活随笔為你收集整理的struts2 漏洞分析 及解决办法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ThinkPad(E431)光驱改SSD
- 下一篇: demiiris (pymel) for