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