本稿では、TryHackMeにて提供されている「Advent of Cyber 2」ルームに関する攻略方法(Walkthrough)について検証します。
「Advent of Cyber 2」は「free room」(無料)で提供されています。購読を必要とせずに仮想マシンを「展開(Deploy)」することができます。
『Advent of Cyber 2』のWalkthroughインデックスを「[TryHackMe] Advent of Cyber 2に参加してみた」にて公開しました。
[Day 17] Reverse Engineering: ReverseELFneering
ストーリー
エルフ・McSkidyは低レベルの言語に触れたことがありません。 - これはクリスマスモンスターを倒すために彼らが学ばなければならないことです。
radare2は、バイナリのリバースエンジニアリングと分析のためのフレームワークです。バイナリを逆アセンブルし(マシンコードを実際に読み取り可能なアセンブリに変換し)、バイナリをデバッグする(ユーザーが実行をステップ実行してプログラムの状態を表示できるようにする)ために使用できます。
rahash2
コマンドにて調査対象のファイルchallenge1
について調べてみます。
$ ls -l challenge1
-rwxr-xr-x 1 501 dialout 844648 Dec 17 19:46 challenge1
$ rahash2 -amd5 challenge1
challenge1: 0x00000000-0x000ce367 md5: 702022338bfaa1bc23c325fd1e747d10
$ rahash2 -asha256 challenge1
challenge1: 0x00000000-0x000ce367 sha256: 4507ad08b6ed1d5f3ef2a2e3f4a1064d0b8425cccb50ac8c28da8435a9d0f9e5
radare2の起動
引数に解析したいプログラムのファイル名challenge1
を指定して、radare2
を起動します。
d
スイッチをつけることで、デバッグモードradare shell
で起動することが可能です。
$ r2 -d challenge1
Process with PID 3340 started...
= attach 3340 3340
bin.baddr 0x00400000
Using 0x400000
asm.bits 64
Warning: r_bin_file_hash: file exceeds bin.hashlimit
[0x00400a30]>
基本情報
バイナリの情報を調べたい場合、iI
コマンド(Binary info)で表示できます。
radare2
は「1文字 <-> 1命令」となっています。各々の文字に意味づけが行われています。各コマンドの末尾に?
を付けることでコマンドのヘルプを参照できます。
[0x00400a30]> iI
arch x86
baddr 0x400000
binsz 842534
bintype elf
bits 64
canary true
class ELF64
compiler GCC: (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
crypto false
endian little
havecode true
laddr 0x0
lang c
linenum true
lsyms true
machine AMD x86-64 architecture
maxopsz 16
minopsz 1
nx true
os linux
pcalign 0
pic false
relocs true
rpath NONE
sanitiz false
static true
stripped false
subsys linux
va true
bintype
、class
、os
の各フィールドから、challenge1
ファイルがLinuxで動作する32ビットの実行可能なELFファイルであることを示しています。
arch
、bits
、endian
、machine
の各フィールドから、そのファイルがx86コードでビルドされたことを示しています。
さらに、lang
フィールドから、ファイルがC言語からコンパイルされたことを示します。
これらの情報は、逆アセンブルやデバッグの際における前提情報として役立ちます。
解析
解析の依頼
バイナリが開いたら、最初にradare2
に対して解析を依頼する必要があります。そのコマンドはa
(nalyze)コマンドです。関数部のフラグを特定し、Visual Mode
上で解析していきます。
最低限の解析であれば、aa
(analyze all)を使用します。aaa
、aaaa
とオプションを増やすことで解析の程度を広げていくことが可能です。
自動的に解析を行いたい場合には、radare2
起動時に引数として-A
あるいは-AA
を指定する方法もあります。
$ r2 -d -AA challenge1
Process with PID 3512 started...
= attach 3512 3512
bin.baddr 0x00400000
Using 0x400000
asm.bits 64
Warning: r_bin_file_hash: file exceeds bin.hashlimit
[Invalid address from 0x004843acith sym. and entry0 (aa)
Invalid address from 0x0044efc6
[x] Analyze all flags starting with sym. and entry0 (aa)
関数名の調査
自動解析(aa
,aaa
など)で取得した関数のリスト(l
ist)をafl
(all function list)にて表示させることが可能です。
ほとんどの実行可能プログラムには、main
という名前のエントリポイントがあります。
ここでは、grep
にてafl
の実行結果からmain
として定義されたエントリポイントのみをフィルタリングします。
カレントアドレスの移動
main
関数へ移動する場合にはs
(eek)コマンドを使います。
[0x00400c81]> afl | grep main
0x00400de0 114 1657 sym.__libc_start_main
0x0048fa40 16 247 -> 237 sym._nl_unload_domain
0x00403ae0 308 5366 -> 5301 sym._nl_load_domain
0x00470430 1 49 sym._IO_switch_to_main_wget_area
0x00403840 39 672 -> 640 sym._nl_find_domain
0x00400b4d 1 35 main
0x0048f9f0 7 73 -> 69 sym._nl_finddomain_subfreeres
0x0044ce10 1 8 sym._dl_get_dl_main_map
0x00415ef0 1 43 sym._IO_switch_to_main_get_area
[0x00400c81]> s main
[0x00400b4d]>
自動解析にてmain
関数は(0x00400b4d 1 35 main
)と特定できました。
ここで、プロンプトに注目してください。現在のアドレス([0x00400c81]
)からs main
にて[0x00400b4d]
へ移動することができました。
グラフビュー表示
VV
コマンドを使用すると、現在のアドレスを開始地点としてグラフビュー(Visual Mode
)を表示することができます。
[0x00400b4d]> VV
この画面ではvim
と同様にhjkl
で上下左右に移動することができます。
q
キーでradare shell
に戻ったり、:
キーで一時的にradare shell
を使用することが可能です。
逆アセンブル
逆アセンブルの結果を表示するには、p
(rint)出力とdf
(disassemble function)を組み合わせます。
ここでは、main
関数を対象としています。
ここに表示されているのは、main
関数のアセンブリ命令です。これよりデバッグツールを使用してインストラクションを解読していきます。
インストラクションの解読
まず、main
関数に格納されている変数が3つ確認できます。
; var int64_t var_ch @ rbp-0xc
; var int64_t var_8h @ rbp-0x8
; var int64_t var_4h @ rbp-0x4
Day 17 - #1.
What is the value of local_ch when its corresponding movl instruction is called (first if multiple)?
最初のmovl
命令に対する変数local_ch
の値について問われています。問われている箇所を抜粋しました。
0x00400b5f 8b45f4 mov eax, dword [var_ch]
ブレイクポイントの設定
radare shell
画面にてdb
(debug breakpoint)で設定することが可能です。
0x00400b5f
にブレイクポイントを設定します。dc
(Debug Continue)にて、その時点まで実行します。
db 0x00400b5f
dc
hit breakpoint at: 400b5f
radare shell
画面にてpx
(Print heXdump)でlocal_ch
の値を確認します。
px @ rbp-0xc
Day 17 - #2.
What is the value of eax when the imull instruction is called?
ds
(debug step)にて、imull
命令まで実行させます。
dr
(Debug cpu Registers)にて、EAX
(rax)の値を確認します。
Day 17 - #3.
What is the value of local_4h before eax is set to 0?
次の命令の前における、local_4h
の値を確認する必要があります。
0x00400b69 b800000000 mov eax, 0
次のコマンドで確認します。
px @ rbp-0x4
これにて、17日目のミッションが終了です。
参考情報
- /var/log/Sawada.log, radare2 覚書, 2018/11/10
- Reginald Wong, Mastering Reverse Engineering: Re-engineer your ethical hacking skills, 2018/10/31 - 書籍サポート GitHub
- ごちゃごちゃしたIT勉強記録, radare2メモ書き, 2018/09/13
- pancake, 「radare2」トーク/ワークショップAVTokyo 2017, 2017/11/02
- 拾い物のコンパス, 使えれば良いやradare2(静的解析編), 2016/10/26
- 電気通信大学MMA, CTF/Toolkit/Radare
Walkthrough
- NEERANJAN MURUGAN, Advent of Cyber 2 ~ Try Hack Me
- tocto, Day 17 | Advent of Cyber 2
- John V, Advent of Cyber Day 17: ReverseELFneering with Assembly