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

首页

1305分析

作者 recor 时间 2020-02-27
all

(360 A-TEAM 長期招收高級安全研究人員,APT 攻防人員,請聯系[email protected]

兩個CVE

CVE-2018-1305

CVE-2018-1304

從造成的影響方面來講,都是雞肋。從原理上講有點像,基本可以認為是同一個。從分析角度來講,這兩個都比較簡單。

這裡只對 CVE-2018-1305 進行簡要分析。

背景知識

Java EE 提供了類似ACL 許可權檢查的注解,可以直接用於修飾Java Servlet,用於對Servlet 進行ACL 保護。

簡要分析

現假設有兩個Servlet:

Servlet1,訪問路徑為/servlet1/*

Servlet2,訪問路徑為/servlet1/servlet2/*

Servlet1 上有如下圖的Security Constraint(簡單理解就是ACL):

Servlet2 上並沒有ACL。

然而因為Servlet2 的訪問url 位於Servlet1 的下一級(/servlet1/servlet2 是 /servlet1/ 的“子目錄”),所以Tomcat 中正常的程式碼邏輯應該是,雖然Servlet2 上面沒有ACL,但是Servlet2 應該繼承Servlet1 的ACL。

正常情况應該是:

先訪問/servlet1,返回403,因為請求被ACL 攔截了

再訪問/servlet1/servlet2,返回403,因為請求被ACL攔截

那麼實際的問題在哪裡?

Tomcat 在接收到Servlet 訪問請求後,在實例化Servlet 對象之前,會先掃描被訪問的Servlet 上注册的ACL。如果存在ACL,則將ACL 規則添加到一個Context 唯一的清單中。隨後再檢查當前訪問的Servlet 是否被ACL保護。

ACL 掃描org.apache.catalina.authenticator.AuthenticatorBase#invoke:

ACL檢查org.apache.catalina.authenticator.AuthenticatorBase#invoke:

問題出在,如果在Servlet1(/servlet1)被訪問之前,有人先訪問了 Servlet2(/servlet1/servlet2)。流程如下:

Tomcat 接收到Servlet2 的訪問請求

Tomcat 掃描Servlet2 上注册的ACL,發現Servlet2 上沒有註冊ACL

Tomcat 檢查Servlet2 是否被ACL保護。這一步,因為Servlet2 在Servlet1 之前被訪問,所以導致Servlet1 上注册的ACL規則還沒有被Tomcat 發現。所以,原本應該被Servlet1 的ACL規則保護的Servlet2,就處在了未受保護的狀態。

實例

訪問 http://localhost:8080/CVE-2018-1305/servlet1/servlet2,此時servlet1 的ACL 沒被Tomcat 加載,所以訪問成功

訪問http://localhost:8080/CVE-2018-1305/servlet1,被拒絕訪問了,此時Tomcat 加載了servlet1 的ACL

再訪問 http://localhost:8080/CVE-2018-1305/servlet1/servlet2,被拒絕訪問了,因為Tomcat 已經加載了servlet1 的ACL

Tomcat的修復

Tomcat 的修復了ACL 注册的管道。以前是採用,在Servlet 真正被訪問之前才去注册此Servlet 上的ACL。現在改成了,在Context 啟動的時候,就去掃描該Context下所有的Servlet 上注册的ACL,並添加到acl 清單中。

在任何一個Context 啟動時,Tomcat 都會自動調用:

org.apache.catalina.startup.WebAnnotationSet#loadApplicationServletAnnotations

而其中,添加了如下ACL 相關程式碼:

影響範圍

只有當你使用的Tomcat 處於受影響的Tomcat 版本,而且你的應用依賴於Java EE Constraints 來進行ACL 保護的時候,才受影響。

360 A-TEAM是隸屬於360企業安全集團旗下的純科技研究團隊。團隊主要致力於Web滲透,APT攻防、對抗,前瞻性攻防工具預研。從底層原理、協定層面進行嚴肅、有深度的科技研究,深入還原攻與防的科技本質。

歡迎有意者加入!