読者です 読者をやめる 読者になる 読者になる

CTFとの向き合い方 ~CTFで消耗しているすべての人へ~

この記事はCTF Advent Calendar 2016の25日目の記事になる予定だったのですが、タイムリーな議論が起きているため早い内に公開したいという気持ちと、3日目担当のBo Wangさんが記事を書かれていないように思えるので、3日目兼25日目の記事として足して2で割って14日目に公開したいと思います。この文章は1年以上僕の恨みつらみを込められて作成された文章です。

 

序文

近年、CTFがある程度人権を得て情報系の競技としてポピュラーになった気がしています。しかし、それにともなってCTFで消耗してる人が多くなった気がしましたので、僕も昔から消耗してきた身として、個人的なCTFとの向き合い方をポエムしようかなと思いこの記事を作成しました。

 

お前誰

最近はCTFを現役でやるだけの体力がなくなってきていて、もしかすると最近始めた皆さんは僕や僕のチームのことを存じ上げないかもしれないので、一応自己紹介を初めにしておきましょう。

筆者のCTF戦績の一部

  • SECUINSIDE 2014 Finals 4位
  • DEFCON 2014 Finals 13位
  • CODEGATE 2015 Junior 優勝
  • HITCON 2015 Finals 9位
  • DEFCON 2016 Finals 8位

 

一応CTFは5年ほどやっていることになり、おそらくこれを読んでいる皆さん以上か同じ程度には近年のCTFを理解しているつもりでいます。

一方でまだ学生の身分である私は、現実のセキュリティ、いわゆる業務などに関しては少し疎い面があります。勘違いしてそうな所はまたコメントなり個人的になり教えていただけると嬉しいです。あ、でも脆弱性報告とかはたまにしています。そのお金でデコンパイラ全部付いているIDA Pro買ったり更新しているので。

 

それでは僕が実際に見かけたいくつかの消耗パターンの、原因と思われるものに言及していきましょう。

1. CTFを語る時はジャンルと想定する参加者側のレベルに気をつけよう

当たり前な気はしますが、CTFにおける何かしらの主張というのは、ジャンルによって当てはまったり当てはまらなかったりすることがあります。何に関する話なのか(例えばバイナリを扱うジャンルに関してなのかなど)を明確にしましょう。

そして、参加者のレベルに気をつけましょう。こんなことはあまり言いたくないですが、どれぐらい出来る人間に関して言ってるのかによって、主張が正しいかどうか違ってくる場合があります。例えば次の主張は多分正しいです。「世界の有名なCTFの決勝に安定して参加しているようなチームは、実際のセキュリティの世界においても何かしらの偉大な功績を残していることが多い」。PPPやShellphishなどをみるとこれらのチームがアカデミックな世界においても類稀なる進捗を生み出しているのは明らかで、あるいはgeohotや韓国のチームは著名なアプリケーションの重大な脆弱性を報告している例がたくさんあります。逆にそうでないチームも含めて、言及の対象を「CTFを少しでもやっている人間」に広げると、さっきの主張は全く的外れになるでしょう。

 

2. 出るCTF、解く問題を正しく選んで消耗しないようにしよう

CTFを新しく始めた知り合いの話なんかを聞いていると、どの大会や問題に手を出せば良いのかということが分からず、適当にやってみた結果、何も分からなくてCTFの面白さに気づけないまま諦めるみたいな状態に陥っている人がいるように見受けられます。

このような人に送るアドバイスとしては以下のようなものがあります。

自分の出来る事、ジャンルを見極めましょう

情報セキュリティというのは他の情報系技術があって初めて、副次的に考える必要が生じる分野なわけです。つまり、何らかの分野のセキュリティを考えたいとなった時に、そのベースとなる技術の知識がない状態では考えようがないでしょう。それは情報セキュリティが競技化したCTFにおいても当てはまる話です。当たり前ですが、何の知識もない状態で問題を解ける人間なんているはずがありません。自分が何が得意なのか、どういった種類の問題なら解けるのかなどを見極めることが、CTFに参加し問題を解く第一歩になることは明らかです。この記事はCTF初心者に向けたものではないので、詳しく扱うことはありませんが、最近だとちゃんとそういったことを解説している記事とかはあるんじゃないでしょうか。よく知りません。

過去問を見てCTFの形式や傾向を見ましょう(例えばDEFCONにはWebは出ません)

