簡単にGuardDutyの検知をテストするためにIAMの権限昇格をするスクリプト書いてみた

GuardDutyの検知テストを環境影響少なく簡単に実行するためにスクリプトを作りました。Finding type: PrivilegeEscalation:IAMUser/AdministrativePermissionsを検知できるはず!
2020.06.11

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、臼田です。

みなさん、AWSのセキュリティについて勉強していますか?(挨拶

今回は、GuardDutyを反応させる環境影響の少ない簡単なスクリプトが無いかなーと思って探しても見当たらなかったので、自分で権限昇格するPythonのスクリプトを書いたので共有します。

2021/08/24追記 現在この手法は「PrivilegeEscalation:IAMUser/AdministrativePermissions」がアーカイブされたため動作しません

背景

GuardDutyの通知をテストする方法は既存でもいくつかあります。しかしながら私は環境影響が少なく簡単なものが欲しかったのです。順に見ていきましょう。

デフォルトの結果サンプル

まず代表的なものはGuardDutyに元々備わっているGuardDuty 結果サンプルの生成機能を利用することです。

下記に手順が紹介してあります。(少しUIが古いですがほぼ一緒)

これはGuardDutyのコンソールからポチッと一発で使えるという非常にお手軽なテストなのですが、残念なのは「サポートされている検索タイプごとに 1 つの結果サンプル」が出力されるということです。つまり、メールとかSlackで通知の登録をしているとバコバコいっぱい通知が来てしまいます。つらい。

AWS Labsのテスター

GitHubのawslabs/amazon-guardduty-testerにてAmazon Guardduty Testerが公開されています。公式が用意してくれているちゃんとした(labsですが)テスターです。

CloudFormationのテンプレートが用意されていて、攻撃と防御のサーバーが立ち上がり、ログインしてスクリプトを実行すると5つの攻撃が実行されます。本格的!

でもこれもちょっと重たいですね。

脅威リストで検知

GuardDutyには脅威リストという、ブラックリストをユーザーで設定することが可能です。これにより任意のIPからのアクセスを脅威だと検知させることが可能です。お手軽です。

手順は下記で紹介されています。

リストを設定するだけなので簡単といえば簡単です。でもIPリストはS3にアップロードしないといけません。

あとなんと言ってもブラックリストを汚したくないですね…環境に手を加えたくないのです。

つまりいいテスターがない

無いなら自分で作ればいいじゃない。

スクリプト作った

というわけで作りました。

コンセプトとしては、環境影響がなるべく無いこと。

EC2関連の検知だとEC2を立てたりしないといけないので、IAMの権限昇格にしました。フロートしては下記のようになっています。実行する側はAdminを持っている想定です。

  • IAMユーザーを作成する(名前に日時を入れて重複エラーにならないようにする)
  • IAMユーザーにIAMFullAccessをアタッチする
  • アクセスキーを作成する
  • 作成したIAMユーザーで自身にAdministratorAccessをアタッチする
  • IAMユーザーを削除する

これで少なくともFinding type: PrivilegeEscalation:IAMUser/AdministrativePermissionsが検知されます。(多分)

とりあえず手元で検証している限りではうまく動いて検知してくれるようになったので公開します。実行環境はPython 3.7.4です。

from datetime import datetime
import time
import boto3

admin_policy = "arn:aws:iam::aws:policy/AdministratorAccess"
iamfull_policy = "arn:aws:iam::aws:policy/IAMFullAccess"

name = 'test-user-' + datetime.now().strftime('%Y%m%d%H%M%S')

iam = boto3.resource('iam')
user = iam.User(name)

# create test user
user.create()
print("[+] User Created.")
print("[+] User name: " + user.user_name)
access_key = user.create_access_key_pair()
user.attach_policy(
	PolicyArn=iamfull_policy
)
print("[+] AccessKey Created.")
print("[+] Wait 10s...")
time.sleep(10)

# privilege escalation
tmp_iam = boto3.resource('iam', aws_access_key_id=access_key.id, aws_secret_access_key=access_key.secret, aws_session_token=None)
tmp_user = tmp_iam.User(name)
tmp_user.attach_policy(
	PolicyArn=admin_policy
)
print("[+] Privilege escalation Complete.")

# delete test user
user.detach_policy(
	PolicyArn=iamfull_policy
)
user.detach_policy(
	PolicyArn=admin_policy
)
access_key.delete()
user.delete()
print("[+] User Delete Complete.")

途中でsleepしているのは作成してすぐにアクセスキーを利用しようとすると、時刻のズレからエラーになったためです。NTP合わせているのにどうしようもならなかったのではさみました。

実行すると下記のようにアラートしてくれました。

(この通知はChatbotを利用してSlack通知したものです。きれいに表示されて最高ですね!詳細は新しくリリースされたAWS Chatbotを使ってGuardDutyのSlack通知をするといいよって話)

この時は実行から26分くらいで検知してくれています。まあ大体の検知はこんなもんですね。すぐ飛ばしたいだけならサンプルが一番早いかもしれません。

場合により、Finding type: Recon:IAMUser/UserPermissionsが一緒に検知されるかもしれません。この辺はブラックボックスなのでよくわからないですね。

ただ権限昇格しているので、その分は出ると思います。

スクリプトの通りユーザーはすぐに削除しても適切に検知してくれました。原理としてはCloudTrailのログを見ているだけなので、リソースが残っているかは関係ないんですね。

もしスクリプトが途中で失敗したら手動でユーザーの削除などしてください。

あとはもちろん、今後もずっと検知してくれたりする保証とかも無いのと、動作保証できるわけではないので、スクリプトの活用は自己責任でお願いします。

まとめ

GuardDutyのテストを環境影響を与えないように簡単に実行するために、IAMの権限昇格をするPythonスクリプトを書いてみました。

自分用に作りましたが、役に立ったらうれしいでーす。