MBSD Cybersecurity Challenges 2021 参加記
MBSD Cybersecurity Challenges 2021
こんにちは。y0d3nです。
去年WAffleを作ったチームにokodayonを加えた4人でMBSD Cybersecurity Challenges 2021に出場しました。
プロダクト名はHimawari。申し込み開始直後から5カ月フルで取り組みました。
リポジトリは後日公開します。
自分のHimawariのイメージは「誰でも使えるけど、対象の仕様を把握していれば精度があがる」という感じです。
サイトの開発者が使うことを最優先して設計していました。
メンバーはこんなかんじ。
l7elVliとokodayonはIPFactoryに所属していないので、After_the_CMとして出場。
チームのアピール文は「セキュリティチョットワカル」でした。
↓ エントリチーム一覧
コンテストついてと途中で起こった出来事等について書きます。
競技設定
「よし、脆弱性診断を内製化しよう」
コスト削減のため社員に脆弱性診断を担当させたい。
診断ツールの開発を外部委託。
参加者は委託された側として、診断ツールを作成する。
スケジュール
チームエントリー受付 2021年7月19日(月)~11月19日(金)
コンテンツ提出期限 2021年11月19日(金)
一次審査結果発表 2021年11月26日(金)
本番サイト診断 2021年12月6日(月)~12月10日(金)のうち、4時間
最終審査会 2021年12月16日(木)
エントリーから提出期限までは4カ月。最終審査会まで含めると5カ月。
8, 9月あたりは夏休みなので、結構時間はとれました。
1次審査 競技概要
Webアプリの脆弱を調査するための診断ツールの作成
診断ツール・ソースコード・インストール手順書や操作説明書を提出
(操作説明書は開発エンジニアが操作する前提で書くこと)
1次審査 審査観点
脆弱性の検出率や検出時間など、診断ツールの有効性を示すこと。
診断ツールが正常に動くこと。動作環境や操作説明をわかりやすくすること。
診断ツールの操作が単純なこと。開発エンジニアが操作するのを想定すること。
検出率や制度を向上させるための機械学習やクローリング機能、非破壊等の他の診断ツールとの差別化を図る機能については特に注力して評価されるとのこと。
最終審査 競技概要
クラウド環境上に用意された本番サイトでの検出率で評価(false positiveやfalse negativeは減点)
診断結果は運営が指定したフォーマットで出力すること。(フォーマットは一次審査突破したらわかるらしい)
エントリー ~ 一次審査提出
エントリーが完了。本格的に作業開始と行きたいところですが、
WebSecが自分しかわからない現状はだいぶきつい。
幸いエントリー時の追加情報で採点対象となる脆弱性は公開されていたため、
それぞれの項目についてWeb sec academyの基礎的な問題を合計40問ほどピックアップしました。
色とりどりの済スタンプですが、discordに4人分の:done:
スタンプを作成して進捗管理してました。
(色はそれぞれの好きなカラーコードに従っています)(ガントチャートでもこの色を使ってる)
調査
8月序盤は主に既存の診断ツールの調査。中旬になってからコーディングを開始。
githubにpushし始めようとしましたが、プロダクト名が決まっていません。(7月の時点で案出しはしていた)
自分が出した案からいくつか抜粋します。(後半でだんだんボカロオタクが露呈する)
crepe (WAffleのライバル的存在として), pancake, CATERPILLAR (arachniに対抗して), trigger-happy, freshlessburger (fresh ness burgerによく行くので、パロディ), surges, phony, Thanatos, hedgehog, meteor, anatomy, Muffet, Ariados, starduster, sunflower, FireFlower
sunflowerを提案したときにfutabatoが「結構前にHimawari提案したんだよね」となったのですが、Himawariの語感が良くて割と気に入り、全員一致でHimawariに決まりました。
ひまわりの花言葉に「あなただけを見つめる」というものがありますが、診断を行う上での「スコープ」に通じるものある気がします。(だいぶこじつけ)
一応診断をやっている身としてはスコープの概念は大事にしたいと思っているので、この花言葉は気に入っています。
クローラー
9月に入り、ある程度クローラーが完成してきたところで、BadStoreをクロールしたときにエラーがでていることに気付きました。
runtime error: index out of range [0] with length 0 : /mnt/c/Users/yoden/.../Himawari/models/crawler/forms.go:27 (0x75a6e4) SetValues: r.Form.Action = input[0].Action
ここはレスポンスにformがあるときのみ実行されます。対象になっていたページを確認したところ、inputもある。
input[0]でindex out of rangeが起こるはずがありません。
デバッグしてみると面白いことが起きていたので、別のエントリとして書きます。
「壊れてしまった特別なFrom」近日公開します
いくつかのやられサイトをクロールしているうちに、クロール結果のsitemapをインポート・エクスポートできたら面白いんじゃないかと思ってjsonに変換できるようにしました。 これでクロールを何回もする必要がなくなったり、クロールに不備があった場合に手書きで編集できます。
Himawariはjsに対応していないので、jsで画面遷移するような場合もjson手書きすればscanできるようになっ
スキャンに必要そうな情報を持たせたらフィールドが増えてしまいましたが、それ以上に使い勝手が良くなった感じがして気に入っています。
(今回の利用者は自社のWebサイトをスキャンするので、その目線からでも良い機能だと思っています。)
スキャナー
クロールがほぼ完成したので、スキャン機能を実装していく。
クエリやBodyだけでなくRefererなどのヘッダにもペイロードをセットすること、セッションがある場合のCookieをどうするかなど、いろいろと話し合いましたが、思ったより大変そうで「急がないとやばい」という気持ちが芽生えました。
検知方法(基準)から考えてOS Command Injectoinでsleepさせるのが一番検知しやすいと思い、まずはOS Commnad Injectionの作業から。
スキャンを実装するにあたってやはりやられアプリが必要だと思い、急遽Sunflowerという名前で作成し始めました。
https://github.com/y0d3n/Sunflower/
SunflowerはHimawariのテスト用に作りましたが、同時にHimawariの有効性を示す良い実験台になりました。
(Sunflowerに刺さるようにHimawariを調整してる部分もあるので精度評価等には向きませんが・・・)
URL, Query Parameter, POST Body, User-Agent, Cookie, Referer等、どこに脆弱性があるかは完全に実装次第なので、とりあえずいろんな箇所にOS Command injectionを作りこんで共有しました。
以下、Sunflowerで実装した脆弱性です。
- OS Command injection
URL Path、URL Queryのパラメータ名、value、User-Agent、Cookie、Referer、Bodyのパラメータ名、value、301リダイレクト先(session)、307リダイレクト先(post) - SQL injection
timebased、errorbased
それぞれmysql, mssql, pgsql - Directory Traversal
絶対パス、相対パス - XSS
Reflect XSS、Stored XSS、inputタグのvalueの中に出力されるXSS、textarea内に出力されるXSS - Open Redirect
- Directory Listing
- csrf
- HTTP Header injection
それぞれの脆弱性毎にブランチを作成し、最低限の構成でテストできるようにしています。
が、同じコンテナ名で違うDockerfileとかがあるのでcheckoutすると起動できなかったりする。。。
Sunflowerに集中している間、チームの3人がスキャンをほぼ完成させてくれました。(というより、3人が集中してスキャンを実装するためにSunflowerを作ってた)
他のチームとの差別化になると思い、StoredXSSの検知にチャレンジ。
それまでは数分程度だった(確実に刺さるペイロードのみに絞ってたので早かった)スキャンが4時間になってしまい、StoredXSSの検出はオプションにすることになりました。
UI
11月に入ったころにスキャンが大体完成。
エラーハンドリングの見直しや、他の機能の微調整を済ませ、UI作成に取り掛かり始めました。
4人ともフロントを触ったことが全くなかったので苦しかったです。
全員でUIに取り掛かりたいところでしたが、スキャン機能にも改善点がいくつかでてきました。
この時点では、ログイン必須のページがクロール・スキャンできませんでした。
なのでログインの情報を入れた場合はburpのマクロみたいに毎回ログインのリクエストを送信することに。cookie jarとかの扱いが割と面倒でした。
締め切り当日。
Goとnuxtをシェルスクリプトで一気に起動するためにディレクトリ構成を変えたら動かなくなりました。
結論から言うと相対パスの所為だったのですが、胃がキリキリしたし変な汗かいてました。。
4カ月ずっと作ってきたものが最後の1日で全く動かなくなるの、本当に心臓によくないです。。。
↓ 学校が閉まった後カラオケに逃げ込むオタク達
カラオケきた pic.twitter.com/5pxvtNKs8b
— よーでん (@y0d3n) 2021年11月19日
一次審査提出 ~ 一次審査結果発表
締め切りに間に合わずに修正をあきらめていた部分の修正をしながら、一次の結果を待ちます。
代表者にメールが来ると書いてありましたが、例年"専門学校と経営"さんで結果が公開されているのは確認しています。ここで力の見せ所(?)です。
"専門学校と経営"さんのページを見ていたら、公開されているページのURLがhttps://setten.sgec.or.jp/cooperation/093.html
となっていたので、094.html
で公開されるだろうと予想して094.html
を数分おきに更新しました。
ずっと404だったので退屈な作業になっていたのですが、16:45分頃に公開されました。
一次突破。とりあえず一安心です。
一次審査結果発表 ~ 本番サイト診断
診断に向けて調整をしていきます。
バグややり残しがポンポン見つかりました。
結構致命的だったのが、ループが一つ多かったせいでscanの時間が10倍程度かかるようになっていたことです。
もともと「こんな時間かかるわけないんだよな・・・」とは思っていたのですが、なかなか原因が見つかりませんでした・・・
その機能で2時間以上かかっていたscanが15分くらいで終わるようになり、「もっと早く気づけてれば・・・!」ってずっと言っていました。
本番サイト診断
本番サイト診断。制限時間は4時間。
ツールの微調整は許されていたので、対象の挙動を見ながらチューニングします。
本番サイトについてですが、まずログイン機能がないと門前払い。ログインしてからも想定していたより複雑な仕様。
どんな方針でツールを作っていたかの運要素が強い印象でした。
結果は結構残念な感じ。
手動でXSSやディレクトリトラバーサル、オープンリダイレクトを見つけていたのですが、Himawariの仕様からして対応できなかったりスキャンしなおす時間がなかったり、結構悔しい感じで終わりました。
開発者が使いやすいように、手動の挟まる余地のないツールを作ったチームは同じくらいの結果しか出てないだろうと思います。相性次第でだいぶ点差つけられてしまうので結構辛い。
終わった後、logを見てたらオープンリダイレクトとHTTPヘッダインジェクションがありそうなところや、robots.txtの存在に気付きました。
明らかにadminページっぽいのがあってとても悔しかったです。。。。
時間が足りない。焦りすぎてあり得ないミスがありました。
Himawariはもともとサイトの開発者向けに作ったということもあり、対象サイトの仕様を把握してからゆっくりサイトに沿ってチューニングできていればもっと違ったのかなという印象です。
本番サイト診断 ~ 最終審査会
診断が終わった後はもう切り替えてスライド作り。
Himawariを使いたくなるようなスライドを作っていくのですが、この辺のシナリオも難しい。
- プレゼン相手は誰なのか。
実際に使う相手にプレゼンするなら、「こんな機能があります!」とアピールすればよいが、
経営層相手なら、技術的な話がわからない可能性も考慮しなければならない。 - 一次審査で提出したのは"大会の都合上提出"したのか、"外注元に納品"したのか。
前者ならHimawariがどんなツールなのかをアピールしなければならないし、
後者なら「どんなツールなのか」は相手は分かっていることになるので、蛇足になる。
と、いろいろなシナリオのメタ読みが飛び交いました。
最終審査会
各チームツールのプレゼンを行っていく。
全チームの内容をくまなく聞いていたのですが、0xDEADBEEFさんがCDPでDOM based XSSの検出をしていたのが印象的でした。利用者はブラウザを触る必要はないけど、jsの実行やセッション等をChromeに任せることが可能で、シンプルに関心。
DOM based XSS以外にもいろいろな脆弱性の検知を実装していて、一次審査の得点は間違いなく0xDEADBEEFさんが一位だと思いました。(結論から言うと当たっていた)
弊チームの発表資料です。
発表はfutabatoがやってくれました。
全部聞いたところ、プレゼンはダントツ一位だと思ったのですが、プレゼンも同率一位という結果でした。
がっつり技術的な話をしていたチームも点数が高かったので、今年のプレゼン相手は別に経営層とかじゃなかったということかな。
賞品
最終審査会に参加したチームには参加賞があり、上位三チームには以下のような賞品。
順位 | 賞品 |
---|---|
1位 | Surface Go3 + TypeCover アマゾンギフト券 ¥20,000 Burp Suite Professional 1年間ライセンス |
2位 | iPad(2021年モデル/256GB) アマゾンギフト券 ¥10,000 |
3位 | Kindle Paperwhite シグニチャーエディション(32GB) アマゾンギフト券 ¥5,000 |
結果
合計点では3位。やはり検出点がだいぶ足を引っ張っています。
今回は自動診断ツールの結果で競うということなので、手動でやった宣言をしているチームは検出点が半減しています。
順位 | チーム名 | 学校名 | 一次審査 | 検出点 | プレゼン | 合計点 |
---|---|---|---|---|---|---|
1 | 帰ってきた電子遊戯部 | 新潟コンピュータ専門学校 | 25 | 17 | 27 | 69 |
2 | 0xDEADBEEF | ECCコンピュータ専門学校 | 27 | 16 | 24 | 67 |
3 | After_the_CM | 情報科学専門学校 | 25 | 9 | 27 | 61 |
4 | OS | 日本工学院北海道専門学校 | 20 | 7 | 20 | 47 |
5 | ステークホルダー | 北海道情報専門学校 | 20 | 8 | 18 | 46 |
6 | c2VjdXJpdHk= | 日本工学院専門学校 | 19 | 9 | 13 | 41 |
7 | チームグー。 | 創造社デザイン専門学校 | 18 | 3 | 16 | 37 |
8 | 福岡 | 東京電子専門学校 | 18 | 0 | 18 | 46 |
9 | どみねいたあず。109 | 創造社デザイン専門学校 | 19 | 4 | 12 | 35 |
10 | くまドン | 日本工学院専門学校 | 16 | -1 | 16 | 31 |
一番楽しかったこと
去年作ったWAF (WAffle) をSunflowerにセットしてスキャンした事。
自分達が作ったやられアプリを自分達が作ったWAFに防御させて自分達が作ったスキャナーでスキャンした。(自作OS民の自作ブラウザ感がある。)
WAffleのblacklistをちゃんと書いたら、WAffleで対応してる分はHimawariでは検知できなくなった。(まぁ自分で調整したのでそれはそうだが)
いろいろ頑張ったなぁという気持ち。
一番ためになったこと
コメントアウトなどのルールを序盤に決めておかないと後々苦しむ。
「何をしているか」より「何故しているか」を書くこと。
もっと期間に余裕があったらリーダブルコードでも読んでおけばもっと違ったかもしれない。
反省点
本番サイトの診断
だいぶコケた。
例えばjsで通信が発生していたページに脆弱性がある場合、jsonを手動で書かなければいけない。
これは対象サイトの仕様を把握していないとjsonをすぐに書くのは難しい。
急いでいたし、対象サイトの仕様を知らないので、jsonを手書きした際にミスをしていて時間を無駄にしてしまいました。
ローカルプロキシでやってるチームはjsやセッション管理等をブラウザに任せているのでアドバンテージが大きい。
ローカルプロキシの診断ツールが開発者にとって使いやすいかはさておき、本番サイトの診断で使うのは作った自分達です。
多少開発者にとって使いにくくても一次の点数はそこまで落ちないようでしたし、 自分たちが使いやすいツールを作った方が得でした。
インストール
「動作保障環境」の記述についてです。 "動作保障"と"推奨環境"は別で、動作を保証できるのはあくまで自分たちでやっていた環境です。
推奨環境を書くための動作確認をやっている暇がなくて自分たちの環境を「動作保障環境」として書いたのですが、それが推奨環境として受け取られてしまったようでした。
FBに「インストール手順が複雑だった」のように書かれていた時は「どこか他のチームと間違えてるんじゃないか?」とびっくりしました。(インストールはシェルスクリプトで1発だったので・・・)
最新版でも動くとは思うので、一言添えていればよかったです。
感想
「もっとああしていれば」や「あれに対応していれば」等、反省点ばかりでした。
本気で最優秀賞を狙っていたのでめちゃめちゃ悔しいですが、とても楽しい5カ月間でした。
もっと精進します。
この記事はIPFactory Advent Calendar 2021の12/17分です。
IPFactoryというサークルについてはこちらをご覧ください.
昨日はmorioka12による「バグバウンティで初めてCriticalな脆弱性を見つけたまでの話(WIP)」でした。
明日はy0d3nによる「壊れてしまった特別なForm」です。