アルゴリズム弱太郎

Twitter @01futabato10

MBSD Cybersecurity Challenges 2021 参加記

この記事はIPFactory Advent Calendar 2021 22日目の記事です。

qiita.com

こんにちは、futabatoです。
2021年の下半期はMBSD Cybersecurity Challenges 2021に参加していました。

コンテストの概要は以下のページやy0d3nの参加記をご覧ください。

setten.sgec.or.jp

y0d3n.hatenablog.com

私が参加したチームAfter_the_CMは第三位でした。
第三位で嬉しい気持ちは一つもなく、悔しい気持ちと反省でいっぱいです。

本記事では、7月19日から12月16日までの5カ月間をy0d3nとは違った視点で振り返ります。
結構ダラダラと書いています。


7月19日まで

MBSD Cybersecurity Challenges 2021の課題は「セキュリティ関連ツールの開発」であることは数週間前に公表されていました。IPFactoryの先輩が過去に最優秀賞を獲得したという記事を見てかっこいいなぁとずっと感じていたので、自分もそのような(セキュリティに限らず)コンテストがあれば是非参加して一番を獲りたいという思いはありました。

これらの記事はコンテスト終盤にモチベーションを上げるためによく読ませてもらっていました。

scan.netsecurity.ne.jp

blog.8ay.ac

azara.hatenablog.com

WAffleを開発したチームに声をかけてみて、やる気を伺ったところ興味があるようだったので3人で課題の7月19日を待ちました。

コンテストには最大4人までチームを組むことができるので、もう1名誰かを誘うことができました。ほとんど私の希望ですが、okodayonくんを誘ってみたところ食いついてくれたのでチームメンバに加わってもらいました。

個人的にはokodayonくんを誘ったのは正解だったかなと思っています。技術を心から楽しんでくれるところや誰とでも仲良く接することができる人の好さは至る所で現れてきます。チームとしてプロジェクトを進めていくのであれば楽しいほうがいいはずです。彼の醸し出す雰囲気には幾度となく助けられてきました。

7月19日

コンテストの課題が発表されました。2021年の課題は「脆弱性診断ツールの開発」でした。
課題が公表されたときの正直な気持ちは「ちょっと辞めとこっかな」でした。

脆弱性診断ツールなんて作れるの…?」

Webについてほとんど勉強したことがなく、HTTPやWebセキュリティについて何も知らない人間が4カ月で診断ツールを開発するなんてできないと感じていました。4カ月あれば何かできるかもしれませんが、自分の実力との乖離がありすぎてかなり怖かったです。わからないなりにこれから学ばなければいけない量を考えてみるだけで怖くて、高すぎる壁に怯えて参加を躊躇っていました。

そんなビビり野郎がいる一方で、他の3人はやる気に満ち溢れていました。 夏休みはすべてコンテストに捧げること、okodayonl7elvliはWebについて膨大な知識を獲得する必要があることに対する覚悟はできていたようです。

数十分悩んでいましたが、僕自身がバカでかい壁にひよっているだけで特にやらない理由はないことに気づいたのでチームメンバーに背中を押してもらう形で参加を決定しました。背中を押してくれたチームメイトには感謝しています。

7月下旬まで

特に誰がリーダーのようなことをするのかは明確に決めていませんが、自然と自分がプロジェクトを管理する立場になっていました。
1次審査提出締め切り日まで18週あったので、しっかりとプロジェクトを進めていくための土台を整備していきました。

連絡ツール

プロジェクトの連絡ツールにはDiscordを利用していました。 VCを使ったミーティングの実施やタスクの連絡だけでなく、分報(times)やGitHubのWebhookの整備をしました。 資料置き場にはGoogle Driveを活用して、Google Docs, SpreadSheet, Slide等もたくさん活用しました。

ガントチャート

タスク管理を1つの表にまとめるためにGoogle SpreadSheet活用してガントチャートを作成しました。

f:id:futabato0110:20211222180651p:plain
ガントチャート

最初の1カ月ほどはガントチャートを使って管理していましたが、次第に誰も確認しないものになっていきました。
理由としては単純にGitHubの方でタスク管理するようになったからで、複数タスク管理するものがあるとどうしても使いやすい方が使われていきます。
自分の担当しているタスクがどれくらいかかってしまっているのが視覚的にわかってしまうので、早く片付けなきゃと思えるのは良かったのかなと思います。

8月上旬まで

