安全圈 | 专注于最新网络信息安全讯息新闻

首页

struts2最近量產漏洞分析(2013

作者 landy 时间 2020-02-25
all

by空虛浪子心https://inbreak.net微博:http://t.qq.com/javasecurity可能是由於溝通問題,導致struts2官方對我提交的S2-012漏洞名稱理解錯誤,漏洞描述為struts2的某個示例應用出現漏洞,但是struts2是按照框架出現漏洞修補的。而這個s2-012竟然引發了一連串血案。其實發這篇文章,我非常惱火,任誰手裡有一個0day,捂了半天,結果又被別人公開,都會非常惱火。去年我在XCON發佈的S2-012漏洞,其實struts2還存在相似的漏洞。在struts中,框架接收到的用戶輸入,除了參數、值以外,還有其他地方,比如檔名。這個漏洞,是struts2對url中的檔名做了解析,導致的ognl程式碼執行。這中間存在一些科技細節,下麵展開分析。enableOGNLEvalExpression的騙局從漏洞公告上看到這個詞,很容易認為是struts2把ognl運算式幹掉了,可以選擇終結一切。事實上禁止的是OGNL的其中一種調用管道,而這種調用管道,也只是在S2-013這裡調用。struts2有另外一段威武的程式碼,真正在防守這個漏洞。

原本是這樣寫的,程式碼走到translateAndEncode就會調用ognl執行,它的邏輯一共包括ognl的translate,以及urlencode這兩個功能。

補丁之後,這裡被改為僅僅urlencode,不再做ognl執行。這個和enableOGNLEvalExpression沒有任何關係。

我沒有細看內容,只看方法名的變動,就感覺可以洗洗睡了,不必往下跟進了。allowStaticMethodAccess騙局一直以來allowStaticMethodAccess是struts2的poc標配,從第一個poc出現開始,就一直存在。在2013年5月27日,也就是前幾天,大家可以自行查看SVNlog,struts2做了一件很猥瑣的事情,把以下程式碼删除了:

這個動作直接導致一個結果,以後在OGNL的POC中執行

一定會報錯的,因為沒有set方法了。很有終結一切的意思,就像以後有新的OGNL漏洞,就不能寫這一句了。但是我可以繞過這個東西,下麵結合s2-015漏洞做個示例。struts2框架s2-015吐槽這個漏洞,被人公佈出來,實際上,發佈者一共發佈了幾個漏洞,包含S2-015、以及S2-012。具體地址在

非常詳細,某同事認為他比我分析的好,所以我就不寫翻譯了,大家自己看。後來仔細想了想,猜測老外可能遇到s2-012,導致了該文章的發佈,當然,這只是我的個人YY。發佈者手握2個0day,很不幸,我也有這兩個0day,去年xcon發佈了一個,之後提交了官方,但是他不知道,因為官方到今年才公開修補。前幾天官方突然公開修補了我發佈的一個0day,這個老外看到s2-012後,可能也非常惱火,因為這個漏洞和他手頭分析的0day剛好相同,所以一怒之下和其他0day一起發出來了,共同組成一篇文章。可以看到,發佈者直接從blog發佈,之後官方才收到消息開始修補。這個漏洞的觸發程式碼展現形式和s2-012非常像,所以理解了s2-012後,可以聯想到這個0day,很容易通過測試出來,我當時也是看到類似的使用,隨手測試就發現了。相信有很多漏洞,都是類似的情况下發現的。甚至可能不止我們手裡有,其實你也非常惱火。S2-015的poc在老外的文章中如下:

由於POC中存在#_memberAccess[“allowStaticMethodAccess”]=true,所以發佈者提到陞級到s2-014可以緩解。其實發佈者誤解了,但是struts2開發者沒有誤解,所以趕緊推出了S2-015。但是如果不講出來,你還是會發現那個POC在S2-014之後其實不能打,就如老外文章中所說,被緩解了。那要怎麼打呢?OGNL的POC有個小技巧這個東西的含義,是允許靜態方法執行,那麼官方禁止修改這個設定,意思就是永遠禁止靜態方法執行。因為POC中的“@[email protected]”其實就是在執行靜態方法,所以才一定要開啟靜態,但是這只是java程式碼的一種寫法罷了。我們可以用另一個寫法,繞過這個限制。

這段程式碼中,沒有調用任何靜態方法,僅僅是new一個對象,之後執行其中一個動態方法,所以不必allowStaticMethodAccess一樣能達到執行系統命令的效果。這個小技巧,可以幹很多事情。1、可以繞過某些WAF,我不告訴你是哪些,免得你拿去騙獎品。2、可以為以後新的OGNL程式碼執行鋪路,避免0day來了,我們居然因為這個不會寫POC。S2-015的修補簡單說一句,這裡沒有什麼研究價值,這次修補,官方採用了限制action的名稱,只能

總結struts2出現過的ognl運算式輸入點1、request參數名2、request參數值3、request檔名4、request的cookie名5、respose的body慘不忍睹,好像HTTP頭基本都出了問題,也沒剩下多少了。一個流行框架,能够在這麼多地方出現遠程程式碼執行,真是難為struts開發者了。同時也問一下使用struts的同學們,你們這些年,是怎麼過來的?在阿裡巴巴,我時常分析struts2漏洞然後發報告,有時候會是0day,那就要出個補丁給各個項目用,最後等到官方發佈補丁時,我們再評估是否需要重新更新回去。導致我們時常勸說開發人員儘量不要使用這個框架,尤其是項目初期評審時,發現struts2,深惡痛絕,說很多很多話用於嚇唬開發人員。在這種趨勢下,我對這個東西已經再無任何僥倖心理,决定推出一個虛擬補丁。至於阿裡的真實方案,我肯定不能告訴大家,但是可以講講思路。統一防禦方案首先陞級到最新版本。在ognl這個語言的入口,加入攔截程式碼,一旦發現危險調用,直接幹掉。程式碼原理是,在OGNL執行之前,對語句做判斷,看到有黑名單的程式碼,就幹掉。理論上,開發人員理論上不會自己寫OGNL用於操作檔案,執行命令等,他們最多從session中取一個值,或者在頁面上取一個值。覆蓋掉Ognl.Ognl類,添加如下程式碼:

為什麼要加入QQ郵箱呢?具體原因不說,只說結果,結果是,我的郵箱可以收到0DAY,你如果真的看懂了,自己猜猜原因?by空虛浪子心https://inbreak.net微博:http://t.qq.com/javasecurity