2年前からヒッソリ参戦するようになったリバースエンジニアリング専門のCTF Flare-On Challenge。
今年は3問目で撃沈。(ちなみに去年は2問目で撃沈、一昨年は3問目で撃沈)
1問目と2問目の解法及び3問目の試行錯誤をまとめておく。
今年は引っ越しの準備等で時間を取られたので(言い訳)、来年はじっくりやれるといいなあ。
主催者公式のWriteUpはこちら
01 credchecker
admin.html
というHTMLファイルに埋め込まれたJavaScriptを解析する問題。
以下が肝となるコード。
var form = document.getElementById("credform");
var username = document.getElementById("usrname");
var password = document.getElementById("psw");
var info = document.getElementById("infolabel");
var checkbtn = document.getElementById("checkbtn");
var encoded_key = "P1xNFigYIh0BGAofD1o5RSlXeRU2JiQQSSgCRAJdOw=="
function dataEntered() {
if (username.value.length > 0 && password.value.length > 0) {
checkbtn.disabled = false;
} else {
checkbtn.disabled = true;
}
}
function checkCreds() {
if (username.value == "Admin" && atob(password.value) == "goldenticket")
{
var key = atob(encoded_key);
var flag = "";
for (let i = 0; i < key.length; i++)
{
flag += String.fromCharCode(key.charCodeAt(i) ^ password.value.charCodeAt(i % password.value.length))
}
document.getElementById("banner").style.display = "none";
document.getElementById("formdiv").style.display = "none";
document.getElementById("message").style.display = "none";
document.getElementById("final_flag").innerText = flag;
document.getElementById("winner").style.display = "block";
}
else
{
document.getElementById("message").style.display = "block";
}
}
Base64エンコードされたgoldenticket
というパスワードを渡すとP1xNFigYIh0BGAofD1o5RSlXeRU2JiQQSSgCRAJdOw==
という文字列とビット演算を行い、フラグを復号する。
以下のスクリプトを書いてフラグを取得した。(スクリプトを書いてから、「admin.htmlのフォームにAdminというユーザー名とgoldenticketをBase64エンコードして入力すればフラグ取得できたじゃん」と気づいた)
#!/usr/bin/env python
import base64
decoded_key = base64.b64decode("P1xNFigYIh0BGAofD1o5RSlXeRU2JiQQSSgCRAJdOw==")
password = base64.b64encode("goldenticket")
flag = ''
for i in range(len(decoded_key)):
flag += chr(ord(decoded_key[i]) ^ ord(password[i % len(password)]))
print(flag)
$ python credchecker-solver.py
enter_the_funhouse@flare-on.com
フラグはenter_the_funhouse@flare-on.com
02 known
32ビット PEファイルを解析する問題。ランサムウェアによって暗号化された(という設定の)ファイル数種類と復号ツールUnlockYourFiles.exe
を渡される。

UnlockYourFiles.exe
に正しい復号鍵を入力すれば暗号化されたファイルが復号される。おそらく復号されたファイルにフラグが記載されているものと思われる。
UnlockYourFiles.exe
を眺めてみたところサブルーチン0x4011f0にてファイル復号の処理を見つけた。


サブルーチン0x4011f0は引数として8バイトの復号鍵と暗号化されたファイルへのポインタを受け取り、ビット演算を行って暗号化されたファイルを復号する。復号の処理は以下の通り。
.text:00401203 8A 1C 31 mov bl, [ecx+esi] ; decryption key
.text:00401206 8A 04 39 mov al, [ecx+edi] ; pointer to buffer
.text:00401209 32 C3 xor al, bl
.text:0040120B D2 C0 rol al, cl
.text:0040120D 2A C1 sub al, cl
.text:0040120F 88 04 39 mov [ecx+edi], al ; copying decrypted data to buffer
.text:00401212 FE C1 inc cl
ファイルを復号するにはどうにかして復号鍵を入手する必要がある。この時点で判明しているのは鍵のサイズが8バイトで、ファイルは一度に8バイトずつ復号されるということ。
手元には暗号化されたファイルが数種類あるので、known plaintext attackの要領で復号鍵を入手することができる。
暗号化されたファイルの中から暗号化前の先頭8バイトのパターンが予測できそうなファイルを探してみると、capa.png.encrypted
というファイルが目についた。ファイルの拡張子から推測するに元のファイルはPNGの画像ファイルと思われる。PNGは先頭の8バイトが89 50 4E 47 0D 0A 1A 0A
で固定されているのでknown plaintext attackにはおあつらえ向きである。PNGのヘッダー89 50 4E 47 0D 0A 1A 0A
を総当りで暗号化して、capa.png.encrypted
の先頭8バイトのパターンと一致すれば、その時の鍵の組み合わせが復号鍵ということになる。
復号処理から逆算すると、暗号化の処理は以下のようになる。
add al, cl
ror al, cl
xor al, bl
inc cl
総当り攻撃にはCyberChefを用いた。
- PNG ヘッダー
89 50 4E 47 0D 0A 1A 0A
から1バイトをInput欄に入力 - Operationの組み合わせはFrom Hex + ADD + Rotate right + XOR Brute Force
- ADD と Rotate rightに渡す値は初期値が0で、その後1バイト暗号化するごとに加算し、8バイト暗号化されるごとに0に戻る
- Output欄から
capa.png.encrypted
と一致するバイトパターンを見つけて、そのときに使用されたXOR鍵を控える - 最初に戻って処理を繰り返す
以下の画像はPNGヘッダーの1バイト目0x89
が0x4e
という鍵で暗号化されていることを示している。