実装に入るまで1カ月弱、勉強と調査に時間を充てました。
ここで時間を掛けすぎだと後出しじゃんけんのように指摘するのは簡単ですが、何も知らない3人がツールの全体像が見えないなかでいきなり実装を始めたほうがよいとはなかなか思えません。数日でも早められるように努力すべきだったかもしれませんが、ある程度は必要な時間だったとは思います。

調査

既存の脆弱性診断ツールの調査

「よしやろう!」と意気込んでも私たちは脆弱性診断ツールについて何も知らなかったので、既存の脆弱性診断ツールの調査から始めました。
脆弱性診断ツールについて調べてみたところ、こちらの記事に出会いました。非常にわかりやすく解説されており、こちらの記事のおかげで「脆弱性診断ツールって頑張ったら作れるのかもしれない」と思えたのでとても印象に残っています。

qiita.com

また、20程の既存の脆弱性診断ツールをリストアップしました。 OSSとして公開されているツールは実装のヒントになることが実際に多かったです。

プロジェクトの序盤では、GrabberとArachniを主に参考にしていました。 Grabberはかなり古いですが、非常にコンパクトなのでソースコードを読んでいくうえで欲する情報が見つかりやすいと考え、参考にしていました。

github.com

Arachniはオープンソースの代表的な脆弱性診断ツールの1つです。論文を読んでいくなかでもかなり見かけました。 GitHubリポジトリはArchive化されていますが、ツールとしての完成度の高さから参考にしていました。

github.com

序盤は上記の2つですが、脆弱性検出アプローチを調査している頃はZAP, Wapiti, Vegaあたりも参考にしていました。

github.com

wapiti-scanner.github.io

github.com

機械学習の検討

私は少し機械学習を齧っているため、他チームとの差別化を図るために機械学習の検討をしました。

機械学習に限らず脆弱性診断ツール絡みの論文を数十本リストアップして気になった論文から目を通していきました。

f:id:futabato0110:20211222215015p:plain
リストアップしていった論文集

結果的には機械学習のアプローチを採用することはできませんでした。
Webのドメインについて何もしらない状態で一人で十分な精度が出るまでの仮説検証を回していける自信がありませんでした。 ツールの完成が最優先事項で、機械学習が思うようにうまくいかなかった場合はそこに掛けていた時間すべてが無駄になる(評価される場所がないという意味)ので、2, 3週間調査した後は機械学習のアプローチを取らないこととしてチーム内で合意を取りました。

CSRFの検出はとても難しく、Himawariもステータスコードに依存する判定基準だったので、そこで機械学習が使えていたらインパクトはあったのかなと思います。 CSRF脆弱性検出アプローチに機械学習を取り入れている論文を見つけているので、機会があればBlogにしようと思います。

01futabato10.hateblo.jp

勉強

Web Security Academy

y0d3nの参加記でも紹介されていますが、彼が40問ほどWeb Security Academyから問題をPick Upしてくれたので、3人はそれを解いてWebセキュリティについての勉強をしていきました。普通に面白かったです。

portswigger.net

脆弱性への理解

診断結果のレポートに提示する脆弱性の概要、対策方法等を様々な文献を参照してこの時点で文章にまとめていきました。
レポート機能を実装する段階ではなく、序盤に片付けておいたのは良かったかなと思います。

書籍

私はWebについて知らなかったので、有名なこれらの本を読み漁りました。
三ヶ月くらい毎日徳丸本を読んでいると本に書いてある内容が次第に理解できていったような気がします。

wasbook.org

gihyo.jp

www.shoeisha.co.jp

技術選定

私たちの開発した脆弱性診断ツール「Himawari」はGo言語製です。
「Goの○○なところが良いから」等というような高尚な理由はありませんが、Goを採用しました。
Goを触ったことあるのはチームで2人だけでしたが、Goは非常に学習コストが低く、人が書いたコードも読みやすく感じたので個人的にはGoを選んでよかったかなと思っています。

GUIプログラミングは避けたかったのでWebUIにする以外の選択肢はチームの中でなかったかのように思います。
WebUIにはNuxt.jsを採用していますが、触りだしたのは11月になってからでGoのAPIサーバが出来上がってから一気にWebUIを仕上げました。

8月下旬まで

実際に開発が始まり、まずはSitemapとCrawlerの実装から始まりました。
y0d3nに独自のデータ構造を持つSitemapを提案いただいたので、そのSitemapに合う形に情報を収集できるCrawlerを実装しました。

