IERAE CTFを支える技術 @ GMO IERAE HackNight #2 「IERAE CTFで学ぶセキュリティ技術&インフラ開発」

2.7K Views

July 24, 25

スライド概要

GMO IERAE HackNight #2 「IERAE CTFで学ぶセキュリティ技術&インフラ開発」
https://ierae.connpass.com/event/359736/

profile-image

GMOサイバーセキュリティ byイエラエ株式会社

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

ダウンロード

関連スライド

各ページのテキスト
1.

IERAE CTFを支える技術 icchy

2.

whoami • icchy • 元CTFプレーヤー • 現役ではない(non-active) • TokyoWesternsというチームのリーダー • CTF運営経験 • 2016~2020: TWCTF • 2017~2019: CODE BLUE CTF • 2021~2024: ACSC (Asian Cyber Security Challenge) • 2024~2025: IERAE CTF

3.

CTFとは? • JeopardyとかA&DとかKoHとかいろいろ • 今日はJeopardyの話 • 目的を達成(flagを得る)ためにあの手この手でアプローチ • 脆弱性を悪用する(セキュリティコンテストなので) • 愚直に自動化する(パソコンコンテストなので) • 作問者の頭の中をエスパーする(そういうこともある) • なんでもアリ

4.

CTF運営の課題 • コスト • インフラコスト • 運用負荷 • 問題デプロイ • デバッグ・トラブルシューティング • 安定性 • 負荷対策 • 公平性 • チート対策 • 環境再現性

5.

CTFを開催するのに必要な要素 • 問題文と答え(一番重要) • 提出回答を記録しておくしくみ • 極論Google Formとかでもいい • 過去にはそういうCTFもあった • ルール • 参加者に何をされても文句を言わないならなくてOK • とはいえ今どきのCTFはそんなに甘くない • 添付ファイルは必須 • リモートサーバーが必要な問題とか • チームごとに隔離された環境とか必要

6.

CTFに必要なオペレーション • スコアサーバーデプロイ • スコアサーバー本体のデプロイ • 問題文、ファイルの同期 • 問題デプロイ • アプリケーションのデプロイ • インフラ • 問題非公開時のアクセス制限 • 負荷監視・デバッグ • サポート • 質問対応 →自動化したい

7.

Case Study: TWCTF (gen1; Azure) • スコアサーバーデプロイ • スコアサーバー本体のデプロイ • 問題文、ファイルの同期 → Rails app on VM → Webブラウザから直接 • 問題デプロイ • アプリケーションのデプロイ → itamae (Ruby) • インフラ • 問題非公開時のアクセス制限 → Azure Firewall • 負荷監視・デバッグ → Metrics, SSH • サポート • 質問対応 → IRC

8.

Case Study: CBCTF (gen2; Google Cloud) • スコアサーバーデプロイ • スコアサーバー本体のデプロイ • 問題文、ファイルの同期 → Rails app on GKE → スクリプト化 • 問題デプロイ • アプリケーションのデプロイ → Cloud Run/VM • インフラ • 問題非公開時のアクセス制限 → VPC Firewall Rules • 負荷監視・デバッグ → Metrics, SSH • サポート • 質問対応 → IRC

9.

既製CTFスコアサーバー • CTFd • 言わずと知れた有名スコアサーバー • Django製 • rCTF(→ otter-sec/rctf) • CTFチームredpwnによるスコアサーバー • TypeScript製 • 他にもたくさん • pdogg/ctfmanager, parasol, minictf, fbctf, kosenctfx, etc. • frontend + server app + RDBMSの構成がほとんど

10.

本題 IERAE CTFインフラの作り方

11.

IERAE CTFの要件 • 問題文に添付ファイルが含められること • 動的スコアであること • ランキングが見られること • リモートサーバーを使った問題がホストできること • +チームごとに隔離された環境が作成できること • いい感じのCTF Ops体験 • デプロイが自動化される • 手元のdocker composeの環境がほぼそのままデプロイできる • Gitで管理した問題が同期される • ほぼ同一のテスト環境が建てられる • 他多数

12.

