見出し画像

DEF CON 30 Car Hacking Village CTF備忘録~首位から4位への転落~


 こんにちは。DEF CON 30のCar Hacking Village(CHV)のCTFにチーム名tyt4001として参加してきました。公式な結果としては総合4位となっているものの、タイトルに挙げた通りもともと発表されていたルールに則った採点結果では首位でした。本件、採点内容が確定するまでに紆余曲折がありました。本ブログではCHV運営側へのコメントおよび今後DEF CON CHVへの参加を検討している方々への注意喚起も含めて、今回の経緯と顛末を記したいと思います。

幻のスコアボード


1.       CTFの開催スタイル

 DEF CON 30におけるCHVのCTFは現地参加とオンライン参加のハイブリット開催とされており、現地でしか解答できない問題とオンラインからも解答できる問題とに分かれていました。我々tyt4001は当社から参加するメンバー4名とパートナー企業から2名の計6名チームで参戦しました。現地とオンラインの振り分けは、現地参加2名、オンライン参加4名であり、現地参加組は主に現地で解答するCTF問題と主催者との折衝を担当し、オンライン参加組はオンラインから対応可能な問題を中心に担当しました。

2.       現地で解答するCTF問題

 現地には実際に車に搭載されているECUなどの機材が配置されておりそれらを用いた問題に解答します。CTF問題の対象となる機材にPCから接続し、情報を読み解いたり、挙動を制御したりする問題が主でした。中にはデバイスとBluetoothで接続して機器の情報を読み解く問題もありました。

 いずれの問題も現地からでなければ解答することは困難です。しかしながら、tyt4001はRaspberryPiを現地に持参して踏み台として設定することで、オンライン参加メンバーも現地でしか回答できない問題を解答できるようにしていました。

3.       オンラインから対応可能な問題

 今回の目玉でもあった出題のテーマがCloudCarに関するものです。過去のCHVでもオンラインで解答できるCTF問題は存在していましたが、CloudCarではコースを仮想の車(CloudCar)が走っている環境に対してSSHで接続してECUの情報を解析し、車の情報や挙動を操作する問題や、仮想の車がコースを周回した数が加点対象になっていました。


Lap Points:
In order to encourage a healthy and functional virtual car, each lap around the virtual track is worth either 1 point (on Friday through Saturday at 10 AM), 2 Points (on Saturday after 10 AM through Sunday at 10 AM), and 5 points (Sunday from 10 AM to 12 PM).


https://www.carhackingvillage.com/ctf-rules-2022

 ルールに記載のあるとおり、CloudCarの周回数による加点は、1日目は1点、2日目は2点、3日目は5点の配点になっており如何にこの高得点が割り当てられた周回数を攻略するかがポイントとなっていました。また、CloudCarの情報や挙動に関連する問題は配点が高かったため、tyt4001でもCloudCarの解答にメンバーを多めに割り当てました。

 下図がCTFにおける最大の得点値のうち、CloudCarが最低限締める割合を可視化したグラフです。実際には、周回数による加点が加わるので如何にCloudCarで得点することが大事だということが一目瞭然です。なお、CloudCarよりも初期状態では点数配分が高いRed Balloonについても後に触れるため、覚えておいて頂きたいです。

