# AWS CloudTrail でセキュリティ脅威を検知し、インシデントを調査する（2026年版）：CISベンチマーク監視・GuardDuty/Security Hub連携・フォレンジック調査の実践

> CloudTrailでの脅威検知とインシデント調査の実践。証跡停止(StopLogging)などの攻撃の兆候検知、CIS AWS Foundations Benchmark準拠アラート、GuardDuty/Security Hub連携、Athenaフォレンジック、ログ整合性検証による否認防止を公式に忠実な実コードで。

- 公開日: 2026-06-27
- 著者: 友田 陽大
- タグ: AWS, CloudTrail, セキュリティ, インシデント対応, 脅威検知, アーキテクチャ設計
- URL: https://tomodahinata.com/blog/aws-cloudtrail-security-threat-detection-incident-response-guide
- カテゴリ: AWS CloudTrail 監査・ガバナンス
- 総合ガイド: https://tomodahinata.com/blog/aws-cloudtrail-audit-logging-governance-security-guide

## 要点

- 最優先の検知は『攻撃者が証跡を止める瞬間』。StopLogging/DeleteTrail/UpdateTrail/PutEventSelectors を EventBridge→Lambda/SNS で秒単位に検知する
- root利用・未認可API急増・MFAなしサインイン・IAM昇格などの定番監視アラートは CloudTrail公式の3例ではなく CIS AWS Foundations Benchmark（Security Hub CloudWatch.1〜14）由来。出典を正しく言える状態で設計する
- マネージド検知（GuardDuty/Security Hub/Detective）はいずれもCloudTrailを入力にしている。GuardDutyのIAM系FindingはCloudTrail管理イベントのML異常検知が中心
- 調査はAthena/Lakeの横断クエリで『侵害プリンシパルの全行動』を時系列で再構成し、証拠保全はログ整合性検証(validate-logs)とS3 Object Lockで否認不能にする
- 検知→トリアージ→スコープ特定→封じ込め→証拠保全、というIRプレイブックを最初から設計に織り込む

---

深夜2時。「**本番アカウントで見覚えのないIAMユーザーが作られている**」というアラートで叩き起こされたとします。あなたが最初に見るべきは何でしょうか。

答えは1つです。**CloudTrail はまだ生きているか。** 攻撃者が最初にやることの定番が「証跡を止めて足跡を消す」ことだからです。証跡が止められた後のログには、肝心の侵害行為が映っていません。検知も調査も、まずここから始まります。

私はサーバーレス（Lambda + DynamoDB）の[決済プラットフォームの信頼性レイヤー](/case-studies/payment-platform-reliability)を設計・主導し、**本番稼働中の二重課金0件**を維持してきました。その規律の核は「正しさを、後からでも否認不能に証明できる状態を、最初から設計しておく」ことです。お金が動くシステムでは、「たぶん大丈夫」は通用しません。**誰が・いつ・どの権限で・どこから何をしたか**を改ざん不可能な形で残し、いざという時に秒単位で引ける——その土台が **CloudTrail を中心としたセキュリティ運用** です。

この記事は、CloudTrail を「監査ログの置き場」で終わらせず、**脅威検知・不正検知・インシデント調査（フォレンジック）の実戦プレイブック**として組み上げるためのガイドです。検知の実コード、CISベンチマーク準拠の監視、GuardDuty/Security Hub/Detectiveとの連携、Athena/Lakeの調査クエリ、そして証拠保全までを一気通貫で扱います。

> **この記事の前提と分担**：CloudTrail の基本設定（マルチリージョン証跡・暗号化・整合性検証の有効化・EventBridge/CloudWatch連携の仕組みそのもの）は [CloudTrail 完全ガイド（ピラー記事）](/blog/aws-cloudtrail-audit-logging-governance-security-guide) が担当します。本記事はそこを土台に、**セキュリティ運用とフォレンジックの深掘り**に集中します。仕様・条件・Finding名はすべて AWS 公式ドキュメント（2026年6月時点）に照合しています。料金・マネージド機能のステータスは改定が速いので、本番投入前に必ず最新の公式を確認してください。アカウントID(`111122223333`)・バケット名・リージョンは例示です。

---

## 0. メンタルモデル：CloudTrail は「検知」と「調査」の土台、そして「証拠」

セキュリティ運用の文脈で、CloudTrail の役割を3つに分けて固定します。これがこの記事全体の地図です。

> **検知（Detection）＝ いま起きていることに気づく。** リアルタイム性が命。EventBridge / CloudWatch メトリクスフィルタ / GuardDuty。
>
> **調査（Investigation）＝ 過去に何が起きたかを横断クエリで再構成する。** 網羅性が命。Athena / CloudTrail Lake。
>
> **証拠（Evidence）＝ 「確かにこの認証情報がこのAPIを叩いた」と否認不能に証明する。** 完全性が命。ログ整合性検証 / S3 Object Lock。

