log4j 漏洞检查:如何快速检测是不是在 mavevn/图像中使用了 log4j? “mvn dependency:tree”没有给出完整的图片

Posted

技术标签:

【中文标题】log4j 漏洞检查:如何快速检测是不是在 mavevn/图像中使用了 log4j? “mvn dependency:tree”没有给出完整的图片【英文标题】:log4j vulnerability check: how to quickly detect if log4j is used, in mavevn/in an image? "mvn dependency:tree" does not give a full picturelog4j 漏洞检查:如何快速检测是否在 mavevn/图像中使用了 log4j? “mvn dependency:tree”没有给出完整的图片 【发布时间】:2022-01-16 20:32:46 【问题描述】:

好的,这是我的问题:

如何输出你的服务/应用程序的完整依赖树,并找出角落的某个地方是否使用了log4j?考虑到mvn dependency:tree 不允许您遍历底部。检查一下:当我在 pom.xml 上执行 mvn dependency:tree 时,它会给出如下内容:
[INFO] |  |  +- io.quarkus:quarkus-core:jar:2.4.1.Final:compile
[INFO] |  |  |  +- jakarta.enterprise:jakarta.enterprise.cdi-api:jar:2.0.2:compile
[INFO] |  |  |  |  \- jakarta.el:jakarta.el-api:jar:3.0.3:compile
[INFO] |  |  |  +- jakarta.inject:jakarta.inject-api:jar:1.0:compile
[INFO] |  |  |  +- io.quarkus:quarkus-ide-launcher:jar:2.4.1.Final:compile
[INFO] |  |  |  +- io.quarkus:quarkus-development-mode-spi:jar:2.4.1.Final:compile
[INFO] |  |  |  +- org.jboss.logging:jboss-logging:jar:3.4.2.Final:compile
[INFO] |  |  |  +- org.jboss.logmanager:jboss-logmanager-embedded:jar:1.0.9:compile
[INFO] |  |  |  +- org.jboss.logging:jboss-logging-annotations:jar:2.2.1.Final:compile
[INFO] |  |  |  +- org.jboss.threads:jboss-threads:jar:3.4.2.Final:compile
[INFO] |  |  |  +- org.jboss.slf4j:slf4j-jboss-logmanager:jar:1.1.0.Final:compile
[INFO] |  |  |  +- org.graalvm.sdk:graal-sdk:jar:21.2.0:compile

现在我明白了,+-\- 用于以某种方式替换 (但直到 5 分钟前我发现它令人困惑),所以它们不是“未扩展”。但是,如果某些依赖项的 pom 使用 log4j,我不做任何事情是否安全?例如,当我在https://search.maven.org/artifact/org.jboss.logging/jboss-logging/3.4.2.Final/jar 中检查org.jboss.logging:jboss-logging:jar:3.4.2.Final:compile 时,我看到使用了org.apache.logging.log4j:log4j-core:2.11,但后来它被排除在外。所以我知道 Quarkus 是安全的。但是,我是否必须检查我在依赖关系树中找到的每个 jar 的 pom 以找出使用的和未使用的?

如果我正在使用某处的基础映像,我如何在步骤 1 中执行此过程?我怎么知道我的基础镜像易受攻击,因为它在依赖树的某个角落使用 log4j2

这里有一些背景:https://nvd.nist.gov/vuln/detail/CVE-2021-44228

编辑: 现在我认为设置 env var 可能会更好,所以它会一劳永逸地解决它。

【问题讨论】:

mvn dependency:list?请注意,您正在寻找的特定包以及为什么并不真正相关。 你只是读错了。 mvn dependency:tree 是完整的树。这些依赖不是“未扩展”——它们只是没有任何依赖。 好的,现在我明白了,只有列表中的最后一项使用\-,而之前的所有项目都使用+-。但是,如果某些依赖项的 pom 使用 log4j,我是否必须更改我的应用程序以设置 env var 以防止其记录? 【参考方案1】:

你可以使用:

mvn dependency:tree -Dincludes=*log4j*

它将在其 groupId 的任何位置找到任何具有“log4j”的依赖项和传递依赖项。

输出示例:

\- org.springframework.boot:spring-boot-starter-web:jar:2.6.0:compile
[INFO]    \- org.springframework.boot:spring-boot-starter:jar:2.6.0:compile
[INFO]       \- org.springframework.boot:spring-boot-starter-logging:jar:2.6.0:compile
[INFO]          \- org.apache.logging.log4j:log4j-to-slf4j:jar:2.14.1:compile
[INFO]             \- org.apache.logging.log4j:log4j-api:jar:2.14.1:compile