常設型CTFサイトに関しては、自分の好きな時間に好きな問題を解けるわけですから特に言うことはありませんが、競技時間のあるCTF(常設型CTFのしっくりくる対義語欲しいんですけど誰か作って欲しい)に関してはそうもいきません。大抵のコンテストは24時間以上開催されるものが多いので、真剣にやろうと思うと、健康的な日常生活の時間を犠牲にしたり、社会人や忙しい学生の方であれば、参加するために事前から予定をあけるなどの労力がかかるわけで、参加コストが中々高いことは否定できないでしょう。そのように参加コストが高いコンテストにせっかく参加したにも関わらず、自分の解ける問題が一切でなくて時間溶かしたアビャ~となってしまっては、全くもって骨折り損のくたびれ儲けです。このような事態を避けるために有効な手立てとしては、出ようと考えている大会の過去問を眺めてみることです。大体どのようなジャンルの問題が、どのような難易度で出るのかということがはっきりします。もちろん年度によって多少の難易度のブレがあったり、例えばCODEGATEなどは数年に一度運営が変わってしまって何もかもが変化してしまうことだってありますが、特に初心者の方など、初めのうちは参加する前に自分の丈にあった大会なのかということは考えてもいいのではないでしょうか。知り合いの方を例に取ると、DEFCONはWebが出ません...

評判を見て出るCTFを選びましょう

悲しいことですが、大会の品質は常に保証されているわけではありません。一般に、実力の伴っていないチーム、運営が企画した大会というのは概して経験者からはクソCTFと呼ばれるものが多いのが現状でしょう。初心者の方からすると、何がクソで何がクソでないかというのは判断しかねると思いますが、大雑把に説明してしまえば、「問題の解法に論理的妥当性があるか」と「どのような立場の人間でも公平に解けるような解法が存在するか」ということです。後は個々人の感覚によるものになってしまいますが、「問題(解法に必要とされる発想)が面白いか」、「問題の典型性が低いか(既出でないか、ツールゲーでないかなど)」、「問題の現実性は高いか」なども、クソかどうかという判定において良く考慮される要素です。後半の要素に関しては、個人の好みとして割り切ってしまえるものが多いですが、解法の論理性と公平性に関しては、欠かしてはいけないものだと思っています。あなたは「URLを推測します。どこにも公開していませんが、ctf.shit.net/shit_problem_exampleというURLがあるので接続できれば答えが出ます」(もっと分かりやすい例では「僕はカレーが好きなので答えはカレーでした」)と言われて納得できますか。また、そんな問題から何を学べるんでしょうか。強いて言うならそんな大会には二度と出ないでおこうということでしょう。おそらく何がクソで何がクソでないかをそこまで判断出来ない初心者の方でも、このような問題には理不尽さやつまらなさというものを感じてしまうのではないでしょう。そして、数多のコンテストが開かれている今日では、このような問題を平気で出してしまうような、全くもって考えが浅い運営がいるという現実があります。これは別に実力がないから運営をするなという話ではないのですが(まあ実力がなくて面白いコンテストができるのかには疑問がありますが)、せめて論理性だけは欠かないようにして欲しいことです。というかなんでこんな問題を出してしまうのでしょうか。このような理不尽を経験したことが、怒りを覚えたことがないのでしょうか。それは概してCTFに参加したことがないということで、だから僕はしきりに運営をする人間はCTFに参加すべきだというわけです。

 こんな当たり前に見える、一般に批判なしに受け入れるしかなさそうことを、いちいち言ってもらわないと分からない人が、問題を作ってるんでしょうか...(こみ上げる怒り)

学びは面白さとは少し独立してしまっているので、どちらかといえば競技として、僕は学びより面白さを優先すべきだと思いますが、どちらにしても学びがあるということは良いことですネ。

 

まあということで、参加者側は、CTFTimeやTwitterでの評判など、色々参考にして参加を検討する姿勢があって良いと思います。クソCTFに時間を吸われるのは時間の無駄です(一方で、中々この世からなくならないクソ問題を解くためにクソCTFに出て耐性をつけるべきという一理ある意見もありますが。一般にクソ問題を解く能力はなぜかクソ問題に費やした時間に比例する傾向が経験則上あります)。

 

3. CTFと実際のセキュリティと比較して消耗しないようにしよう

色々な運営などに携わることもあって、「セキュリティ関係の仕事をしているから」、「セキュリティに関連する技術を高めたいから」という理由でCTFに出ようとする人が多く見受けられるように感じます。あるいは、運営側もしかり。