当時はHTTPリクエストやHTMLについての理解がかなり乏しいうえGoも書けなかったので、設計から実装まで時間は結構かかってしまったかなと思います。その分勉強になったことはたくさんあるので、Crawlerがある程度形になったあとは比較的スムーズに実装が進んでいった気がします。

HTMLパーサにはgoqueryを採用しました。CrawlerからXSSの検知まで助けてもらったので大変感謝しています。

github.com

10月下旬まで

8月9月は夏休みだったので、アルバイト等以外の時間はプロジェクトに注ぎました。週2回のミーティングには毎度ちゃんと出席してもらってありがたかったです。
10月に入ると授業が再開されるうえ、学園祭の準備でほとんど時間が取れないことが予想されたため、若干焦っていました。

9月10月は主にScannerの実装をしていました。
脆弱性検出のパイプライン(「サイトマップから情報を取り出してペイロードを搭載したリクエストを生成 → 脆弱性ごとの検出アプローチの適用 → Issueへの登録」)はokodayonに作ってもらいました。
脆弱性の判断基準を自分の言葉で説明しなければいけない場面が多かったので、そこで一気にWebセキュリティへの解像度が高まっていったように感じます。

okodayonにパイプラインを作ってもらっている間に、僕とl7elvliペイロードの用意と論文や既存の脆弱性診断ツールのコードから使えそうな検出アプローチを探していきました。
独自のSitemapを用意しているため、目新しいアプローチを見つけたとしても実際に取り入れるには難しい場合が多かったです。

パイプラインを作ってくれた後はスムーズに脆弱性の検出アプローチを実装していくことができました。

また、y0d3nがSunflowerという検証用のやられアプリを開発してくれました。

github.com

Scannerの大まかな設計が終わった後は、y0d3nにはSunflowerを準備してもらって、他3人でScannerを実装していきました。
Sunflowerのお陰でHimawariが全8種の脆弱性を実際に検出できることがわかったので、Sunflowerは僕らに安心と自信を与えてくれるものでした。
当たり前のように検証環境があるのはありがたい限りです。 (y0d3nには頼りっぱなしですね、彼がいなければHimawariを完成することすらできませんでした。)

11月19日まで

WebUIの実装

10月でScannerが完成し、「URLを入力 → Crawl → Scan → レポート提示」までが完了しました。 提出期限3週間ほど残したところでNuxt.jsを使ったWebUIの開発に時間を注ぎました。 誰一人Frontendを触ったことが無かったので、時間の無い中でかなり厳しいことをチームに強いてしまったなと感じています。

「componentって何?」というところからよく完成まで持っていってくれたと思います。 (幸いにも)10月でScannerが完成していたので、ワンチャンある状態でUIに集中できたのがよかったなと思います。

ドキュメントの作成

コンテストの1次審査にはツールの有効性を示すためのドキュメントを執筆する必要がありました。
そのドキュメントは書いた量に比例して得点がもらえると思っていたので、Himawariについての説明をかなり丁寧に書きました。 Crawlerから各種脆弱性検出アプローチのアルゴリズムまで改めてソースコードをすべて読んで、自分の言葉で表現していきました。 毎日夜20時に学校から追い出されてしまうので、一人スタバで23時まで居残りしていながらコツコツと執筆しました。 終わりが見えてきてしまったのもあり、11月あたりから急に体力が落ちてきて精神的にもとても辛い作業でした。

チームのメンバーにはドキュメントの心配はせずにWebUIの実装に集中してほしかったのでドキュメントについての言及は一切しなかったのですが「ドキュメントどうしよう」と思わせてしまっていたとは思うので、ちゃんと連絡をすべきだったかなとは反省しています。

精度評価

Himawariのドキュメントにはアルゴリズムの解説だけでなく有効性を示す必要があったので、何かしらの形で精度を算出して文章にする必要がありました。 具体的な評価に関してはここでは書きませんが、論文の中でよくベンチマークとして利用されていたWAVSEPを中心に精度評価を行いました。

github.com

11月19日

1次審査のためのコンテンツ提出日はソースコードの変更はありませんでしたが、ドキュメントがあと一歩完成していなかったので23時までカラオケに籠って執筆していました。

提出した瞬間の達成感はあまりありませんでした。とにかく体力の限界と、プレッシャーによるストレスでただただ休んで寝たいという気持ちしかありませんでした。

11月26日