| 観点 | 何で実現するか | 重視する性質 | 時間軸 |
| --- | --- | --- | --- |
| 検知 | EventBridge → Lambda/SNS、CloudWatch メトリクスフィルタ+アラーム、GuardDuty | レイテンシ（秒〜分） | いま |
| 調査 | Athena（S3上のログ）、CloudTrail Lake（Trino SQL） | 網羅性・横断性 | 過去（90日超） |
| 証拠 | ログ整合性検証（SHA-256 / digest チェーン）、S3 Object Lock / MFA Delete | 完全性・否認防止 | 事後 |

CloudTrail のイベントには、検知・調査の両方で繰り返し使う「核となるフィールド」があります。これを身体に入れておくと、後のクエリもフィルタもすべて読み解けます（公式の `userIdentity` / イベントレコード仕様より）。

| フィールド | 意味 | 検知・調査での使いどころ |
| --- | --- | --- |
| `userIdentity.type` | 呼び出し主体の種別 | `Root` / `IAMUser` / `AssumedRole` / `Role` / `FederatedUser` / `AWSService` / `IdentityCenterUser` |
| `userIdentity.arn` | 主体のARN | 侵害プリンシパルの特定・全行動の追跡キー |
| `userIdentity.sessionContext.attributes.mfaAuthenticated` | MFA認証されたセッションか | `false` のサインインを警戒 |
| `eventName` | 呼ばれたAPI | `StopLogging`、`CreateAccessKey` など、操作の中身 |
| `eventSource` | サービス | `cloudtrail.amazonaws.com`、`iam.amazonaws.com` など |
| `sourceIPAddress` | 呼び出し元IP | 不審なIP・Tor・国外からのアクセス |
| `errorCode` | エラー | `AccessDenied` / `UnauthorizedOperation` の急増＝偵察の兆候 |
| `awsRegion` | リージョン | 使っていないリージョンでの操作＝侵害の兆候 |
| `readOnly` | 読み取り専用か | 書き込み系（破壊的操作）を優先監視 |

> **注意：** `userIdentity.type` の正しい値に `IdentityCenterUser` はありますが、`IAMIdentityCenter` という値は存在しません。フィルタやクエリを書くときに混同しないこと。

---

## 1. 最優先の検知：攻撃者は最初に「証跡を止め」にくる

冒頭のシナリオに戻ります。インシデント検知で**最も価値が高い1本**は、地味ですが「**CloudTrail 自体への改ざん操作**」の即時検知です。なぜなら、ここを止められると以降のすべての検知・調査の前提が崩れるからです。

監視すべき `eventSource` は `cloudtrail.amazonaws.com`、`eventName` は次の4つが中心です。

| eventName | 攻撃者の意図 |
| --- | --- |
| `StopLogging` | 証跡を止めてログ記録を停止する（足跡消し） |
| `DeleteTrail` | 証跡そのものを削除する |
| `UpdateTrail` | 証跡の設定を改ざん（マルチリージョン解除・ログ先変更など） |
| `PutEventSelectors` | 記録対象イベントを絞り、自分の操作を記録対象外にする |

これは「過去のログを後で見返す」では遅すぎます。**ニアリアルタイムで秒単位**に検知する必要があるため、CloudWatch メトリクスフィルタ（数分のバッファがある）ではなく、**EventBridge → Lambda/SNS** が第一選択です。EventBridge は CloudTrail のAPIコールを `detail-type: "AWS API Call via CloudTrail"` として受け取れます。

### EventBridge ルール（Terraform）

```hcl
# 証跡改ざん操作をニアリアルタイムで捕捉する EventBridge ルール
resource "aws_cloudwatch_event_rule" "cloudtrail_tampering" {
  name        = "detect-cloudtrail-tampering"
  description = "Detect attempts to stop, delete, or weaken CloudTrail logging"

  event_pattern = jsonencode({
    "detail-type" : ["AWS API Call via CloudTrail"],
    "detail" : {
      "eventSource" : ["cloudtrail.amazonaws.com"],
      "eventName" : ["StopLogging", "DeleteTrail", "UpdateTrail", "PutEventSelectors"]
    }
  })
}

resource "aws_cloudwatch_event_target" "tampering_to_sns" {
  rule      = aws_cloudwatch_event_rule.cloudtrail_tampering.name
  target_id = "notify-secops"
  arn       = aws_sns_topic.security_alerts.arn
}

# Lambda でトリアージ情報を整形してから通知したい場合は、こちらをターゲットに
resource "aws_cloudwatch_event_target" "tampering_to_lambda" {
  rule      = aws_cloudwatch_event_rule.cloudtrail_tampering.name
  target_id = "triage-lambda"
  arn       = aws_lambda_function.tampering_triage.arn
}
```

### トリアージ用 Lambda（TypeScript）

通知をただ飛ばすだけでなく、「誰が・どこから・どの証跡を」止めようとしたかを即座に読める形に整えます。アラートは「読めば判断できる」状態で届けてこそ意味があります。