4.       CloudCar

 CloudCarの周回にはGas O’lean(ガソリン)が必要です。また、フロントガラスが汚れる仕掛けに対応するためのLemmon Ade(ウォッシャー液)も必要です。これらは運営スタッフや会場内に設置されているとアナウンスされていました。実際には、スタッフにコーヒーを含む物品との物々交換や腕立て伏せの回数で勝負したりすることで入手が可能で、現地メンバーは多くの時間を会場内で費やしました。その結果、Gas O’leanカードを7枚、Lemmon Adeを11枚入手することに成功しました。これらの枚数は他のチームよりも多く入手できていたのではないかと思います。なお、事前のルール説明では他のVillageの運営スタッフにもカードが配られていると説明されていたため全てのVillageを回ったものの、どのVillageの運営スタッフもそれぞれのカードの存在を知りませんでした。

 CloudCarの解析を進めた結果、初日の早い段階で特定のCANコマンドを送信し続けることでガソリンなしでも走行できる方法を発見できました。ガソリンなしで走行することは現実にはあり得ないため主催者にバグとして報告しましたが、バグではなく仕様であるとの解答を得ました。これにより以降はガソリンなしでも走行ができる状態になりました。(※ ガソリンが有る状態で走行する方が安定して走行できたため、入手できたGas O’leanカードは全て使い切っています。)

 走行速度の改ざん方法に関しては、初日に所定のCANパケットに対してペイロードを改ざんしてリプレイすることで127km/hまで加速させられることを発見していました。これらの手法を組み合わせることで、初日の内に周回数として123周を記録しました。

 しかし、初日の終了後に運営者から以下のtweetが投稿されます。tweetの記載ではtweetの投稿時点までの周回数は記録されている様に受け取れますが、実際には初日の周回数はカウントされなくなりtyt4001が記録した123周は無効になりました。(※ さらにこの後も何度かカウントがリセットされました)

https://twitter.com/CarHackVillage/status/1558459849951784960

翌日の運営者からのtweetで「周回数カウントの再開」と「周回数のカウントが3日開始時に停止されること」がアナウンスされました。

https://twitter.com/CarHackVillage/status/1558584233337057280
https://twitter.com/CarHackVillage/status/1558692738291249152

(※)上図のTweet時刻はそれぞれ日本における時刻となります。

 2日目時点でtyt4001はさらに解析を進めており、特定のECUに対してSecurityAccessを取得したセッションで速度改ざんパケットを送信することで255km/hで走行できる手法を発見していました。

 ここで、2日目の17:30(オンサイトでの競技の終了時刻)の時点で、tyt4001が主催者に対して「ルールに沿っている」と確認が取れた内容を記載します。

・   2日目の周回数はルール通り2倍してポイントに加算される
・   2日目の会場が終了してもCloudCarは有効のため3日目開始(10:00)まで走らせ続けて問題ない
・   ガソリンなしで走行できるのは仕様
 
 これらの内容を踏まえ、tyt4001はCloudCarを終夜連続走行させることで周回数を稼ぎ、周回数のカウント停止時間までに1,533周を記録しました。なお、下図の右側のScoreは周回数とは別にCloudCarの情報や挙動を操作する問題に対する回答による点数となっていますが、全体のCTFとは点数の重み付けが異なったり、チームによっては何故か満点を超えられたりする状況で回答状況を個々に運営が確認していました。

 CloudCarのSimulatorにはバグとも仕様とも受け取れる以下の様な問題があり幾度となく走行が停止していました。

・   複数人でシミュレータを立ち上げると正常に動作しない
・   正常走行中に速度が0になりCANコマンドに応答しなくなる
・   ガソリンがある状態でも車が走り出さない
・   カメラアングル切り替えでシミュレータが停止する
・   シミュレータがブラウザごと停止する

 これらの要因から走行が停止する時間は少なからずあったものの、正常走行時に確認したところtyt4001が2周する間に他のチームは1周しかできていなかったことから255km/hでの走行法にたどり着けたチームはtyt4001だけだったと考えていました。(※ 255km/hの走行に関しては最終日に主催者から「CloudCarを255km/hで走行させる方法を見つけたのはtyt4001だけであり、賞賛に値する」という旨の寸評を頂いており、運営に認められた正規の手法であることが確認できています。)

