【実務・中級編】 IAM権限昇格攻撃のパターンと防御策 – インフラ・ネットワーク & クラウドセキュリティ防御ガイド

エンジニア諸君、現場での運用は順調か?
今日は少し「ヒリつく」話をしよう。クラウドインフラ、特にAWSを触っていると「とりあえず動くように」と、甘いIAM権限を付与した経験があるはずだ。だが、その一枚のポリシーが、攻撃者にとっての「黄金の鍵」になることを忘れてはならない。

今日は、攻撃者が喉から手が出るほど欲しがる「権限昇格の特急券」、iam:PassRole と iam:CreatePolicyVersion について、現場のリアルな視点から解説する。

—

1. 攻撃者の視点:なぜ「権限の受け渡し」が狙われるのか

攻撃者は、最初から管理者権限を奪うような派手な攻撃はしない。まずはEC2のWebサーバーなどで脆弱性を突き、メタデータサービス(IMDS)から一時的な認証情報を抜き取る。そこからが彼らの腕の見せ所だ。

狙い目1:iam:PassRole の悪用

この権限は「特定のIAMロールをリソース(EC2など)に割り当てる」権利だ。もし君が、開発者に「EC2を作成する権限」と「PassRole権限」をセットで渡していたら? 攻撃者は、自分の管理下にあるEC2を立ち上げ、そこにフルアクセス権限を持つロールを付与する。これで、君のクラウド環境は完全に掌握されたも同然だ。

狙い目2:iam:CreatePolicyVersion の悪用

これは既存ポリシーに新しいバージョンを上書きする権限だ。攻撃者は既存の制限されたポリシーを読み取り、Action: "*" を含む強力なポリシーに書き換えて「有効化(SetDefaultPolicyVersion)」する。数秒で昇格完了だ。

—

2. 防御策:IAMポリシーの「最小権限」をコードで実現する

防御の鉄則は「リソースを制限すること」だ。Resource: "*" と書くのは、玄関の鍵を道端に置くのと同じことだ。

セキュアなポリシーの書き方(JSON)

以下の設定は、特定のロール以外には PassRole を許可しない、実務で使える鉄板の構成だ。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "RestrictPassRoleToSpecificRoles",
      "Effect": "Allow",
      "Action": "iam:PassRole",
      "Resource": [
        "arn:aws:iam::123456789012:role/App-Production-Role"
      ],
      "Condition": {
        "StringEquals": {
          "iam:PassedToService": "ec2.amazonaws.com"
        }
      }
    }
  ]
}
  • ポイント: Resource でロールを絞ることで、攻撃者が勝手なロールを作成・割り当てすることを物理的に不可能にする。

—

3. 実践:運用中の「昇格」を検知する Python スクリプト

インフラが巨大になると、誰がいつポリシーを変更したか追いきれない。AWS SDK(Boto3)を使って、不審なアクションを常時監視するスクリプトをCI/CDや定期実行ジョブに組み込むことを推奨する。

import boto3

# IAMクライアントの初期化
iam = boto3.client('iam')

def audit_policy_versions(policy_arn):
    """
    特定のポリシーに対し、許可されていないバージョン作成がないか確認する
    """
    versions = iam.list_policy_versions(PolicyArn=policy_arn)
    
    for version in versions['Versions']:
        # バージョンが多すぎる、または更新頻度が異常な場合はアラート
        if version['IsDefaultVersion'] == False:
            print(f"[!] 注意: 未使用のポリシーバージョンが存在します: {version['VersionId']}")
            # 運用ルール:不要なバージョンは即座に削除すべき
            # iam.delete_policy_version(PolicyArn=policy_arn, VersionId=version['VersionId'])

# 実行例
target_policy = "arn:aws:iam::123456789012:policy/UserManagementPolicy"
audit_policy_versions(target_policy)

—

4. 現場のセキュリティ担当者からの提言

「権限は、後から追加する」のが最も安全だ。

1. IAM Access Analyzer の活用: AWSが提供するこのツールは、外部からアクセス可能なリソースを自動で炙り出してくれる。これを使わずに寝るのは、家中の窓を開けっ放しで寝るようなものだ。
2. インラインポリシーの禁止: 管理が煩雑になり、意図しない権限昇格の温床になる。全て「マネージドポリシー」として切り出し、バージョン管理(Terraform等)下で運用せよ。
3. ガードレールの設定: Service Control Policies (SCPs) を使い、ルート組織レベルで iam:CreatePolicyVersion などを制限する。個別の開発者が頑張っても破れない「絶対領域」を構築するのが、組織を守る責任者の役割だ。

セキュリティとは、完璧な製品を買うことではなく、「攻撃者が嫌がる泥臭い設定を、愚直に積み重ねること」だ。

今回のポリシー設定、明日からの環境に反映できそうか? もし「面倒だ」と感じたら、その瞬間に君のシステムは脆弱になっている。コードを書くときと同じ熱量で、IAMポリシーも一行一行、丁寧に書いてくれ。期待している。

コメント

タイトルとURLをコピーしました