🛡

Security Hubウォークスルー

2024/02/22に公開

AWSでセキュリティの話をすると必ず登場するSecurity Hubですが、この手のサービスってそれらしいデータやリソースがないとどう使えるのかイメージしにくいんですよね。ちょうどAWS Security Hub Workshopにトライさせていただく機会があったので、その時のスクショを使ってSecurity Hubで実現できるユースケースやTipsを紹介しようと思います。

Security Hubとは

ワークショップの解説によると、AWSリソースに対するCSPM (Cloud Security Posture Management) サービスです。AWSが提供する他のセキュリティサービス (ConfigやGuardDutyなど) はもちろん、OSSや3rdパーティーのソリューションと連携して、検出結果の集約と対応ができるサービスです。主な特徴は次の通り。

  • Organizationsのメンバーアカウントや各リージョンの情報を集約
  • 複数のセキュリティ基準 (AWS FSBP, CIS AWS Foundations Benchmark, PCI DSS, NIST SP800-53など) をサポート
  • ダッシュボードやインサイト(検出結果に特定のフィルタを適用したもの)を用いた視覚的な状況把握
  • 対応の自動化(EventBridge等と連携)
  • 手動対応の定型化
  • 検出結果を最終更新日から90日間保存

公式ドキュメントの解説はこちら

図で見ると各サービスがどのように連携するのかイメージしやすいと思います。
SecuirtyHub

画面のウォークスルー

サマリダッシュボード

ウィジェットがいくつか並んでいて、複数のカットから現在の状況が把握できるようになっています。セキュリティスコアの数字が見えると改善のモチベも上がりますね。各ウィジェットから、ウィジェットのコンテンツに応じてフィルタが適用された状態で、検出結果の一覧に飛ぶことができます。(Chromeのデバッグツールで全画面スクショ撮ったんですが、CSSの問題なのか上手く撮れずスイマセン)
Dashboard-1
サマリダッシュボード
re:Invent 2023ではウィジェットのカスタマイズやフィルタリングのサポートが発表されました。このワークショップで使用している「AWS統合による最新の検出結果」はデフォルトでは表示されなくなっていますが、ウィジェットを追加できます。
Dashboard-2

セキュリティ基準

Security Hubがサポートしているセキュリティ標準の一覧と、それぞれへの適合状況をスコアで確認できます。特定のセキュリティ標準のON/OFFもここで可能です。(マネコンは翻訳の問題で「標準」と「基準」で表現が揺れていますが、本記事では以降「標準」で統一します)
Standards

コントロール

コントロール画面では管理策の一覧に対してその適合状況を確認することができます。選択したセキュリティ標準に応じて、必要なコントロールが選択されます。
Control

検出結果とインサイト

検出結果画面では、各データソースから収集された検出結果を一覧で確認することができます。フィルタを追加して絞り込むことができ、フィルタされた検出結果の分布も可視化されます。よく使うフィルタ条件は「インサイトの作成」から保存することができます。
Findings
インサイトとして保存すると、フィルタ条件に合致する検出結果の推移をインサイト画面で視覚的に確認できるようになるので、チェック観点などに応じてインサイトを作成しておくと良いと思います。
Insights

検出結果の調査

コントロールからConfigのタイムラインへ

コントロール画面でEC2.13「セキュリティグループは、0.0.0.0/0 または ::/0 からポート 22 への入力を許可しないようにする必要があります」というコントロールに違反しているリソースとその経緯を調べてみましょう。

コントロールの一覧から「ID」列のEC2.13を選択すると、EC2.13に関するチェック結果が表示され、チェックはConfigによって行われていることがわかります。「調査」の列にある「Configルール」を選択すると、当該リソースのタイムラインに飛ぶことができ、いつコントロール違反につながる変更があったのか特定することができます。
EC2.13-1
EC2.13-2

検出結果からConfigのタイムラインへ

検出結果画面からも各検出結果の調査が可能です。下記の画面はあるEC2インスタンスについての検出結果に絞り込んだものですが、検出を行った製品 (Product) がSecurity Hubとなっているものがあることに気づくと思います。Security Hubは連携サービスから検出結果を受け取るだけでなく、自身でもチェックを行います。試しに、IMDSv2の利用に関する検出結果を選択すると、検出ルールに飛ぶことができます。
(検出画面でのEC2インスタンスの絞り込みはインスタンスIDではなくARNで指定)
IMDSv2-1
すると、このルールはAWS Configで実装されていることが分かりました。SLRとはService-Linked Roleのことです。
IMDSv2-2
インスタンスを選択し、タイムラインを表示すると、このインスタンスがAutoScalingによって起動されたことが分かります。
IMDSv2-3

検出結果の通知

