如何使用GuardDuty在AWS上构建可视化的SIEM系统

背景
        随着国家对数据安全的要求越来越高,企业对于安全的重视程度也在不断提升。光环有云始终将客户环境的安全作为头号任务之一。本篇文章通过使用AWS GuardDuty以及Kibana实现了对客户资源安全防护的可视化报表功能并且在收到安全威胁后可以发送相应通知,帮助客户更好的了解资源安全情况。
相关概念简介
Amazon GuardDuty是一项托管威胁检测服务,可持续监控恶意或未经授权的行为,以帮助保护您的 AWS 账户和工作负载。启用 GuardDuty 并开始监控:

  • 异常 API 活动
  • 可能未经授权的部署和受损实例
  • 攻击者的侦察。

GuardDuty 分析和处理 VPC 流日志、AWS CloudTrail 事件日志和 DNS 日志数据源。您无需手动管理这些数据源,因为在您激活 GuardDuty 时会自动利用和分析这些数据。例如,GuardDuty通过独立且重复的流日志流直接从 VPC 流日志功能使用VPC 流日志事件。因此,您不会对现有工作负载产生任何操作负担。

GuardDuty 通过生成您可以在 GuardDuty 控制台中查看或通过Amazon CloudWatch Events使用的安全调查结果来帮助发现您的 AWS 环境中的潜在威胁,该服务使警报可操作并更容易集成到现有事件管理和工作流系统中。

在这篇文章中,我们将向您展示如何创建一个包含如下可视化的仪表板:

图 1:示例可视化

图 1:示例可视化

您将了解如何使用 AWS 服务为您的 GuardDuty 调查结果提供解决方案,以便您可以记录和可视化它们。

服务包括:

架构图及相关说明
下面的架构图描述了将创建的一系列服务。

图 2:架构图

图 2:架构图

我们将通过数据流来解释架构并重点介绍您可以使用的其他自定义设置。

  1. Amazon GuardDuty 在账户中启用并开始监控 CloudTrail 日志、VPC 流日志和 DNS 查询日志。如果检测到威胁,GuardDuty 会将结果转发给 CloudWatch Events。对于新生成的调查结果,GuardDuty在调查结果的 5 分钟内根据其 CloudWatch事件发送通知。CloudWatch Events 允许您将上游通知发送到根据您配置的事件模式过滤的各种服务。我们将配置一个仅转发来自 GuardDuty 服务的事件的事件模式。
  2. 我们在 CloudWatch 事件规则中定义了两个目标。第一个目标是用于传送到 Elasticsearch 域和 S3 存储桶的 Kinesis Firehose 流。第二个目标是用于电子邮件/短信发现结果通知的 SNS 主题。我们会将所有调查结果发送给我们的目标;但是,您可以使用 Lambda 函数(或通过与 CloudWatch 事件规则匹配的事件模式)过滤和格式化您发送的结果。
  3. Firehose 流将调查结果提供给 Amazon Elasticsearch,后者为我们的事件调查结果提供可视化和分析。该流还将调查结果传送到 S3 存储桶。S3 存储桶用于长期归档。这些数据可以扩充您的数据湖,您可以使用Amazon Athena等服务来执行高级分析。
  4. 我们将使用 Kibana 和 Elasticsearch 查询领域特定语言 (DSL) 搜索、探索和可视化 GuardDuty 发现,以获得有价值的见解。Amazon Elasticsearch 有一个内置的 Kibana 插件来可视化数据并执行操作分析。
  5. 为了提供一种简化且安全的身份验证方法,我们使用 Amazon Cognito 用户池向 Kibana提供用户身份验证。这种方法可以提高传统 IP 白名单或代理基础设施的安全性。
  6. 我们的第二个 CloudWatch Event 目标是 SNS,它订阅了电子邮件终端节点,允许您的运营团队在收到新的 GuardDuty 事件时接收电子邮件(或 SMS 消息)。