5.       競技の後の協議

 CTFは現地時間の14日、正午に終了しました。CloudCarの周回を除いたポイントによる順位は以下になります。

 この時点でtyt4001は4位に付けていました。ここで、主催者は5位以上のチームに対して5位から順に個別に呼び出し、話をしたいと言いました。我々の番がくると、主催者からは次の様に言われました。

 「ほかのチームはバグ等のためフルに環境を使うことができなかった。ついては君たちの周回数は規程通り2倍の加点とするが、ほかのチームにその半分の加点を行うことを了承して欲しい」

 積み上げた1,533周はECUに対する詳細な解析と現場でのカード収集、終夜の連続走行がなければ稼げないものであり、半分とは言え加点としては大きすぎると思えたものの、こちらからの提案を主催者は承諾せず、なし崩し的に了承せざるを得ない状況になりました。ただし、獲得ポイントの合計は加点方式が異なってもtyt4001が首位になれる値であったため我々の優勝は確定していると考えていました。

5.1.       協議 – 1

 CloudCarの周回数の加点が行われ、予想通りtyt4001は首位となりました。

 しかしながら優勝を喜んだのもつかの間、ここで2位のチームにさらに点数が追加され順位が入れ替わりました。彼らのポイント内訳は以下のようになっていました。

 右上にあるlapsの1,533は主催者から告知されたtyt4001の周回数分を補填した点数と思われます。左下lapsは彼らのチームのみに加点された理屈に合わない点数であり、これには他のチームからも疑義が申し立てられました。後に、この点数は問題点を報告した特別賞であると報告がありました。それでもlapsの300点までであればtyt4001は依然首位を保っていたものの、さらに彼らのチームにのみ周回数分の2倍の164点がも加えられることになりtyt4001は2位に転落しました。300点、164点と追加で加点されたことで順位が変動し、他のチームにはその様な加点が行われなかったためその内容の透明性が疑われたことから会場は紛糾しました。

5.2.       協議 – 2

 特別加点で逆転された驚きもありましたが、運営に対してそれならば1日目の周回数の加点を行うべきだと主張し、それが受け入れられました。

 この123点の加点で再度tyt4001は首位に返り咲いたものの、加点に関してルールが容易に何度も上書きされる状況に強い違和感を覚えました。

5.3.       協議 – 3

 ほかのチームも不透明な加点に関して強く物言いをしていました。特に900周以上の周回を積んでいたチームはtyt4001の周回数(1,533)では割に合わない(本来であれば1,533点以上が加算される)と主張しました。これについては、tyt4001も同意していました。

 また、tyt4001としても不透明な加点について当然物言いをしました。そもそも合意したのはtyt4001の周回数「1,533のみ」の加点であり、それ以外の加点については後付けの、言ってみれば後出しジャンケンであるため、そのような加点がなされるのであれば、そもそも周回数1,533の加点もtyt4001は合意しませんでした。

 その後、主催者は長い協議に入りましたが、その参加者を含め、内容や論点について参加者に伝えられることはありませんでした。その上で前出(下記)のTweetを根拠として周回数の加点を取り消すと通告してきました。

5.4.       協議の結果:首位から4位へ

 最終的に、運営は自分達のルールに記載していたCloudCarの周回数による加点の一切を行わないと通告しました。そしてその根拠として、「自分のTweetでCloudCarの環境は信頼できない(un-reliable)と明記してきた。途中で以後カウントすると書いたがやはり自分はun-reliableのままだと思っていたし、すべてのチームに対してfair(公平)でありたい」と告げました。CloudCarのun-reliableな環境は万人にun-reliableであり、それはtyt4001も同様に影響を受けていました。前述したとおり、CloudCarの挙動には怪しいものが多々あり、正常に走行させるには怪しい挙動を避けながら走らせる種々の工夫が必要になりました。以下に問題を回避して走行させた一例を示します。

  • 複数人でシミュレータを立ち上げると正常に動作しない問題
    → 1人を選任で対応させるようにした

  • 正常走行中に速度が0になりCANコマンドに応答しなくなる
    → 都度画面を確認して停止した場合にはCANコマンドの送信をやり直したり、シミュレータを再起動したりした

  • ガソリンがある状態でも車が走り出さない
    → 正常走行時にdumpしていたcanパケットをリプレイすることで走り出すことを発見したため初動では都度canパケットをリプレイすることで対応した

  • シミュレータがブラウザごと停止する
    → 停止するごとに起動し直した