每个模式段都是可选的,并且支持完整和部分 * 通配符。空模式段被视为隐式通配符。

例如,org.apache.* 将匹配组 id 以 org.apache. 开头的所有工件,而 :::*-SNAPSHOT 将匹配所有快照工件。

另见maven doc

编辑

然后您很可能希望使用以下命令排除这些依赖项:

<dependency>
    <groupId>your dep groupId</groupId>
    <artifactId>your dep artifactId</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-to-slf4j</artifactId>
            </exclusion>
    </exclusions>
</dependencies>

备注

在撰写本文时,它是任何版本

Maven Repository 上提供了带有漏洞的 Log4j 版本

【讨论】:

是的,实际上grep 没有必要;谢谢【参考方案2】:

我们面临的情况是,我们正在构建一个基于 Red Hat JBoss AMQ 6 的应用程序 foo。使用 jib maven 插件,我们的代码将被构建到一个 uber jar 中并放在 /opt/xxx 下执行,基础镜像会将其他jar放入到/opt/amq/lib下的镜像中。

步骤 1

对于我们的代码,我们这样做:

mvn dependency:tree | grep log4j

我们发现其他团队的一些开发团队带来了可传递的 log4j 1.17 左右。另一个团队会处理它;在此之前,作为一种解决方法,我们将删除

JMSAppender.class SocketServer.class SimpleSocketServer.class

在我们的内部工件中手动从 jar 中下载,这样从那里下载的每个 jar 都将缺少类文件。

如果你无法修复你的内部 Nexus repo/artifactory,你可以在本地 Maven 注册表(~/.m2 下)找到 log4j 的 jar 并删除该类;然后你再次构建你的应用程序;但请记住不要使用-U 从远程注册表重新下载 jar。

第二步

在包含 log4j 的基础镜像中查找其他库更为复杂。我必须首先找出图像中的内容。我先把docker save官方的amq63 for Openshift 镜像成一个tarball;然后,我提取 jar 并使用 grep 搜索 jar。

docker save <image-name> -o amq63.tar

解压tar,进入每一层的文件夹,使用这个脚本:

#!/bin/bash
for f in $(find . -name "*.jar"); do 
    echo $f
    jar -tvf $f | grep -E "(*JMSAppender*.class|*SocketServer.class|*log4j*.class)"
    if [[ $? -eq 0 ]]; then
        # only uncomment these lines after confirmation!
        #echo Removing class file from $f
        #zip -d $f "*JMSAppender.class" "*SocketServer.class" "*SimpleSocketServer.class"
    fi
done

然后你手动把解压出来的文件夹拖到每个图层文件夹的layer.tar中,你再把每个图层和tar打包在一起。 (GNU tar 总是会在 tar 文件中添加根目录.,您需要将其删除。我使用方法here;记住不要以任何形式压缩,只需使用tar cf xxx.tar,不要使用@ 987654339@/j/b,由于jib插件无法识别压缩的tar,它只接受未压缩的tar)

我发现jib maven插件可以从本地tar文件中加载图片,比如tar://path/to/file.tar,所以我们可以修改jib插件中的&lt;from&gt;元素指向修改后的tar并重新构建。所以,如果它在target 中,就把它写成tar://target/foo.tar。如果是绝对路径,则为:tar:///home/me/foo.tar

另外,我们也应该更改配置文件的访问权限,使其成为只读的。

编辑: 并且,如果你想从一个正在运行的 pod 中编辑 jar,它是行不通的,因为你需要重新启动才能重新加载类文件,但不能重新启动 pod;它们是不可变的;配置映射更改将持续存在,但 pod 中的状态不会。

【讨论】:

【参考方案3】:

请记住始终从下面列出的资源中查看最新信息


直接回答问题: 检查代码中的 Log4J 依赖关系:

我认为 WesternGun 的回答很好......但我个人认为最简单的做法可能是构建您的应用程序(如果您还没有),然后递归搜索构建的应用程序的目录结构以查找匹配的 JAR 文件正则表达式log4j-core-2.([0-9]+\.)1,2jar(将检测易受CVE-2021-45046...CVE-2021-44228...CVE-2021-45105 影响的版本)。如果您还想检测旧版本(它们有自己的严重严重性 CVE 并且还需要升级),那么 REGEX 将只是 log4j 并且您必须手动找出哪些特定的 jar 是易受攻击的。 它实际上可能能够进一步完善...但我不确定 特定 jar 文件是否是其他 CVE 的问题:CVE-2019-17571 和 CVE-2021-4104 Reddit thread: log4j_0day_being_exploited cntl+f for .class and .jar recursive hunter 将为您提供一些工具来帮助您进行递归搜索

