Log4j漏洞源碼分析,學(xué)到啦!
點擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”
優(yōu)質(zhì)文章,第一時間送達(dá)
這幾天Log4j的問題消息滿天飛,今天我們就一起來看看從源碼角度看看這個漏洞是如何產(chǎn)生的。
大家都知道這次問題主要是由于Log4j中提供的jndi的功能。
具體涉及到的入口類是log4j-core-xxx.jar中的org.apache.logging.log4j.core.lookup.StrSubstitutor這個類。
原因是Log4j提供了Lookups的能力(關(guān)于Lookups可以點這里去看官方文檔的介紹),簡單來說就是變量替換的能力。
在Log4j將要輸出的日志拼接成字符串之后,它會去判斷字符串中是否包含${和},如果包含了,就會當(dāng)作變量交給org.apache.logging.log4j.core.lookup.StrSubstitutor這個類去處理。
相關(guān)的代碼下面這個
首先是org.apache.logging.log4j.core.pattern.MessagePatternConverter這個類的format方法

圖中標(biāo)注1的地方就是現(xiàn)在漏洞修復(fù)的地方,讓noLookups這個變量為true,就不會進(jìn)去里面的邏輯,也就沒有這個問題了。
圖中標(biāo)注2的地方就是判斷字符串中是否包含
${,如果包含,就將從這個字符開始一直到字符串結(jié)束,交給圖中標(biāo)注3的地方去進(jìn)行替換。圖中標(biāo)注3的地方就是具體執(zhí)行替換的地方,其中
config.getStrSubstitutor()就是我們上面提到的org.apache.logging.log4j.core.lookup.StrSubstitutor。
在StrSubstitutor中,首先將${和}之間的內(nèi)容提取出來,交給resolveVariable這個方法來處理。

我們看下resolver的內(nèi)容,它是org.apache.logging.log4j.core.lookup.Interpolator類的對象。

它的lookups定義了10中處理類型,還有一個默認(rèn)的defaultLoopup,一種11中。如果能匹配到10中處理類型,就交給它們?nèi)ヌ幚?,其他的都會交給defaultLookup去處理。
匹配規(guī)則也很簡單,下面簡單舉個例子。
1.如果我們的日志內(nèi)容中有${jndi:rmi://127.0.0.1:1099/hello}這些內(nèi)容,去掉
${和},傳遞給resolver的就是jndi:rmi://127.0.0.1:1099/hello。2.
resolver會將第一個:之前的內(nèi)容和lookups做匹配,我們這里獲取到的是jndi,就會將剩余部分jndi:rmi://127.0.0.1:1099/hello交給jdni的處理器JndiLookup去處理。

圖中標(biāo)注1的地方入?yún)⒕褪?strong>jndi:rmi://127.0.0.1:1099/hello
圖中標(biāo)注2的地方就是jndi
圖中標(biāo)注3的地方就是rmi://127.0.0.1:1099/hello
圖中標(biāo)注4的地方就是處理器
JndiLookup類的對象圖中標(biāo)注5的地方就是jndi來處理的入口
關(guān)于jndi相關(guān)的,以及漏洞如何復(fù)現(xiàn)網(wǎng)上有一大把的教程,這里就不展開了。
關(guān)于漏洞的修復(fù)。

主要是通過設(shè)置noLookups變量的值,不讓它進(jìn)去這個if里面的邏輯。
這個變量的值是來自下面這個屬性

所以在在代碼中加入System.setProperty("log4j2.formatMsgNoLookups","true");這句也就可以了。當(dāng)然網(wǎng)上有更多其他的修復(fù)方法,這里就不討論了。
? 作者?|??wang03
來源 |??cnblogs.com/wbo112/p/15690699.html
加鋒哥微信:?java1239?? 圍觀鋒哥朋友圈,每天推送Java干貨!

