Automotive CTF 2024 世界決勝 - 体験記 & Writeup
デトロイトで開催されたAutomotive CTFの決勝に “TeamOne” チームとして参加し、出場6チーム中 4位 でした。
(※所属とは無関係に個人活動として参加)
CTFを初めて1年ちょっと、まさか世界で戦う機会に預かれるなんて思ってもみませんでした。良い経験になりました。
前回の日本決勝の記事 と同様に、体験記と自分が解いた問題のwriteupを書きます。実機がないと再現できない問題ばかりなので(出場した方以外は)「ほーん」くらいにお読みください。
目次
体験記
10/26(木)から日本のコンピューターセキュリティシンポジウムに参加するため、他のコンテスト参加者よりも前入り・早帰りでデトロイトに行きました。
ヘンリー・フォード博物館に行ったり、
カナダとの国境にもなっている川に浮かぶベル島という景色最高の島に行ったり、
地元のビール醸造所に行ったりしてました。デトロイトはあんまり観光地という感じではないですが、早朝のベル島は人も少なくめちゃ気に入りました。
10/21(月)の10:00-17:00がコンテスト。日本決勝と同様、RAMN を使った問題が大半でしたが、他に自動車のスピードメーター(裏側写真だけ…)を使った問題、NFCカードの問題などありました。
問題のボリュームも難易度も国内決勝と比べて体感3倍くらい上がっており、多くの問題が解き切れず… それでもチームで分担したり協力したりで良い戦いができたと思います。
大会後の懇親会では、前年度覇者のpwnalone氏(高レベルなwriteupを拝見して会いたいと思ってた)やRAMN問題の作問者(トヨタの同僚 but 話したの2,3年ぶり)とお話できたりして来てよかった感がありました。
コンテスト中から一貫して順位や他チームのスコアは非公開で、10/25(水)の表彰式で初めて発表されます。日本時間の木曜早朝にチームメンバーからのdiscordメッセージで4位と教えてもらいました。即席チームとしては頑張れたと思うけど微妙に悔しい!
会場は Newlab という自動車やらハードウェアに関連するスタートアップが利用するイケてる建物(自動車も搬入できる!)で、気持ちよくコンテストに取り組めました。運営の方々、ありがとうございました!!!!
Writeup
解いた問題の雑writeupです。問題の原文をメモってなく、機械翻訳のものになります…
RAMNカテゴリ
ECU CのUDS問題を2問解いた。
ECU Cが対応していたUDSサービスは以下。
1 | % caringcaribou uds services 0x7e2 0x7ea |
DYNAMICALLY_DEFINE_DATA_IDENTIFIER (0x2c) は初見。
[C] CVE-2017-14937
0x1111に何かを書き込み、0x0000に何かを読みに行く。
1 | # Diagnostics Session 0x04 に入る |
[C] DID not done
フラグは0x0803e000にある26バイトの文字列だが、Read Memory By Addressがそれを読み込ませてくれない :(
DYNAMICALLY_DEFINE_DATA_IDENTIFIER とかいうサービス、とにかくネットに情報がなく、sub func以下のパラメーターの指定方法が不明。
とりあえずsub funcを総当りしてみる。
1 | % caringcaribou uds subservices 0x00 0x2c 0x7e2 0x7ea |
ネットを探すと、0x02は “Define by Address” ということでアドレスをDIDに紐づく値にセットできるっぽい?
isotpdump -s 7e2 -d 7ea -c -a -u can0
しながらガチャガチャ試すと、 incorrectMessageLengthOrInvalidFormat
エラーが返るケースと requestOutOfRange
エラーが返るケースがある。後者のほうはアドレス値とかDIDが間違ってると推測でき、望みがあると判断した。
更にガチャガチャし、以下の命令フォーマットであることを突き止める。
1 | echo "2c 02 XX XX YZ 08 03 e0 00 1A" | isotpsend -s 7e2 -d 7ea can0 |
XX XX
: DIDY
: 「長さ」を表現するためのバイト長。本問では 26 を表現したいので、Y=1
で良いZ
: 「開始アドレス」を表現するためのバイト長。本問ではZ=4
で良い08 03 e0 00
問題文で指定された開始アドレス1A
: 問題文で指定された26バイト
ということで
1 | echo "2c 02 XX XX 14 08 03 e0 00 1A" | isotpsend -s 7e2 -d 7ea can0 |
までは決まるが、 XX XX
を適当に決めても requestOutOfRange
エラーのまま。
なんか使えるDIDはないかと、DIDのマッピング表が載っているページ を眺める。
0xF300 – 0xF3FF : Dynamically Defined Data Identifier
あった!!!
1 | echo "2c 02 F3 00 14 08 03 e0 00 1A" | isotpsend -s 7e2 -d 7ea can0 |
これで isotprecv -s 7e2 -d 7ea can0
でASCIIエンコードされたフラグを得る。
I am Speed カテゴリ
スピードメーターが会場にデデンと置かれている。既に電源とCAN-to-USBデバイスが配線されており、PCにUSB刺して以下のコマンド打つだけでCAN通信ができるようになる。
1 | sudo ip link set can0 type can bitrate 500000 |
実は決勝対策でスピードメーターを購入して一通りのCANおしゃべりを試していた。役立った。
ECU hack - スピードメーター編 (Notion記事)
問題文はメモしてないので、うろ覚えの題意を書く。
can-utils
題意: 速度計を荒ぶらせるコマンドを
bh{ls -al}
のような形式で提出せよ
cangenでファジングする問題。
ほぼ https://laysakura.notion.site/ECU-hack-127e7f3e990d8022836fd15524b24794#127e7f3e990d80f19a10dfae079758b9 でやった通り。
まずリプレイするデータを作成。
1 | sudo ip link add dev vcan0 type vcan |
canplayer
でファジング開始。
1 | grep "vcan0 0" candump-FF.log | canplayer can0=vcan0 |
速度計やその他のランプ・ビープ音が荒ぶる。
どのCAN IDが速度計に対応するか探す。1桁目が 2
であることはすぐ分かったので、そこから二分探索。
1 | % grep "vcan0 2" candump-FF.log | canplayer can0=vcan0 |
CAN ID 0x202 が速度計に対応するらしい。
Peter Parker
題意: パーキング状態かを示すCAN IDを
bh{0x123}
形式で答えよ
candumpを眺めていると、CAN ID 0x40AでVINらしきものが流れている。VINは MM7DJ2HAAKW382130
だった。
どこかのサイト(忘れた)でVIN検索すると、マツダ車らしい。
https://github.com/commaai/opendbc/blob/master/opendbc/dbc/mazda_2017.dbc のDBCファイルを眺める。
GEARの 552
(10進数) が正解っぽい。16進数だと 0x228
。