CTFインフラの作り方 IERAE CTFにおける • スコアサーバー • 問題インフラ それぞれについて解説

13.

スコアサーバー

14.

スコアサーバーの要件 • スコアサーバーに必要な機能 • 問題文が見られる、ファイルがダウンロードできる • Flagが送信できる • 他チームの回答状況、ランキングが見られる • etc. • 固定で表示すれば良いデータと動的に生成するデータがある • あらゆるWebアプリケーションに言えること

15.

スコアサーバーのインフラ選定 • トラフィック特性 • 開始直後が一番跳ねる • 基本的に常駐インスタンスは非効率 • FaaSなどのスケールしやすい構成の方が便利 • 動的に生成しなければならない箇所 • 回答状況(動的スコアリング) • ランキング • (必要なら)問題サーバーの情報 → 以外とシンプルなロジックで完結する 開始時刻

16.

動的なデータを表示する方法 1. ユーザーに提示する際に生成する(on-demand) 2. あらかじめ生成しておき、そのデータを読ませる(pre-gen)

17.

on-demand • アプリケーション側でデータを加工し、整形する • 利点 • 常に最新のデータを返せる • 欠点 • 常にサーバーを動かしている必要がある

18.

pre-gen • 必要なデータをあらかじめ生成しておき、それを表示 • 利点 • ユーザーからのリクエストに対してスケールしやすい • 欠点 • リアルタイムデータを扱えない

19.

スコアサーバーとやりとりされるデータ • スコアサーバー → ユーザー • ルールなどの固定テキスト • 問題文 • 問題ファイル • 問題の得点 • 他チームの回答状況、ランキング • ユーザー固有の情報(ニックネーム、チームなど) • ユーザー → スコアサーバー • ログイン • チーム作成 • フラグ提出 赤字:動的に生成される情報

20.

スコアサーバーとやりとりされるデータ • スコアサーバー → ユーザー 赤字:動的に生成される情報 • ルールなどの固定テキスト pre-genで実現できそう • 問題文 • 問題ファイル • 問題の得点 • 他チームの回答状況、ランキング • ユーザー固有の情報(ニックネーム、チームなど) • ユーザー → スコアサーバー • ログイン • チーム作成 • フラグ提出

21.

pre-genのデータをどこに置くか • マネージドDBは高い • インスタンスを建てるタイプは特に高い • Google Cloud SQL • Amazon RDS • Firestoreという選択肢 • Google Cloudが提供するクラウド上のNoSQLデータベースサービス • クライアントから直接データをクエリできるという特徴がある • 安い(基本的に無料枠で十分; 50,000 read/day, 20,000 write/day) • リアルタイムアップデートに対応

22.

Firestore • 特徴(公式ページより抜粋) • 柔軟性 • 高性能なクエリ処理 • リアルタイムアップデート • オフラインサポート • スケーラビリティのある設計 • セキュリティルールによりアクセス制限が可能

23.

Firestore: セキュリティルールのしくみ • データをクエリするときに条件が指定可能 • 例: resource.data.public == true(publicというフィールドがtrueの み) • 指定した条件のみでクエリすることを許可 • 全件取得はできない • 異なる条件(resource.data.public == false)もできない

24.

Firestore: 型について • スキーマレスなので型がない • バグの温床 • どうするか?→zod • FirestoreのDataConverterと 組みわせることで型を付与 • TypeScript側のチェックにより ランタイムエラーはほぼなくなる

25.

Firestoreで制御できないロジック • flag submission • flagが正しいかチェックし、回答状況を更新 • ランキング更新、動的スコアの更新 • Firestore上の回答状況を見て定期的に更新 • ユーザー作成、チーム作成 • ユーザーからのリクエスト時に作成 → Cloud Functionで実装(定期実行についてはスケジューラ)

26.

スコアサーバー:その他 • フロントエンドどこに置く? • Firebase Hosting • 認証どうする? • Firebase Authentication • 問題ファイル(attachments)はどこに置く? • Cloud Storage • 問題のデプロイは? • GitHubと連携してCloud Buildが勝手に同期してくれる • attachmentsも自動生成してアップロード(手動は事故の元) • 検証環境は? • Cloud Identity Platform (Firebase Authentication) のテナ