在运行应用程序时检测 Log4J 的使用(在容器中与否无关紧要):

转到Reddit thread: log4j_0day_being_exploited 和cntl+f 以获取Vendor Advisories。在列表中搜索您正在运行的任何软件/插件。如果您正在运行列表中的某些内容并且有可用的更新,请更新。 然后转到同一网站并 cntl+f 获取Vulnerability Detection。使用那里的工具。如果您检测到漏洞,请修复。 然后转到同一网站并 cntl+f 获取Exploitation Detection。使用那里的工具。这些将检测您是否已经受到攻击。如果您检测到自己受到攻击,请根据需要进行补救并响应该攻击。

更多资源

https://www.reddit.com/r/blueteamsec/comments/rd38z9/log4j_0day_being_exploited/ 这个包含大量有用信息,包括检测器、更多资源链接、非常容易理解的补救步骤等等 https://www.cisa.gov/uscert/apache-log4j-vulnerability-guidance https://github.com/cisagov/log4j-affected-db https://logging.apache.org/log4j/2.x/security.html

补救措施:CVE-2021-45046 ... CVE-2021-44228 ... CVE-2021-45105 虽然大多数需要知道的人可能已经知道足够多的知识来做他们需要做的事情,但我想我还是会把这个放在以防万一......

遵循这些资源中的指导......它可能会改变,但是

截至 2021 年 12 月 18 日

基本上是

尽可能删除 log4j-core JAR 文件 从两台正在运行的机器上立即修复和 在您的源代码/源代码管理文件中,以防止未来的构建/发布/部署覆盖更改 如果这不可能(由于依赖),请升级它们 如果你运行的是 Java8,那么你可以升级到 log4j 2.17.0+ 如果您运行的是早期版本的 Java,则可以升级到 log4j 2.12.3 如果您运行的是旧版本的 Java,则需要升级到最新版本的 Java,然后使用最新版本的 Log4J 同样,这些更改必须同时发生在正在运行的机器和代码中 如果由于某种原因这两种方法都不可能……那么从 log4j-core JAR 中删除 JndiLookup.class 文件是非补救性的。 在 Linux 上使用zip 命令提供了一种止损选项,默认情况下该命令与大多数 Linux 发行版一起打包。 zip -q -d "$LOG4J_JAR_PATH" org/apache/logging/log4j/core/lookup/JndiLookup.class 在撰写本文时,大多数 Windows 上的止损选项在线指南都说要执行以下操作(再次...假设您无法执行上述删除 JAR 或升级选项之一): 安装类似 7-zip 的东西 找到所有 log4j-core JAR 文件,并为每个文件执行以下操作... 重命名 JAR 以将扩展名更改为 .zip 使用 7-zip 解压缩 JAR(现在有一个 .zip 扩展名) 从解压缩的文件夹中找到并删除 JndiLookup.class 文件 路径是\\path\\to\\unzippedFolder\\org\\apache\\logging\\log4j\\core\\lookup\\JndiLookup.class 删除旧的 JAR 文件(现在扩展名为 .zip) 使用 7-zip 重新压缩文件夹 重命名新的 .zip 文件夹以将扩展名更改为 .jar 还有一些使用 Power Shell 的选项 Reddit thread: log4j_0day_being_exploited ctrl+f 表示“PowerShell”

如果您只有 1 或 2 个 JAR 文件要处理并且您不介意安装 7-zip 或者您有 PowerShell 可用,这很好。但是,如果您有很多 JAR 文件,或者您不想安装 7-zip 并且无权访问 Power Shell,我创建了一个开源 VBS 脚本,无需安装即可为您完成任何附加软件。 https://github.com/CrazyKidJack/Windowslog4jClassRemover

阅读自述文件和发行说明https://github.com/CrazyKidJack/Windowslog4jClassRemover/releases/latest

【讨论】:

以上是关于log4j 漏洞检查:如何快速检测是不是在 mavevn/图像中使用了 log4j? “mvn dependency:tree”没有给出完整的图片的主要内容,如果未能解决你的问题,请参考以下文章

在 gradle 传递依赖项中检测 Apache Log4j 漏洞的存在

SPARK 应用如何快速应对 LOG4J 的系列安全漏洞

SPARK 应用如何快读应对 LOG4J 系列安全漏洞

CDH/HDP/CDP等大数据平台中如何快速应对LOG4J的JNDI系列漏洞

静态代码检测工具Wukong对log4J中的漏洞检测分析及漏洞修复

如何检测 OS X 是不是处于暗模式?