ですが、僕は楽しむという目的がなく、義務や使命感のためにCTFに参加しているのであれば、すぐにやめるべきだと思います。それはなぜか。

実世界においてセキュリティに関連する何かをする時にCTFをする必要は一切ない

一例を上げましょう。

あなたは業務でマルウェアを読まないといけなくなりました。あなたはマルウェアマルウェア解析に関する知識が皆無です。この時、CTFに出て技術を磨くのは最善の方法でしょうか?

おそらくCTFは役に立たないことはないでしょうが、CTFでマルウェアを読まずとも、仕事場に読む環境があるのだからそちらで経験を積めばいいのではないでしょうか?そもそも問題で常にマルウェアが出るとは限りませんし、どの程度現実に即しているのかということは保証、判断しかねるでしょう。もちろんステップアップ的な面でCTFを使いたくなるモチベーションもあるのですが、それはCTFでなくても代用できる方法はいくつかあるはずです。

もう一例出すと、脆弱性を探すという行為に関しては、CTFだとexploitを書く必要がありますが、実際の脆弱性調査ではPoCを書かなければならないことは稀でしょう。怪しいなと思った部分は攻撃できるできないに関わらず全て修正すればいいのですから。

CTFは全く役に立たないか?

一方で、CTFに出ている人間が実際のセキュリティ関係の何かでは役に立たないというのも間違いです。たまにそういう主張をしている人がいるように思えます。ああ、勘違いしてほしくないのは、これは、「CTFに出ている人間が絶対に現実でも役に立つ」といってるわけではありません。相関がないと言っているのです。また、先ほども書いた通り、その人間のCTFの実力、つまり参加者のレベルにもよって、「役に立つ」かは変わるのではないですか。極端な例では、CTFに興味があって最近初めてみましたという人に、何も知らない上司が「君はセキュリティに強いのか、じゃあこれをやってみてくれ」と実務を与えて「役に立たなかった」と喚いているようなものです。そもそもCTFをやったことがない人はCTFをやったことがある人のCTFの実力を判定することは絶対に不可能なので、こういうレッテル貼りは良くないのではと思います。

CTFも強くて実世界でも強い人、CTFには出ていなくて実世界で強い人、CTFは強くて実世界ではあまり関係ない仕事をしている人、これらの3種類の人々がたくさんいる時点で、CTFと実世界の何かの相関を測ろうというのはありえないことだと思うのです。

 

しかし、これもまた一方で、CTFをやっている人間が実務では役に立たないという主張をする人の気持ちもよく理解できます。僕はこの文章から分かる通り、CTFを批判から庇護したいという気持ちは少々ありますが、どちらかというと実際のセキュリティにおいては全く役に立たないかあるいはする必要が無いという主張に賛同出来るところが多いです。

まず、大きな前提として「CTFは解けるように作られている」のです。もっと言えば開催期間の24~48時間以内に解けるようなサービスしか登場しないのです。それは非現実的でしょう。そもそも現実では解法があるのかどうかすら分からない"問題"を何日も掛けて調査するんですから。所詮CTFは箱庭のお遊びであって、結局現実の業務において必要なスキルや能力全てを問えるものではないということです。

 

しかし、これも、これもまた、一般には言えても僕個人からするとまだ例外があると思えます。

CTFはExploitationの技術を学ぶには最適なゲームです。

現実でexploitを、それもとても高度な代物を書く必要がある境遇にある人というのはとても少なくて、PoCを示すことで報奨金の金額が変わったり、顧客に脆弱性の深刻度を説明する際の説得力が上げられたり、jailbreakや諜報活動をしているなどで実際に攻撃する必要がある場合(これはよろしくないですが)ぐらいしかないので、ほとんどの人には当てはまらないのかもしれないです。

しかし、僕個人としてはこのような状況に陥ることがたまにありえるというのと、実際に陥るような仕事をしている人がいるということです。

