Amazon GuardDuty を S3 にエクスポートし Athena で検索(手動でパーティション作成)

2020年7月5日

概要

やりたいこと

GuardDuty の検知結果を S3 にエクスポートし、 Athena で検索する。

Amazon GuardDuty

AWS 環境の脅威検知を行ってくれるサービス。

検知した結果(Findingと呼ぶ)は GuardDuty コンソールで確認できる。また、CloudWatch Events を経由してアラートとして飛ばすこともできる。

GuardDuty を S3 にエクスポートするため、KMS にてキーを作成しておく。

KMS ( Key Management System )

がんばって読む。

Athena

Amazon Athena は、標準 SQL を使用して S3 にあるファイルに対して分析することができる。

Athena はスキャンするデータ量によって課金額が決定される従量課金制のため、クエリで日付などで範囲指定する必要がある。

別記事でもっと調べる。

実践

GuardDuty を S3 にエクスポート

KMS キー登録

デフォルトのポリシーに GuardDuty にキーの使用を与える

  1. KMS コンソール
  2. カスタマー管理型のキー
  3. キーの作成
    1. キーのタイプ : 対象
    2. エイリアス : guardduty-alert
    3. キーの管理者 : なし
    4. キーの使用アクセス許可を定義 : なし
    5. キーの使用を GuardDuty に与えるポリシーを追加
      {
        "Sid": "Allow GuardDuty to encrypt findings",
        "Effect": "Allow",
        "Principal": {
          "Service": "guardduty.amazonaws.com"
        },
        "Action": "kms:GenerateDataKey",
        "Resource": "*"
      }
    6.  作成

最終的なキーポリシーは以下になった。

{
    "Version": "2012-10-17",
    "Id": "key-consolepolicy-3",
    "Statement": [
        {
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": "自分のIAMのやつ"
            },
            "Action": "kms:*",
            "Resource": "*"
        },
        {
            "Sid": "Allow GuardDuty to use the key",
            "Effect": "Allow",
            "Principal": {
                "Service": "guardduty.amazonaws.com"
            },
            "Action": "kms:GenerateDataKey",
            "Resource": "*"
        }
    ]
}

GuardDuty 設定

新規に S3 バケットも作成する。

  1. GuardDuty コンソール
  2. 設定
  3. 結果のエクスポートオプション
  4. S3 バケット項目で「今すぐ設定する」
  5. 新しいバケット
    1. 名前 : guardduty-alert
    2. ログファイルのプレフィックス : 無記入
    3. KMS 暗号化 : アカウントからキーを選択する
  6. 作成

「発行先が正常に作成されました。」と画面にでればOK。

アラートを出すために、「結果サンプルの生成」をクリック。
GuardDuty コンソール上へはすぐ表示されるが、S3 へのエクスポートには時間がかかるため、「更新された結果の頻度 」を15分ごとにしておく。

GuarDuty ログを Athena で検索

AWS 公式ドキュメントにて Athena のクエリ例を載せてくれているが、そこに GuardDuty はない。。

と思ったら、英語版の公式ドキュメントには存在した。 

テーブル化

SQLで扱うために、テーブルの構造を定義する。

GuardDuty 保存している S3 バケット(今回は guardduty-alert)とアカウントIDの部分を修正して、 Athena コンソールより下記クエリを実行する。

CREATE EXTERNAL TABLE `gd_logs` (
  `schemaversion` string,
  `accountid` string,
  `region` string,
  `partition` string,
  `id` string,
  `arn` string,
  `type` string,
  `resource` string,
  `service` string,
  `severity` string,
  `createdate` string,
  `updatedate` string,
  `title` string,
  `description` string)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
 LOCATION 's3://guardduty-alert/AWSLogs/account-id/GuardDuty/'
 TBLPROPERTIES ('has_encrypted_data'='true')

テーブルに gd_logs というテーブルが作成されていることを確認。

検索クエリ

公式ドキュメントに載っているクエリを実行してみる。
DNS data exfiltration アラートのみに絞り、件数を集計している。

今回はクエリスキャン量が大したことないため問題ないが、Athena は重量課金性のため、パーティションを指定すべき。

SELECT
    title,
    severity,
    type,
    id AS FindingID,
    accountid,
    region,
    createdate,
    updatedate,
    json_extract_scalar(service, '$.count') AS Count,
    json_extract_scalar(resource, '$.instancedetails.instanceid') AS InstanceID,
    json_extract_scalar(service, '$.action.actiontype') AS DNS_ActionType,
    json_extract_scalar(service, '$.action.dnsrequestaction.domain') AS DomainName,
    json_extract_scalar(service, '$.action.dnsrequestaction.protocol') AS protocol,
    json_extract_scalar(service, '$.action.dnsrequestaction.blocked') AS blocked
FROM gd_logs
WHERE type = 'Trojan:EC2/DNSDataExfiltration'
ORDER BY severity DESC

結果が出力されれことを確認。

エラー

HIVE_CURSOR_ERROR: The authorization header is malformed; the region ‘us-east-1’ is wrong; expecting ‘ap-northeast-1’ (Service: Amazon S3; Status Code: 400; Error Code: AuthorizationHeaderMalformed; Request ID: 9243E101D4A819E3; S3 Extended Request ID: mZXATe+m34Nkdb5JoaaZxdLYBpByv0tVvJZCXtE1mZsspdFBEmMSin0ssdE+diUzBkSKolNIGBc=)

Athena と S3 のリージョンが違ったままクエリを実行すると、こういったエラーが起きるから気をつけること。

参考

結果のエクスポート

[アップデート] GuardDuty の検出結果を S3 にエクスポート出来るようになりました

GuardDutyの検出結果をエクスポートするためのKMSキーとS3バケットをCloudFormationで作った