示例:检测 Log4Shell 安全漏洞

安全漏洞 CVE-2021-44228CVE-2021-45046 Apache Log4j 库版本 2.0 至 2.15。Apache Log4j 实用程序是用于记录请求的常用组件。此漏洞(也称为 Log4Shell)可能会允破解许运行 Apache Log4j 2.0 版到 2.15 版的系统,并允许攻击者执行任意代码。

此漏洞不会影响 Cloud Logging 或其提供的代理从第三方应用收集日志,但如果您使用 Log4j 2,则您的服务可能会受到影响。

您可以使用 Cloud Logging 来识别可能的攻击。本文档介绍了如何执行以下操作:

  • 使用日志浏览器查询日志,了解利用 Log4j 2 漏洞的现有尝试。
  • 确认您已启用的缓解技术(如 Google Cloud Armor 安全政策)且 Identity-Aware Proxy 访问权限控制已正确配置,并通过阻止这些利用 Log4j 2 漏洞尝试按预期运行。
  • 创建提醒政策,以便在可能的漏洞消息写入日志时收到通知。

查看 Google Cloud 的 Log4j 2 安全建议,了解我们当前的 Google Cloud 产品和服务评估。您可以通过阅读美国国家标准与技术研究院 (NIST) 的 CVE-2021-44228 漏洞报告来评估您的风险。

Cloud Logging 检测

Cloud Logging 查询结果仅包括已存储在日志存储桶中并且还位于用户指定的保留期限内的日志。虽然大多数 Google Cloud 服务在默认情况下都会启用日志,但您的查询中不包含已停用或排除的日志。我们建议您在整个环境中开启日志,以便更清楚地了解环境。

如果您使用的是 HTTP(S) 负载均衡器,则必须启用日志记录,才能在 Cloud Logging 中使用请求日志。同样,如果您有诸如 Apache 或 NGINX 之类的网络服务器在虚拟机上运行,但尚未安装 Ops AgentLogging 代理,则这些日志无法在 Cloud Logging 中访问。

您可以使用日志浏览器来帮助检测利用 Log4j 2 漏洞的服务出现的潜在攻击。如果您使用 Cloud Logging 将请求记录到服务中,则可以检查包含用户生成的内容的 httpRequest 字段是否存在潜在漏洞。

