8/25から9/9の2週間という長期間*1で開催されていた。メンバー5名からなるチーム藤原豆腐店*2で参加して、2位。日本チームとそれ以外とでブラケットが分かれていたけれども、国内順位と総合順位の両方で2位だった*3。国内決勝にはほぼ確実に進めるだろう*4。
さて、本大会は大きな欠陥のあるルール設計であったり、問題の質の低さであったり、フラグフォーマットの不統一や不明瞭さのような本質とは直接関係のない部分での問題であったり、粗が目立っていた。言いたいことは山ほどある*5が、もし次回大会が開催されるのであれば、改善されていることを祈りたい。
ルールの欠陥については後述する。問題の質については、合理的な手順では到底正解へたどり着けない、いわゆるエスパー要素で問題の「難易度」を担保しようとするのは、どうかやめていただきたい。このようなCTFの面白さ(あるいは、Automotive CTFの公式ページで主張している "high-stakes global automotive-focused CTF" と呼ぶに足る要素)から逸脱した試みは、プレイヤーの怒りと失望をもたらすだけだ。もっとも、これを日本語でブログ記事に書いていても運営には伝わらないので、surveyで伝えたいところ*6。
writeup
[Stego 10] Stego 1 (xxx solves)
Find the hidden text
隠されたテキストを見つけてください。
添付ファイル: bhlogo.png
CTF運営のBlock Harborのロゴが与えられている。なぜステガノグラフィーの問題がこのCTFで出されているのかよくわからない*7けれども、うさみみハリケーンに同梱されている青い空を見上げればいつもそこに白い猫で色々見ていると、緑色と青色のLSBで FoundME
というメッセージが隠されていた。
そのまま提出すると通った。
FoundME
[Misc 515] Gameboy Game (xxx solves)
Who needs a defcon badge when you've got an emulator? Dodge some cones, have some fun.
エミュレーターがあればDEFCONバッジはいらないですよね?コーンを避けて、楽しみましょう。
添付ファイル: game.gb
ゲームボーイのゲームのROMが与えられている。mGBA等のエミュレータに与えると、次のように起動できた。コーンを避けつつバッテリー(円形のオブジェクト)に接触して点数を稼ぎ、32767点ちょうどのときに矢印に当たればクリアらしい。
頑張れば通常プレイでも達成できそうだけれども、それは時間の無駄なのでメモリハックを試す。mGBAでTools → Game state views → Search memoryからメモリ検索用のツールを開き、まず 0
で New Search
する。バッテリーに接触してポーズし、Search Within
で現在のスコアを検索し、先程まで値が 0
だったが今は現在のスコアになっている箇所を探す。何度かスコアを変化させて絞り込んでいくと、0xcb93
に現在のスコアが格納されていることがわかる。
Tools → Game state views → View memoryで 0xcb93
に移動し、メモリを書き換えると、スコアを32767点にできた。
このまま矢印に接触すると、フラグが表示された。素直で面白い問題だった。今回見た問題の中で一番面白く感じた。
BH{CARS_HATE_CONEZ?}
[xNexus 160] Web RCE Anomaly (xxx solves)
An RCE has been logged in xNexus, what was the exploit used? The answer should be enclosed in the proper flag format of this game.
xNexus account - https://(省略)
Note: Modificiation of the account password will result in immediate disqualification of your ENTIRE team from the CTF. DO NOT MODIFY.
xNexusにログとして記録されたRCEは、どういうエクスプロイトが使用されましたか?本ゲームのフラグ形式で答えを囲む必要があります。
xNexusアカウント - https://(省略)
注意:アカウントパスワードは変更しないでください。変更した場合、失格とさせていただきます。
VicOneが提供している、脅威を可視化できるxNexusというプラットフォームへの接続情報が与えられている。問題文から察することができるけれども、どうやら全チームが同一の環境らしい。メニューの項目がそこそこある中でひとつひとつ、ポチポチ触っていると、Incident Detection → OAT DetectionsからShellshock(CVE-2014-6271)が検知されている様子が確認できた。
ではと BH{Shellshock}
を試す。通らない。色々試していると、全小文字の bh{shellshock}
で通った。フラグフォーマットに大文字小文字にと、まったく本質的ではない部分で少し悩んでしまった。こんなどうでもいいところでcase-sensitiveにフラグの受け付けをされても困る。
Shellshockを悪用した攻撃が検知されたという情報を見つけた時点で解けたといってもよい(これがこの問題でもっとも本質的な部分である)わけで、BH{Shellshock}
でも BH{SHELLSHOCK}
でも、なんなら問題文での指定を無視して bh{}
で囲んでいない、かつ一般的な表記でない shell shock
やCVE番号を提出した場合でも通すべきではないか。
このShellshockはfalse positiveだったり、あるいは検知して侵入は防がれていたりで実はrabbit holeであって、ほかにShellshock以外の脆弱性を使ってRCEにいたっている記録があるのではないかと考えてしまった。あるいは、問題文では「どういうエクスプロイト」かと聞かれているから、答えるのは脆弱性の通称ではないのかとも。が、これ。「検出された脆弱性のCVE番号を bh{}
で囲ったものをフラグとして提出してください。例: bh{CVE-2024-4577}
」 ぐらいに明確な形で指定してほしい。
bh{shellshock}
[xNexus 885] Can bus anomaly #1 (xxx solves)
Analyze CAN Bus Data anomalies and find the pattern. Answer should be enclosed in the standard format flag.
xNexus account - https://(省略)
Note: Modificiation of the account password will result in immediate disqualification of your ENTIRE team from the CTF. DO NOT MODIFY.
CANバスデータの異常を分析し、パターンを見つけてください。回答を標準のフラグ形式で囲んでください。
xNexusアカウント - https://(省略)
注意:アカウントパスワードは変更しないでください。変更した場合、失格とさせていただきます。
このプラットフォームでは、不審なCANのデータが検知された際にその内容も記録されており、先程使ったIncident Detection → OAT Detectionsで、個別のデータの詳細から閲覧できるようになっている。
1個1個CANのデータを手作業で見ていくのも面倒なので、というよりも何千件もあってとても無理なので、叩かれているAPIを解析することにした。ChromeのDevToolsでNetworkタブを開いてレスポンスを眺めていると、主たるデータは /internal/uic/bff/api/v1/detection/query
から得ていることがわかった。パラメータとして取得する期間であったり、ページングにあたっての1ページあたりのデータ数であったりが与えられている。このリクエストを改変して、2024-02-25以降の全件を取得しJSONとして保存した。
次のスクリプトで、CANのIDとデータをペアとして出現した全組み合わせを出力する。
import binascii import re s = '' for i in range(1, 10): with open(f'aa-{i}.json') as f: s += f.read() a = re.findall(r'can_frame\\\\\\": \\\\\\"([0-9a-f]+)', s) b = re.findall(r'can_id\\\\\\": 0x([0-9a-f]+)', s) for x, y in zip(a, b): print(x, y)
実行結果は次の通り。
$ python3 s.py | sort -k 2 | uniq 0000000000000000 00000000 0101010101010101 00000000 0202020202020202 00000000 0b0b0b0b0b0b0b0b 00000000 1234 00000000 0000400000000000 00000094 0000800000000000 00000094 0200000000000000 00000094 0279660000000000 00000094 1337c00000beff00 00000094 6c346700000000 00000094 005000007a370200 000000aa 0000 000002bc 038a 000002bc 0503 000002bc 1234 000002bc 005000007a370200 00000323 005000007a370200 00000427 005000007a370200 00000465 005000007a370200 000004e8 005000007a370200 00000554 005000007a370200 00000560 0210020000000000 00000645 0211010000000000 00000645 023e000000000000 00000645 0314ff0000000000 00000760 0354ff000000346c 00000768 037f147800000000 00000768 6f6d346e00000000 00000768 037472793a5e2065 1cebff29
「CANバスデータの異常」だとか「パターン」だとか言われても指示があまりに曖昧で、かえって思考にあたってのノイズにしかならない。一度問題文のことは忘れてエスパーによって変な部分を見つけることにする。特に以下のデータがCANのデータとしては不自然な上に、ほぼASCIIの範囲内で構成されており、また繰り返し送信されており怪しい。
0279660000000000 00000094 6c346700000000 00000094 6f6d346e00000000 00000768 0354ff000000346c 00000768
デコードすると以下のような文字列が出てくる。
yf l4g om4n 4l
om4n…fl4g…オマーンの国旗? いや、そんな問題やCTFと関係なさそうなフラグであるわけはないと思いつつも一応試し、失敗し、また別のそれっぽい文字列ができないかと適当に組み合わせていく。4nom4lyfl4g
(= anomaly flag)という文字列が見えた。
これを問題文の指示通りに「標準のフラグ形式」にあわせて提出すると、無事正答と判定された。明確に bh{}
で囲めと指示してほしい。ここまでで大文字である BH{}
で囲んだり、あるいは囲まなかったりと「標準のフラグ形式」も何もないフラグが出現しているのだから。なお、フラグフォーマットについて、ルールページでは「典型的なフラグのフォーマットはBH{FLAG}です」または「Typical flag format is BH{FLAG}」とされている。
CANについて何も詳しくない人間がエスパーだけで完全に通してしまったわけだけれども、詳しい人であればより筋道の通った解法で解くことができたのだろうか。特に文字列の並び替えについて、適当に組み合わせることでそれっぽい単語が出てきた、というようなものでなく、この順番が正しいと確証を持って言えるような証拠はあったのだろうか。
bh{4nom4lyfl4g}
[xNexus 940] Can bus anomaly #2 (xxx solves)
Someone is trying to disable the ESP and the power assisted system. Go track that anomaly with CAN ID 0x0645 and determine what car is being targeted for that kind of attack. The vehicle is the flag enclosed in the proper flag format.
xNexus account - https://(省略)
Note: Modificiation of the account password will result in immediate disqualification of your ENTIRE team from the CTF. DO NOT MODIFY.
誰かがESPとパワーアシストシステムを無効にしようとしています。CAN ID 0x0645でその異常を追跡し、そのような攻撃の対象となっている車を特定してください。その車が適切なフラグ形式で囲まれたフラグです。
xNexusアカウント - https://(省略)
注意:アカウントパスワードは変更しないでください。変更した場合、失格とさせていただきます。
#1
の続きらしい。/internal/uic/bff/api/v1/detection/query
から得られた、CAN IDが0x0645であるデータは次の通り。jptomoyaさんの見解では「EPSを無効化しようとしてるという問題文と合致し」ているということだった。しかしながら、同APIで得られる情報にはさらに有益なものはないように思える。
0210020000000000 00000645 0211010000000000 00000645 023e000000000000 00000645
ところで、フラグとして求められているのは「what car is being targeted for that kind of attack」もしくは「攻撃の対象となっている車」だ。これまたどの程度の粒度で答えればよいかわからないような曖昧さで大変困ってしまう。VIN、車種、型式、色々考えられるけれども。少なくともVINはAPIから得られたものを、VIN単体、bh{}
や BH{}
で囲ったものを投げてもどれも通らない。
Satokiさんがフラグフォーマットについて運営に聞いたところ、bh{Toyota Hilux Conquest}
のような粒度で答えろということだった。どうせ聞かれたら答えるのならば、最初から問題文で例示すればよいではないか。何度も聞かれているだろうし、後からでも書き加えればよいではないか。なぜこういった形で解答にあたってほとんど必須とも言えるような情報を隠し、悩みに悩んでわざわざ運営にまで聞きに行った一部のチームだけ特定の情報を得られているというフェアでない状況を作り出すのか、理解に苦しむ。
さて、「トヨタのHilux Conquest」というレベルで車の情報がわかるような証拠はどこかにあるだろうか。まずAPIにそういった情報がないか疑う。またDevToolsを眺めていると、/internal/uic/fats/api/v1/integration_config/bh/targets
で以下のようなJSONが返ってきていた。ターゲットに紐づいたキーワードとして Lexus
とある。しかしながら、Hilux Conquest
という例と比較すると情報が足りないように思える。一応 Lexus
や Lexus LX
等のそれっぽいものを試してみるものの、いずれも通らなかった。
{ "code": 0, "message": "Success", "data": { "targets": [ { "id": "3c7d4fb4-1ca4-4300-bf09-c41e0e11103d", "type": "keyword", "name": "Mach-E", "is_linked": 1, "keyword_list": [ "Lexus" ], "keyword_sync_time": "2024-04-26T01:23:11.743Z" }, { "id": "94bc2c27-ae8c-4239-bc1a-f35ef3daba77", "type": "keyword", "name": "BWI", "is_linked": 0, "keyword_list": [], "keyword_sync_time": "0001-01-01T00:00:00Z" }, { "id": "ecbd493c-760c-46fa-ae2c-321bc0f5a7b5", "type": "xCarbon", "name": "Mach-E BMS", "model_id": "Mach-E", "device_type": "BMS", "is_linked": 1, "keyword_list": [], "keyword_sync_time": "0001-01-01T00:00:00Z" }, { "id": "377ff399-45c9-4292-acce-bd9e2b6a6a26", "type": "xCarbon", "name": "Mach-E CGW", "model_id": "Mach-E", "device_type": "CGW", "is_linked": 0, "keyword_list": [], "keyword_sync_time": "0001-01-01T00:00:00Z" } ] } }
もっと深い情報が得られるAPIがあるのではないか。チームieraeのWebが得意なtyageさんがすでに解いているとスコアボードからわかっていたから、そういったWebベースのアプローチを考えた。こういうちょっとしたメタな情報にも頼りたくなるほどに、何をすればよいのかわからない。
このプラットフォームのフロントエンドはVite + Reactで作られているようだけれども、JSファイル中にAPIの一覧は存在していないか。/assets/index-CuKdG4TM.js
を眺めていると、次のようなものが見つかった。これまで見たことのないAPIも含まれているように思える。ただ、どれも微妙そうだ。隠しAPI等を触っていると、問題文中の「アカウントパスワードは変更しないでください。変更した場合、失格とさせていただきます」のような注意に引っかかってしまうかもしれないので、どうしても解けないという場合に詳しく見ることにした。
zT0="internal/uic/bff/api/v2/session/" DY0="internal/uic/bff/api/v1/user/switch" OT0="internal/uic/idp/api/v1/token/api/issue/3rd/svp" hT0="internal/uic/bff/api/v1/vehicle/brand/0/models" TT0="login/verify_activation_code" vT0="login/setup_password" mT0="internal/uic/bff/api/v1/account/change_password" qT0="internal/uic/bff/api/v1/account/list" CT="internal/uic/bff/api/v1/account" gT0="internal/uic/bff/api/v1/account/send_mail" …
悩んでいるうちに、CODEGATE CTF 2024決勝大会のためにソウルへ飛ぶ日が来てしまい、一旦中断する。ほかのメンバーもほとんどが同じく韓国へ行く中で、我々は暇な時間に取り組んだり、あるいはjptomoyaさんが日本でじっくり考えたりしてくれていた。我々はこの問題だけを残した状態であったが、韓国へ行っている間にイエラエが全完し追い抜かれてしまう。仕方がない。
CAN IDについて「700番代以外に診断通信が載るのは車種が絞られる」のではないか。(0x0645のデータとは関係ないが)DEF CONのCar Hacking Village CTFで出たらしい問題のデータと類似しているものがあり、これと関連しているのではないか。悩んでいる中で、jptomoyaさんやsugiさんからこういったアイデアが出ていた。
後者のsugiさんのアイデアを少し掘ってみることにした。別のソースであるところのNRIセキュアさんのブログでNDIASさんのメンバーが出したレポートを読んだり、YouTubeに上がっている同CTFをレポートしている動画を確認したりしてみるものの、特に有益な情報は得られなかった。同CTFで登場した車の情報を投げたりしてみるものの、これも通らなかった*8。
jptomoyaさんは、前者のアイデアをさらに深堀りして、CAN IDからこの車はTeslaではないかと推理をしていた。なるほど、やはり問題文で言及されている通りにCANのデータが重要なのだろうと思い直す。
韓国から帰国した後に、この問題を再び見る。攻撃対象の車がTeslaのものであると仮定して、なにか情報を得られないかと思い、雑に問題文で言及されているCAN IDと組み合わせて「"0x0645" tesla」で検索してみたところ、FREE-FALL: HACKING TESLA FROM WIRELESS TO CAN BUSという資料を見つける。送信されているバイト列が一致している。この攻撃の対象となっている車はなにか。1ページ目に次のような記述があった。
We have successfully tested our vulnerabilities on Tesla Model S P85 and P75, the latest version at that time was as follows.
試してみる。Tesla Model S P85
が正解であった。前述のようにこれが我々に残された最後の問題であり、ふざけるなよという気持ちもありつつ、ようやくこのCTFから解放されたという爽快感もあった。xNexusや、そもそもCANやら車やらにはまったく詳しくないので、この怒りが正当なものかはわからない。
とりあえず、bh{Toyota Hilux Conquest}
というフラグの例を出しておいて結局ここまで詳しく解答しなければならなかったという点で、運営のミスリーディング*9には怒りを覚えているけれども、実はxNexusのどこかのAPIからTesla Model S P85という情報が得られたのかもしれない。まともな解法が存在していることを祈りたいし、運営が自らwriteupを公開することを願いたい。
bh{Tesla Model S P85}
ルール面での問題について
このCTFを勝ち進んでいくと、最終的にアメリカはデトロイトで10月下旬に開催される決勝大会へ、VicOneが旅費・滞在費を負担の上で参加することができる。日本の大会は経済産業省主催で「Automotive CTF Japan」とされており、こちらはまず今回のオンライン予選があり、そこから上位5チームが国内決勝へ進み、そしてさらにその上位2チームがデトロイトの決勝へ進むという流れになっていた。デトロイトの決勝には海外からも4チームが参加する。これらの海外チームについては、同じオンライン予選から直接選ばれるようになっていた。
さて、これを見ると日本チームがデトロイトの決勝へ進みやすくなる良心的なルールに思える*10けれども、今回は違っていた。今回は日本チームであるierae, 藤原豆腐店, FCCPCが海外チームを含めた総合順位で4位以内に入っていた。これらは海外チームであったならばそのままデトロイト決勝へ行けるところ、ルールの解釈によっては、日本チームであったがためにわざわざ日本決勝まで勝ち抜かなければならないという理不尽な状況に陥る可能性がある。
英語版のルールにはグローバル枠の参加資格に "From any country/region" とあり、日本在住者はグローバル枠では参加できないとする記述は見当たらないことから、日本チームがグローバル枠で参加する余地も残されているように思える*11。上述の3つの日本チームはグローバル枠としてデトロイトの決勝へ進出できるか、もしくは日本枠からグローバル枠へ切り替えることはできるかと、Discordの誰でも閲覧可能な質問用チャンネルで日本側運営とグローバル側運営の双方へ同時に、9/3に質問した*12。
日本運営からは、日本語版のルールでは日本在住者はグローバル枠で参加できないとしている(ならば、英語版のルールの記述や、同様の質問へのBlock Harborの対応はなんなのだろうか)と同日に回答があった*13。問題を認識しつつも「来年もAutomotive CTFを開催する場合は、今回いただいたご意見については改めて検討」するとし、まさに今、解決へ動いていただけない(少なくとも表面上はそう見える)という、事なかれ主義ともいえる運営による不作為を残念に思った。
グローバル運営からは、9/6に "It is under review" という返答があったが、9/9 12時時点でまだ質問への明確な回答は得られていない。9/13に日本決勝がある(予選からもう少し間隔を空けてほしいし、それで土日でなく金曜日開催というのは困る人が多いと思うのだけれども…)ので、早く回答があると嬉しい。両運営の、あるいはどちらか一方の適正な判断を期待している。もっとも、グローバル運営の方もDiscord上で(私の質問には回答しないまま)次のようなアナウンスをしており、まったく期待できないのだけれども。
The Block Harbor x VicOne Automotive CTF Season 2 Qualification rounds have come to close! Thanks for playing everyone! We will confirm the winners soon. For those entering the next rounds of the competition we will reach you via email.
(2024-09-09追記)残念ながら以下のような回答があり、グローバル運営もこの理不尽なルールを是とするということだった。
Since we had multiple sponsors including the Ministry of Economy, Trade, and Industry in Japan, there was an additional event locally intended for the residents of Japan. We will consider a single bracket in next years competition to alleviate this issue. Although there was a discrepancy in the global rules and Japanese rules about which bracket you could signed up for, both rules were clear once you established and competed in the [Japan] backet you could not switch to [rest of world] bracket.
(追記終わり)
*1:全部で29問と少なく、早々に複数チームが全完しており、問題数やその難易度に対しては長すぎたように思える。ただ、それは普段からCTFをアホみたいに遊んでいるプレイヤーの発想であって、普段から遊んでいない人にも遊んでもらえる、長い期間のどこか時間のあるタイミングで、あるいはじっくりと取り組んでもらえるといったことを考えると、開催期間が長いというのは問題ではないように思う。勝つ気で挑戦しているチームにとっては苦しい期間が長く続くことになるが…
*2:メンバーの名字にちなんでおり、自動車に関連するCTFであったことを絡めてこのチーム名を提案したところ通った。なお、頭文字Dは未読だし未視聴だ
*3:イエラエはさすがの強さを見せていた
*4:なにか理由をつけてBANされない限りは
*5:正直なところ、大きな問題が複数あるために、列挙しようにも細かな問題を思い出せない
*6:あるならば
*7:それだけでなく、1カテゴリとして独立させられるほどにステガノグラフィーの問題が出題されるのもよくわからない。これは "high-stakes global automotive-focused CTF" ではなかったか。自動車に関連しておりかつステガノグラフィー問であるというのも意味がわからないが
*8:あり得ないと思いつつも、あり得ないと思ったアイデアが通ってしまうのをほかの問題で何度も見てきたから、まったくもって合理的でないひどいアイデアでも、思いついたらとりあえず試していた
*9:運営によるミスリーディングはこの問題に限らない
*10:つまり、日本チームが総合順位で4位以内に入れない状況であったならば、日本チームにとって利益となるようなルールであった。その場合は私は不満を抱かなかっただろうし、ポジショントークと思われ得るという自覚はある
*11:また、CTF開始前に同様の質問をした際に、今回CTFを運営しているBlock Harborから、日本在住者でもグローバル枠で参加可能であると回答が得られたという他チームの方がいた
*12:ieraeやFCCPCを含む他チームの方々から、同チャンネルでこの質問に関連する様々な意見を投稿いただいており、深く感謝している。ありがとうございます
*13:英語版のルールでそのような記述があると示しつつ質問したのだけれども、その記述の違いには日本運営からは言及がなかった