Slide 1

Slide 1 text

KomeKaigi 2026 (October 31, 2026) 攻撃 3 時間 vs 復旧 10 時間。 アクセスキー流出の非対称性を体感するために CTF を作った話 Speaker : @kazzpapa3(ICHINO Kazuaki)

Slide 2

Slide 2 text

本日のキーワード 用語 ざっくり言うと AWS アカウント AWS を使うための契約単位。サーバーやデータなどのリソースはすべてこの中に作られる 「クラウド上の自分専用の区画」 API プログラムから AWS を操作するための窓口。画面(コンソール)でのクリック操作も、裏 側ではすべて API 呼び出し クレデンシャル(認証情 報) AWS に「自分は誰か」を証明する情報の総称。パスワードやアクセスキーなど IAM(ユーザー / ロール / ポリシー) 「誰が・何をしてよいか」を管理する仕組み。ユーザーは ID、ロールは一時的に借りる権 限の役割、ポリシーは許可・禁止のルール アクセスキー プログラムから AWS を操作するための ID とシークレットの組(API キー相当)。有効期 限がなく、削除するまで使え続けるため、漏れると第三者に使われ続ける 一時認証情報 数分〜数時間で自動的に無効になる認証情報。漏れても被害の時間を限定でき、現在はこち らが推奨 CloudTrail 「いつ・誰が・どの API を実行したか」を記録し続けるサービス。いわば監視カメラの録 画で、被害調査はこのログを読み解くことになる CTF(Capture The Flag) セキュリティの知識や技術を競うゲーム形式の競技。問題の中に隠された答えの文字列(フ ラグ)を見つけて提出すると得点

Slide 3

Slide 3 text

Biography { "Bio": { "Name": "ICHINO Kazuaki a.k.a. kazzpapa3", "Organization": "A certain AWS partner company", "Role": "Technical Support Engineer", "Favorite AWS Services": [ "AWS CLI", "AWS CloudTrail", "Kiro CLI" ], "Less Favorite People (as a Support Engineer)": [ "クレデンシャル情報を雑に扱う人" ], "Personal Interest": "初音ミク", "Socials": { "Twitter/X": "@kazzpapa3", "LinkedIn": "https://www.linkedin.com/in/kazzpapa3/" } } }

Slide 4

Slide 4 text

Who ? 何をしている人 ? @kazzpapa3 / #KomeKaigi 4 / 40

Slide 5

Slide 5 text

AWS のパートナー企業でテクサポをやっています お客様 - 弊社 - Amazon Web Services(AWS)という関係性で AWS アカウントをお客様へ再販しています 契約関係上、お客様は AWS への直接的なパスを持たないので、弊社が 代わりにサポート窓口を設け、AWS になりかわって技術サポートを行 います お客様からの問い合わせに対して、「公式ドキュメントで仕様が公開さ れているか」「発生事象の再現性があるか」を確認し、AWS に聞くし かない、となった時点で AWS Support に問い合わせをしています @kazzpapa3 / #KomeKaigi 5 / 40

Slide 6

Slide 6 text

基本的に弊社を介することとなる 弊社(リセラー) お客様 AWS アカウント お問い合わせ AWS 上記の構図となるため、AWS から届く通知も弊社を通ることになる 不正な利用が疑われる事象が AWS からの E メールや AWS が起票する サポートケース(アウトバウンドケース)として届く そのため、私の所属部署での、問題発生の把握に繋がっている @kazzpapa3 / #KomeKaigi 6 / 40

Slide 7

Slide 7 text

昨今、アクセスキーの不正利用が本当に多い スパムメールの配信元 としてや DoS 攻撃など悪事に加担するケース 情報の改変や削除、持ち出しによる漏えい アクセスキーをはじめとした永続的なキーの不正利用による利用料高騰 流出したキーに付与されている権限に応じ影響の大小が大きく異なる 調査範囲が広がり、修復時の対応範囲の広さにも繋がっている 過去の私の対応では、攻撃者の仕込みは約 17 分、不正リソースが出来 上がりきるまで 3 時間ほどだった事象に対し、封じ込めから不正リソー スの削除まで 10 時間ほど要した例もあった @kazzpapa3 / #KomeKaigi 7 / 40

