Log4j漏洞深度回顧系列之一:攻擊背景?
開源日志記錄工具Apache Log4j曾被爆出一個嚴重的遠程代碼執(zhí)行漏洞,攻擊者可以借此構(gòu)造惡意請求,觸發(fā)遠程惡意代碼的執(zhí)行。消息爆出后,該漏洞引起了極大的關(guān)注。小半年過去了,相關(guān)熱度逐漸消退,是時候?qū)φ麄€過程進行一個徹底的總結(jié)回顧,并從中吸取教訓,避免以后再遭遇類似的問題。
加入Client-Side Protection & Compliance,防范每一次用戶數(shù)據(jù)外泄!
符合 PCI DSS v4.0 標準,助您嚴防網(wǎng)站惡意代碼和漏洞!
進一步了解Akamai的網(wǎng)絡(luò)安全服務(wù)方案!
這一系列文章總共分為四篇,Akamai將結(jié)合自身技術(shù)團隊的了解,Akamai與全球客戶合作過程中應對該漏洞和其他安全隱患所積累的經(jīng)驗,以及Akamai對整個互聯(lián)網(wǎng)流量的洞察,向大家介紹Log4j漏洞的起因、傳播范圍、利用方式、演變路徑,以及最重要的:我們所有人都需要從中吸取的教訓。
這就開始吧,本篇主要介紹Log4j漏洞的一些背景信息。
一、時間線
2021年11月24日,Apache基金會接到通知,稱已被廣泛使用的,基于Java的日志庫工具Log4j存在重大漏洞,可能導致隱私信息泄漏和遠程代碼執(zhí)行(RCE)。而該漏洞自2013年就一直存在了。
第二天,Apache基金會保留了CVE-2021-44228并開始研究解決方案。接下來的12天里,為了解決此問題,他們對源代碼進行了多處修改,并于2021年12月9日公開披露了這個漏洞。
公布后,圍繞該漏洞開始出現(xiàn)如洪水般的攻擊嘗試,并且在那之后,攻擊規(guī)模和范圍一直以驚人的速度增長。
二、Log4j到底是什么?
要真正理解該漏洞,首先需要知道Log4j到底是什么。Log4j是Java社區(qū)中一個被開發(fā)者廣泛使用的庫,提供了一個簡單但強大的框架,可用于記錄錯誤信息、診斷信息等。
Log4j提供了很多讓人印象深刻的功能,其中之一是將日志記錄至多個目標位置,包括但不限于控制臺、文件、遠程TCP服務(wù)器、Syslog、NT Event Log以及電子郵件。此外,它還支持對日志消息、日志事件、自定義布局等內(nèi)容進行分層過濾。
簡而言之,Log4j提供了完整豐富的功能,使其受到開發(fā)者的廣泛歡迎,從而導致從Web應用程序到嵌入式設(shè)備,各種地方都能見到Log4j的身影。
三、查找和嵌套
Log4j支持多種強大功能,其中最知名的功能之一應該是查找(Lookup)。該功能使得開發(fā)者可以將變量或表達式嵌入到Log4j在進行輸出之前自動評估的文本中。例如,開發(fā)者可以編寫代碼將下列文本記入日志:
“${date:MM-dd-yyyy} All Systems Good”
Log4j會將其中的模式${date:MM-dd-yyyy}識別為一種日志查找,并盡職地將該表達式替換為“今天”的日期。舉例來說,如果今天是2021年12月20日,那么在將上述日志輸出到目標位置前,Log4j會將其內(nèi)容改為:
“12-20-2021 All Systems Good”
對開發(fā)者來說這很方便。如果不使用這種功能,開發(fā)者必須手工編寫代碼查詢?nèi)掌冢瑢⒏袷秸{(diào)整為字符串,將其附加到日志行,然后輸出。盡管這樣的代碼寫起來并不麻煩也不費事,但畢竟與軟件的核心業(yè)務(wù)邏輯毫無關(guān)系,并且最終也會在一個個項目中不斷延續(xù)下去。
通過使用Log4j庫中現(xiàn)成的功能,開發(fā)者可以專注于項目中更重要的開發(fā)工作,讓Log4j處理與日志有關(guān)的各種任務(wù)。
Log4j支持很多這種類型的查找表達式。讓我們再來看看另外兩個與本文內(nèi)容密切相關(guān)的:env和lower。env可以將主機系統(tǒng)上的環(huán)境變量包含到日志行中。例如,開發(fā)者可以將下列文本記入日志:
“The current user is ${env:USER}”
假設(shè)軟件正在以管理員用戶的身份運行,上述日志會輸出如下的內(nèi)容:
“The current user is Administrator”
與將新數(shù)據(jù)注入文本的env和date不同,lower可用于操作已經(jīng)存在的內(nèi)容。Log4j會直接將表達式中出現(xiàn)的英文字母轉(zhuǎn)換為小寫形式。例如:
“The lower case text is ${lower:ABCDEFG}”
會輸出為:
“The lower case text is abcdefg”
這個例子本身似乎感覺沒什么意義,為何不自己將字母轉(zhuǎn)換為小寫呢?別忘了,Log4j還允許將查找表達式嵌套在一起,此時就厲害了。
我們可以將前兩個表達式嵌套為這種形式:
“The lower case current user is ${lower:${env:USER}}”
這會導致Log4j首先將${env:USER}表達式評估為Administrator,隨后將其送入lower,產(chǎn)生小寫的administrator,最終會輸出如下的內(nèi)容:
“The lower case current user is administrator”
四、JNDI
雖然date、env和lower都很有趣并且實用,但這個漏洞之所以能夠存在,還離不開JNDI查找。JNDI(Java Naming and Directory Interface,Java命名和目錄接口),是一種內(nèi)置于Java開發(fā)和運行時環(huán)境中的機制,可通過一個通用接口以簡單的方式查詢各種目錄服務(wù)中的信息。
實際上,可支持的目錄服務(wù)分為多種類型。例如,JNDI支持查詢DNS服務(wù)器以發(fā)現(xiàn)主機的IP地址,并能查詢AD和LDAP中的目錄實體。它甚至支持查詢正在運行中的Java環(huán)境本身以獲取Environmental Entries,例如當前正在運行的軟件的專用配置選項。
Log4j中的JNDI查找表達式可供開發(fā)者通過日志文本中嵌入的表達式直接訪問這個極為強大的子系統(tǒng)。舉例來說,如果開發(fā)者試圖將下列字符串記入日志:
“The current mail host is ${jndi:java:comp/env/mailhost}”
Log4j會將${jndi:java:comp/env/mailhost}表達式識別為JNDI查找,并將java:comp/env/mailhost這個偽URL傳遞給JNDI子系統(tǒng)。JNDI會將這種特定的URL類型識別為查詢,進而在當前運行的組件查找一個名為mailhost的配置選項。
假設(shè)該選項被配置為http://mymailserver.example.com,JNDI會將該信息回傳給Log4j,隨后Log4j會將查找表達式替換為http://mymailserver.example.com,并產(chǎn)生如下的輸出結(jié)果:
“The current mail host is mymailserver.example.com”
五、理解該漏洞的存在
簡而言之,Apache Log4j的這個漏洞為攻擊者提供了一種重大的機會,因為該庫廣受歡迎,尤其是其查找、嵌套和JNDI功能更是如此。雖然這些功能為開發(fā)者提供了很大的便利,但也催生了可能借此通過請求泄漏數(shù)據(jù)或?qū)е逻h程代碼執(zhí)行的機會。了解這些背景信息后,我們可以開始更好地理解這個漏洞,以及攻擊者的利用方式了。