如何找出我正在使用的 Log4J 版本?

mar*_*rea 7 java log4j

标题说明了一切。众所周知,类路径中至少有 4 或 5 个 log4j jar。我如何知道我使用的是哪个版本?

Tho*_*ann 54

在得知我的服务器可能容易受到新的 Log4j 漏洞(CVE-2021-44228)攻击后,我来到了这里。因此,我需要知道我是否安装了过时/易受攻击的 Log4j 版本 2。

这里以前的答案无助于检测旧版本,因为它们是为了让已经运行的 Java 代码找出该代码使用的 Log4j 版本,而我需要知道是否有任何Java 应用程序可能使用易受攻击的版本。

这是我所做的:

sudo find / -name 'log4j*'
Run Code Online (Sandbox Code Playgroud)

这列出了我的 (Linux) 服务器上的所有 Log4j 相关文件。这向我展示了几个 1.x 版本(不易受到此特定 CVE 的影响)和一个 2.15.0 文件(已包含 CVE 的修复程序)。

如果您运行此命令并找到包含 2.x 的文件或文件夹名称,其中 x < 15,那么您可能容易受到攻击,并且需要弄清楚如何尽快更新您的文件。

警告

有人警告我,这对于我的目的来说还不够,因为 Log4j 文件可能隐藏在 .jar 文件中,而该find命令无法发现该文件。

更新

这是一个公共项目,它尝试扫描所有 .jar 文件,以便也在档案中找到 Log4j 代码:Log4-Detector

  • 要列出系统上包含易受攻击的类文件的所有 JAR 文件(即使是在 fat JAR 中),您可以使用: `for f in $(find / -name '*.jar' 2&gt;/dev/null); 执行 echo "检查 $f..."; 解压缩 -l "$f" | grep -F org/apache/logging/log4j/core/lookup/JndiLookup.class; 完成` (21认同)
  • 请注意,Log4j v1 也可能受到影响:https://nvd.nist.gov/vuln/detail/CVE-2019-17571 (6认同)
  • Log4j 1.x 还有其他漏洞。/sf/answers/4928366061/。 (2认同)

Ant*_*uge 13

我不希望这是首选方法,但这是我确定我的软件使用的 Log4j 版本的方法:

\n

使用 .zip 归档实用程序打开或提取 Log4j .jar 的内容(Windows\xc2\xa0Explorer支持此操作)。导航到“ META-INF ”子目录并在文本编辑器中打开文件“ MANIFEST.MF ”。找到以“ Implementation-Version ”开头的行,这是 Log4j 版本。

\n

显然,这不是一个程序化的解决方案。但如果您只是想知道您正在使用什么版本并且您有 .jar 存档,那么它就可以了。

\n

我注意到Package.getSpecificationVersion(),正如Loic M.\ 的回答Package.getImplementationVersion()中提到的,and 适用于其他 .jar 库,但不适用于我的 Log4j。我使用的版本可能不支持它。

\n

我下载了2.13.1版本来尝试上述方法,发现它们确实可以使用。所以我的版本(1.2.16)不支持它们并返回了null

\n


小智 7

这取决于ClassLoader,但是看一下示例,您可以getImplementationVersionLayoutlog4j的类上调用该方法:

org.apache.log4j.Layout.class.getPackage().getImplementationVersion()
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案,也许是正确的,但我得到了该类的所有空值。您提供的文档说它适用于 1.2 和 1.3。这可能意味着我正在使用版本 2。 (2认同)
  • 我下载了 Log4j 的更新版本([2.13.1](https://downloads.apache.org/logging/log4j/2.13.1/))并发现 `getImplementationVersion` 和 `getSpecificationVersion` 方法确实可以使用它。对于旧版本,请参阅[下面我的答案](/sf/answers/4290833851/)。 (2认同)

Shi*_*and 6

要了解Java 运行时的 Log4j 版本:

LOGGER.info("Log4j version: " + org.apache.logging.log4j.util.PropertiesUtil.class.getPackage().getImplementationVersion());
Run Code Online (Sandbox Code Playgroud)

或者

System.out.println("Log4j version: " + org.apache.logging.log4j.util.PropertiesUtil.class.getPackage().getImplementationVersion());
Run Code Online (Sandbox Code Playgroud)


小智 5

删除所有不需要的版本的 JAR 文件(一个就足够了),并查看文件名来找出剩下的版本 \xe2\x80\x99。

\n

例如:

\n
log4j-1.2.17.jar\n
Run Code Online (Sandbox Code Playgroud)\n


Bün*_*ürk 5

我编写了一个小型 Bash 脚本来检查该服务器上每个 Log4j JAR 文件的版本。它从清单文件中读取版本信息,因为信任文件名有一点风险。

locs=( $(sudo find / -name 'log4j*'|grep jar) )
fcount=${#locs[@]}

echo "Found $fcount jar files"
echo " "

for (( j=0; j<${fcount}; j++ ));
do
    unzip ${locs[$j]} META-INF/MANIFEST.MF
    mv META-INF/MANIFEST.MF META-INF/MANIFEST$j.MF
done

echo " "
for (( j=0; j<${fcount}; j++ ));
do
    echo ${locs[$j]}
    tail -2 META-INF/MANIFEST$j.MF
done
Run Code Online (Sandbox Code Playgroud)

  • 可能运行 http://shellcheck.net/ 并修复它报告的各种问题。只要在“find”输出到达时对其进行循环就可以避免数组遇到的多个问题。简而言之, `sudo find / -name 'log4j*.jar' -exec sh -c '...您的循环代码在这里...' _ {} +` (4认同)

小智 5

  1. 由于不同 Log4j 依赖项中的相同类有多个版本,因此它们中的任何一个都可以在运行时加载(假设相同的类名存在于不同的 JAR 文件中)。

  2. 我使用EclipseIntelliJ IDEA提供的插件来查看Maven依赖关系树。然后我排除旧版本,只拥有所需的 Log4j 版本。