Slide 8

Slide 8 text

作成経緯やモチベーション アクセスキーの流出の調査や封じ込めの支援などを通じて、犯行者の一 定の行動が見えてきていた もしかしたら Kiro など生成 AI では、攻撃者の多くが行う行動を、既 知の手法としてそれらを理解しているかも?と考えた 別界隈 で CTFd という OSS があることを知ったので簡単に作れるか もしれない、という期待 Kiro CLI を利用して Vibe Coding 的に作ってみよう! そして、漏れたキーを使って 第三者によって行われた API 実行を客観 的に調査することの難しさ、めんどくささを体験してもらいたい! @kazzpapa3 / #KomeKaigi 8 / 40

Slide 9

Slide 9 text

開発初期に投入したプロンプト @kazzpapa3 / #KomeKaigi “ “CTFd を用いて、アクセスキー流出事例をテーマとした CTF ゲーム環 境を作りたい 流出したキーの特定から封じ込め、犯行者に実行されたアクションの 特定を行うシナリオで CloudTrail のログを解析してフラグを検索ある いは結合し回答する形式にしたいです 9 / 40

Slide 10

Slide 10 text

出来上がったモックアップ Terraform で出来上がる AWS 環境を使った仕組みができた 合わせて作成されたセットアップスクリプトによって、CloudTrail の ログを模した json ファイル群を作成、S3 バケットにアップロード し、CTF のフラグの検索用の元ソースとして利用する形となっていた 問題の作成もセットアップスクリプトで行うように定義されており、 ctfcli で CTFd 環境にチャレンジをインストールする形式も出来上がっ ており、ほぼ修正なしで利用できる状況だった @kazzpapa3 / #KomeKaigi 10 / 40

Slide 11

Slide 11 text

問題の作成も AI がやってくれた また、問題についても Kiro CLI が作成してくれており、このゲームを 用いたコミュニティイベントを実施した際のバージョンでも 7 割ほどは Kiro CLI が作成した問題を採用した 作成された問題は、実際の事象発生中に見かける攻撃手法であったこと から採用した このことからも 生成 AI も理解している、広く知られた攻撃手法 な のだと再認識した 最初の Kiro CLI へのプロンプト実行から 3 時間程度で実際に遊べる状 況まで仕上がっており、一度所属企業内で遊んでみている @kazzpapa3 / #KomeKaigi 11 / 40

Slide 12

Slide 12 text

モックができたころの様子 当時は 20 問だったよう この後、社内有志むけにゲーム大会を開催 して、手応えと修正ポイントを踏まえ改良 に進みます @kazzpapa3 / #KomeKaigi 12 / 40

Slide 13

Slide 13 text

改良 @kazzpapa3 / #KomeKaigi 13 / 40

Slide 14

Slide 14 text

その 1 - スケーラビリティを向上させたい EC2 インスタンス1台で CTFd を稼働させる構成となっており、デー タベースには CTFd 既定の SQLite を使用することとなっていた 多人数でゲームを行う場合にボトルネックになる可能性があり、Kiro CLI に性能評価を求めてみると以下のような回答が得られた @kazzpapa3 / #KomeKaigi 14 / 40

Slide 15

Slide 15 text

その 1 - Kiro の回答 “SQLite の特性 読み取りは複数同時に可能だが、書き込みはデータベース全体をロ ックする(WAL モードでも writer は1つ) CTFd はフラグ提出のたびに INSERT が走るので、同時提出が集中 @kazzpapa3 / #KomeKaigi “ するとロック待ちが発生する 15 / 40

Slide 16

