虽然已经有了一些优秀的工具来帮助组织扫描其环境中易受严重 Log4J / CVE-2021-44228 漏洞影响的应用,但我认为:
因此,Log4Shell Sentinel 应运而生。Log4Shell Sentinel 是一款基于文件的扫描器,具有一些独特的功能。它并非要取代所有其他可用工具,而是可以与之互补。
Log4Shell Sentinel 是一款基于文件的扫描器。它通过扫描目标系统中以下文件格式的工件来搜索基于 Java 的应用:
| 文件类型 | 说明 |
|---|---|
| 简单 jar | 这种情况是指 log4j-core 文件未嵌入其中。 |
| Fat / Uber jar | uber jar(超级 jar) 是一种将你的类 / 包以及应用的所有依赖项(库、资源和元数据文件)都包含在单个 jar 文件中的 jar。这是最常用的部署方式。 |
| WAR | war(Web 应用归档)文件是一种除包含你的库和其他资源外,还包含 JSP、HTML 和 JavaScript 代码的文件。这种格式不太常用。 |
| EAR | ear(企业应用归档)是另一种在 Jakarta EE 部署中更常用的格式。 |
并搜索存在漏洞的 log4j-core jar 实例。然后它会:
计算工件的 MD5 哈希。这使分析人员能够识别运行在不同机器 / 容器上的同一应用,并将其视为单个发现
对于确定为属于容器(例如:/var/lib/docker/overlay2/192768f471818601094bf4edd96d14bfc0e2b178a04a2efd00b2231ad4e46b33/merged/app/spring-boot-application.jar)的文件,它会承担将文件映射到对应镜像的重任。例如,它会将上述路径转换为以下镜像:ghcr.io/christophetd/log4shell-vulnerable-app:latest。由于各种容器运行时以不同方式存储此映射,这可以为分析人员节省大量时间。这也使分析人员能够将运行单个应用的多个容器视为单个发现。
它会移除无用的匹配项,例如当前未运行的容器(包括缓存镜像)对应的匹配项。这使分析人员能够专注于重要内容,并再次节省大量无谓的工作。
它允许分析人员根据以下条件忽略匹配项:
这使分析人员能够移除已知不存在漏洞的应用,或对应于不会构成威胁的基于 CLI 的应用。例如,如果检测到 Logstash 实例,分析人员可以选择忽略它(如果他们不运行该工具,或只是偶尔从命令行运行它)。
它针对与 Ansible 等配置管理工具配合使用进行了优化,让你能够在几分钟内快速扫描你的环境。
有关 Log4Shell Sentinel 添加的元数据增强的详细信息,请参阅我的博客文章。
最简单的方式是直接下载预编译的二进制文件。
同样,这也很直接。不过,你可能希望构建一个静态编译版本,以规避环境中任何与 GLIBC 相关的差异。该工具使用以下默认使用 CGO 的模块:
os/usernet要构建一个使用这些库的 Go 原生版本的静态编译版本,只需克隆仓库,然后运行:
$ CGO_ENABLED=0 go build -ldflags="-s -w"
$ ldd log4shell_sentinel
not a dynamic executable
$ ./log4shell_sentinel -h
NAME:
Log4Shell Sentinel - by Osama Elnaggar
USAGE:
log4shell_sentinel [global options] command [command options] [arguments...]
VERSION:
v1.0.0
COMMANDS:
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--path value, -p value Path to search (default: ".")
--no-banner, --nb Suppress banner (default: false)
--no-messages, --nm Suppress messages except for CSV output (default: false)
--no-header, --nh Suppress header in CSV output (default: false)
--imd5 value, --im value Ignore MD5 hashes. Refer to the GitHub page for expected format
--ipath value, --ip value Ignore file path matches. Refer to the GitHub page for expected format
--icimage value, --ic value Ignore container image matches. Refer to the GitHub page for expected format
--print-headers, --ph Print CSV Headers only (default: false)
--help, -h show help (default: false)
--version, -v print the version (default: false)
开箱即用时,扫描器只会扫描当前目录。例如:
$ ./log4shell_sentinel
░█░░░█▀█░█▀▀░█░█░█▀▀░█░█░█▀▀░█░░░█░░░░░█▀▀░█▀▀░█▀█░▀█▀░▀█▀░█▀█░█▀▀░█░░
░█░░░█░█░█░█░░▀█░▀▀█░█▀█░█▀▀░█░░░█░░░░░▀▀█░█▀▀░█░█░░█░░░█░░█░█░█▀▀░█░░
░▀▀▀░▀▀▀░▀▀▀░░░▀░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░░░▀▀▀░▀▀▀░▀░▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀
- A CVE-2021-44228/CVE-2021-45046/CVE-2021-45105 Scanner
- v1.0.0
- by Osama Elnaggar
[*] WARNING: Running as non-root user.
Non-readable files / dirs will be skipped
Container mapping will fail
[*] Starting shallow scan ............ [DONE]
[*] Starting deep scan ............... [DONE]
[*] Calculating MD5 hashes ........... [DONE]
[*] Performing container image lookups [DONE]
[*] Processing ignore list(s) ........ [DONE]
[*] Generating output ................ [DONE]
IP,Hostname,AppName,Team,Ignore (Y/N),Comments,MD5Hash,Timestamp,Container,ContainerImage,FullPath,Version
192.168.121.121,server3,,,,,4e615cd580758b70c49ade1f79103328,2021-12-21T07:38:09Z,true,ghcr.io/christophetd/log4shell-vulnerable-app:latest,/run/containerd/io.containerd.runtime.v2.task/k8s.io/dc2c9c214809f506283c917244cd126a9b056ac7274322d12b59c9196d95dd9b/rootfs/app/spring-boot-application.jar,log4j-core-2.14.1.jar
如果你以非 root 用户身份运行它,你会立即收到 警告,因为它需要 root 权限:
即使没有 root 权限,它也仍然可以工作,但可能无法提供最佳结果。
一个示例发现结果如下所示:
IP,Hostname,AppName,Team,Ignore (Y/N),Comments,MD5Hash,Timestamp,Container,ContainerImage,FullPath,Version
192.168.121.121,server3,,,,,4e615cd580758b70c49ade1f79103328,2021-12-21T07:38:09Z,true,ghcr.io/christophetd/log4shell-vulnerable-app:latest,/run/containerd/io.containerd.runtime.v2.task/k8s.io/dc2c9c214809f506283c917244cd126a9b056ac7274322d12b59c9196d95dd9b/rootfs/app/spring-boot-application.jar,log4j-core-2.14.1.jar
某些字段有意留空,供分析人员在 Excel 等工具中填写。每个字段的简要说明如下所示:
该工具提供以下选项:
Log4Shell Sentinel 的一个在其他工具中未见的独特功能,是能够将文件系统扫描中发现的 jar 转换为对应的容器镜像。例如:
/var/lib/docker/overlay2/192768f471818601094bf4edd96d14bfc0e2b178a04a2efd00b2231ad4e46b33/merged/app/spring-boot-application.jar
上述路径可转换为 ghcr.io/christophetd/log4shell-vulnerable-app:latest。由于各种容器运行时以不同方式存储此映射,这可以为分析人员节省大量时间。这也使分析人员能够将运行单个应用的多个容器视为单个发现。该解决方案目前支持以下查找:
最初识别出的应用数量可能会让你应接不暇,或者你可能希望先关注已识别应用的某个子集,例如首先面向外部用户的应用。或者你可能希望关注某个合规范围。为支持这一点,该应用支持指定一个列表。Log4Shell 目前支持 3 个忽略列表:
它期望输入的并不是简单列表,而是 CSV 文件。这鼓励分析人员记录他们忽略某个发现结果的原因。当分析人员处理发现结果,并通过手动或自动源代码分析或 DAST 工具等识别出不存在漏洞的应用时。
该列表是一个 CSV 文件,格式如下:
MD5Sum,AppName,Reason
AppName 和 Reason 列可以为空,但它们的存在是为了让你跟踪包含或排除特定应用的原因。
注意:由于此功能使用为应用计算的 MD5 哈希,因此它仅适用于 fat / uber jar、EAR 或 WAR 应用。
例如,如果我们有以下发现结果:
IP,Hostname,AppName,Team,Ignore (Y/N),Comments,MD5Hash,Timestamp,Container,ContainerImage,FullPath,Version
192.168.121.121,server3,,,,,4e615cd580758b70c49ade1f79103328,2021-12-21T07:38:09Z,true,ghcr.io/christophetd/log4shell-vulnerable-app:latest,/run/containerd/io.containerd.runtime.v2.task/k8s.io/dc2c9c214809f506283c917244cd126a9b056ac7274322d12b59c9196d95dd9b/rootfs/app/spring-boot-application.jar,log4j-core-2.14.1.jar
并确定该应用_不存在漏洞_,我们可以简单地将以下内容保存到 hashes.csv 中:
4e615cd580758b70c49ade1f79103328,Demo App,Not vulnerable
然后重新运行它:
# ./log4shell_sentinel --im hashes.csv --path /
上述发现结果将被抑制。
该列表是一个 CSV 文件,格式如下:
Container Image,AppName,Reason
在上述示例的基础上,我们可以通过创建一个如下所示的 images.csv 文件,让它忽略任何容器镜像为 ghcr.io/christophetd/log4shell-vulnerable-app:latest 的发现结果:
ghcr.io/christophetd/log4shell-vulnerable-app:latest,,
然后通过以下命令运行它:
# ./log4shell_sentinel --ic images.csv -p /
同样,我们之前的发现结果将被抑制。
同样,这是一个 CSV 文件,格式如下:
Path,AppName,Reason
使用上面的示例,如果我们创建以下 paths.csv 文件:
/run/containerd/io.containerd.runtime.v2.task/k8s.io/dc2c9c214809f506283c917244cd126a9b056ac7274322d12b59c9196d95dd9b/rootfs/app/spring-boot-application.jar,Demo App,Not vulnerable
之前的发现结果将被抑制。
警告:在可能的情况下,最好使用 MD5 哈希或容器镜像名称进行抑制,因为路径可能不唯一。
虽然在单台服务器上运行 Log4Shell Sentinel 完全没有问题,但当它与你最喜爱的配置管理工具(Ansible、Chef、Puppet、Salt、AWS SSM 等)甚至诸如 parellel-ssh 之类的简单并行 SSH 工具结合使用时,才能真正发挥其威力。
这为你带来许多好处,包括:
有关实际运行的完整示例,请参阅我的博客文章
请参阅大规模扫描你的环境部分。
root 用户身份运行(它需要访问你的应用可能安装的位置)或未指定正确的 path 有关。建议你以 root 用户身份运行,并设置 --path /截至 v1.0.0,该工具目前支持以下映射:
如果你使用的是其他任何运行时,则映射将无法工作。如果你使用的是上述之一,则可能是因为你未以 root 用户身份运行该工具,或者所使用的套接字 / 文件位于非默认位置。
开发者:Osama Elnaggar
| 字段 | 示例 | 说明 |
|---|
| IP | 192.168.121.121 | 如果实例有多个 IP,则添加主 IP |
| Hostname | server3 | 主机名 |
| AppName | 此项在扫描完成后由用户自行填写 | |
| Team | 此项在扫描完成后由用户自行填写 | |
| Ignore (Y/N) | 此项在扫描完成后由用户自行填写 | |
| Comment | 此项在扫描完成后由用户自行填写 | |
| MD5Hash | 4e615cd580758b70c49ade1f79103328 | 我们应用的唯一指纹 |
| Timestamp | 2021-12-21T07:38:09Z | 执行扫描时的时间戳。如果你想聚合同一主机的多次扫描结果,这会很有用 |
| Container | true | True = 这是一个容器 |
| ContainerImage | ghcr.io/christophetd/log4shell-vulnerable-app:latest | 如果检测到容器,这是对应的镜像 |
| FullPath | /run/containerd/io.containerd. runtime.v2.task/k8s.io/.../spring-boot-application.jar | 发现结果的完整路径。在此示例中,易受攻击的 JAR 文件是 fat / uber jar 的一部分 |
| Version | log4j-core-2.14.1.jar | 检测到的 log4j-core 版本 |
| 选项 | 说明 |
|---|
--path value, -p value | 指定要搜索的路径。默认情况下,它搜索当前目录。重要:建议你将其设置为 / 以覆盖整个文件系统 |
--no-banner, --nb | 抑制横幅(banner)的显示 |
--no-messages, --nm | 抑制诸如进度相关的消息等提示信息 |
--no-header, --nh | 抑制 CSV 输出的表头。在跨多台服务器运行时建议使用 |
--imd5 value, --im value | 忽略 MD5 哈希。更多信息请参阅 忽略列表 部分 |
--ipath value, --ip value | 忽略文件路径匹配项。 更多信息请参阅 忽略列表 部分 |
--icimage value, --ic value | 忽略容器镜像匹配项。更多信息请参阅 忽略列表 部分 |
--print-headers, --ph | 仅打印 CSV 表头。当你在多台服务器上运行 Log4Shell Sentinel 并汇总结果时,通常会禁用表头输出。此命令仅输出表头,以便你可以将其添加到 Excel 工作表中 |