```ts
import type { EventBridgeEvent } from "aws-lambda";
import { SNSClient, PublishCommand } from "@aws-sdk/client-sns";

const sns = new SNSClient({});
const TOPIC_ARN = process.env.SNS_TOPIC_ARN!; // 環境変数のみ。ハードコード禁止

// CloudTrail 経由の API コール詳細（必要フィールドのみ）
interface CloudTrailDetail {
  eventName: string;
  eventSource: string;
  sourceIPAddress?: string;
  awsRegion?: string;
  userIdentity?: {
    type?: string;
    arn?: string;
    sessionContext?: { attributes?: { mfaAuthenticated?: string } };
  };
  requestParameters?: Record<string, unknown>;
}

export const handler = async (
  event: EventBridgeEvent<"AWS API Call via CloudTrail", CloudTrailDetail>,
): Promise<void> => {
  const d = event.detail;
  const id = d.userIdentity;

  const message = [
    "[CRITICAL] CloudTrail tampering detected",
    `eventName : ${d.eventName}`,
    `principal : ${id?.arn ?? "unknown"} (type=${id?.type ?? "unknown"})`,
    `mfa       : ${id?.sessionContext?.attributes?.mfaAuthenticated ?? "n/a"}`,
    `sourceIP  : ${d.sourceIPAddress ?? "unknown"}`,
    `region    : ${d.awsRegion ?? "unknown"}`,
    `time      : ${event.time}`,
    `params    : ${JSON.stringify(d.requestParameters ?? {})}`,
  ].join("\n");

  await sns.send(
    new PublishCommand({
      TopicArn: TOPIC_ARN,
      Subject: `CloudTrail tampering: ${d.eventName}`,
      Message: message,
    }),
  );
};
```

> **設計の勘所**：「証跡を止められない」ようにする**予防**もセットで考えます。組織レベルで `cloudtrail:StopLogging` / `cloudtrail:DeleteTrail` を SCP で拒否すれば、メンバーアカウントの侵害プリンシパルでは証跡を止められません。SCP による多層防御とマルチアカウント監査の設計は [Organization Trail / マルチアカウント監査ガイド](/blog/aws-cloudtrail-organization-trail-multi-account-audit-guide) で詳述します（本記事では深追いしません）。検知（この章）と予防（SCP）は両輪です。

---

## 2. 攻撃の兆候を検知する：CISベンチマーク準拠アラート集

証跡改ざんの次に張るべき網が、「侵害の典型的な振る舞い」への監視アラートです。ここで**最重要の honesty point**を1つ。

> **よく知られた「root利用」「未認可API」「MFAなしサインイン」などの監視アラートは、CloudTrail のユーザーガイドの『例』ページに載っているものではありません。** CloudTrail 公式が「例」として挙げているメトリクスフィルタは、実は**たった3つだけ**です。

CloudTrail 公式ドキュメントの「CloudWatch アラーム例」ページが提供するのは、次の3例のみです。

| 監視対象 | メトリクスフィルタが拾う eventName | メトリクス名 |
| --- | --- | --- |
| セキュリティグループ変更 | `AuthorizeSecurityGroupIngress`〜`DeleteSecurityGroup` のSG操作群 | `SecurityGroupEventCount` |
| コンソールサインイン失敗 | `ConsoleLogin` かつ `errorMessage = "Failed authentication"` | `ConsoleSigninFailureCount` |
| IAMポリシー変更 | `PutUserPolicy`〜`DetachGroupPolicy` のIAMポリシー操作群 | `IAMPolicyEventCount` |

なお、コンソールサインイン失敗のフィルタパターンは公式通り次の通りです（このまま使えます）。

```text
{ ($.eventName = ConsoleLogin) && ($.errorMessage = "Failed authentication") }
```

では、世間で「CloudTrail監視のベストプラクティス」として広まっている**root利用・未認可API・MFAなしサインイン・CMK無効化…**といった定番アラート群はどこから来ているのか。出典は **CIS AWS Foundations Benchmark**（および AWS Security Hub の CIS 標準コントロール）です。正確には、Security Hub の **CloudWatch.1 〜 CloudWatch.14** コントロールが、CIS の各推奨（v1.2.0 の 3.x / v1.4.0 の 4.x）に対応しています。

> **なぜ出典を正しく言えることが重要か。** 監査やレビューで「これは何に準拠した監視ですか」と問われたとき、「CloudTrail公式の例です」と答えるのは不正確で、信頼を損ないます。「CIS AWS Foundations Benchmark の §3/§4、Security Hub の CloudWatch コントロールに準拠しています」と言えることが、設計の説明責任そのものです。

### CIS準拠の監視アラート一覧（Security Hub CloudWatch コントロール）

公式の Security Hub ユーザーガイドに基づく対応表です。各コントロールは「CloudTrail → CloudWatch Logs にログを流し、メトリクスフィルタ＋アラームを置く」という同じ仕組みで実装します。