Slide 16 text

その 1 - Kiro の回答 “現実的な目安 体感 ~10人 問題なし 10〜30人 ほぼ問題ないが、一斉提出時に稀に数百ms の遅延 30〜50人 スコアボード表示やフラグ提出で体感できる遅延が出始める 50人〜 外部 RDS を使うことを推奨する @kazzpapa3 / #KomeKaigi “ 参加者数 16 / 40

Slide 17

Slide 17 text

その 1 - Kiro の回答 “ボトルネックになるポイント 1. フラグ提出: INSERT + 正誤判定。一斉に提出が集中する競技開始 直後やヒント公開直後が最も負荷が高い 2. スコアボード: 全チームのスコアを集計する SELECT。参加者が増 えるとクエリが重くなり、かつ書き込みロックと競合する 3. CTFd 自体が Gunicorn (デフォルト1 worker): SQLite のロック @kazzpapa3 / #KomeKaigi “ 以前に、アプリケーションレベルの並列処理能力が限定的 17 / 40

Slide 18

Slide 18 text

その 1 - Kiro の提案 Kiro に対して「スケールしやすくかつサーバレスでも環境をデプロイ できるようにしたい」と伝えたところ、「デプロイモード」として 「EC2 モード」と「Fargate モード」を作りましょう、と言ってくれ て、これもほぼ一発で動作するようにしてくれた デプロイモードの切り替えも Terraform の terraform.tfvars で ctfd_mode 変数に定義するだけの簡単設定にしてくれるなど、いい感 じにやってくれた @kazzpapa3 / #KomeKaigi 18 / 40

Slide 19

Slide 19 text

その 2 - よりリアリティを出す スケーラビリティは向上しましたが、CloudTrail のログを S3 からダウ ンロードしてローカルで調査するとなると、 cat *.json | jq 祭り、 grep 祭りになってしまうなという気がした どうせなら AWS アカウント内でちゃんとログが出ている方が良いが、 私が思いつく方法も Kiro に聞いた結果も、結局実際の API 実行をする しかなさそうだった 結局、実際に攻撃して AWS API の履歴を CloudTrail に残して、 CloudTrail のログを確認するための API 操作をやることで解析できる 形とした @kazzpapa3 / #KomeKaigi 19 / 40

Slide 20

Slide 20 text

改良 1 , 2 により実現できるようになったこと 1. S3 バケットにある CloudTrail のログをダウンロードし、手元で解析を 行う 2. AWS アカウントにコンソールログインして GUI で CloudTrail を調 査、解析を行う 3. AWS アカウントに AWS CLI 経由でアクセスし、CLI で CloudTrail の 調査、解析を行う 4. 上記のいずれの手法でも AI Agent に壁打ちしたり、自律的な調査を AI にやってもらうこともできるようになった @kazzpapa3 / #KomeKaigi 20 / 40

Slide 21

Slide 21 text

その 3 - 参加者向けガイドドキュメントの自動生成 セキュリティ界隈の方だと CTF(Capture The Flag)というものにつ いての一定の理解はあるかもしれませんが、JAWS 界隈ではあまり見聞 きしたことがなく、私も別界隈で初めて知った感じ そのため、「フラグ」というものがどのようなものかの解説と、ゲーム の中で何を問われているか、何を見つけて回答すればいいのか、などの 説明も必要だと感じた そのため、基本的に定型化しておき、CTFd のゲーム環境が構築される と同時に、参加者向けのドキュメントも自動生成させることを目指した @kazzpapa3 / #KomeKaigi 21 / 40

Slide 22

Slide 22 text

