誰が「特権」を握っているか?――IAM監視を自動化し、攻撃者の侵入路を塞ぐ実務
現場で数々のインシデントを見てきた経験から言わせてもらうと、「IAMポリシーの変更」は、攻撃者が虎視眈々と狙う最大の特等席だ。
多くの開発者は「AWSのマネジメントコンソールやTerraformで権限を付与したから安心」と思っている。だが、もし君の管理するIAMユーザーのアクセスキーがGitHubに流出し、攻撃者が iam:PutRolePolicy や iam:CreateAccessKey を叩いたとしたら? 彼らはその瞬間から、君のクラウド環境の「管理者」になる。
今日は、教科書的な「ログを有効にしましょう」という話は飛ばす。実戦で生き残るための、CloudTrailとGuardDuty、そしてLambdaを組み合わせた「攻撃者完全排除」の仕組みを解説する。
—
1. 攻撃者が狙う「盲点」:なぜIAM変更は即時検知が必要なのか
攻撃者は侵入後、まず「権限昇格」を試みる。具体的には以下の手法が定番だ。
- バックドア作成: 既存の権限の低いIAMユーザーに
AdministratorAccessを付与する。 - キーの不正発行: 自分たちのための新しいIAMユーザーを作成し、アクセスキーを生成して永続的な足場を確保する。
これらが実行された時、通知が来るのが「翌日」では遅すぎる。攻撃者は数分で環境を破壊し、データを暗号化し、バックアップまで消去するからだ。我々が目指すべきは、イベント発生から数秒以内に検知し、即座にその操作を「無効化」する自動応答だ。
—
2. 実装:EventBridgeとLambdaによる「即時遮断」アーキテクチャ
ここでは、PutRolePolicy(特権の付与)が実行された瞬間に、自動的にそのポリシーを削除し、Slack等へアラートを送るPython実装を紹介する。
Step 1: EventBridgeルールの設定
まず、AWS EventBridgeで「IAMポリシー変更イベント」を拾う。
// EventBridgeルールのイベントパターン
{
"source": ["aws.iam"],
"detail-type": ["AWS API Call via CloudTrail"],
"detail": {
"eventSource": ["iam.amazonaws.com"],
"eventName": ["PutRolePolicy", "PutUserPolicy", "CreateAccessKey"]
}
}
Step 2: 自動応答するLambda関数(Python)
このコードは、不正な操作を検知した瞬間に、そのIAMユーザーやポリシーの紐付けを即座に剥がすための基礎ロジックだ。
import boto3
import json
iam = boto3.client('iam')
def lambda_handler(event, context):
# イベントの詳細情報を取得
detail = event['detail']
user_name = detail['userIdentity']['userName']
event_name = detail['eventName']
print(f"警告: 不審な操作 {event_name} がユーザー {user_name} によって実行されました。")
# ここに「許可リスト」を実装するのがコツ
# 特定のCI/CDロール以外からの操作なら即座に遮断するロジックを入れる
if "Authorized-Admin-Role" not in user_name:
# 例:IAMユーザーのキーを無効化する処理
# iam.update_access_key(UserName=user_name, AccessKeyId='...', Status='Inactive')
# 本番運用では、ここでSNSを通じた緊急通知と、
# 当該IAMユーザーの全ポリシーアタッチ解除を行うのが定石
return {"status": "Blocked", "user": user_name}
return {"status": "Allowed"}
—
3. 「GuardDuty」との合わせ技:守りを固める極意
IAMの監視だけでは足りない。攻撃者は「誰が操作したか」を隠蔽するために、IPアドレスを偽装したり、Tor経由でアクセスしてくる。
ここで GuardDuty の出番だ。GuardDutyは、IAMの操作だけでなく、VPCフローログやDNSクエリをAIで解析し、「異常なIPからのアクセス」や「未知のAPIコール」を検知する。
実務的な設定のポイント
- GuardDutyの「自動アーカイブ」をオフにする: 全てのFindingsは必ず監視ツール(SplunkやDatadog、またはAWS Security Hub)に集約すること。
- Lambdaとの連携: GuardDutyが「UnauthorizedAccess:IAMUser/MaliciousIPCaller」を検知した際、自動的にそのIPをWAF(AWS WAF)のブロックリストに追加するルールを組め。これが「動的防御」だ。
—
4. セキュリティチーフからの提言:泥臭い現場の教訓
最後に、コード以上に大切なことを伝えておく。
1. 最小権限の原則は「教条的」に守れ: 「開発環境だから」とフル権限を与えていないか? 開発者に必要なのは、特定のリソースに対する操作権限のみだ。AdministratorAccess を安易にアタッチする文化は、今日で終わらせろ。
2. ログの完全性を確保せよ: CloudTrailのログは、S3 Object Lock をかけて改ざん不能(WORM: Write Once Read Many)にすること。攻撃者は侵入後、まず最初に「自分の痕跡」を消そうとする。ログが消せない環境を作るのが、最大の防御だ。
3. たまには「レッドチーミング」を: 自分で組んだこの自動応答システムが本当に動くか、テスト環境で実際に権限を昇格させて検知・遮断が走るか試してほしい。動かないセキュリティシステムは、ただの飾りだ。
セキュリティは「導入して終わり」ではない。攻撃者は常に進化する。だが、今回紹介したような「異常を即座に検知し、自動で遮断する」アーキテクチャを組んでおけば、攻撃者に与えるダメージを最小限に抑え、君のシステムは圧倒的に堅牢になるはずだ。
さあ、次のデプロイの前に、IAMの権限を見直そうじゃないか。
コメント