| Security Hub コントロール | 監視対象 | 対応する CIS |
| --- | --- | --- |
| CloudWatch.1 | root ユーザーの利用 | CIS v1.2.0/3.3, v1.4.0/4.3 |
| CloudWatch.2 | 未認可API呼び出し（`AccessDenied`/`UnauthorizedOperation`） | CIS v1.2.0/3.1 |
| CloudWatch.3 | MFAなしのマネジメントコンソールサインイン | CIS v1.2.0/3.2 |
| CloudWatch.4 | IAMポリシー変更 | CIS v1.2.0/3.4, v1.4.0/4.4 |
| CloudWatch.5 | CloudTrail設定変更 | CIS v1.2.0/3.5, v1.4.0/4.5 |
| CloudWatch.6 | コンソール認証失敗 | CIS v1.2.0/3.6, v1.4.0/4.6 |
| CloudWatch.7 | CMK（顧客管理キー）の無効化・スケジュール削除 | CIS v1.2.0/3.7, v1.4.0/4.7 |
| CloudWatch.8 | S3バケットポリシー変更 | CIS v1.2.0/3.8, v1.4.0/4.8 |
| CloudWatch.9 | AWS Config設定変更 | CIS v1.2.0/3.9, v1.4.0/4.9 |
| CloudWatch.10 | セキュリティグループ変更 | CIS v1.2.0/3.10, v1.4.0/4.10 |
| CloudWatch.11 | NACL（ネットワークACL）変更 | CIS v1.2.0/3.11, v1.4.0/4.11 |
| CloudWatch.12 | ネットワークゲートウェイ変更 | CIS v1.2.0/3.12, v1.4.0/4.12 |
| CloudWatch.13 | ルートテーブル変更 | CIS v1.2.0/3.13, v1.4.0/4.13 |
| CloudWatch.14 | VPC変更 | CIS v1.2.0/3.14, v1.4.0/4.14 |

> **補足（公式の注記より）**：Security Hub のこれらのコントロールは「**CISが規定する正確なメトリクスフィルタ**」と完全一致しないと `FAILED` になります。フィールドや語句を独自に足すと不合格です。一方で IAMポリシー変更(CloudWatch.4)・ルートテーブル変更(CloudWatch.13) の**修復手順例**だけは、AWSが「IAM/EC2のAPIコールのみを対象にする」よう CIS のパターンと意図的に変えた推奨を提示しています。準拠目的なら CIS のパターンを厳密に使い、運用ノイズ削減目的なら AWS の修復例を使う、と使い分けます。

### 実装例1：未認可API（AccessDenied 急増）の検知 — CIS 3.1 / CloudWatch.2

侵害された認証情報を握った攻撃者は、まず「この認証情報で何ができるか」を探ります。その過程で **`AccessDenied` / `UnauthorizedOperation` が短時間に急増**します。これは偵察の極めて有用なシグナルです。

```hcl
# CIS AWS Foundations Benchmark 3.1 / Security Hub CloudWatch.2 準拠
# 未認可API呼び出しの検知（CISが規定する正確なパターン）
resource "aws_cloudwatch_log_metric_filter" "unauthorized_api_calls" {
  name           = "CIS-UnauthorizedAPICalls"
  log_group_name = var.cloudtrail_log_group_name # CloudTrailの配信先ロググループ

  pattern = "{ ($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\") }"

  metric_transformation {
    name      = "UnauthorizedAPICalls"
    namespace = "CISBenchmark"
    value     = "1"
  }
}

resource "aws_cloudwatch_metric_alarm" "unauthorized_api_calls" {
  alarm_name          = "CIS-3.1-UnauthorizedAPICalls"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = 1
  metric_name         = "UnauthorizedAPICalls"
  namespace           = "CISBenchmark"
  period              = 300
  statistic           = "Sum"
  threshold           = 1
  alarm_description   = "CIS 3.1: Unauthorized API calls detected"
  alarm_actions       = [aws_sns_topic.security_alerts.arn]
  treat_missing_data  = "notBreaching"
}
```

### 実装例2：root ユーザーの利用検知 — CIS 1.7/4.3 / CloudWatch.1

root は全権限を持つため、日常運用での利用は原則ゼロであるべきです。`userIdentity.type` が `Root` で、かつ AWS サービス自身による呼び出し（`invokedBy`）でないものを拾います。

```hcl
# CIS / Security Hub CloudWatch.1 準拠：root ユーザー利用の検知
resource "aws_cloudwatch_log_metric_filter" "root_usage" {
  name           = "CIS-RootAccountUsage"
  log_group_name = var.cloudtrail_log_group_name

  pattern = "{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }"

  metric_transformation {
    name      = "RootAccountUsage"
    namespace = "CISBenchmark"
    value     = "1"
  }
}

resource "aws_cloudwatch_metric_alarm" "root_usage" {
  alarm_name          = "CIS-RootAccountUsage"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = 1
  metric_name         = "RootAccountUsage"
  namespace           = "CISBenchmark"
  period              = 300
  statistic           = "Sum"
  threshold           = 1
  alarm_description   = "CIS: Root account used"
  alarm_actions       = [aws_sns_topic.security_alerts.arn]
  treat_missing_data  = "notBreaching"
}
```

