こんにちは!クラウドインフラやサーバーのセキュリティ、なんだか難しそうだな……と感じていませんか?
「ちゃんと設定したはずなのに、どこからか侵入されてしまった」
「開発者が便利に作業できるように権限を渡したら、それが原因で乗っ取りにあった」
現場の第一線でセキュリティを見ていると、こんな悲鳴をよく耳にします。特に、AWSなどのクラウド環境でよく使われる「IAM(Identity and Access Management)」という権限管理の仕組みは、一歩間違えると「泥棒に自宅の合鍵を勝手に複製されてしまうような状態」を作り出してしまいます。
今回は、新人のIT担当者や、これからセキュリティをしっかり学びたい開発者の皆さんに向けて、IAMの権限昇格(アタックパス)の恐ろしい手口と、それをピシャリと防ぐための具体的な防御策を、身近な例えを交えながら優しく紐解いていきますね。一歩ずつ、一緒に学んでいきましょう!
—
1. 身近な例えで理解する「IAM権限昇格」の恐怖
まずは、クラウドの権限管理を「マンションのセキュリティ」に例えて考えてみましょう。
あなたはこのマンションのオーナー(管理者)です。新しい管理人(開発者やアプリケーション)を雇うことになりました。
この管理人に「掃除用具入れ(特定のサーバー)を開ける鍵」を渡すのは当然ですよね。
しかし、ここでうっかり「合鍵を勝手に作る機械(ポリシーの作成権限)」や、「自分より偉い人の姿形に化けられる変装セット(PassRole)」を管理人に触れるようにしてしまったらどうなるでしょうか?
悪意ある第三者がその管理人の部屋に忍び込み、部屋の中にあった「合鍵作成機」を使って、マンション全体のマスターキーを勝手に作ってしまった……これが、クラウドの世界で起こる「権限昇格攻撃」の正体です。
攻撃者は、最初から「最強の権限」を持っているわけではありません。
最初は「ただの平社員(弱い権限)」としてシステムに侵入し、システムの中に転がっている「ちょっと危ない設定の隙」を巧みに組み合わせて、気づいた時には社長(管理者権限)になり代わってしまうのです。
—
2. 攻撃者が好んで使う「2つの裏口」
クラウドの現場で、攻撃者が特に好んで悪用する代表的な2つのパターンを見ていきましょう。怖がる必要はありません。仕組みを知れば、必ず対策できますからね!
パターンA:iam:PassRole を使った「身代わり乗っ取り」
iam:PassRole は、ざっくり言うと「自分が持っている権限を、別のサービス(例えばサーバーやLambdaなどのプログラム)に『はい、あげる!』と渡すことができる機能」です。一見すると、アプリケーションを動かすために必要な便利な機能なのですが……。
もし、権限が弱いはずの開発者が、「自分よりもはるかに強い権限(例: フルアクセス権限)」を別のサービスにパスできる状態になっていたらどうでしょう?
1. 攻撃者は、弱い権限を持つ開発者のアカウントを乗っ取る。
2. 攻撃者は、その権限を使って「強い権限を持ったサーバー(あるいは裏で動くプログラム)」を新しく起動する。その際、iam:PassRole で強い権限をそのサーバーにペタッと貼り付ける。
3. 攻撃者は、その新しく起動した「強い権限を持つサーバー」にログインし、やりたい放題暴れ回る。
自分が持っていない強い権限であっても、「人(サービス)に渡す権限」を持っているだけで、間接的にその強力な権限を手に入れてしまうという巧妙な手口です。
パターンB:iam:CreatePolicyVersion を使った「こっそりルール改ざん」
AWSの権限は「ポリシー」というルールブックで管理されています。
iam:CreatePolicyVersion は、そのルールブックの「新しいページ(バージョン)」を追加できる権限です。
「新しいページを追加できるだけなら、古いページが見られれば安全じゃない?」と思いますよね。ここが落とし穴です。
攻撃者はこの機能を使って、自分が持っているルールの「新しいバージョン」を作り、その中に「なんでもできる全許可(AdministratorAccess)」の記述をこっそり書き込むのです。そして、その新しいバージョンを有効化します。
一瞬にして、ただの一般ユーザーが、システム全体の最高権限者に早変わりしてしまいます。
—
3. 実践!安全なIAMポリシーの書き方と防御策
それでは、こうした「合鍵の勝手な複製」や「身代わりの悪用」を防ぐために、私たちはどのようなポリシーを書けばよいのでしょうか?
現場でそのまま使える、安全な設定のサンプルを見ていきましょう。
対策1:PassRole を使うときは「誰に」「どの権限を」渡すか厳格に縛る
Resource や条件(Condition)を省略して *(すべて許可)にしてしまうのが、セキュリティ事故の最大の原因です。
「誰にでも、どんな強力な権限でもパスしていいよ」という状態を絶対に作らないようにします。
以下は、特定の信頼できるサービス(例: Lambda)に対してのみ、特定の安全な役割(Role)だけをパスできるように制限したIAMポリシーの例です。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowPassSpecificRoleToLambdaOnly",
"Effect": "Allow",
"Action": "iam:PassRole",
// パスできるロールを特定のARN(識別子)を持つものだけに限定する
"Resource": "arn:aws:iam::123456789012:role/MyApplicationExecutionRole",
"Condition": {
"StringEquals": {
// この権限を受け取れるのは「Lambdaサービス」だけですよ、と厳しく縛る
"iam:PassedToService": "lambda.amazonaws.com"
}
}
}
]
}
対策2:ポリシーの作成・編集権限は「自分自身」に影響させない
iam:CreatePolicyVersion や iam:PutUserPolicy といった権限を与えるときは、「自分が持っている権限よりも強い権限を勝手に作れないようにする」ことが鉄則です。
開発者や一般ユーザーには、ポリシーの変更権限自体を渡さないのがベストですが、もしどうしても一部の管理作業で必要な場合は、ターゲットとなるリソースを最小限に絞り込みましょう。
以下は、自分自身の権限を昇格させるようなズルができないように配慮した、安全なポリシー設計の考え方を取り入れた例です。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowManagingOnlySpecificAppPolicies",
"Effect": "Allow",
"Action": [
"iam:CreatePolicyVersion",
"iam:SetDefaultPolicyVersion"
],
// システム全体のポリシーではなく、特定のプロジェクト用のポリシーだけに操作を限定する
"Resource": "arn:aws:iam::123456789012:policy/ProjectA-*"
}
]
}
このように、Resource に * を使わず、あらかじめ決められたプレフィックス(ProjectA-* など)を持つリソースだけに操作を限定することで、万が一アカウントが乗っ取られても、被害をそのプロジェクトの範囲内に最小限に食い止めることができます。
—
4. まとめ:一歩ずつ、安全なインフラを作っていこう
今回は、IAMの権限昇格攻撃の仕組みと、それを防ぐためのポリシーの書き方について解説しました。
- 権限昇格とは、弱い権限から「設定の隙」をついて強い権限へ成り代わる手口である。
iam:PassRoleは、誰に・何の役割を・どのサービスへ渡すのかをConditionやResourceで徹底的に絞り込む。- ポリシーの作成・編集権限(
iam:CreatePolicyVersionなど)は、決して*で野放しにせず、特定のスコープに限定する。
セキュリティの対策は、最初から完璧にやろうとすると息が詰まってしまいます。
まずは現在動いているシステムのIAMポリシーを開いて、「おっと、ここに * がついていないか?」と確認してみることから始めてみてください。
あなたのその小さな確認と丁寧な設定が、会社の大切なシステムとデータを守る最高の盾になります。一歩ずつ、確実に安全なインフラを作っていきましょう!
コメント