以下のファイルが与えられた。
These files were given:
distributed_files/headless_horseman をmain関数から以下の関数が呼び出されていることがわかった。
print_intro:メッセージを出力する。offer_pumpkins:scanf関数の書式%dで整数を読み込む。count_offering:読み込んだ整数をfirst_count関数およびsecond_count関数でチェックし、両方のチェックに通過したらdump_heads関数を呼び出す。
first_count関数は、入力の上位16ビットが 0xdead かをチェックしている。
second_count関数は、入力の下位16ビットが 0xface かをチェックしている。
(second_count関数は逆コンパイル結果では入力全体をチェックしているように見えるが、アセンブリコードを見ると下位16ビットしか見ていないことがわかる)
合わせると、0xdeadface、すなわち -559023410 を入力すればいいことがわかる。
distributed_files/headless_horseman を-559023410 を入力すると、以下の6個のファイルが出力された。
Decompiling distributed_files/headless_horseman using main calling these functions:
print_intro : Print some messages.offer_pumpkins : Read an integer using the function scanf with the format specifier %d.count_offering : Check the integer read by functions first_count and second_count, and call the function dump_heads if the input passes both checks.
The function first_count checks if the upper 16 bits of the input is 0xdead.
The function second_count checks if the lower 16 bits of the input is 0xface.
(The function second_count looks as if it is checking the whole input, but reading the assembly code reveals that it is checking only the lower 16 bits.)
Combining these, the value to input is 0xdeadface, which means -559023410.
I executed distributed_files/headless_horseman on -559023410.
As a result, it produced these 6 files:
dessicated_headfetid_headmoldy_headputrid_headshrunken_headswollen_head
各ファイルの内容を確認すると、それぞれELFヘッダーのようだった。
そこで、これらのファイルを distributed_files/body_bag ディレクトリ内のファイルと総当りで合体させる以下のプログラムを作成し、実行した。
Checking the contents of each files, they looked ELF headers.
I created this program to concatenate the files with the files in the directory distributed_files/body_bag using all combinations, and executed that.
できたファイル群を readelf -lS でチェックすると、以下の3個のファイルのみエラーが出なかった。
I checked the resulting files using the command readelf -lS. As a result, these 3 files didn't produce any errors while the other files did:
dessicated_head_decomposing_bodymoldy_head_bloated_bodyshrunken_head_rotting_bodyそこで、これらのファイルをGhidraで逆コンパイルした。
dessicated_head_decomposing_body では、main関数からkatrina関数が呼ばれていた。
katrina関数では、メッセージを出力した後文字列を読み込み、それをencrpyted_words (21 09 04 09 1C 00 7F 24 00 1A 09 1C 28 00 00) とxorして出力していた。
ここで出力されるメッセージの中に、以下の部分があった。
Seeing this, I decompiled these files using Ghidra.
In the file dessicated_head_decomposing_body, the function main calls the function katrina.
The function katrina prints some messages, reads a string, and print the string with exclusive-ored with encrpyted_words (21 09 04 09 1C 00 7F 24 00 1A 09 1C 28 00 00).
The message printed here contained this part:
'Drat! it looks like I encrypted my portion but I cant seem to remember what I used!'
'can you help me out? I was never very creative with these things, maybe try the street I grew up on? or my Home Town?'
distributed_files/README.txt を読むと、「the village of Sleepy Hollow」についてのお話が書かれていた。
そこで、Sleepy Hollow とのXORをとった。
Reading distributed_files/README.txt, I found a story about "the village of Sleepy Hollow".
Seeing this, I calculated XOR with Sleepy Hollow on
結果は really_loves_ となった。
moldy_head_bloated_body では、main関数からichabod関数が呼ばれていた。
ichabod関数では、check_surroundings関数を呼び出し、その返り値が0ならprint_incantation関数を呼び出していた。
print_incantation関数では、"ZmxhZ3t0aGVfaG9yc2VtYW5fanVzdF8=" をb_decode関数に渡した結果を出力していた。
そこで、このデータにCyberChefの From Base64 を適用してみた。
The result was really_loves_.
In the file moldy_head_bloated_body, the function main calls the function ichabod.
The function ichabod calls the function check_surroundings, and when its return values is 0, it calls the function print_incantation.
The function print_incantation prints the result of the function b_decode with "ZmxhZ3t0aGVfaG9yc2VtYW5fanVzdF8=" passed as an argument.
Seeing this, I tried applying "From Base64" to the data on CyberChef.
結果は flag{the_horseman_just_ となった。
shrunken_head_rotting_body では、main関数からbrom関数が呼ばれていた。
brom関数は、local_10の値が指定のものだったらprint_flag関数を呼ぶ処理をしていた。
print_flag関数では、letters、to_replace、buff の値を用いて何かを出力していた。
そこで、print_flag関数の処理を再現する以下のプログラムを書き、実行した。
The result was flag{the_horseman_just_.
In the file shrunken_head_rotting_body, the function main calls the function brom.
The function brom calls the function print_flag if the value of local_10 is what is expected.
The function print_flag prints something based on the values of letters, to_replace, and buff.
Seeing this, I created this program to mimic what is done in the function print_flag, and executed that.
結果は pumpkin_pie} となった。
これらの3個のファイルの解析結果を繋げることで、flagが得られた。
The result was pumpkin_pie}.
I obtained the flag by concatenating what are obtained from these 3 files.