ここまででできるようになったこと 1. Terraform Deploy Flow terraform.tfvars - ctfd_mode - s3 - live - investigation_mode - ec2 - fargate Terraform ec2 terraform apply s3 EC2 モード s3 モード setup.sh ログ生成 + CTFd 登録 ctfd_mode? fargate live Fargate モード live モード investigation _mode? 2. CTFd Deploy Mode EC2 モード (少人数向け) Fargate モード (大規模: 50人〜) 攻撃再現環境 IAM User + S3 + Lambda VPC Docker (CTFd) EC2 参加者 IAM + 制限付き Policy OR ALB 参加者 IAM User + 制限付き Policy ECS Fargate Aurora Serverless v2 IAM CTFd x2 IAM NAT Gateway @kazzpapa3 / #KomeKaigi ElastiCache Redis 22 / 40

Slide 23

Slide 23 text

ここまででできるようになったこと 3. Investigation Mode s3 モード (デフォルト) live モード (実践的) Python generate-logs.py ✔ 単一アカウントで可 ✔ 追加コストなし 記録 API 実行 S3 参加者 模擬 CloudTrail JSON ログ aws s3 cp + jq で解析 OR Lambda (攻撃実行) Route 53 CloudTrail 記録 us-west-2 / eu-west-1 Secrets Manager ✔ 実際の CloudTrail イベント ✔ 実務に近い体験 Organizations + SCP 必須 ⚠ 記録 RDS lookup 参加者 aws cloudtrail lookup-events 4. Participant Guide (MkDocs) participant-guide/ docs/*.md mkdocs build (Material theme) S3 参加者 イド内容 • はじめに • 調査方法 (S3/Live) • ステージ概要 • トラブルシューティング 参加者 静的サイト ホスティング @kazzpapa3 / #KomeKaigi 23 / 40

Slide 24

Slide 24 text

ここまででできるようになったこと 1. terraform.tfvars で Deploy モードと Investigation モードを定義す る 2. Deploy モードの設定に応じて CTFd の実行環境が構築される 3. Investigation モードの設定に応じてログを生成 or 攻撃スクリプトが 実際の AWS API を実行 → それぞれに応じて設問と回答を生成 4. 参加者向けガイドドキュメントを自動作成 @kazzpapa3 / #KomeKaigi 24 / 40

Slide 25

Slide 25 text

現状の設問の概要 @kazzpapa3 / #KomeKaigi 25 / 40

Slide 26

Slide 26 text

第一波: アクセスキー流出 (Stage 1-5) # 1 2 3 4 5 難易度 ★☆☆ ★★☆ ★★☆ ★★☆ ★★★ カテゴリ ヒント 発案者 Recon GuardDuty の findings を読む Kiro Investigation CloudTrail ログの分析 Kiro Investigation S3 操作の追跡 Kiro Containment AWS CLI で封じ込め実行 Kiro Persistence 複数リージョンの調査 Kiro @kazzpapa3 / #KomeKaigi 26 / 40

Slide 27

Slide 27 text

第二波: 横展開と深い侵害 (Stage 6-19) # 6 7 8 9 10 11 12 13 14 15 16 17 18 19 難易度 ★★☆ ★★☆ ★★☆ ★★☆ ★★★ ★★★ ★★★ ★★☆ ★★★ ★★☆ ★★☆ ★★★ ★★☆ ★☆☆ カテゴリ ヒント 発案者 Investigation AssumeRole の痕跡 Kiro Investigation 複数リージョンの EC2 操作 Kiro Forensics CloudTrail 自体への攻撃 Kiro Network セキュリティグループの変更 Kiro Persistence SSM コマンドの内容 Kiro Investigation DNS レコードの変更 Kiro Persistence Lambda + EventBridge Kiro Investigation Secrets Manager へのアクセス Kiro Investigation RDS スナップショットの共有 Kiro Persistence インラインポリシー Kiro Persistence コンソールアクセスの追加 Kiro Persistence MFA デバイスの設定 Kiro Investigation S3 バケットポリシー Kiro Investigation 失敗した操作の痕跡 Kiro

Slide 28

Slide 28 text

第三波: 阻止できた大規模攻撃 (Stage 20-23) # 20 21 22 23 難易度 ★★★ ★★☆ ★★★ ★★☆ カテゴリ ヒント 発案者 Persistence IAM ロールの信頼ポリシー書き換え 筆者 Investigation オプトインリージョンの有効化試行 筆者 Persistence ASG + ECS による自動復活クラスター 筆者 Investigation SageMaker ノートブック起動試行 筆者 このカテゴリは実際の攻撃(被害)から新たな手法を見出し、筆者にて 発案して実装した 実際に高額利用につながった事例であるため、攻撃の再現による費用発 生を抑えるため、SCP(Service Control Policy)で阻止できたことに して、事例の習熟につながるように設計した @kazzpapa3 / #KomeKaigi 28 / 40

Slide 29

Slide 29 text

最終問題 (Stage 24) # 24 難易度 ★★★ カテゴリ Forensics @kazzpapa3 / #KomeKaigi ヒント 全体タイムラインの把握と整理 発案者 Kiro 29 / 40

Slide 30

Slide 30 text

いざ、実演 @kazzpapa3 / #KomeKaigi 30 / 40

Slide 31

Slide 31 text

JAWS-UG 神戸支部でゲーム大会として開催 私が共同運営する JAWS-UG 神戸支部でハイブリッド型のイベントと して開催 37 名の方に参加いただけて、概ね完走していただくことができた AI Agent を駆使し最速で回答をされる方、縛りプレイとして AI を使わ ず自力かつ CLI で CloudTrail を調査された方、AI を相談相手として ヒントの使用を抑えた方、など、想定通り、多種多様な取り組みかたを していただけたようでした @kazzpapa3 / #KomeKaigi 31 / 40

Slide 32

Slide 32 text

いい感じじゃね? @kazzpapa3 / #KomeKaigi 32 / 40

Slide 33

Slide 33 text

ご参加者からのフィードバック “ “「アクセスキー漏洩によるインシデント対応」がテーマのCTFにおい て、参加者に永続アクセスキーを配布している矛盾。CTF終了3日後も キーが有効なまま残っており、テーマで学ぶべき教訓を運営側が実践 できていない。(原文ママ) たしかに! @kazzpapa3 / #KomeKaigi 33 / 40

Slide 34

Slide 34 text

再掲)改良 1 , 2 により実現できるようになったこと 1. S3 バケットにある CloudTrail のログをダウンロードし、手元で解析を 行う 2. AWS アカウントにコンソールログインして GUI で CloudTrail を調 査、解析を行う 3. AWS アカウントに AWS CLI 経由でアクセスし、CLI で CloudTrail の 調査、解析を行う 4. 上記のいずれの手法でも AI Agent に壁打ちしたり、自律的な調査を AI にやってもらうこともできるようになった 2 を実現するのに IAM ユーザーを発行し、3 の実現のためにアクセス キーを配布する という実装になっていた 34 / 40

Slide 35

Slide 35 text

フィードバックを踏まえた最新の構成 Cognito + EC2 フェデレーション発行サーバによる一時認証情報発行 AWS Cloud / Account (ap-northeast-1 ほか) victim-env(被害環境・調査対象リソース) ctfd-fargate 専用 VPC (10.0.0.0/16) データイベント記録 customer-data-prod aws-ctf-cloudtrail aws-ctf-evidence aws-ctf-docs CloudTrail (顧客データ / 攻撃対象) (証跡ログ保管) (GuardDuty findings) (参加者ガイド/公開Web) aws-ctf-trail(マルチリージョン) Internet Gateway NAT Gateway + EIP ALB (HTTP:80) forward :8000 Public Subnet × 2 (AZ-a / AZ-c) ALB・NAT GW を配置 (map_public_ip=true) AssumeRole IAM User: dev-tanaka IAM Role: admin-role IAM Role: Lambda: ctf-verify-containment IAM Role: (被害者 / AdministratorAccess) (攻撃者が AssumeRole)system-health-check (Stage4 検証 / フラグ発行) verify-containment (backdoor Lambda 実行ロール) (verify Lambda 実行ロール) イメージ取得 Private Subnet × 2 (AZ-a / AZ-c) live モード限定リソース MySQL :3306 Redis :6379 Route 53 Hosted Zone Secrets Manager example-corp.com(Stage11) prod/database/credentials(Stage13) RDS: prod-database MySQL db.t3.micro(Stage14) ECS Cluster aws-ctf-ctfd ECS Service (Fargate) ctfd × 2 tasks (port 8000) Aurora Serverless v2 MySQL (ctfd DB) ElastiCache Redis cache.t4g.micro Security Groups: alb / ecs(8000) / db(3306) / redis(6379) CTFd 利用 SSM SendCommand ターゲット(Fargate モード時に main.tf が作 成) auth(cognito モード)— クレデンシャル配布基盤 IAM Role: ctfd-exec (TaskExecutionRole) CloudWatch Logs /ecs/aws-ctf-ctfd InitiateAuth EC2: aws-ctf-ctfd (t3.nano) IAM Role: ssm-target SSM Agent 有効 (SSMManagedInstanceCore) Cognito User Pool + ClientEC2: token-server (t3.micro) (参加者認証) Flask :8080 / default VPC ログイン/クレデンシャル取得 HTTP :8080 AssumeRole(一時認証情報発行) CTF 参加者(ブラウザ / CLI) IAM Role: token-server IAM Role: participant (AssumeRole + Cognito + SSM) (参加者用 / 時間制限付き権限) SG: token-server (HTTP:8080 公開) / InstanceProfile 35 / 40

Slide 36

Slide 36 text

AI Agent によるゲーム作成を通じた学び・まとめ @kazzpapa3 / #KomeKaigi 36 / 40

Slide 37

Slide 37 text

可能性は広がるが、微妙に実装が古かったりする 要件定義がなくても、自然言語と対話でゴールを目指すことは容易 人間側にやりたいことがあり、判断基準も明確であれば、モック作成ま では最短で行えることが多い 明示的に指示しないと、昔のベストプラクティスのまま実装していたり する 今回、ゲーム参加にアクセスキーへの依存をする実装になっていたの が好例 性質上、アクセスキーの撤廃をしたい立場であり、それがふさわしく ないなら、明示的な禁止行為として指示すべきだった @kazzpapa3 / #KomeKaigi 37 / 40

Slide 38

Slide 38 text

その後、何人かの AWS 関係者とも会話しましたが 割と普通に AI Agent が生成してくるスクリプトは、永続的なクレデン シャルに依存した実装をしてくることが多そう 「今は」ベストプラクティスではないものの、「過去に」多く採用され ていた実装方法なので、引きずられている可能性はあるかもしれない 生成は AI でできるようになったものの、今のベストプラクティスを踏 まえているか?の目線は大事 そのため、ベストプラクティスが変遷していくことを理解し、今回のよ うな勉強会なども通じて、常にキャッチアップを怠らないようにしない といけない、と再認識しました @kazzpapa3 / #KomeKaigi 38 / 40

Slide 39

Slide 39 text

このゲームを一般提供できるよう調整中です 環境構築以外の問題作成部分も自動で行っているので、設問と回答をど のように秘匿するかを思案中です とはいえ、そこまでこのゲームを攻略したい人もいないだろうから、 ふわっとパブリック公開しようかな?と考え中 もう一度社内でゲーム大会をしてみたいので、それが終わる 11 月半ば までは非公開にしますが、今後 OSS 化できたらと考えています その際にはぜひ、漏れたキーを使って 第三者によって行われた API 実 行を客観的に調査することの難しさ、めんどくささを体験してみてくだ さい @kazzpapa3 / #KomeKaigi 39 / 40

Slide 40

Slide 40 text

Security is job zero. Thank you.