> **ノイズ対策**：これらのアラームには必ず `alarm_actions`（SNS等）を設定してください。Security Hub の **CloudWatch.15「アラームにアクションを設定すべき」/ CloudWatch.17「アラームアクションは有効化すべき」**（こちらは NIST 系コントロール）が、まさに「アラームを作ったのに通知先が無い／無効」という典型的な穴を突きます。検知の最後の1メートル＝通知が繋がっていなければ、検知器は存在しないのと同じです。

---

## 3. マネージド検知に乗る：GuardDuty / Security Hub / Detective

メトリクスフィルタは「事前に決めたパターン」しか拾えません。**未知の・異常な振る舞い**を捕まえるには、CloudTrail を入力にした **マネージドの検知サービス**に乗るのが正攻法です。3つの役割分担を押さえます。

| サービス | 役割 | CloudTrail をどう使うか |
| --- | --- | --- |
| **Amazon GuardDuty** | 脅威検知（ML/異常検知/脅威インテル） | CloudTrail の管理イベント・S3データイベントを**基盤データソース**として、MLで異常APIや既知の悪性パターンを検出 |
| **AWS Security Hub** | CSPM（態勢管理）/ コンプライアンス | CIS・AWS FSBP 等の標準でアカウントを採点。GuardDuty等のFindingを集約 |
| **Amazon Detective** | 調査（investigation graph） | CloudTrail等から**調査グラフ**を構築し、Findingの背後関係を可視化 |

### GuardDuty：CloudTrail 由来の代表的な Finding（公式の IAM Finding タイプ）

GuardDuty は CloudTrail の**管理イベント**を主データソースに、IAMエンティティ／アクセスキーに関する Finding を生成します（Resource Type は `AccessKey`）。公式ドキュメントに記載のある、CloudTrail を入力とする代表的な Finding を分類して挙げます。

**ML異常検知系（`*:IAMUser/AnomalousBehavior`）— データソースは CloudTrail 管理イベント**

| Finding タイプ | 意味（攻撃のどの段階か） | 既定の重大度 |
| --- | --- | --- |
| `CredentialAccess:IAMUser/AnomalousBehavior` | 認証情報の収集（`GetPasswordData`/`GetSecretValue` 等が異常な形で） | Medium |
| `DefenseEvasion:IAMUser/AnomalousBehavior` | 防御回避（`StopLogging`/`DeleteFlowLogs` 等の停止・削除） | Medium |
| `Discovery:IAMUser/AnomalousBehavior` | 偵察（`DescribeInstances`/`ListAccessKeys` 等の列挙） | Low |
| `Exfiltration:IAMUser/AnomalousBehavior` | データ持ち出し（`CreateSnapshot`/`PutBucketReplication` 等の制御プレーン操作） | High |
| `Impact:IAMUser/AnomalousBehavior` | 破壊・改ざん（`DeleteSecurityGroup`/`PutBucketPolicy` 等） | High |
| `Persistence:IAMUser/AnomalousBehavior` | 永続化（`CreateAccessKey`/`ImportKeyPair` 等） | Medium |
| `PrivilegeEscalation:IAMUser/AnomalousBehavior` | 権限昇格（`AddUserToGroup`/`PutUserPolicy` 等） | Medium |
| `InitialAccess:IAMUser/AnomalousBehavior` | 初期アクセス（`GetAuthorizationToken` 等） | Medium |

**シグネチャ／脅威インテル系**

| Finding タイプ | 意味 | 既定の重大度 |
| --- | --- | --- |
| `Policy:IAMUser/RootCredentialUsage` | root サインイン認証情報でAPIが呼ばれた | Low |
| `Stealth:IAMUser/CloudTrailLoggingDisabled` | CloudTrail のロギングが無効化された | Low |
| `Stealth:IAMUser/PasswordPolicyChange` | アカウントのパスワードポリシーが弱体化された | Low〜High |
| `Recon:IAMUser/MaliciousIPCaller` | 既知の悪性IPからリソース列挙系APIが呼ばれた | Medium |
| `Recon:IAMUser/TorIPCaller` | Tor 出口ノードからリソース列挙系APIが呼ばれた | Medium |
| `UnauthorizedAccess:IAMUser/MaliciousIPCaller` | 既知の悪性IPからAPIが呼ばれた | Medium |
| `UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS` | EC2の一時認証情報がAWS外のIPから使われた（認証情報窃取） | High |
| `UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B` | 同一IAMユーザーで世界各地から短時間に複数回サインイン成功 | Medium |