SecurityHubはEventBridgeと連携することで、重要度の高いコントロール違反が生じた場合等に通知を行うことができます。ここではSNSを用いてメールで通知する例を紹介しますが、Slack等の3rdパーティソリューションへの通知も可能です。

SecurityHubは検出結果をEventBridgeに送信するので、EventBridgeでルールを作成するだけです。ルール作成前に、通知先のSNSトピックや通知先の登録を行っておきましょう。今回はHIGHもしくはCRITICALな検出結果を通知したいので、イベントパターンは下記のようになります。

{
  "source": ["aws.securityhub"],
  "detail": {
    "findings": {
      "Severity": {
        "Label": ["HIGH", "CRITICAL"]
      }
    }
  }
}

Notification-1

上記だけで通知は行えるようになるのですが、本文にデカいJSONが書いてあるメールが届いて、とてもじゃないけど読む気になれないので、見やすく整形しましょう。整形の手段としては、入力トランスフォーマーを使用するLambdaを使用するのが一般的だと思いますが、ここでは入力トランスフォーマーを使用してみます。

EventBridgeの通知先となるターゲットの選択画面で、折りたたまれている「追加設定」を開くと、入力トランスフォーマーの設定が可能です。既存ルールもルールの編集から設定可能なのでルールを再作成する必要はありません。
Notification-2

入力パスとテンプレートで出力をコントロールするのですが、「出力を生成」ボタンを押すと出力がどのようになるかシミュレーションできるので、サンプルイベントにメールで届いたJSONを設定して試すとわかりやすいと思います。

入力パス
{
  "account_id": "$.detail.findings[0].AwsAccountId",
  "finding_type": "$.detail.findings[0].Types[0]",
  "finding_description": "$.detail.findings[0].Description",
  "finding_severity": "$.detail.findings[0].FindingProviderFields.Severity.Label",
  "workflow_state": "$.detail.findings[0].WorkflowState"
}
テンプレート
"Account ID: <account_id>"
"Severity: <finding_severity>"
"Workflow State: <workflow_state>"
"Finding Type: <finding_type>"
"Description: <finding_description>"

メール本文は人間が読むのでダブルクォーテーションを含めたくなかったのですが、Invalid InputTemplateというエラーが出るのでやむを得ず上記のようにしています。re:Postのトラブルシューティングでも「改行を含むテンプレートを保存したときに Invalid InputTemplate エラーが表示される場合は、各行を二重引用符で閉じます。」と書かれていました。

ややこしいことに、ダブルクォーテーションがなくてもシミュレーション結果はエラーにならず、ダブルクォーテーションを入れると実際に届くものとは少し異なる結果になるので、是非修正してほしいところです。
Notification-3
Notification-4
実際に届くメール

対応の自動化

検出結果の重要度の変更

同じコントロール違反でも環境によって重要度が変わってくる場合があると思います。本番環境タグのついたEC2インスタンスについてGuardDutyが検出した検出結果の重要度をHIGHにしてみましょう。

オートメーション画面で「ルールを作成」選択し、「Elevate severity of findings that relate to important resources」というテンプレートからルールを作成します。既存の条件にResourceTagsを追加し、Environmentタグの値がProductionと一致するという条件を追加します。ルール名や説明はご自由に。
Automation-1
指定した条件が期待通りかプレビューで確認することができます。
Automation-2
自動アクションで重要度にHIGHを指定します。
Automation-3

検出結果に情報を追加

検出結果が報告されると、トリアージの段階でどの環境に関するものか調べ記録すると思いますが、これを自動化できると便利です。本番環境用のアカウントのリソースから報告された検出結果にタグと注釈をつけてみましょう。

オートメーション画面で「ルールを作成」選択し、カスタムルールを作成します。条件にAwsAccountIdを追加し、値に本番環境のアカウントIDを指定します。
Automation-4
自動アクションで、「注」に注釈を、「ユーザ定義フィールド」でKeyにEnvironment、ValueにProductionを設定します。
Automation-5
検出結果の一覧を見ると、更新日時の横にアイコンが表示され、選択すると先ほど設定した注釈が自動的に追加されて検出結果が更新されていることが分かります。
Automation-6
検出結果の履歴でも、オートメーションルールによって検出結果が更新されていることが分かります。
Automation-7

検出結果の抑制

大量の検出結果が報告されると、重要なものを見落とす可能性が高くなります。Inspectorが重要度INFORMATIONALまたはLOWと報告する検出結果を非表示にしてみましょう。

オートメーション画面で「ルールを作成」選択し、カスタムルールを作成します。条件にProductNameを追加し、値にInspectorを指定します。さらに条件にSeverityLabelを追加し、値にINFORMATIONALLOW指定します。
Automation-8
自動アクションで、「ワークフローステータス」にSUPPRESSEDを、「注」に注釈を設定します。
Automation-9