httpRequest 字段中的值可能包含 ${jndi:ldap:// 等字符串令牌,但漏洞被利用的方式有许多变体。例如,您可以通过多种方式使用转义或 Unicode 来避免检测。以下字符串展示了一些常见示例,这些示例展示了针对您系统的攻击尝试,但这并非详尽的变体集:

${jndi:
$%7Bjndi:
%24%7Bjndi:
${jNdI:ldAp
${jndi:${lower:l}${lower:d}${lower:a}${lower:p}:
${${lower:j}${lower:n}${lower:d}i:
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}:
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}

您可以在日志浏览器中创建查询,以扫描一些可能的漏洞字符串。例如,以下查询尝试匹配 HTTP(S) 负载均衡器请求日志中的 httpRequest 字段中字符串 ${jndi: 的各种混淆变体。请注意,查询中使用的正则表达式不会检测所有变体,并且可能导致假正例:

resource.type="http_load_balancer"
httpRequest.requestUrl=~"(?i)(\$|\%24)(\{|\%7b).*j.*n.*d.*i.*(\:|\%3a)" OR
httpRequest.userAgent=~"(?i)(\$|\%24)(\{|\%7b).*j.*n.*d.*i.*(\:|\%3a)" OR
httpRequest.referer=~"(?i)(\$|\%24)(\{|\%7b).*j.*n.*d.*i.*(\:|\%3a)"

只需更改 resource.type 值,即可使用上述查询来扫描其他服务中的请求日志,。

扫描大量日志时,上一个查询可能需要很长时间才能完成。为加快查询运行速度,您可以使用索引字段(如 resource.typeresource.labelslogName)将查询范围缩小到一组特定服务或日志流。

检测匹配的日志条目并不表示成功的入侵。如果检测到匹配项,我们建议您遵循组织的突发事件响应流程。如果有匹配项,可能表示有人正在利用您的项目或工作负载中的漏洞。或者,如果您的应用在 HTTP 请求字段中使用 ${jndi: 等格式,则可能是假正例。请仔细检查您的日志,确保此格式不属于正常的应用行为。 优化查询,使其适合您的环境。

搜索违规 IP 地址

如果找到匹配的结果,并且想要在发送此类请求的远程 IP 地址上聚合,请将 remoteIp 字段添加到日志浏览器中的日志字段窗格。如需添加 remoteIp 字段,请点击匹配日志条目中的字段值,然后选择将字段添加到日志字段窗格,如以下屏幕截图所示:

将“remoteIp”字段添加到“日志字段”窗格,以确定发送最匹配请求的 IP 地址。

现在,您可以在日志字段窗格中查看发送匹配请求的主要远程 IP 地址:

顶部移除的 IP 地址会显示在日志浏览器中。

这样您就可以深入了解这些 Log4j 2 漏洞利用扫描的来源。其中一些可能是您已配置的应用漏洞扫描工具(例如 Web Security Scanner)的合法扫描。如果您使用的是 Security Command Center 中的 Web Security Scanner,请记下 Web Security Scanner 使用的静态 IP 地址范围

搜索目标应用并验证缓解技术

您可能还需要聚合目标应用,并确定恶意请求是否已经实际到达您的应用。如果您已启用使用 Google Cloud Armor 提供的安全政策或 Identity-Aware Proxy (IAP) 提供的访问权限控制的缓解技术,您还可以验证 HTTP(S) 负载均衡器日志中记录的信息是否按预期工作。

首先,将目标应用添加到日志字段窗格,选择其中一个日志条目结果,展开 resource.labels,点击 resource.labels.backend_service_name 字段值,然后选择将字段添加到日志字段窗格

您现在可以看到 Log4j 2 漏洞扫描所针对的热门应用或后端服务。如需确定这些漏洞利用尝试是否已到达后端服务,请使用由 HTTP(S) 负载均衡器填充的 jsonPayload.statusDetails 字段,以了解请求是代理到后端,还是成功被 IAP 或 Google Cloud Armor 等服务成功阻止。点击日志条目结果中的 jsonPayload.statusDetails 字段值,然后选择将字段添加到日志字段

现在,您可以在日志字段窗格中查看请求的处理方式:

最有针对性的后端服务会显示在日志浏览器中

在此示例中,大多数请求被 IAP 阻止,如果在后端服务上启用,则需要验证用户的身份并使用上下文,然后才允许访问。这些被 IAP 阻止的请求会将 statusDetails 设置为 handled_by_identity_aware_proxy。此外(或者)如果使用 Google Cloud Armor 并将正确的安全政策附加到后端服务,则所有 Google Cloud Armor 阻止的请求都会将 statusDetails 设置为 denied_by_security_policy。如需详细了解如何将新的预配置 cve-canary WAF 规则应用于您的 Google Cloud Armor 安全政策,请参阅 Google Cloud Armor WAF 规则以帮助缓解 Apache Log4j 漏洞

如需进行过滤以显示任何实际到达后端服务的请求,请在日志字段窗格中的 statusDetails 下选择 response_sent_by_backend。请考虑为这些后端服务启用 IAP 和/或应用带有预配置 cve-canary WAF 规则的 Google Cloud Armor 安全政策,以帮助阻止这些漏洞利用尝试。

创建基于日志的提醒

设计完在服务中查找受影响日志的查询后,您可以使用该查询创建基于日志的提醒,以便在新日志条目与该查询匹配时收到通知。此提醒可以转发到您的组织的安全运营中心 (SOC) 或适当的突发事件响应团队。

如需了解如何创建基于日志的提醒,请参阅创建基于日志的提醒(日志浏览器)。创建提醒时,请务必使用针对漏洞字符串的查询,而不是示例中指定的查询。

为基于日志的指标创建提醒政策

如需监控哪些端点或服务正在记录可能的漏洞尝试,请创建基于日志的指标的提醒政策:

  1. 创建基于日志的指标,用于计算日志中可能出现的漏洞字符串的出现次数。例如,您可以使用 使用 Google Cloud CLI 创建此类指标:

    gcloud logging metrics create log4j_exploits \
    --description="Detect log4j exploits" \
    --log-filter='httpRequest.requestUrl=~"(?i)(\$|\%24)(\{|\%7b).*j.*n.*d.*i.*(\:|\%3a)" OR httpRequest.userAgent=~"(?i)(\$|\%24)(\{|\%7b).*j.*n.*d.*i.*(\:|\%3a)" OR httpRequest.referer=~"(?i)(\$|\%24)(\{|\%7b).*j.*n.*d.*i.*(\:|\%3a)"'
    

    如需详细了解如何创建基于日志的指标,请参阅 配置计数器指标

  2. 创建提醒政策,以便在达到所选发生次数时收到通知。如需了解如何设置提醒政策,请参阅创建关于计数器指标的提醒政策

后续步骤