> **CredentialAccess:IAMUser/CompromisedCredentials との違い**：これは ML 異常検知ではなく **Amazon の脅威インテリジェンス**で「漏洩済み」と判定されたアクセスキーが使われたことを示す High の Finding です。データソースは「Foundational Data Source Protection に含まれる機能」と公式に記載されており、上記の `AnomalousBehavior` 系（CloudTrail管理イベントのML）とは生成根拠が異なります。混同しないこと。

GuardDuty の Finding は EventBridge に流れます（`detail-type: "GuardDuty Finding"`）。これを使えば、第1章と同じ要領で「重大度7以上の Finding が出たら即SNS／自動封じ込めLambda」を組めます。GuardDuty 単体の多層・マルチアカウント設計（委任管理者・EventBridge自動対応・Terraform）は [GuardDuty 深掘りガイド](/blog/aws-guardduty-threat-detection-multi-account-terraform-eventbridge-guide) に分けてあります。

```hcl
# GuardDuty の重大度の高い Finding を SecOps に即通知する
resource "aws_cloudwatch_event_rule" "guardduty_high_severity" {
  name = "guardduty-high-severity-findings"
  event_pattern = jsonencode({
    "source" : ["aws.guardduty"],
    "detail-type" : ["GuardDuty Finding"],
    # GuardDuty の severity は数値。7.0 以上 = High 以上を対象にする
    "detail" : { "severity" : [{ "numeric" : [">=", 7.0] }] }
  })
}
```

### Security Hub：CISスコアで「検知の網の穴」を可視化する

GuardDuty が「動的な検知」なら、Security Hub は「**静的な態勢の採点**」です。前章で挙げた CloudWatch.1〜17 を含む CIS / AWS FSBP 標準を有効化すると、「root監視アラートが無い」「CloudTrail設定変更の監視が無い」といった**検知の穴そのもの**が `FAILED` として一覧化されます。検知器を作ったつもりで作れていない、を防ぐ装置です。

---

## 4. インシデント調査プレイブック：Athena / Lake でのフォレンジック

検知の次は調査です。検知が「点」なら、調査は「線と面」——**侵害プリンシパルの全行動を時系列で再構成**し、被害範囲（スコープ）を確定させます。

90日を超える期間、あるいは大量ログの横断クエリには **Athena**（S3上のCloudTrailログをそのままSQL）が現実的です。スキャン量＝課金なので、**パーティション射影（partition projection）**で日付・リージョンを絞り込むのが鉄則です。CloudTrail Lake は Trino SQL で不変のイベントデータストアを直接クエリできますが、**2026年5月31日をもって新規顧客の受付を終了**しています（既存顧客は継続利用可）。新規構築では Athena + S3 が標準解です。

> 以下の Athena クエリは、CloudTrail ログ用の外部テーブル（パーティション射影付き）が作成済みである前提です。テーブル定義（`ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'` とパーティション射影プロパティ）の作り方はピラー記事に譲ります。

### IRプレイブック：検知 → トリアージ → スコープ → 封じ込め → 証拠保全

```text
1. 検知    : EventBridge / GuardDuty / CISアラームで気づく
2. トリアージ: 「本物か・誤検知か」「侵害プリンシパルは誰か(ARN)」を確定
3. スコープ : Athena/Lake で侵害ARNの全行動を時系列再構成、被害範囲を確定
4. 封じ込め : 鍵の無効化/失効、ポリシーのデタッチ、セッションの取り消し
5. 証拠保全 : 整合性検証(validate-logs)、ログの隔離コピー、否認不能化（第5章）
```

ステップ3「スコープ特定」で使う、現場で繰り返し叩くクエリを挙げます。

### クエリ1：侵害プリンシパルの「全行動」を時系列で再構成

トリアージで特定した ARN が、いつ・どこから・何をしたか。これが調査のすべての起点です。

```sql
-- 侵害が疑われるプリンシパルの全 API コールを時系列で並べる
SELECT
  eventtime,
  eventsource,
  eventname,
  sourceipaddress,
  awsregion,
  errorcode,
  readonly
FROM cloudtrail_logs
WHERE useridentity.arn = 'arn:aws:sts::111122223333:assumed-role/AppRole/suspicious-session'
  AND timestamp BETWEEN '2026/06/26' AND '2026/06/27' -- パーティション射影で絞る
ORDER BY eventtime ASC;
```

### クエリ2：永続化の兆候 — アクセスキーの新規作成

攻撃者は足場を固めるためにアクセスキーを作ります（GuardDuty の `Persistence:IAMUser/AnomalousBehavior` と対応）。

```sql
-- 調査期間内に作成されたアクセスキー（誰が・誰に対して・どこから）
SELECT
  eventtime,
  useridentity.arn          AS actor,
  responseelements,         -- 作成されたキーIDやユーザー名が入る
  sourceipaddress
FROM cloudtrail_logs
WHERE eventname = 'CreateAccessKey'
  AND timestamp BETWEEN '2026/06/20' AND '2026/06/27'
ORDER BY eventtime ASC;
```

### クエリ3：権限昇格の兆候 — IAM の付与系操作