一次審査を通過することができました。
流石に一次審査に落ちるようなクオリティのものは提出していないと自負していたので当然のように通過するとは思っていましたが、いざ結果を見る瞬間はドキドキだったし、通過していることを確認した瞬間は確かに嬉しかったです。

12月上旬まで

一次審査に通過することができたので本番サイトへの診断と最終審査会への発表準備を始めました。 スライドの作成には想像以上にかかってしまうことがなんとなくわかっていたため、この時点で発表者を決定しました。

チームで推薦を出して発表者を選びました。僕になりました。 僕は結構緊張しいで発表も特にうまくない人間なので、点数のことを考えたら避けてほしい気持ちがありましたがy0d3n, okodayon, l7elvliの3人とも僕を推薦してくれたので、「何か思ってくれてるんだろうな」というのをなんとなく感じて、信頼に応えたいなと思い発表者を引き受けました。

スライド作成に集中させて欲しいことは伝えたので、他3名で本番サイトへの診断準備をしてほしいとお願いしました。 実はこのあたりが私たちのチームが最優秀賞を獲れる獲れないの境目だったなと感じています。

本番サイトへの診断

本番サイトへの診断についてはy0d3nの記事もご覧ください。

y0d3n.hatenablog.com

本番サイトへの診断はかなり苦しい結果となってしまいました。
診断後のチームのムードは良くはなく、最優秀賞が一気に獲れないかもしれないと感じた日でした。

振り返ると、本番サイトへの診断の失敗は完全にこちらの準備不足です。

11月16日の提出時点で体力は尽きてるし、プレッシャーや疲労からメンタルも若干やられ気味だったので集中力がまず落ちていました。
そうなると、視野が狭まって目先のことばかり気にしてしまいます。

個人的には詳細な診断手順書を作成しておくことを考えていました。
本番は緊張や想定外の出来事から頭があまり回らないはずなので、想定できるすべての場合を考えて不具合等への対処の仕方を決めておきべきだったはずです。本番はその手順書を参照してやるだけの状態にしていたかったですが、今手元にある診断手順書は雑なものです。
Error Handlingはしているとはいえ、今まで不具合が起きていなかった部分にも疑ってそこで不具合がでたらどうすることをしっかりと考えて文章に残しておくのは面倒の極みです。
それでも、目の前に転がっている新たな診断対象に診断をかけて未知のパターンを探すことに専念するよりかは、もっと診断の手順を我々の間で定めておくべきでした。

一度議論していた内容を診断手順書にメモをしていなかったので本番で完全に忘れてしまっていたり、今まで起きていなかった部分での不具合がちょうど発生したりと、想定外の出来事はある意味では必然的に起きてしまったように思えます。
診断の手順を定めていなかったからすべてその場その場での対応になってしまいました。頭が回っていなければもっと点数は低かったかもしれません。

僕はスライドの作成にかなり意識が持っていかれていて、他の3人が今どうしているのかが正直掴めていませんでした。
診断手順書があまり作られていなくて大丈夫かなと感じた瞬間は確かにありましたが、自分のキャパシティの狭さや体力や精神力が相まってそこまで手を回すことができませんでした。ずっと密な連携をしてきたのにここに来て疎になる進め方をしてしまったのをとても悔やんでいます。

12月16日まで

チーム全員のメンタルがやられている中、無心で発表への準備を進めていきました。

苦しい結果を招いてしまったのは自分ではありますが、どんよりとした雰囲気の中で太陽のようにメンバーを元気づけられたり、少なくともいつもと同じように落ち着いて振舞えたらなと何度も思いました。
そうは思えていましたが、実際には全くできていなかったと思います。
僕はとても心が弱いうえ、その時の感情が顔や発言にわかりやすく反映してしまうので、負の感情を抑え込もうとするのに精一杯でした。

おおよそ発表の筋はできていたので、それをスライドに落とし込む作業に移っていましたが、それに結構時間がかかってしまいます。
ドキュメントの時のように一人スタバで23時まで居残りしていながらコツコツと作成しました。
スタバの店員さんには抹茶ティーラテのTallサイズを頼む人として認識されていたと思います。

スライドは前日の深夜まで作成していて、当日の提出期限数分前に満足のいくものが完成しました。

12月16日

発表は言いたいことはほぼほぼすべて伝えることができたかなと思います。
発表時間も数秒残しと、一度も発表練習をしていないわりには良いペースで発表できました。
スライドの作成にはかなり時間を割いたので、是非ご覧ください。