例えばGoogleのProject Zeroは、今まで任意のコード実行が不可能だと思われていた脆弱性に対して、任意のコード実行を獲得する手法を公表することがしばしばあり、The Poisoned NUL Byte 2014 editionもその1つです。これは簡単に言うと、「heapのメタデータを1byteだけNULL文字で書き換えられるという脆弱性で、任意のコード実行は可能か」という未解決だった問題で、答えはyesだったという話です。上記のURLにも書かれている通り、これは非常に攻撃可能か疑わしいぐらいにとても小さな脆弱性で、クラッシュ以外引き起こすことが出来ないと判定されて修正の優先度を下げられる可能性すらあるようなものなのです。そして書かれている通りこれはとてもwargame、CTFらしい状況というわけです(ということもあって、少なくともExploitationの問題に関しては、現実性という指標を持って測ろうとするのは良くないのではないかと思います。"CTFらしい状態"に、現実のExploitationがなっているのですから、問題の現実性もクソもないです)。

なぜCTFらしいのでしょうか。まず1つは、CTFは如何なる問題設定もし得るという時点で、色々な場合においてどうexploitを書くかということを練習できるわけです。これは教科書的なROPの攻撃方法だけ知っているというのでは対応出来ない問題が出題されても対応できるような、攻撃手法やheapなどのexploit対象に対する本質的な理解が深まることを意味しています。

もう1つは、CTFでは攻撃に必要な最小の条件を考えやすいということです。これは出題側の話になりますが、例えばExploitationの問題を出すとして、どこまで使える脆弱性や環境に制限を付け加えても解くことが出来るのかというのを考えることによって、難しい問題を作ることができます。poisoned NUL byteも「脆弱性の中でもcriticalになりづらいoffbyoneでかつNULL文字でしかbuffer overflowしない」という時点でその一例であって、PPPは自身の主催するPlaid CTFにおいて、これを本質とした問題Plaid DBを出題し、一時期騒がれました。数年前までのCODEGATEにも、とても解けるようには見えない問題に対して知られていない攻撃方法を考えされる様な形で高得点問題を出す傾向がありました。

 

論旨を正しく抑えられる文章を読む力のある人であれば、「こいつここに来て主張が二転三転しているぞ」と思ったかもしれませんが、結局の所全体を通して、僕が「CTFと現実を結びつけること」に関して言いたかったのは、様々な主張があることも、そう主張する理由も理解できますが、無限に例外を考えられるので、不毛だからマジでやめろということです。

 

結局CTFとはどう向き合うべきか?

CTFはつまるところ、「やれば少しは学びがあるのでそこそこ美味しい遊び」という認識を持つべきです。正直当たり前の結論だと思うのですが、それでも時たま物議を醸すことがあるということは、この認識が出来ていない人が多いのでしょう。趣味でトライアスロンをしたりするのとあまり変わりません。

個人的な話をすると、僕はCTFの本質はパズルであると思っています。受験における有機化学がパズルであると主張されるように、CTFも必要な単調作業、知識をすべて取り除いた時、本質として残るのはパズルでしかないと思っています(もしかすると、「パズルになっていない問題は、面白くない問題やクソ問である」と言ってしまえるかもしれません。流石に過激かな)。パズルは好きな人がやるものです。数独が嫌いな人は、数独の大会に無理して出るものではないし、または数独の問題を作るべきでもないでしょう。スリザーリンクに面白さを感じない人は、スリザーリンクを面白いと思う人が、どういう問題のどういう所に面白さを感じるか分からないでしょう。その状態で"面白い"問題を作れるわけがないでしょう。よく周りのCTFプレイヤーが"脳汁が出た"という表現を使いますが、パズルを解くことによって生まれる、そのようなアハ体験を経験したことがないのであれば、あなたはCTFを理解していないのかもしれません。

もう一度引用しましょう

 僕たちは超能力者になりたいわけでも、スクリプトキディになりたいわけでもなく、頭を使ってパズルを解きたいだけなのです。学びを求めてCTFをしてる人には反感買うかもしれませんが、上に書いたように僕はその場合CTFじゃなくても大丈夫だと思っているので、なぜCTFか、CTFでないといけないか、CTFに何を求めているのかといえば、頭を使うことだと考えます。

 

まとめ

1. 3. では、CTFについて一般論を語るのは難しいということを説明したつもりです。

そして2.では、特に初心者の人がなにで詰まっているように見えるかということとCTFの腐敗について紹介しました。流石にたくさんの人々全員は相手していられないので、親切に色々解説する気力はもう僕には残っていませんが、後は皆さんで考え、なんとかしてくれることを祈っています。

 

以上が僕のCTFに対する距離の取り方、考え方であり、皆さんの参考になればと思いこの記事を作成しました。意見、質問、反論等はこのブログのコメント欄に書いてもらうのが一番良いと思います。よろしくお願いします。炎上だけは怖いのでやめてください。