```sql
-- 権限昇格に使われがちな IAM 操作を洗い出す
SELECT eventtime, useridentity.arn AS actor, eventname, requestparameters, sourceipaddress
FROM cloudtrail_logs
WHERE eventsource = 'iam.amazonaws.com'
  AND eventname IN (
    'AttachUserPolicy', 'AttachRolePolicy', 'AttachGroupPolicy',
    'PutUserPolicy', 'PutRolePolicy', 'PutGroupPolicy',
    'AddUserToGroup', 'CreatePolicyVersion', 'UpdateAssumeRolePolicy'
  )
  AND timestamp BETWEEN '2026/06/20' AND '2026/06/27'
ORDER BY eventtime ASC;
```

### クエリ4：データ持ち出しの兆候 — スナップショット共有・バケット公開

`Exfiltration:IAMUser/AnomalousBehavior` が捉える制御プレーン操作を、調査で裏取りします。

```sql
-- スナップショットの外部共有・S3公開化など、持ち出しに繋がる制御操作
SELECT eventtime, useridentity.arn AS actor, eventname, requestparameters, sourceipaddress
FROM cloudtrail_logs
WHERE eventname IN (
    'ModifySnapshotAttribute',     -- スナップショットを他アカウントへ共有
    'CreateSnapshot',
    'PutBucketPolicy',             -- バケットポリシーの書き換え
    'PutBucketAcl',
    'PutBucketReplication',        -- 別バケットへの複製設定
    'DeleteBucketPublicAccessBlock'-- パブリックアクセスブロック解除
  )
  AND timestamp BETWEEN '2026/06/20' AND '2026/06/27'
ORDER BY eventtime ASC;
```

### クエリ5：ソースIP・セッションの追跡 — 横展開の把握

侵害が「1つのARN」に留まっているのか、それとも横展開しているのか。**怪しいIPを軸に**、そのIPから操作したすべてのプリンシパルを洗い出します。

```sql
-- 特定の不審 IP から行動したすべてのプリンシパルと操作
SELECT
  useridentity.arn AS actor,
  useridentity.type AS actor_type,
  eventname,
  COUNT(*) AS calls,
  MIN(eventtime) AS first_seen,
  MAX(eventtime) AS last_seen
FROM cloudtrail_logs
WHERE sourceipaddress = '203.0.113.45'
  AND timestamp BETWEEN '2026/06/20' AND '2026/06/27'
GROUP BY useridentity.arn, useridentity.type, eventname
ORDER BY calls DESC;
```

### クエリ6：MFAなしセッションの炙り出し

```sql
-- MFA 認証されていないセッションでの書き込み系操作（侵害セッションの疑い）
SELECT eventtime, useridentity.arn AS actor, eventname, sourceipaddress
FROM cloudtrail_logs
WHERE useridentity.sessioncontext.attributes.mfaauthenticated = 'false'
  AND readonly = false
  AND timestamp BETWEEN '2026/06/26' AND '2026/06/27'
ORDER BY eventtime ASC;
```

> **コストの落とし穴**：`WHERE timestamp BETWEEN ...` のパーティション射影条件を**毎回必ず付ける**こと。これを忘れると数年分・全リージョンのログを全スキャンし、課金が跳ねます。Athena はスキャンしたGB数で課金されるため、フォレンジックでも「まず日付で絞る」が癖になるまで徹底します。

---

## 5. 証拠保全と否認防止：「確かにこの認証情報がやった」を証明する

調査でスコープが固まったら、最後は**証拠保全**です。ここを疎かにすると、せっかくの調査結果が「改ざんされていないと証明できない」ために、監査・法的手続き・社内説明で力を失います。

### ログ整合性検証：改ざん検出と否認防止

CloudTrail のログファイル整合性検証は、**SHA-256 によるハッシュ化**と **SHA-256 with RSA による電子署名**で構築されています。1時間ごとに、その時間に配信されたログファイル群への参照とハッシュを含む **digest ファイル**が作られ、各 digest は前の digest の署名を含む形で**鎖（チェーン）**になります。これにより、ログの**改ざん・削除・偽造を検出**でき、さらに「**ある期間にログが1つも配信されていないこと**」すら積極的に主張できます。

公式の表現がこの機能の価値を端的に言い表しています。

> 検証済みのログファイルは、**「特定のユーザー認証情報が特定の API アクティビティを実行した」と積極的に主張(assert positively)できる**——これが、セキュリティ・フォレンジック調査における否認防止の核心です。

検証は AWS CLI 一発で実行できます。

```bash
# S3 上の指定期間のログを digest チェーンに照らして検証する
aws cloudtrail validate-logs \
  --trail-arn arn:aws:cloudtrail:ap-northeast-1:111122223333:trail/org-audit-trail \
  --start-time 2026-06-26T00:00:00Z \
  --end-time   2026-06-27T00:00:00Z
```