上記の総当たり攻撃の結果、復号鍵はNo1Trust
(Hex: 4e 6f 31 54 72 75 73 74
) と判明した。
あとはUnlockYourFiles.exe
を実行して入手した鍵を入力すればファイルを復号できる。。と思ったのだが、鍵を入力してもファイルが復号されなかった。
鍵は正しいはずなので、自力でファイルを復号することにした。ファイル名とファイルサイズから推し量るにcritical_data.txt.encrypted
にフラグが記載されていると思われる。スクリプトを書くか逡巡したのち、CyberChefによる復号を決行した。
critical_data.txt.encrypted
から1バイトをInput欄に入力- Operationの組み合わせはFrom Hex + XOR + Rotate left + SUB
- XORの値はNo1Trustから1バイトずつ入力
- Rotate leftとSUBの値は初期値が0で、その後1バイト復号するごとに加算し、8バイト復号されるごとに0に戻る
- 最初に戻って処理を繰り返す
以下の画像はcritical_data.txt.encrypted
の最初の1文字目は(
であることを示している。

critical_data.txt.encrypted
の復号結果は以下のとおり。
(>0_0)> You_Have_Awakened_Me_Too_Soon_EXE@flare-on.com <(0_0<)\r\n
フラグはYou_Have_Awakened_Me_Too_Soon_EXE@flare-on.com
03 antioch
Docker及び64ビット ELFファイルを解析する問題。antioch.tar
というファイルを渡されるので、解凍すると無数のディレクトリとファイルが作成された。どうやらantioch.tar
はDockerのイメージをtarファイルとして保存したものである模様。a13ffcf46cf41480e7f15c7f3c6b862b799bbe61e7d5909150d8a43bd3b6c039.json
というJSONファイルを覗いてみるとAntiochOS
というファイルを参照していた。またmanifest.json
を覗いてみると7016b68f19aed3bb67ac4bf310defd3f7e0f7dd3ce544177c506d795f0b2acf3/layer.tar
というファイルを参照していた。ディレクトリ7016b68f19aed3bb67ac4bf310defd3f7e0f7dd3ce544177c506d795f0b2acf3
に移動し、layer.tar
を展開すると件のAntiochOS
という64ビットのELFファイルが解凍された。
$ 7z l layer.tar
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=utf8,Utf16=on,HugeFiles=on,64 bits,8 CPUs x64)
Scanning the drive for archives:
1 file, 14848 bytes (15 KiB)
Listing archive: layer.tar
--
Path = layer.tar
Type = tar
Physical Size = 14848
Headers Size = 1536
Code Page = UTF-8
Date Time Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
2021-07-23 11:21:55 ..... 13016 13312 AntiochOS
------------------- ----- ------------ ------------ ------------------------
2021-07-23 11:21:55 13016 13312 1 files
$ file AntiochOS
AntiochOS: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
AntiochOS
を眺めてみたところ、いくつか興味深いスタック文字列を発見した。


さらに解析を進めたところ、AntiochOS
は以下のコマンドを受け付けることが判明した。
- quit : プログラムを終了する。
- help : ヘルプを表示する。。が特に有用な情報は表示されない
- consult (サブルーチン 0x401460) : "Consult the Book of Armaments!"というメッセージとともに正体不明のデータを表示する。
- approach (サブルーチン 0x401640) : "Approach the Gorge of Eternal Peril!" というメッセージを表示した後、 以下の質問を表示する
- What is your name?
- What is your quest?
- What is your favorite color?
- 上記の3つの質問に対して正しく答えていくと"Right. Off you go. #" というメッセージとともに何らかのデータを表示する模様。
上記のコマンドで特に興味深いのはconsultとapproachである。approachコマンドの各質問に対して正しい答えを入力すればフラグを取得できるものとアタリをつけて、まずはapproachコマンドから解析した。
まず手始めにデバッガでジャンプ命令を操作して上記の3つの質問をバイパスしたあとに"Right. Off you go. #" のメッセージの直後にメモリにフラグらしきデータがないか確認してみたが空振りに終わった。やはり質問に対して正しい回答を入力しないとフラグを取得できない模様。
"What is your name?"と"What is your favorite color"という質問への回答についてはサブルーチン0x401B50にて何らかのチェックを行っているようだったが、処理が複雑で具体的に何をするコードかわからなかった。