如果您想将来自多个区域的发现集中到一个 S3 存储桶中,您可以调整此服务。您将通过在远程区域中配置 Kinesis Firehose 以指向集中区域中的 S3 存储桶来部署服务的前端。您可以利用 Kinesis Firehose 配置中的前缀来标识源区域。

部署步骤
安装基础设施此 CloudFormation 模板将安装 GuardDuty 可视化所需的解决方案和组件:选择按钮以启动堆栈当您开始堆栈创建过程时,系统会提示您输入以下信息:

  • 堆栈名称 — 这是您将创建的堆栈的名称
  • EmailAddress — 此电子邮件地址用于在 Cognito 中创建用户名和 SNS 主题的订阅者。
  • ESDomainName — 这将是给 Elasticsearch 域的名称。
  • IndexName — 这将是 Firehose 创建的用于将数据加载到 Elasticsearch 的索引。
图 3:“创建堆栈”界面

图 3:“创建堆栈”界面

在Kibana中启用Cognito身份验证

要对 Kibana 中托管的仪表板启用用户身份验证,您需要启用来自在 Cloudformation 模板中创建的 Elasticsearch 域的集成。

  1. 打开 AWS 控制台并选择Cognito服务。选择管理用户池以访问在 Cloudformation 中创建的用户池。选择以名称VisualizeGuardDutyUserPool开头的用户池,然后在App Integration菜单项下,选择Domain name。
    图4:“域名”界面

    图 4:“域名”界面

  2. 您需要创建一个唯一的域前缀,以允许 Kibana 使用 Cognito 进行身份验证。输入唯一的域前缀(它只能包含小写字母、数字和连字符)。输入前缀后,选择“检查可用性”按钮以确保它在该地区可用。如果可用,请选择“保存更改”按钮。
  3. 从 AWS 控制台中,选择 Cloudformation 服务。
  4. 选择您为服务创建的模板,选择输出选项卡,然后在值下复制ESCognitoRole的值。当您启用 Elasticsearch 的 Cognito 身份验证时,您将使用此角色。
    图 5:“输出”选项卡和“ESCognitoRole”键

    图 5:“输出”选项卡和“ESCognitoRole”键

  5. 接下来,浏览到 Elasticsearch 服务,选择您从 CloudFormation 模板创建的域,然后选择配置集群按钮:
    图 6:“配置集群”按钮

    图 6:“配置集群”按钮

  6. 在Kibana 身份验证部分下,选中启用 Amazon Cognito 进行身份验证复选框。您将看到几个需要配置的字段,包括:Cognito 用户池、Cognito 身份池和IAM 角色名称。为这些字段提供值后,选择提交按钮。
    图 7:“Kibana 身份验证”界面

    图 7:“Kibana 身份验证”界面

  7. 集群重新配置将需要几分钟才能完成处理。当您看到域状态为Active 时,您可以继续。
  8. 最后,确认您从 SNS 收到的订阅电子邮件。查找来自以下地址的电子邮件:AWS Notifications <no-reply@sns.amazonaws.com>,打开消息并选择确认订阅以允许 SNS 在 SNS 主题收到有关新 GuardDuty 调查结果的通知时向您发送电子邮件。

设置 Kibana 仪表板并启用 GuardDuty

现在,您可以使用自定义可视化设置 Kibana 仪表板。

    1. 打开 CloudFormation 服务页面并选择您之前创建的堆栈。
    2. 在输出部分下,复制 Kibana URL。
      图 8:复制 Kibana URL

      图 8:复制 Kibana URL

    3. 将 Kibana URL 粘贴到新的浏览器窗口中。
    4. 检查您的电子邮件客户端。您应该有一封包含 Cognito 临时密码的电子邮件。复制临时密码并使用它登录 Cognito。如果您还没有收到电子邮件,请检查您的电子邮件垃圾文件夹。您还可以在从 CloudFormation 堆栈创建的 Cognito 用户池中创建其他用户,以提供其他用户 Kibana 访问权限。
      图 9:带有临时密码的电子邮件示例

      图 9:带有临时密码的电子邮件示例

    5. 在登录提示处,输入 CloudFormation 模板创建的 Cognito 用户的电子邮件地址和密码。将出现更改密码的提示。更改密码以继续。Cognito 用户池要求:大写字母、小写字母、特殊字符和长度至少为 8 个字符的数字。
    6. 是时候将映射信息添加到您的索引中,以指示 Kibana 将某些字段作为 geopoints交付。这允许使用坐标图正确显示这些字段。在左侧菜单中选择Dev Tools:
