クラウドエース全体でハッキングコンテスト(Capture The Flag)やってみた 2nd
はじめに
記事の目的
こんにちは、クラウドエース所属で
以前記事にてご紹介いたしましたセキュリティギルド主催イベント「社内 CTF(Capture The Flag)大会」の第二弾を実施いたしました。
前回開催時も記事にてレポートし、社内外より好評コメントをいただきましたので、第二弾の開催レポートも共有いたします。
本日は、その結果と解説を踏まえ、読者の皆様にも Google Cloud のセキュリティについて今一度見つめ直していただく場となれば幸いです。
CTF とは
CTF(Capture The Flag)とは、ざっくり言えばシステム内に隠された文字列等の答えを見つけ、その正確性と速度を競うハッキングコンテストです。
本件では、Google Cloud に特化したシナリオを作成し、セキュリティギルドのメンバー(以下、ギルメンと呼称)によって実際にシステムを構築しました。
CTF(Capture The Flag)とは、情報セキュリティの分野では、専門知識や技術を駆使して隠されているFlag(答え)を見つけ出し、時間内に獲得した合計点数を競うハッキングコンテストを指します。
https://www.nri-secure.co.jp/glossary/ctf
クラウドエース版 CTF のシナリオ
今回の CTF では「SQL インジェクション」をテーマに、Gemini と WorkAIzer によって生成しました。
WorkAIzer(ワークアイザー)とは、同グループ会社である吉積情報株式会社が開発した、複数の生成AIモデルを統合的に利用できる法人向けプラットフォームです。
アーキテクチャ(イメージ図)
ポイント
本件では、ユーザ登録制の仮想的な WEB サービスを舞台に、ログイン画面に潜む脆弱性を利用して SQL インジェクションを試みられた状況を想定しました。
SQL インジェクションとは、WEB アプリケーションの脆弱性を突いて、悪意のある SQL 文をデータベースに送り込み、不正にデータを取得したり操作したりする攻撃手法のことです。
Google Cloud に限らず、SQL インジェクションは多くのシステムで被害が度々発生しており、IPA によるコンピュータウイルス・不正アクセスの届出事例としても公開されております。
よくあるものとして、ログイン認証を不正に突破したり、データベースから情報を漏洩させる、といったケースがあります。
本件では、グループディスカッションを通じてどのように Google Cloud で防御するのか考えていただくことをゴールとしました。
解説
STEP1 SQL インジェクションを試みる
SQL インジェクションは著名な攻撃手法であるため、検索すれば様々な解説とともにサンプルクエリも掲載されています。
本件ではシンプルな悪意のあるクエリを利用して試みます。
ログインフォームに SQL インジェクションを試みた結果、不正にログイン情報を取得することができてしまいました。
これにより、パスワードなどのログイン情報がわからなくてもログイン認証を不正に突破することができます。
また、この手法を発展させてデータベース内のテーブルを削除(drop)させる命令も実行することができてしまいます。
STEP2 防御方法を学ぶ
防御方法① アプリケーションの改修
基本となる防御方法として、アプリケーションの改修が挙げられます。
ユーザから見える(入力できる)部分で入力内容をそのまま SQL 文として解釈できる状態では本件のような攻撃が成立してしまいます。
解決策として、プレースホルダを利用して入力内容を文字列として扱い、入力値をそのままクエリ実行しないよう処理する方法が挙げられます。
また、特定の文字入力を制限したりエスケープ処理することも有効です。
- e.g.)「’」を「”」,「”」を「””」,「\」を「\」にする
アプリケーション改修例として、PHP 言語で記述されたアプリケーションコードのうち、プレースホルダなしの脆弱なケースとプレースホルダありの安全なケースを比較します。
//プレースホルダなし
4,5c4,11
< // 結果を取得
< $result = mysqli_query($conn, "SELECT email, passwd FROM users WHERE uid='$uid' AND passwd='$pass'");
---
//プレースホルダあり
> // SQLクエリをプリペアドステートメントで作成(プレースホルダを使用)
> $stmt = mysqli_prepare($conn, "SELECT email, passwd FROM users WHERE uid = ? AND passwd = ?");
> // プレースホルダに値をバインド(文字列として)
> mysqli_stmt_bind_param($stmt, "ss", $uid, $pass);
> // クエリ実行
> mysqli_stmt_execute($stmt);
> // 結果を取得
> $result = mysqli_query($stmt);
このとき、アプリケーションがデータベースにアクセスする際に使用するデータベースユーザには、最小権限の原則に則り必要最小限の権限のみを割り当てるようにしましょう。
- e.g.)SELECT 権限のみを付与し、INSERT、UPDATE、DELETE といった不要な権限は付与しない
防御方法② Cloud Armor で防御する
Google Cloud ネイティブな防御方法として、Cloud Armor が挙げられます。
Cloud Armor は Google Cloud が提供するマネージド WAF(Web Application Firewall)です。
保護ルールをセキュリティポリシーとして定義し、ロードバランサの背後のアプリケーションに紐づけることで本件の SQL インジェクションのような各種攻撃から WEB アプリケーションを保護することができます。
保護ルールには Google Cloud で事前に用意された事前構成 WAF ルールを活用することができます。
これにより0ベースでルールやシグネチャを定義する必要なく、ModSecurity Core Rule Set(CRS)ベースの複数のシグネチャからルールを構成することができます。
今回のケースでは sqli-v33-stable
や sqli-stable
などの事前定義ルールが有効です。
表:事前構成ルール名
Cloud Armor ルール名 | CRS バージョン | ModSecurity ルール名 | 現在のステータス |
---|---|---|---|
SQL インジェクション | CRS 3.3 | sqli-v33-stable | sqli-v33-canary と同期 |
SQL インジェクション | CRS 3.3 | sqli-v33-canary | 最新 |
SQL インジェクション | CRS 3.0 | sqli-stable | sqli-canary と同期 |
SQL インジェクション | CRS 3.0 | sqli-canary | 最新 |
rule {
action = "deny(403)"
priority = "100"
match {
expr {
expression = "evaluatePreconfiguredExpr('sqli-v33-stable')"
}
}
}
保護ルールは Common Expression Language(CEL)によって記述することが可能です。
CELルールの詳細は公式リポジトリをご確認ください。
参考情報
また、IPA の「安全なウェブサイト」から、「保険的対策」に記載されたポイントも確認しておきましょう。
- エラーメッセージをそのままブラウザに表示しない
- データベースアカウントに適切な権限を与える
CTF での学び
本件では、攻撃観点だけでなくグループディスカッションを通じた「防御策をチームで考える」という試みにより様々な学びを得ることができました。
- SQL インジェクションは基本的な攻撃手法
- 基本的な攻撃であるからこそ安全な WEB サイトを作るために必ず対策をすべき
- 今回はデータ漏洩をシナリオにしたが、他にもデータベースの書き換えが行われたり、最悪システムを乗っ取られる可能性もある危険な攻撃である
- アプリ側の対策は脆弱性診断で見つけられることがあり有効である
WAF による対策は有効ですが、アプリケーションの動作を阻害する可能性もあり万全ではありません。
原則は、アプリケーションで入力値を適切に検証し安全に SQL クエリを実行するようにしてください。
また、SQL インジェクション以外の攻撃方法も存在するため、必要に応じて IPS/IDS といった防護策も使い、多層的防御を検討してください。
これらをふまえ、読者の皆様におかれましては引き続き安全なシステム設計を計画してください。
参考情報:クエリインサイト(CTF終了時点)
実行されたクエリインサイトを確認すると試行錯誤しながら短時間で多くの攻撃を受けていたことが確認できました。(75回以上/15分)
社内からのコメント抜粋
CTF 終了後に FB アンケートを取った結果、回答者の 87.5% の方が「楽しめた」「Google Cloud の知識が向上した」と回答していました。
また、社内からは以下のようなポジティブなコメントを多数いただくことができました。
- SQL インジェクションの攻撃方法や防御方法について理解を深められた
- 実際に手を動かして体験できたことは有意義だった
- セキュリティ意識向上に役立った
- 特に異なる視点からの意見交換は非常に有益だった
成功の要因分析
また、今回はシニア層からジュニア層へのナレトラを目的に初めて取り入れたグループディスカッションが功を奏し、活発な議論や意見交換が行われたことも成功の要因でした。
前回は SRE 領域を担当するメンバーに絞って実施しましたが、今回はアプリケーション領域やデータ分析領域を担当する様々なメンバに門を開いたことで多角的な議論に繋がったのではないかと考えています。
特に、CTO や部長レイヤーも参加したことで、組織全体でセキュリティに対しての基礎能力向上や重要度の再認識にも繋がったと考えています。
ギルメンの考察
- 参加範囲
- 第 1 回はSRE 部のみで開催したが、技術本部全体で開催したことは門戸を開くことになり、有意義だった
- 幅広い参加者がいたためセキュリティ技術やセキュアアーキテクチャの認知向上に繋がった
- 難易度設定
- 初学者にとって攻撃は難しかったかもしれないが、防御はちょうどよい難易度で、議論も活発に行われていた
- 環境差分
- CTF 環境は脆弱な環境であるため、安全を期して社内プロキシ経由のみ許可するアクセス制御を設定したが、一部社員がプロキシ設定に手間取ってしまった
- プロキシ設定自体は事前に告知していたが、当日確認する人がいたため、CTF 参加に時間がかかった
- 満足度
- ディスカッション形式にしたのは盛り上がった要因に感じる
- 参加者からもディスカッションが有意義だったとコメントがあった
- 時間配分
- 第二弾ということもありオンスケで動けたのは運営側が慣れてきた証拠
- スケジュール通りに動けたのはよかった
- 開催時間は1時間30分が MAX
まとめ
前回に引き続き、セキュリティギルド主催 社内 CTF 大会 第二弾として、前回の改善点を活かしながら活動の幅を広げることができたと考えています。
今後もセキュリティギルドでは Google Cloud のセキュリティに関する技術記事を執筆していきますのでご期待ください。
再三になりますが、本 CTF では「このような脆弱なシステムを構築しないよう学習を通じて意識向上を図る」ことが目的です。
本記事を通じて読者の皆様も意識向上の機会に繋がれば幸いです。
セキュリティギルドメンバーの記事紹介
Discussion