作者:R17a
本文為作者投稿,Seebug Paper 期待你的分享,凡經采用即有禮品相送! 投稿郵箱:paper@seebug.org
近期最火的漏洞莫過于log4j2 RCE漏洞,都說是史詩級的漏洞,那必然要分析下。
0x01 定位漏洞
既然是利用了jndi,那么斷點就打在javax.naming.InitialContext構造方法肯定是沒錯的。
通過回溯,最初調用lookup相關的地方在org.apache.logging.log4j.core.lookup.StrSubstitutor.replace()

進一步回溯分析調用lookup的原因,在MessagePatternConverter.format()中,遍歷每個字符,當匹配到${就調用StrSubstitutor.replace()處理jndi相關信息。

0x02 log4j日志記錄及漏洞分析
在詳細分析前先簡單了解下log4j三大組件:
- Logger:日志記錄器,負責收集處理日志記錄
- Appender:日志存放的地方,負責日志的輸出
- Layout:日志格式化,負責日志輸出的形式
1、在log4j2中通過LoggerConfig.processLogEvent()處理日志事件,主要部分在調用callAppenders()即調用Appender:

2、Appender功能主要是負責將日志事件傳遞到其目標,常用的Appender有ConsoleAppender(輸出到控制臺)、FileAppender(輸出到本地文件)等,通過AppenderControl獲取具體的Appender,本次調試的是ConsoleAppender。

調用ConsoleAppender.tryAppend()嘗試輸出日志

3、首先獲取Layout日志格式,通過Layout.encode()進行日志的格式化

Layout會獲取formatters來完成具體的格式化的事情

4、處理傳入的message通過MessagePatternConverter.format(),也是本次漏洞的關鍵之處,我們具體來看下。首先創建一個workingBuilder,當config存在并且noLookups為false,匹配到${'則調用workingBuilder.append()獲取StrSubstitutor內容來替換原來的信息(這里說明下,jndi執行命令后如果返回了結果就會將其append輸出)

noLookups來自設置來自配置文件,默認值為false,相當于默認支持jndi。


5、StrSubstitutor.resolveVariable()解析變量,調用Interpolator.lookup(),Interpolator有date、 java、marker、ctx、jndi,、main、jvmrunargs、 sys、 env、 log4j共10種

根據前綴獲取lookup為JndiLookup,后續就是jndi處理,這里不再繼續。

0x03 漏洞思考
那么究竟為什么要給log4j2開發jndi功能,特地去官網看了下,開發者最初考慮到使用log4j通過本地文件加載屬性可能不夠用,某些場景需要從更多的地方加載屬性,因此設計了Property Substitution.

jndi是,添加jndi服務主要是為了日志功能更加豐富,但是開發者沒有考慮到jndi可能帶來的危害。我想如果開發者在設計之初就考慮到了潛在的危害,考慮用白名單校驗jndi的地址,便能夠有效避免今天的局面。
https://logging.apache.org/log4j/log4j-2.3/manual/lookups.html#ContextMapLookup

0x04 參考鏈接
https://logging.apache.org/log4j/log4j-2.3/manual/lookups.html#ContextMapLookup
https://www.cnblogs.com/z-x-p/p/11534662.html
https://blog.csdn.net/henry115/article/details/78483457
https://blog.csdn.net/fygkchina/article/details/107183281
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1786/
暫無評論