ログは「死体検分」ではない。クラウド環境を攻め落とすための「生存戦略」
現場のエンジニア諸君。君たちが必死に書いたアプリケーションコードの裏側で、AWSやAzureのIAM権限設定が「誰でも触れる状態」になっていないか?
多くの現場で「ログは取っているから大丈夫」という甘い言葉を耳にするが、CloudTrailやAzure Monitorに溜まった膨大なログの山は、ただの「死体検分」の記録でしかない。攻撃者はログを消す術を知っているし、何より「異常検知」がなされないログは、ただのストレージコストの無駄遣いだ。
今日は、攻撃者が最も好む「権限の昇格」と「バックドアの設置」を、SIEM連携と自動化によってリアルタイムに封じ込めるための、泥臭い実務テクニックを伝授する。
—
1. 攻撃者が狙う「IAMの盲点」
攻撃者が最初に行うのは、スキャンではない。「既存の権限の不整合」を探すことだ。例えば、EC2インスタンスに付与されたIAMロールが、S3全域へのアクセス権(s3:*)を持っていないか?あるいは、Lambda関数が他のIAMユーザーを作成する権限を持っていないか?
彼らは、一度足掛かりを得ると以下の手順で環境を掌握する。
1. AssumeRole を悪用し、権限を横展開する。
2. CreateAccessKey で永続的なバックドアを作る。
3. DeleteTrail や StopLogging で自分たちの痕跡を消す。
これを防ぐには、人間が監視するのではなく、「異常なAPI呼び出しがあった瞬間に、対象のIAMユーザーを自動で無効化する」という自動化パイプラインが必須だ。
—
2. 実装:Pythonによる「権限操作の異常検知」
AWS環境を想定し、CloudTrailのイベントをトリガーにして、権限変更(CreateAccessKey や PutRolePolicy 等)を検知した瞬間にSlackへアラートを飛ばし、即座に該当ユーザーを無効化するLambda関数のエッセンスを紹介する。
import boto3
import json
# IAMクライアントの初期化
iam = boto3.client('iam')
def lambda_handler(event, context):
# CloudTrailから渡されるイベント情報を解析
detail = event.get('detail', {})
event_name = detail.get('eventName')
user_name = detail.get('userIdentity', {}).get('userName')
# 監視対象のアクションリスト
restricted_actions = ['CreateAccessKey', 'PutRolePolicy', 'DeleteTrail']
if event_name in restricted_actions:
# 異常検知:Slack通知および自動遮断のロジック
print(f"警告: 不審な権限操作を検知 - {event_name} by {user_name}")
# 実際の実装では、ここでユーザーのアクセスキーを無効化する
# iam.update_access_key(UserName=user_name, AccessKeyId='...', Status='Inactive')
return {
'statusCode': 200,
'body': json.dumps('Security Alert: Action blocked and notified.')
}
このコードのポイントは、「ホワイトリスト(許可された管理ユーザー)以外による操作」を厳格にフィルタリングすることだ。本番環境では、IAMのタグ付けを活用し、ManagedBy: Terraform といったタグがないユーザーによる変更は全て異常とみなすロジックを組むのが鉄則だ。
—
3. インフラ要塞化:不要なAPIを叩かせない「SCP」の活用
個別のIAM権限設定も重要だが、組織全体を守るなら Service Control Policies (SCP) を使え。特定のリージョン以外での操作を禁止する、あるいは CloudTrail 自体を停止させる権限を全ユーザーから剥奪するのは基本中の基本だ。
以下のJSONは、ルートユーザー以外が CloudTrail の停止や削除を行うことを防ぐためのSCP設定例だ。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyCloudTrailTampering",
"Effect": "Deny",
"Action": [
"cloudtrail:StopLogging",
"cloudtrail:DeleteTrail",
"cloudtrail:UpdateTrail"
],
"Resource": "*",
"Condition": {
"StringNotLike": {
"aws:PrincipalArn": ["arn:aws:iam::123456789012:role/Administrator"]
}
}
}
]
}
—
4. 現場の教訓:完璧な防御は存在しない
どれだけ自動化しても、攻撃者は常に「設定の隙間」を縫ってくる。私がこれまで見てきたインシデントの9割は、技術的な脆弱性ではなく、「開発用と本番用のIAM権限が混同していた」という運用ミスから発生している。
最後に、エンジニアの君たちへアドバイスを送る。
- 権限は「最小」から始めろ: 全てのアクセス許可(
*)を与えるのは、自分の家の鍵を道端に落とすのと同じだ。 - ログを「見る」のではなく「語らせろ」: SIEM(SplunkやCloudWatch Logs Insights)を使って、過去1週間と比べて「異常に多いAPIコール」をグラフ化する習慣をつけろ。
- IaC(Terraform/CloudFormation)で管理せよ: 手動でコンソールからポチポチ設定した権限は、いずれ必ず「野良権限」となり、攻撃の入り口になる。
セキュリティとは、終わりのない泥臭い作業の積み重ねだ。だが、その一歩が君の守るサービスを、そして君自身を救うことになる。今日から、自身の環境の「権限の棚卸し」を始めてみてくれ。それが最高の防御への第一歩だ。
コメント