こんにちは!レッドチームエンジニアの皆さん、そしてセキュリティに興味を持つすべての開発者さん、IT担当者さん!
突然ですが、皆さんの「家」を守る上で一番大切なものは何だと思いますか?そう、多くの方が「鍵」だと答えるのではないでしょうか。鍵がなければ、どんなに頑丈な扉や窓も、泥棒にとってはただの飾りですよね。
これ、実はクラウドの世界でも全く同じなんです。皆さんが日々触れているAWSやGCP、Azureといったクラウドサービスも、その実態は巨大なコンピュータの集合体。そして、そこに保存されたデータや動いているシステムを守る「鍵」が、とんでもなく重要になります。
今回は、そのクラウドの「鍵」の中でも、特に攻撃者に狙われやすい「一時的なアクセスキー」に焦点を当てて、その悪用手口と、私たち守る側がどうやって異常を検知し、対応すべきかを、親しみやすい言葉で徹底解説していきます。
「セキュリティって小難しそう…」と感じる方も大丈夫!家の鍵や防犯の仕組みに例えながら、一歩ずつ一緒に学んでいきましょう!
—
【セキュリティ入門】クラウドの「一時的な鍵」が狙われる!漏洩したアクセスキーからシステムを守る攻撃と検知のリアル
第1章: その「一時的な鍵」、泥棒に狙われていませんか? – アクセスキー悪用のメカニズム
まずは、クラウドの「鍵」がどんなもので、なぜそれが泥棒(攻撃者)に狙われるのか、そのメカニズムから見ていきましょう。
1-1. クラウドの「鍵」って何?:IAMとアクセスキーの基本
皆さんがAWSを使う際、「このサービスは誰が使えるの?」「このデータは誰が見れるの?」という疑問が湧きますよね。それを管理するのが、IAM(Identity and Access Management)というサービスです。
IAMは、例えるなら「身分証明書」と「その身分で何ができるか」という権限のセットを管理する警察署のようなもの。
- IAMユーザー: 個人やアプリケーションに与えられる「身分証明書」です。パスワードや、後述するアクセスキーを持ちます。
- IAMロール: これはちょっと特殊で、「一時的に借りられる身分証明書」と考えるとわかりやすいかもしれません。例えば、EC2インスタンスがS3にアクセスしたいとき、直接IAMユーザーの鍵を持つのではなく、IAMロールを「まとう」ことで、そのロールが持つ権限を使ってS3にアクセスします。
そして、このIAMユーザーやIAMロールが、プログラムからAWSのサービスを操作するために使うのがアクセスキーです。これは、AKIA...で始まる「アクセスキーID」と、それに紐づく秘密の文字列「シークレットアクセスキー」のペアで構成されます。
まるで、あなたの家の玄関の鍵と合鍵のセット、といったイメージですね。この鍵があれば、AWSのAPIを叩いて、S3のファイルを読み書きしたり、EC2インスタンスを起動したり、データベースにアクセスしたり…といった操作が可能になります。
特に重要なのは、IAMロールが発行する「一時的なアクセスキー」です。これは、AssumeRoleという操作を行うことで取得でき、有効期限が設定されています(数分〜数時間)。「一時的だから安全」と思われがちですが、この「一時的」な鍵であっても、ひとたび泥棒の手に渡れば、その有効期間中は家の中を荒らされる危険があるんです。
1-2. 泥棒が「鍵」を手に入れたら?:漏洩からの攻撃シーケンス
では、もしこのアクセスキー(家の鍵)が泥棒の手に渡ってしまったらどうなるでしょうか?
よくある漏洩経路としては、以下のようなものがあります。
- GitHubなどの公開リポジトリ: 開発者が誤ってコード内にアクセスキーをハードコードしてコミットしてしまい、公開リポジトリにプッシュしてしまうケースは後を絶ちません。
- S3バケットの誤設定: アクセスキーを含む設定ファイルやログファイルが、誤って公開設定のS3バケットにアップロードされてしまう。
- 開発者のローカルPC: マルウェア感染やフィッシング詐欺により、開発者のPCからクレデンシャル情報が盗まれる。
- ログファイル: アプリケーションのログにデバッグ目的でアクセスキーが出力され、それが外部に漏れる。
攻撃者(泥棒)は、漏洩したアクセスキーを手に入れると、まず何をすると思いますか?
そう、いきなり派手に暴れるのではなく、まずは「情報収集」から始めます。
1. 足場の確認(get-caller-identity):
泥棒はまず、手に入れた鍵がどの家のものか、誰の鍵かを確認します。
# 現在のアクセスキーが誰のものか、どんな権限を持っているかを確認
aws sts get-caller-identity
これで、アカウントID、ユーザー/ロールのARN(Amazon Resource Name)がわかります。
2. 権限範囲の調査(list-roles, list-users, get-policyなど):
次に、この鍵でどこまでできるのか、家の中のどこまで入れるのかを調べます。
例えば、aws iam list-rolesで他のロールを列挙したり、aws s3 lsでS3バケットの一覧を取得したりします。
「この鍵、もしかしたら他のもっと権限の強い鍵を借りる権限があるんじゃないか?」と、iam:PassRoleやsts:AssumeRoleなどの権限を血眼になって探し、権限昇格を狙います。これが成功すると、泥棒はさらに奥の部屋に入れるようになります。
3. データ窃取(s3 cp, rds download-db-log-fileなど):
権限が確認できたら、いよいよ本命のデータ窃取です。
S3に保存されている機密ファイル、データベースのスナップショット、ログファイルなどを、自身の管理するストレージにコピーしたり、外部に持ち出したりします。
# 攻撃者がS3バケットの内容を自身のS3バケットにコピーする例
aws s3 cp s3://[ターゲットの機密バケット名]/secret_data.zip s3://[攻撃者のS3バケット名]/secret_data.zip --recursive
もしS3バケットのポリシーを操作できる権限があれば、バケットをパブリック公開して一気にデータを持ち出す、なんて荒業も可能です。
4. リソース悪用(ec2 run-instances, ses send-emailなど):
データだけでなく、クラウドのリソースそのものも悪用の対象になります。
- 仮想通貨マイニング: 高性能なEC2インスタンスを大量に起動し、勝手に仮想通貨のマイニングを行います。これは利用料が跳ね上がる直接的な被害につながります。
- スパムメール送信: SES(Simple Email Service)などのメール送信サービスを使って、大量のスパムメールを送信します。
- システム破壊: 無関係なリソースを削除したり、セキュリティ設定を変更したりして、システムを停止・破壊することもあります。
恐ろしいですよね。たった一つのアクセスキーが漏れるだけで、これだけの被害が出る可能性があるんです。まさに、家の鍵が泥棒の手に渡り、家中を物色され、貴重品を盗まれ、さらには家をめちゃくちゃにされる…といった状況に似ています。
第2章: 泥棒の足跡を見つける! – 異常なアクセスパターンの検知
泥棒に侵入されてしまったら、次はその足跡を見つけて、何が起こったのか、どうやって侵入されたのかを突き止め、そして泥棒を追い出す必要があります。クラウドの世界では、「防犯カメラ」と「警報システム」を使ってこれを実現します。
2-1. クラウドの「防犯カメラ」と「警報システム」:ログとGuardDuty
AWSには、皆さんのアカウント内で発生したすべてのAPIコールやイベントを記録してくれる「CloudTrail」というサービスがあります。これは、まさに「誰が、いつ、どこから、何をしたか」を記録する防犯カメラの映像そのものです。何かあった時に真っ先に確認すべき、非常に重要な情報源になります。
しかし、この膨大なCloudTrailのログを人間が一つ一つ監視するのは現実的ではありません。そこで登場するのが、AWSの強力な警報システム「Amazon GuardDuty」です!
GuardDutyは、機械学習や脅威インテリジェンス(既知の攻撃パターン情報)を活用して、皆さんのAWSアカウント内の異常なアクティビティを自動で検知してくれます。例えるなら、家の周りや家の中に設置されたAI警備員ですね。普段とは違う動きや、不審な人物の気配を察知すると、すぐに警報を鳴らして教えてくれる、そんなイメージです。
2-2. GuardDutyで「不審者」を見つけるには?:具体的な検知例
GuardDutyは、以下のようなさまざまなタイプの「不審な行動」を検知してくれます。
- 異常な地理的場所からのアクセス:
普段は日本からしかアクセスがないのに、突然、攻撃者がよく利用する海外のIPアドレスからアクセスキーが使われた場合など。
「家の鍵が、見知らぬ遠い国で使われているぞ!」と警報を鳴らします。
- 異常なAPIコールパターン:
普段はS3にファイルをアップロードするだけのアプリケーションが、急に大量のEC2インスタンスを起動しようとしたり、IAMポリシーを変更しようとしたりする場合など。
「いつもは玄関から入るだけなのに、急に裏口を壊そうとしているぞ!」と異常を知らせます。
- 資格情報が漏洩した可能性:
GuardDutyは、ダークウェブや公開されたリポジトリなどから漏洩したクレデンシャル情報と皆さんのアクセスキーを照合し、一致するものがあれば即座に警告します。
「あなたの家の鍵が、泥棒たちの間で取引されている痕跡があるぞ!」と教えてくれるわけです。
GuardDutyの有効化と設定例
GuardDutyの有効化はとても簡単です。AWSマネジメントコンソールからGuardDutyのサービスページにアクセスし、「GuardDutyの有効化」ボタンをクリックするだけです。
CLIで有効化する場合は、以下のコマンドを実行します。
# GuardDutyを有効化します。
# detector-id が返されるので、控えておきましょう。
aws guardduty create-detector --enable
# 特定のデータソース(S3ログなど)の保護を有効化します。
# これにより、S3へのアクセスログも監視対象となり、不審なS3アクセスを検知しやすくなります。
# <your-detector-id> は上記コマンドで取得したIDに置き換えてください。
aws guardduty update-detector --detector-id <your-detector-id> --data-sources 'S3Logs={Status=ENABLED}'
これだけで、GuardDutyはアカウントの監視を開始し、異常を検知すると「Findings(検出結果)」として通知してくれます。
2-3. CloudTrailで「泥棒の具体的な行動」を追う
GuardDutyが「警報」を鳴らしたら、次はCloudTrailの「防犯カメラの映像」を詳しく見て、泥棒が具体的に何をしたのか、その足跡を追跡します。
調査シナリオ例:
1. GuardDutyが検出: CredentialAccess:IAMUser/AnomalousBehavior (IAMユーザーの異常な振る舞い)が検出されたとします。これは「誰かの鍵が漏洩して、いつもと違う動きをしている!」という警報です。
2. CloudTrailで検索: GuardDutyの検出結果には、通常、関連するAccessKeyIdやSourceIPAddressが含まれています。これらを手がかりにCloudTrailのイベント履歴を検索します。
- 検索クエリの例(CloudTrailコンソール):
- イベントソース:
s3.amazonaws.com(S3へのアクセスを確認) - イベント名:
GetObjectまたはPutObject(ファイルの読み書きを確認) - ユーザー名:
dev-user(特定のユーザーの活動を確認) AccessKeyId:AKIAXXXXXXXXXXXXXXXX(GuardDutyで特定された漏洩キー)SourceIPAddress:203.0.113.42(GuardDutyで特定された不審なIP)
これで、そのアクセスキーがいつ、どこから、どんなAPIを叩いたか、具体的な「泥棒の行動」を特定できます。
CloudTrailログの例と見方:
以下は、CloudTrailログの抜粋です。どこに注目すべきか、日本語のコメントで説明しますね。
{
"eventVersion": "1.08",
"userIdentity": {
"type": "IAMUser",
"principalId": "AIDACKCKCKCKCKCKCKCKC",
"arn": "arn:aws:iam::123456789012:user/dev-user",
"accountId": "123456789012",
"accessKeyId": "AKIAXXXXXXXXXXXXXXXX", // ★ GuardDutyで指摘された漏洩キー!
"userName": "dev-user" // このキーが誰のキーだったか
},
"eventTime": "2023-10-27T10:00:00Z", // イベント発生時刻
"eventSource": "s3.amazonaws.com", // ★ S3サービスへのアクセスだ!
"eventName": "GetObject", // ★ GetObject (オブジェクトの取得) をしている!
"awsRegion": "ap-northeast-1",
"sourceIPAddress": "203.0.113.42", // ★ 不審な海外のIPアドレス!
"userAgent": "aws-cli/2.9.0 Python/3.9.13 Linux/5.10.102-linuxkit", // どんなツールでアクセスしたか
"requestParameters": {
"bucketName": "sensitive-data-bucket", // ★ 機密データが入っていそうなバケット名!
"key": "secret.txt" // ★ 盗まれたファイル名!
},
"responseElements": null,
"requestID": "SOME_REQUEST_ID",
"eventID": "SOME_EVENT_ID",
"readOnly": true, // 読み取り操作かどうか
"resources": [
{
"arn": "arn:aws:s3:::sensitive-data-bucket",
"accountId": "123456789012",
"type": "AWS::S3::Bucket"
}
],
"eventType": "AwsApiCall",
"managementEvent": true,
"recipientAccountId": "123456789012",
"eventCategory": "Management",
"tlsDetails": {
"tlsVersion": "TLSv1.2"
}
}
このログから、「dev-userのAKIAXXXXXXXXXXXXXXXXというアクセスキーが、普段使わない203.0.113.42というIPアドレスから、sensitive-data-bucketという機密バケット内のsecret.txtファイルをダウンロードした!」という具体的な事実が判明します。まさに、防犯カメラの映像が決定的な証拠となる瞬間ですね。
2-4. 泥棒を追い出す!:インシデントレスポンスの初動
泥棒の行動が特定できたら、一刻も早く対処する必要があります。
1. アクセスキーの失効(即時対応!):
最も重要なのは、漏洩したアクセスキーを直ちに無効化することです。これにより、泥棒はそれ以上、その鍵を使ってシステムを操作できなくなります。
# 漏洩したアクセスキーを無効化(非アクティブ化)します。
# <your-access-key-id> には漏洩したアクセスキーIDを指定してください。
# <your-username> には該当のIAMユーザー名を指定してください。
aws iam update-access-key --access-key-id <your-access-key-id> --status Inactive --user-name <your-username>
# もしくは、完全に削除します。(完全に削除すると元に戻せません)
# aws iam delete-access-key --access-key-id <your-access-key-id> --user-name <your-username>
AWSマネジメントコンソールからも、IAMユーザーのページでアクセスキーを選択し、「無効化」または「削除」が可能です。
2. 影響範囲の確認と削除:
- そのアクセスキーで、他にどんなリソースが作成・変更されたか?(例: 不審なEC2インスタンス、新しいIAMユーザー/ロール、S3バケットのパブリック設定変更など)
- データが外部に持ち出されていないか?持ち出された場合は、そのデータの内容や影響度を評価します。
- 不審なリソースは速やかに停止・削除しましょう。
3. 権限の見直し:
漏洩したアクセスキーに、なぜ過剰な権限が付与されていたのかを検証し、最小権限の原則(Principle of Least Privilege)に基づき、必要な権限のみに絞り込むように IAM ポリシーを修正します。
これらのステップは、まさに泥棒を家から追い出し、荒らされた家を元に戻し、二度と侵入されないように防犯対策を見直す作業と同じです。
第3章: そもそも「鍵」を盗まれないために – 事前防御のベストプラクティス
攻撃を受けてからの対処も大切ですが、何よりも「鍵を盗まれないこと」が一番ですよね。ここでは、泥棒に狙われないための事前防御策をいくつかご紹介します。
3-1. 鍵は厳重に管理しましょう
- GitHubなどへのハードコーディング禁止!
これが最も多い漏洩経路です。コードの中にアクセスキーを直接書き込むのは絶対にやめましょう。
代わりに、環境変数、AWS Secrets Manager、AWS Systems Manager Parameter Storeなどのセキュアな方法で管理してください。
# 悪い例: コードに直接アクセスキーを記述
# s3_client = boto3.client('s3', aws_access_key_id='AKIAXXXXXXXXXXXXXX', aws_secret_access_key='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
# 良い例: 環境変数から読み込む
import os
import boto3
# 環境変数 AWS_ACCESS_KEY_ID と AWS_SECRET_ACCESS_KEY に設定されていることを想定
s3_client = boto3.client('s3')
# さらに良い例: IAMロールを利用する(EC2インスタンスなどから)
# この場合、アプリケーションコード内で直接クレデンシャルを指定する必要はありません。
# EC2インスタンスにIAMロールをアタッチしておけば、自動的に一時的なクレデンシャルが提供されます。
# s3_client = boto3.client('s3') # これだけでOK!
- IAMロールの積極的な利用:
EC2インスタンスやLambda関数など、AWSサービスが別のAWSサービスにアクセスする必要がある場合は、IAMユーザーのアクセスキーを直接設定するのではなく、IAMロールを利用しましょう。
IAMロールは、サービスに一時的な権限を付与する仕組みなので、アクセスキーが漏洩するリスクを大幅に減らせます。これは、家に泥棒を入れずに、必要な時だけ警備員に許可証を渡して中に入ってもらうようなものです。
- 最小権限の原則 (Principle of Least Privilege) の徹底:
IAMユーザーやIAMロールに付与する権限は、そのユーザーやサービスが本当に必要な最小限のものに絞り込みましょう。
「念のため全部許可しておこう」という安易な設定は、漏洩時の被害を最大化してしまいます。
例えば、S3の読み取りだけ必要なのに、S3のフルアクセス権限を与えてはいけません。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::your-data-bucket",
"arn:aws:s3:::your-data-bucket/*"
]
}
]
}
これは、「your-data-bucketというS3バケットからオブジェクトを読み取ったり、バケット内のリストを見たりすることだけ許可する」という最小限の権限ポリシーの例です。
3-2. 定期的な鍵の交換(ローテーション)
長期間同じアクセスキーを使い続けるのは危険です。定期的にアクセスキーを交換(ローテーション)する習慣をつけましょう。万が一、過去に漏洩していたとしても、ローテーションしていれば被害を防げることがあります。
これは、定期的に家の鍵を交換するようなものです。
3-3. 多要素認証(MFA)の徹底
IAMユーザーには必ず多要素認証(MFA)を有効にしましょう。パスワードだけでなく、スマホの認証アプリなどで発行されるワンタイムパスワードも入力しないとログインできないようにする仕組みです。
万が一パスワードが漏洩しても、MFAがあれば不正ログインを防ぐことができます。これは、鍵だけでなく、暗証番号も必要になる二重ロックのようなものです。
3-4. セキュリティ意識の向上
そして最後に、最も重要と言っても過言ではないのが、私たち一人ひとりのセキュリティ意識の向上です。
どれだけ優れたツールや設定があっても、使う人が「これくらいなら大丈夫だろう」と油断してしまえば、そこが攻撃の穴となってしまいます。
チーム全体でセキュリティベストプラクティスを共有し、定期的なセキュリティ教育を行うことで、ヒューマンエラーによる漏洩リスクを最小限に抑えましょう。
—
まとめ
皆さん、今回はクラウドにおける「一時的なアクセスキー」の悪用と検知について、泥棒と家の鍵の例えを交えながら、攻撃シーケンスから防御策まで幅広く見てきました。
- アクセスキーはクラウドの「鍵」であり、特に「一時的な鍵」であっても漏洩すれば大きな被害につながる可能性があること。
- 攻撃者は鍵を手に入れると、まず情報収集から始め、権限昇格を狙い、最終的にデータ窃取やリソース悪用を行うこと。
- GuardDutyというAI警備員が異常を検知し、CloudTrailという防犯カメラの映像で泥棒の具体的な行動を追跡できること。
- インシデント発生時は、速やかなアクセスキーの失効と影響範囲の特定・対処が重要であること。
- そして何より、鍵の厳重な管理(GitHubへのプッシュ禁止、IAMロールの利用、最小権限)、定期的なローテーション、MFAの徹底、そしてセキュリティ意識の向上が最大の防御策になること。
セキュリティは、一度設定したら終わり、というものではありません。常に変化する脅威に対して、私たちも学び続け、対策を更新し続ける必要があります。
この記事が、皆さんのクラウドセキュリティ強化の一助となれば幸いです。小難しいと思われがちなセキュリティも、こうして一歩ずつ学んでいけば、必ず身につきます。
さあ、私たちと一緒に、安全なクラウド環境を築いていきましょう!
コメント