走行までの様子は次の動画で確認が可能です。

 運営にはCloudCarのバグの多い環境にはtyt4001も影響を受けており、そのなかで周回を重ねたことをアピールしました。しかし、運営はその申し出がCloudCarの環境をun-reliableであるtyt4001も肯定するものであるから采配に納得するように、と言葉尻だけを捉えるような対応を受け、その姿勢に強く疑問を感じました。結果的にtyt4001は周回数分のポイントを剥奪され、首位から4位まで転落しました。
 余談として現地でのCTFのRed Balloonについては最終日、出題者が帰路についてしまったため回答することができない自体が起き、その不公平さについて運営に苦言を訴えているチームもありましたが既にそれらの出題に回答しているチームがその加点を減算されることはありませんでした。Red Balloonは前出の円グラフのとおり、CloudCarの周回数を加算しない状態では最も得点対象が大きい出題領域でした。一番加点が低い問題でも250点、次点は500点の問題と順位に大きく影響するにも関わらず、CloudCarの周回数による加点と異なり、運営は2日目までに問題を解いたチームの加点を減算することはありませんでした。複数の上位チームがRed Balloonの問題を幾つか2日目終了時点で解いていたにも関わらず運営はRed Balloon の回答による加点は公平さを欠くものと判断しませんでした。

6.       終わりに

 今回のCTFではCloudCarはUDSを使った攻撃が確認できるなど実車に近い反応があり、オンラインからも解答できたこと、また、現地での出題内容も含めてとても充実した内容でした。それだけに、競技終了後にルールを何度も変更し、順位が変動する様を何度も目撃した上で参加した表彰式は大変後味の悪いものとなりました。今回のようにルールが何回も、それも競技の後に変更されてしまっては対処のしようがありません。特に周回数の加点について、2日目時点で加点が無効になることをアナウンスされていればtyt4001としても現地の課題にリソースを割くといった判断ができました。競技終了後にそのようなアナウンスをされてしまっては、後の祭りです。今回の経験ではCHVのCTFに対する今後の関わり方を考える必要があります。

 特に今回のCHVに対してtyt4001としては当社とパートナー企業との合同で技術的な腕試しを目的として参加していました。CTF自体はCloudCarも含めて大変勉強になる良問がそろっており、それらに対してメンバーが一丸となって対応できたことで一体感も生まれ大変良い経験ができました。それが、技術とは無関係な部分で不誠実な対応を受け後味の悪い結果となってしまったことで非常に残念に感じています。tyt4001としてはルールに則り、正当な手段で周回数を積み上げたものと考えています。他のチームが周回数を稼げなかったことは私たちが見つけた方法を彼らが見つけられなかっただけであり、周回を稼げたいくつかのチームしか点が取れなかったと言う理由でその点自体を無効にするようなやり方はCTFの運営者としてあり得ない対応なのではないかと考えます。CTFとは、参加者の創造性を評価するものであり、出題者が想像できなかった様な解き方をする回答者を歓迎するものです。特に全世界で注目されるDEF CONのCTFとして創造性を評価するのではなく否定することは信じがたい事態でした。

謝辞

 日本から参加されたチームND4の方々に開催期間中に諸々お世話になったことを感謝申し上げます。お貸し頂いた機材のおかげで4位に留まることができました。
 一緒に参戦頂いたパートナー企業のお二方にも感謝申し上げます。おかげで対応出来る内容に幅ができ、付加的な加点に繋がりました。
 最後に、ご多忙にも関わらず、本備忘録の内容をご確認頂いた方々に感謝申し上げます。