手動対応の定型化

Lambdaを用いたカスタムアクション

実際のインシデントでは人間による調査が必要な場合が多くあります。しかし、チケットの起票などの初動の手順は定型的なものも多く、これらを自動化することで運用の負荷やリスクを軽減できます。GuardDutyでEC2インスタンスのIAM認証情報の侵害が検出されたという前提で、当該インスタンスを隔離して保全する操作を自動化してみましょう。ここでは、SecuirtyGroupを隔離用SecurityGroupに変更することでEC2インスタンスを隔離します。

隔離用SecurityGroupはアウトバンドルールを空に設定したものを用意します。インバウンドルールはフォレンジック調査用にSSHとRDPでインスタンスにアクセスできるようなルールを設定しておくとよさそうです。(ワークショップのスクショはインバウンドに設定すべきルールをアウトバンドに設定してしまっているので、注意してください。)

SeurityGroupの変更はLambdaで行います。ランタイムはNode.js 18.xを選択してください。ワークショップのサンプルコードを利用させてもらいます。ソースを貼り付けたらデプロイしましょう。

import { EC2Client, ModifyInstanceAttributeCommand } from "@aws-sdk/client-ec2";
const ec2Client = new EC2Client();

export const handler = async (event, context) => {
try {
const findings = event.detail.findings;
const SecurityGroupId = "sg-XXXXXXXXXXXX";
var instanceARN;
if (findings && findings.length > 0){
instanceARN = findings[0].Resources[0].Id;
}

    const command = new ModifyInstanceAttributeCommand({
      InstanceId: instanceARN.split('/')[1],
      Groups: [SecurityGroupId]
    });

    await ec2Client.send(command);

    return 'Updated security group.';

} catch (error) {
console.error('Error:', error);
throw error;
}
};

SecurityGroupを変更するために、Lambda関数の実行ロールにインラインポリシーで許可を追加します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "ec2:*",
                "ec2:Describe*",
                "ec2:ModifyInstanceAttribute"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}

SecurityHubのカスタムアクション画面でカスタムアクションを作成します。といっても指定するのはアクション名とIDだけです。作成したカスタムアクションのARNをメモしておきましょう。(スクショ撮り忘れた)

カスタムアクションを作成すると、検出結果に対してアクションを実行できるようになりますが、Security HubはEventBridgeにカスタムアクションが実行されたことを通知するだけで、カスタムアクションで何を行うかはEventBridgeで設定します。

EventBridgeに移動してルールを作成します。イベントパターンで「イベントソース」はAWSのサービス&Security Hubを選択、「イベントのタイプ」はSecurity Hub Findings - Custom Actionを選択し、特定のカスタムアクションARNのところに先ほどメモしたARNを指定します。
CustomAction-1
ターゲットは先ほど作成したLambda関数を指定します。
CustomAction-2
SecurityHubからカスタムアクションをトリガーしてみましょう。
CustomAction-3
しばらくすると、EC2インスタンスのSGが変更されていることが確認できます。
CustomAction-4

修復のためのソリューション

Lambdaを用いたカスタムアクションを紹介しましたが、検出結果に応じたアクションをひとつずつ作るのは大変です。AWSからASR (Automated Security Response) と呼ばれる修復アクションのアドオンが提供されているので、そちらを試してみます。

ASRを利用するためには次の3種類のCloudFormationテンプレートのデプロイが必要です。

  • 管理スタック (SecurityHub管理者アカウントの単一リージョンにデプロイ)
  • メンバースタック(修復を行う全てのアカウントの全てのリージョン)
  • メンバーロールタック(全てのアカウントの任意の単一リージョン)

スタックのデプロイが完了すると、Security HubのアクションからASRによる修復アクションが選択できるようになります。
ASR-1

アクションを実行すると検出結果が更新されたのが分かります。
ASR-2

しばらくすると、修復が完了し、コントロールのチェックも合格になっていました。
ASR-3

使用状況の確認

SecurityHubは便利な反面、費用が予測しづらく、特に個人の検証アカウントだとONにするのを躊躇うサービスだと思います。「使用」画面を見ると詳細な使用状況がわかるので、30日間のトライアル期間を使って、ONにした場合のコストを見積もってみるとよいかもしれません。
Usage

まとめ

Security Hubの主な機能をユースケースベースで一通り紹介してみました。Slackへの通知やCloud CustodianなどのAWSサービス以外のデータソースとの統合もやりたかったのですが、環境が利用できる時間に制限があり今回はここまでとなります。スクショをたくさん貼ったので、使用感が伝わればうれしいです。

Discussion