图 10:选择“开发工具”

图 10:选择“开发工具”

  1. 将以下 API 调用粘贴到文本框中,以为networkConnectionAction 和 portProbeAction地理定位字段提供适当的映射。这将调用 Elasticsearch API 并更新上述字段的地理位置映射:
    PUT _template/gdt{
      "template": "gdt*",
      "settings": {},
      "mappings": {
        "_default_": {
          "properties": {
            "detail.service.action.portProbeAction.portProbeDetails.remoteIpDetails.geoLocation": {
              "type": "geo_point"
            },
            "detail.service.action.networkConnectionAction.remoteIpDetails.geoLocation": {
              "type": "geo_point"
            }        
          }
        }
      }}
  2. 粘贴 API 调用后,请务必删除大括号后的空格。这允许您选择绿色箭头来执行它。您应该会收到一条消息,表明呼叫成功。
    图 11:粘贴 API 调用

    图 11:粘贴 API 调用

  3. 接下来,启用 GuardDuty 并发送样本调查结果,以便您可以创建包含数据的 Kibana 仪表板。在 AWS 控制台中找到 GuardDuty 服务并选择入门按钮。
  4. 在欢迎使用 GuardDuty页面中,选择启用 GuardDuty按钮。
  5. 接下来,发送一些示例事件。从 GuardDuty 服务中,选择左侧菜单上的设置菜单,然后选择生成示例结果,如下所示:
    图 12:“生成示例结果”按钮

    图 12:“生成示例结果”按钮

  6. 或者,如果您想使用真实的 GuardDuty 结果进行测试,您可以利用Amazon GuardDuty Tester。部署后,您将使用测试器 EC2 实例执行 shell 脚本以生成 GuardDuty 调查结果。有关此选项的其他详细信息,请参阅GuardDuty 文档
  7. 在 Kibana 登录页面的左侧菜单中,通过选择Management创建索引。
  8. 在管理页面上,选择索引模式。
  9. 在“创建索引模式”页面上的“索引模式”下,输入gdt-*(如果您在 Cloudformation 模板中使用了不同的 IndexName,请在此处使用),然后选择“下一步”。

    注意:GuardDuty 调查结果需要几分钟才能生成 CloudWatch 事件、通过管道并在 Elasticsearch 中创建索引。如果最初没有出现索引,请等待几分钟,然后重试。

    图 13:“创建索引模式”页面

    图 13:“创建索引模式”页面

  10. 在时间过滤器字段名称下,从下拉列表中选择时间,然后选择创建索引模式。
    图 14:“时间过滤器字段名称”列表

    图 14:“时间过滤器字段名称”列表

  • 创建脚本字段

    定义索引后,我们现在将创建您的仪表板可视化将使用的两个脚本化字段。

  • 定义严重性级别

1.选择您刚刚创建的索引,然后选择脚本化字段。

图 15:“脚本化字段”选项卡

图 15:“脚本化字段”选项卡

2.选择Add Scripted Field,然后输入以下信息:
      • 名称—— sevLevel
      • 语言——无痛
      • 类型—— 字符串
      • 格式(默认:字符串)——默认
      • 流行度——(保留默认值 0)
      • 脚本——将此脚本复制并粘贴到文本输入字段中:
        if (doc['detail.severity'].value < 3.9) { 
            return "Low";}else {if (doc['detail.severity'].value < 6.9) {
                  return "Medium";
               }return "High";}

3.输入信息后,选择创建字段。

所述sevLevel字段提供作为值到级映射定义由GuardDuty严重性级别。这允许您以更用户友好的格式(高、中和低)而不是神秘的数值来可视化严重性级别。为了生成sevLevel,我们使用了 Kibana无痛脚本,它允许创建自定义字段。

  • 定义攻击类型

