log4j2漏洞分析与思考

本文首发于seebug:https://paper.seebug.org/1786/

近期最火的漏洞莫过于log4j2 RCE漏洞,都说是史诗级的漏洞,那必然要分析下。

0x01 定位漏洞

既然是利用了jndi,那么断点就打在javax.naming.InitialContext构造方法肯定是没错的。

截屏2021-12-13_下午6.44.13

通过回溯,最初调用lookup相关的地方在org.apache.logging.log4j.core.lookup.StrSubstitutor.replace()

截屏2021-12-13_下午7.37.40

进一步回溯分析调用lookup的原因,在MessagePatternConverter.format()中,遍历每个字符,当匹配到${就调用StrSubstitutor.replace()处理jndi相关信息。

截屏2021-12-13_下午7.38.46

0x02 log4j日志记录及漏洞分析

在详细分析前先简单了解下log4j三大组件:

  1. Logger:日志记录器,负责收集处理日志记录
  2. Appender:日志存放的地方,负责日志的输出
  3. Layout:日志格式化,负责日志输出的形式

1、在log4j2中通过LoggerConfig.processLogEvent()处理日志事件,主要部分在调用callAppenders()即调用Appender:

截屏2021-12-13_下午8.50.00

2、Appender功能主要是负责将日志事件传递到其目标,常用的Appender有ConsoleAppender(输出到控制台)、FileAppender(输出到本地文件)等,通过AppenderControl获取具体的Appender,本次调试的是ConsoleAppender。

截屏2021-12-13_下午8.56.31

调用ConsoleAppender.tryAppend()尝试输出日志

截屏2021-12-13_下午9.47.31

3、首先获取Layout日志格式,通过Layout.encode()进行日志的格式化

截屏2021-12-13_下午10.15.05

Layout会获取formatters来完成具体的格式化的事情

截屏2021-12-13_下午10.27.48

4、处理传入的message通过MessagePatternConverter.format(),也是本次漏洞的关键之处,我们具体来看下。首先创建一个workingBuilder,当config存在并且noLookups为false,匹配到${'则调用workingBuilder.append()获取StrSubstitutor内容来替换原来的信息(这里说明下,jndi执行命令后如果返回了结果就会将其append输出)

截屏2021-12-13_下午10.41.59

noLookups来自设置来自配置文件,默认值为false,相当于默认支持jndi。

截屏2021-12-13_下午11.06.27

截屏2021-12-13_下午11.06.01

5、StrSubstitutor.resolveVariable()解析变量,调用Interpolator.lookup(),Interpolator有date、 java、marker、ctx、jndi,、main、jvmrunargs、 sys、 env、 log4j共10种

截屏2021-12-13_下午11.41.38

根据前缀获取lookup为JndiLookup,后续就是jndi处理,这里不再继续。

截屏2021-12-13_下午11.19.31

0x03 漏洞思考

那么究竟为什么要给log4j2开发jndi功能,特地去官网看了下,开发者最初考虑到使用log4j通过本地文件加载属性可能不够用,某些场景需要从更多的地方加载属性,因此设计了Property Substitution.

截屏2021-12-14_上午9.25.22

jndi是是一组Java命名和目录接口,主要用于将JNDI API映射为特定的命名服务和目录系统。添加jndi服务主要是为了日志功能更加丰富,但是开发者没有考虑到jndi可能带来的危害。我想如果开发者在设计之初就考虑到了潜在的危害,考虑用白名单校验jndi的地址,便能够有效避免今天的局面。

https://logging.apache.org/log4j/log4j-2.3/manual/lookups.html#ContextMapLookup

截屏2021-12-13_下午7.51.16

0x04 参考链接

1
2
3
4
https://logging.apache.org/log4j/log4j-2.3/manual/lookups.html#ContextMapLookup
https://www.cnblogs.com/z-x-p/p/11534662.html
https://blog.csdn.net/henry115/article/details/78483457
https://blog.csdn.net/fygkchina/article/details/107183281