解析を続けるうち、"What is your name?"という質問に対しては、以下の名前のいずれかを入力すれば良いことがわかった。
Sir Lancelot
King Arthur
Sir Robin
Sir Bedevere
Black Knight
Tim the Enchanter
Squire Patsy
Squire Concorde
Bridge Keeper
Roger the Shrubber
Prince Herbert
Brother Maynard
Miss Islington
Trojan Rabbit
A Famous Historian
Inspector End Of Film
Lady of the Lake
Green Knight
Sir Gawain
Sir Ector
Sir Bors
Zoot
Dinky
Rabbit of Caerbannog
Dennis the Peasant
Sir Not-Appearing-in-this-Film
Dragon of Angnor
Chicken of Bristol
Legendary Black Beast of Argh
Sir Gallahad
antioch.tar
に含まれている各サブディレクトリ内にはjson
という名前のJSONファイルが存在しており、各ファイルのauthor欄に上記の名前が記述されていた。ちなみにこれらの名前はコメディ映画「Monty Python and the Holy Grail 」の登場人物の名前である。
しかし、"What is your quest?" と "What is your favorite color?" の質問に対する回答はわからず、approachコマンドの解析は断念した。
続いてもう一つの気になるコマンド consultを解析した。どうやらこのコマンドはa.dat
からz.dat
というファイルを読み込んで、なんらかの復号処理をしたのち、復号した内容を出力する模様。

antioch.tar
に含まれている各サブディレクトリ内のlayer.tar
にはa.dat
、b.dat
、c.dat
という無数の.datファイルが含まれていた。しかし、a.dat
からz.dat
まで全ての.datを内包したlayer.tar
はなかった。以下は9a31bad171ad7e8009fba41193d339271fc51f992b8d574c501cae1bfa6c3fe2/layer.tar
に内包されているファイルの一覧である。
Path = 9a31bad171ad7e8009fba41193d339271fc51f992b8d574c501cae1bfa6c3fe2/layer.tar
Type = tar
Physical Size = 88576
Headers Size = 10752
Code Page = UTF-8
Date Time Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
2021-07-20 11:05:14 ..... 4096 4096 a.dat
2021-07-20 11:05:14 ..... 4096 4096 b.dat
2021-07-20 11:05:14 ..... 4096 4096 d.dat
2021-07-20 11:05:14 ..... 4096 4096 e.dat
2021-07-20 11:05:14 ..... 4096 4096 f.dat
2021-07-20 11:05:14 ..... 4096 4096 g.dat
2021-07-20 11:05:14 ..... 4096 4096 i.dat
2021-07-20 11:05:14 ..... 4096 4096 j.dat
2021-07-20 11:05:14 ..... 4096 4096 k.dat
2021-07-20 11:05:14 ..... 4096 4096 l.dat
2021-07-20 11:05:14 ..... 4096 4096 m.dat
2021-07-20 11:05:14 ..... 4096 4096 n.dat
2021-07-20 11:05:14 ..... 4096 4096 p.dat
2021-07-20 11:05:14 ..... 4096 4096 t.dat
2021-07-20 11:05:14 ..... 4096 4096 v.dat
2021-07-20 11:05:14 ..... 4096 4096 w.dat
2021-07-20 11:05:14 ..... 4096 4096 x.dat
2021-07-20 11:05:14 ..... 4096 4096 y.dat
2021-07-20 11:05:14 ..... 4096 4096 z.dat
------------------- ----- ------------ ------------ ------------------------
2021-07-20 11:05:14 77824 77824 19 files
c.dat
、h.dat
、o.dat
、q.dat
、r.dat
、s.dat
、u.dat
が欠けているのがわかる。いずれのサブディレクトリ内のlayer.tar
もこんな調子でファイルが欠けていた。
consultコマンドに正しいファイルを読み込ませることが出来れば、正しい出力結果が表示されてフラグ取得のヒントかフラグそのものを取得できるのでは、と推測したがconsultコマンドが読み込むファイルの条件・法則がわからず。。
結局3問目を突破できず、今年のFlare-On Challengeは終了した。