speakerdeck.com

結果は上記の通り3位でした。
コンテストが終わって数日経って少し冷静にはなれましたが、やはり悔しい気持ちで溢れています。


全体を通して

5カ月間を通して、とても幸せな日々でした。 チーム全員で「最優秀賞を獲得する」という目標を持って全力で取り組んでいる時間は紛れもなく充実していました。 誰かに邪魔されることなく、ものごとに集中できるのはありがたい話です。 このコンテスト開催に携わっていただいた大人の方には改めて感謝申し上げたいと思います。

プロジェクトを管理する立場になって

チームにとって良くない状況になったときに正しく軌道修正ができる人、冷静を装える人がリーダには向いているのかなとつくづく感じます。
良くしたいとは思っても思うだけで実際には振舞うことができなかったので、うまく管理ができなってしまいあと一歩の作業をやりきれなかったと考えています。 3位という結果を招いてしまったことにはとても悔やんでいるし、大変反省しております。

プロジェクトをマネジメントする大変さはよくわかりました。 4人のプロジェクトですら今誰が何をしているのを把握するのはとても大変です。ある程度忙しい方がパフォーマンスが出る、家だと何もしていない謎の時間が生まれるから学校で作業したい人たちが集まっていたのが幸いで、夏休み明けはMax週5のミーティングで4人団子になってプロジェクトを進めていました。連絡はかなり密だったし、誰かが苦戦しているタスクがあればすぐにサポートに入ることができました。中には密な連絡をしていくのが合わないという人もいるかと思うので、4人ともいい意味で似たような人たちで良かったなと思います。

しかし、団子になっていたチームを分けてしまったからこそ1次審査通過後の体制が崩れていったのかなと感じています。 自分自身も疲れてきてしまってから人に気を配ることもできず、大変不甲斐ないです。

人にタスクを与える際も、その人にあった説明の粒度と量と難易度を調節する必要があります。
難しいタスクをろくな説明もなしで投げてしまっても良いことはないです。
自分が「これくらいの説明でいけるだろう」と思った2段階くらい丁寧な表現で、誤解のないように伝えるには経験が必要です。 説明の仕方や話のまとめ方についてはプロジェクトを通じてとても勉強になりました。

説明の仕方はまだしも、難易度の調節は少しでもできるようになった気がしません。
プロジェクトの期間は5カ月もあったので、たくさん成長できる機会がありました。
たくさん成長できる機会があったにもかかわらず、特定のタスクには特定の人ばかりを任せてばかりでした。
多少タスクを終えるのに時間がかかったとしても、今後の成長を見込んで(その人にとって)多少難易度の高いタスクを任せる勇気は自分にあったかというと怪しいです。どうしても安定志向をしてしまします。
その人の成長する機会を僕が奪ってしまった可能性があると考えると、辛いです。

プロジェクトの進行も、それっぽいことを言いながらすべてその場しのぎだったかもしれません。
ツールとしての全体像が見えないときは、ある作業がどれくらい重い作業なのかを推し量ることがなかなかできませんでした。 とりあえず任せる形になって、次どうしようどうしようと意思決定に時間がかかることもありました(4人の中で偉い偉くないの関係はありませんが、プロジェクトを管理する人は暗黙的に50%くらいの意思決定力はあったかもしれません)。
Pull Requestが出されても気づいたら数日放置されていることが多々あったので夜寝る前にReviewを片付けるようにして余計な日数を減らすようにしたり、解散後スタバで一人もくもく会をして消化していたりと、プロジェクトの後れを取り戻すために少し無理する期間が少し長かったです。進め方が悪いのは承知の上ですが、チームに与えているタスク以上の負担を掛けたくなかったので全部自分で解決しようとしたのが精神がすり減る悪循環に陥っていたのかもしれません。

「じゃあ次にやるプロジェクトではそこを改善したい!」という意欲は今はないです。
疲れてしまったのもありますが、まとめていく立場は自分にはあまり向いてないんだなとつくづくと感じた5カ月間でした。


この記事はIPFactory Advent Calendar 2021 22日目の記事です。

qiita.com

昨日21日はry0kvnによる「Windows Kernel Mode Driverのreflectiveなロードをやってみる」でした。

snoozy.hatenablog.com

明日23日はdaiki0508くんによる「BackDoorAPK解析してみた」です。お楽しみに。

daiki0508.hatenablog.com