ログを別の場所（隔離用バケットなど）へ移して検証したい場合は、CLI の検証はログが配信された元の場所を前提とするため、**カスタム検証**を実装します（公式に手順あり）。証拠の隔離コピーを作るなら、この点を設計に織り込んでおきます。

### 否認不能のためのストレージ設計

検証アルゴリズムが堅牢でも、**ログそのものを後から消されたら**意味がありません。証拠としての価値を担保するストレージ設計が必要です。

| 対策 | 何を防ぐか | 補足 |
| --- | --- | --- |
| **S3 Object Lock（WORM）** | ログ・digestの上書き・削除（root権限でも） | コンプライアンスモードなら保持期間中は誰も削除できない |
| **S3 MFA Delete** | digestファイルの不正削除 | 公式が digest 保護策として明示。削除にMFAを要求 |
| **ログアーカイブの隔離アカウント** | 侵害アカウントからのログ破壊 | ログ用S3を別アカウント（Log Archive）に置き、本番アカウントから書き込みのみ許可 |
| **SSE-KMS ＋ 厳格なキーポリシー** | 暗号化と、キー削除によるログ無効化 | CMK無効化はCISのCloudWatch.7で監視する（第2章） |

> **設計思想**：理想は「**ログを生成するアカウント**」と「**ログを保管するアカウント**」を分離することです。本番アカウントが完全に侵害されても、Log Archive アカウントの WORM 化されたログは無傷で残り、否認不能の証拠として機能します。決済基盤で「正しさを後から証明できる状態」を最初から作る、とはまさにこの構えのことです。

---

## 6. まとめ：検知 → 調査 → 保全のチートシート

CloudTrail を「ログ置き場」から「セキュリティ運用の土台」へ引き上げる要点を、最後に一枚に畳みます。

| フェーズ | やること | 使う道具 | 出典・根拠 |
| --- | --- | --- | --- |
| **最優先検知** | 証跡改ざん(`StopLogging`/`DeleteTrail`/`UpdateTrail`/`PutEventSelectors`)を秒で検知 | EventBridge → Lambda/SNS | CloudTrail EventBridge連携 |
| **兆候検知** | root利用・未認可API・MFAなしサインイン・IAM昇格・CloudTrail設定変更 等 | CloudWatch メトリクスフィルタ+アラーム | **CIS AWS Foundations Benchmark / Security Hub CloudWatch.1〜14** |
| **マネージド検知** | 未知の異常APIを ML/脅威インテルで | GuardDuty（CloudTrailが基盤データソース） | GuardDuty IAM Finding（公式） |
| **態勢採点** | 検知の穴（監視欠落）の可視化 | Security Hub（CIS/FSBP） | Security Hub 標準 |
| **調査** | 侵害ARNの全行動を時系列再構成・スコープ確定 | Athena（パーティション射影）/ CloudTrail Lake | — |
| **証拠保全** | 改ざん検出・否認防止 | `validate-logs`、S3 Object Lock/MFA Delete、隔離アカウント | ログ整合性検証（SHA-256 / digest チェーン） |

譲ってはいけない一線はこれです。

> **検知器は通知が繋がって初めて検知器になる（CloudWatch.15/17）。証拠はログが改ざん・削除不可能になって初めて証拠になる（整合性検証＋WORM）。** 「アラームはあるが通知先が無い」「ログはあるが消せる」は、無いのと同じ。

そして最も重要な honesty point を繰り返します。root利用や未認可API監視といった定番アラートは、**CloudTrail公式の『例』ではなく CIS AWS Foundations Benchmark（Security Hub のコントロール）に由来**します。出典を正しく言えることが、監査・レビューでの説明責任そのものです。

---

セキュリティ運用は「設定して終わり」ではなく、**検知 → 調査 → 保全のループを、誰が見ても回せる状態に設計しきれるか**で価値が決まります。私は決済という「お金が動く」領域で、二重課金0件を支える信頼性・監査の設計を主導してきました。「正しさを後から否認不能に証明できる状態」を、最初からコードに落とし込む——その経験を、あなたのAWS環境の**セキュリティ監視・インシデント対応設計**に活かせます。

CloudTrail を軸にした脅威検知・フォレンジック・IR体制の設計でお困りなら、[お問い合わせ](/contact)からお気軽にご相談ください。現状の検知の穴の洗い出しから、一緒に詰めます。

> 関連する深掘り記事：CloudTrailの基本設計は[CloudTrail 完全ガイド](/blog/aws-cloudtrail-audit-logging-governance-security-guide)、GuardDutyの多層検知は[GuardDuty 脅威検知ガイド](/blog/aws-guardduty-threat-detection-multi-account-terraform-eventbridge-guide)、ネットワーク層の防御は[AWS WAF 多層防御ガイド](/blog/waf-defense-in-depth-aws-waf-cloud-armor-owasp-guide)、データストアの権限設計は[DynamoDB セキュリティガイド](/blog/dynamodb-security-iam-fine-grained-access-control-encryption-vpc-endpoint-guide)を参照してください。