27.

問題サーバー

28.

問題サーバーの要件 • 問題サーバーにあってほしい特徴 • デプロイを楽にやりたい • スケールさせたい • 監視とか再起動とかなるべくしたくない • 手元の環境をそのままデプロイしたい • プレイヤー固有の隔離された環境(instance)が欲しい • 問題ファイルはDocker (Docker Compose)で配布する • Docker Composeをそのまま動かしたい • → Kubernetesで動かす

29.

Kubernetes for CTF • スケーラビリティ • 参加者が多くても自動で負荷分散 • 分離性・セキュリティ • namespaceによるリソース分離 • 自動復旧 • アプリケーションが落ちても自動で再起動 • 構成管理・デプロイが容易 • YAMLファイルで定義 • Reconciliation Loopが自動で適用

30.

Google Kubernetes Engine (GKE) • Google Cloudインフラと統合されたK8s Engine • Google Cloudのコンソールからなんでもできる • スケーリング、Nodeの増減 • ログ調査 • LoadBalancerへのIP紐付け • 自動で払い出しが可能 • NetworkPolicy • Calicoを有効化すればファイアウォールと連携

31.

問題デプロイ • 手元はDocker Composeが一般的 • 複数サービスが協調する問題(frontend + backend + DBなど) • Dockerの再現性が高い • Docker Composeをどうやってk8sにデプロイするか? • Kompose(https://kompose.io/)

32.

Kompose • Docker Composeをk8s manifestに変換するCLI • servicesをいい感じにDeploymentやServiceに変換してくれる • Image自体のbuildもできる

33.

問題向けに必要な修正 • 問題同士が通信できるのは困る • 未公開の問題にアクセスされる • 他の環境への影響 → namespaceを区切る • IP制限を正しくかけたい • externalTrafficPolicyをLocalにする • NetworkPolicyを適用

34.

Kompose • 変換例

35.

問題インフラ:その他 • ExternalDNS • DNSサービスと連携してServiceに割り当てられたIPのエントリを作成 • ※今回は使わなかった • インスタンスの払い出し • watch APIでLoadBalancer関連のイベントを監視 • external IPがアサインされたらFirestore側を更新 • private spawner(参加者固有のインスタンス)も払い出せる • 監視・再起動 • 基本的に不要 • ログも出るので作問者の調査も比較的容易

36.

コスト分析

37.

ぶっちゃけいくらかかった? • 結論:ざっくり56,000円(税抜)くらい • 検証環境を6月頭から立ち上げ • 本番(6/21)の直前にスケールアップ • 本番前後一日に絞ると17,187円 • 比較:TWCTF2018(35,828円) • スコアサーバー:9,883円 • 問題サーバー:25,945円

38.

17,187円の内訳 • スコアサーバー(4,001円) • App Engine (Firestore): 2,595円 • Cloud Run Functions: 787円 • Cloud Run: 578円 • Firebase Hosting: 24円 • Cloud Storage: 17円 • 問題サーバー(13,124円) • Compute Engine: 7,390円 • Kubernetes Engine: 1,412円 • Networking: 2,592円 • Artifact Registry: 1,437円 • Cloud Monitoring: 293円

39.

ランニングコスト • スコアサーバー:日額200円程度 • 高負荷時は1,000円程度 • 問題サーバー:必要なインスタンス次第 • 基本はCompute Engineに依存 • 問題を見られるようにしておくだけならほぼかからない • Cloud Storageのみ:日額20円くらい • データソース:Firestore、API:Cloud Functions • オンデマンドのリソース消費はかなり効率が良い

40.

まとめ

41.

まとめ • Firebaseでインフラを作るとコスパがかなり良い • コンピューティングリソースを予約しないサービスは全部そう • FaaSを徹底的に活用することによりコストの最適化ができる • Kubernetesにデプロイするのは体験が良い • IaCにより手動のデプロイ作業が大幅に削減 • 今後の展望 • watch APIではなくCRDを使った方が安定しそう