ペネトレーションしのべくん

さようなら、すべてのセキュリティエンジニア

IAMの権限昇格パスを修正してくれる「IAM-Deescalate」

はじめに

id:shinobe179です。先日、IAMの権限昇格パスを可視化してくれるPMapperを紹介しました。

shinobe179.hatenablog.com

今回は、そのPMapperを利用して、権限昇格パスの修正までしてくれる、IAM-Deescalateを紹介します。次世代ファイアウォールで名を馳せたパロアルト社製。

github.com

下準備

今回、わざと脆弱なIAMロールを2つ作って検証に臨みました。

  • ItsunoManikaDekitetaAdminRole
    • 権限昇格される側
    • AdministratorAccessポリシーが付与されている
    • プリンシパルとして自AWSアカウントIDが指定されている
  • UkkariDekitetaAdminNottoriRole
    • 権限昇格する側
    • ItsunoManikaDekitetaAdminRoleにAssumeRoleできるポリシーが付与されている
    • プリンシパルとしてec2.amazonaws.comが指定されている

この2つがPMapperで検出されるか試したところ、無事検出されました。私の想定では、UkkariDekitetaがアタッチされたEC2インスタンスを乗っ取ってAssumeRoleして……ということを考えていたのですが、更に別のロールからUkkariDekitetaを利用する手もあったみたいです。やっぱりPMapper便利ですね。

セットアップ

IAM-Deescalateの番です。まずはREADMEに従ってセットアップします。ちなみに、この手順でクローンしてきたPMapperは(gathering.pyを置き換えているせいで)通常のPMapperとしては利用できません。ご注意ください。私は10分ぐらいハマりました。

$ mkdir iam && cd iam
$ git clone https://github.com/nccgroup/PMapper.git
$ git clone https://github.com/PaloAltoNetworks/IAM-Deescalate.git
$ cp IAM-Deescalate/misc/gathering.py PMapper/principalmapper/graphing/gathering.py
$ cp IAM-Deescalate/misc/case_insensitive_dict.py PMapper/principalmapper/util/case_insensitive_dict.py
$ cd IAM-Deescalate
$ pip3 install -r requirements.txt

列挙

まずは audit サブコマンドで、管理者相当の権限を保有しているロール(PMapperで言うところのAdmin)と、それらへ権限昇格できそうなロールその他の列挙です。こちらでも、AdminとしてItsunoManikaが、それらへ至るロールのひとつとしてUkkariDekitetaが検出されています。

$ python3 iam_deesc.py audit

  _____          __  __        _____                 
 |_   _|   /\   |  \/  |      |  __ \                
   | |    /  \  | \  / |______| |  | | ___  ___  ___  ___ 
   | |   / /\ \ | |\/| |______| |  | |/ _ \/ _ \/ __|/ __|
  _| |_ / ____ \| |  | |      | |__| |  __/  __/\__ \ (__ 
 |_____/_/    \_\_|  |_|      |_____/ \___|\___||___/\___|

Auditing AWS account xxx ...
Principals with AdministratorAccess permissions:
    user/shinobe
    role/AWSCloudFormationStackSetExecutionRole
    role/cdk-xxx-cfn-exec-role-xxx-ap-northeast-1
    role/ItsunoManikaDekitetaAdminRole

Non-admin principals vulnerable to privilege escalation:
    role/AWSCloudFormationStackSetAdministrationRole
    role/cdk-xxx-deploy-role-xxx-ap-northeast-1
    role/UkkariDekitetaAdminNottoriRole

The audit output is stored at /home/cloudshell-user/work/iam/IAM-Deescalate/output/xxx/audit/privesc.json
You can exclude specific principals from the remediation process by removing them from the "privesc_principal" block.

$ 

修正案の作成

ここからはPMapperにない、IAM-Deescalate独自の機能です。planサブコマンドで、脆弱なIAMロールの修正案を作成してくれます。UkkariDekitetaについては、EffectをDenyにするという単純明快な案を提示してきました。今回、UkkariDekitetaのAssumeRoleは実はいらなかったという設定で、先に進みたいと思います。

$ python3 iam_deesc.py plan
Creating remediation plans for AWS account xxx ...
The remediation plans have been successfully created under /home/cloudshell-user/work/iam/IAM-Deescalate/output/xxx/plan/. Each file under this directory represents one vulnerable principal.
Please review the plans and mark "patch_me" to 1 for the policies to be applied.

$ cat /home/cloudshell-user/work/iam/IAM-Deescalate/output/xxx/plan/role/UkkariDekitetaAdminNottoriRole.json 
{
    "vulnerable_principal": "arn:aws:iam::xxx:role/UkkariDekitetaAdminNottoriRole",
    "reachable_admin_principals": {
        "arn:aws:iam::xxx:role/ItsunoManikaDekitetaAdminRole": [
            {
                "reason": "can access via sts:AssumeRole",
                "remediations": [
                    {
                        "policy": [
                            {
                                "Effect": "Deny",
                                "Action": [
                                    "sts:AssumeRole"
                                ],
                                "Resource": [
                                    "arn:aws:iam::xxx:role/ItsunoManikaDekitetaAdminRole"
                                ]
                            }
                        ],
                        "patch_me": 0
                    }
                ]
            }
        ]
    }
}$ 

修正案の反映

applyサブコマンドで、作成した修正案を実環境へ反映します。実行の前に、修正案の中のpatch_meを0から1にしておきます。どうやら、UkkariDekitetaに対してインラインポリシーをアタッチしたみたいです。念のため説明しておくと、IAMの世界において、明示的な拒否は他の何よりも優先されます。Adminへの権限昇格を許すようなアクションを拒否するポリシーを追加でアタッチすることで、元凶のポリシーを直接いじることなく無力化させられるわけですね。

$ python3 iam_deesc.py apply
Applying the remediation strategy for AWS account xxx ...
Inline policy has been successfully applied to role/UkkariDekitetaAdminNottoriRole
$ 

インラインポリシーできてる!すごいです。念のためauditサブコマンドで確認したところ、脆弱なロール一覧からUkkariDekitetaが消えていました。

修正の取り消し

revertサブコマンドでできます。必要な権限を消してしまった時も慌てずに。

$ python3 iam_deesc.py revert
Reverting the remediation strategy previously applied to AWS account xxx ...
Inline policy for role/UkkariDekitetaAdminNottoriRole has been deleted
$

おわりに

IAM-Deescalateを紹介しました。planapplyを本番環境で使えるかと言うとそんなことはなく、本番を模した検証環境でauditして脅威の確認、planおよびapplyデグレ含め確認をしたうえで、(同じツールでやるかは別として)本番の修正に着手……というユースケースが予想されます。もちろん脅威の修正が最優先ならば、本番環境で出たとこ勝負もあるのかもしれませんが、日頃からこういったツールで脅威分析をして、そういう状況にならないことが重要ですね。綺麗な着地。

検証のために作った2つのロール間になかなか権限昇格パスが認められなくて苦戦しました。IAMポリシーを書く機会が少ないので、いい勉強になりました。