1.现在为 typeCategory 创建第二个脚本化字段。该typeCategory现场提取发现的攻击类型。输入以下信息:

      • 名称—— typeCategory
      • 语言——无痛
      • 类型——字符串
      • 格式(默认:字符串)——默认
      • 流行度——(保留默认值 0)
      • 脚本—— 将此脚本复制并粘贴到文本输入字段中:
        def path = doc['detail.type.keyword'].value;if (path != null) {
            int firstColon = path.indexOf(":");
            if (firstColon > 0) {
            return path.substring(0,firstColon);
            }}return "";

2.输入信息后,选择创建字段。

该typeCategory字段用来定义大类“进攻型”。源字段(detail.type.keyword)提供了很多详细信息(例如:Recon:EC2/PortProbeUnprotectedPort),但我们希望在高层仪表板中可视化“攻击类型”的类别(即仅侦察)。如有必要,我们仍然可以在更细粒度的级别上进行可视化。

  • 创建 Kibana 仪表板

  1. 通过导入包含其定义的 JSON 文件来创建 Kibana 仪表板。为此,请从此处下载 Kibana 仪表板和可视化定义 JSON 文件。
  2. 在左侧菜单中选择管理,然后选择保存的对象。在右侧,选择“导入”。
  3. 选择您下载的 JSON 文件并选择Open。这将导入 GuardDuty 仪表板和可视化。选择是,覆盖所有对象。
  4. 在Index Pattern Conflicts部分的New index pattern 下,选择gdt-*,然后选择Confirm all changes
仪表盘及相关操作
  1. 在左侧菜单中选择仪表板。
  2. 选择警卫职责摘要链接。

您的 GuardDuty 仪表板将如下所示:

图 16:带有标注的 GuardDuty 仪表板

图 16:GuardDuty 仪表板

仪表板提供以下可视化:

  1. 此过滤器允许您从实际结果中过滤样本结果。如果您从 GuardDuty AWS 控制台生成样本调查结果,则此过滤器允许您从控制面板中删除样本调查结果。
  2. 所述GuardDuty -受影响的实例图表其中EC2实例具有相关联的调查结果显示。此可视化允许您通过在图形中选择特定实例来过滤显示中的特定实例。
  3. 在执勤-威胁类型的图表可以过滤对普通物攻型(内圈),以及特定的物攻型(外圈)。
  4. 在执勤-活动每日图表,您可以可视化和在特定的时间或日期过滤器,用来显示该特定时间的调查结果,以及搜索结果中的时间模式。
  5. GuardDuty —前 10 名调查结果按计数提供前 10 名调查结果的列表。
  6. GuardDuty — Total Events根据所选标准提供事件总数。该值将根据定义的过滤器而变化。
  7. 该GuardDuty -热图-端口探头来源国形象化其中port探针选发的国家。这是一个坐标图可视化,可让您查看针对您的实例的端口探测的来源和数量。
  8. 该GuardDuty -网络连接来源国形象化其中蛮力攻击的来源。这是一个区域地图可视化,可让您突出显示暴力攻击的来源国家/地区。
  9. GuardDuty — Severity Levels是一个饼图,按严重性级别(高、中、低)显示结果,您可以按特定级别进行过滤(即仅显示高严重性结果)。此可视化使用我们之前为简化可视化创建的脚本化字段。
  10. 在全GuardDuty表包括所有事件的原始调查结果。这提供了完整的原始事件详细信息以及在非常精细的级别进行过滤的能力。
寄语
AWS描述了一种快速构建服务的方法,以帮助您存档、分析和可视化您的 GuardDuty 调查结果,从而获得具备快速的洞察力和可操作的智能展示报表。您可以通过多种方式扩展此解决方案,包括:

  • 修改使用结构化消息(而不是原始 JSON)发送的警报电子邮件
  • 添加额外的可视化,例如热图或时间序列图表
  • 跨 AWS 账户或区域扩展解决方案。