[TryHackMe] Advent of Cyber 2, Day 17 - Walkthrough -

本稿では、[TryHackMe](https://tryhackme.com/)にて提供されている「[Advent of Cyber 2](https://tryhackme.com/room/adventofcyber2)」ルームに関する攻略方法（Walkthrough）について検証します。
「Advent of Cyber 2」は「free room」（無料）で提供されています。購読を必要とせずに仮想マシンを「展開（Deploy）」することができます。

>『Advent of Cyber 2』のWalkthroughインデックスを「[[TryHackMe] Advent of Cyber 2に参加してみた](https://qiita.com/v_avenger/items/ac9092374e5bf16a2dd0)」にて公開しました。

# [Day 17] Reverse Engineering: ReverseELFneering
# ストーリー
![Day17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/c9af2c36-0005-e55b-9097-f5f717145bb5.png)

>エルフ・McSkidyは低レベルの言語に触れたことがありません。 - これはクリスマスモンスターを倒すために彼らが学ばなければならないことです。

[radare2](https://github.com/radareorg/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.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/c04084ed-1af8-9a49-c937-049821d98735.png)

## 関数名の調査
自動解析(`aa`,`aaa`など)で取得した関数のリスト(`l`*ist*)を`afl`（*all function list*）にて表示させることが可能です。
ほとんどの実行可能プログラムには、`main`という名前のエントリポイントがあります。
ここでは、`grep`にて`afl`の実行結果から`main`として定義されたエントリポイントのみをフィルタリングします。
![afl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/170eecee-a7d5-909d-0ac4-7fde84b2bfa5.png)

# カレントアドレスの移動
`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
```

![VV.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/12e02a87-8d42-07c4-c273-30e47fc8b360.png)

この画面では`vim`と同様に`hjkl`で上下左右に移動することができます。
`q`キーで`radare shell`に戻ったり、`:`キーで一時的に`radare shell`を使用することが可能です。

## 逆アセンブル
逆アセンブルの結果を表示するには、`p`(*rint*)出力と`df`(*disassemble function*)を組み合わせます。
ここでは、`main`関数を対象としています。

![pdf_main.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/dcb53a9f-ef68-aea3-8ba6-04c1196f6544.png)

ここに表示されているのは、`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
```

![rbp-0xc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/cfae5dd0-4f7c-a56e-f548-9972081d5b3a.png)

# 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)の値を確認します。

![eax.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/3ed53c1d-d84e-10c3-8672-649c143558db.png)

# 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
```

![rbp-0x4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/ce625437-61eb-762b-d382-9a1f69e239dc.png)

これにて、17日目のミッションが終了です。

# 参考情報
- /var/log/Sawada.log, [radare2 覚書](https://takuzoo3868.hatenablog.com/entry/radare2_love), 2018/11/10
- Reginald Wong, [Mastering Reverse Engineering: Re-engineer your ethical hacking skills](https://www.amazon.co.jp/dp/178883884X/), 2018/10/31 - [書籍サポート GitHub](https://github.com/PacktPublishing/Mastering-Reverse-Engineering/)
- ごちゃごちゃしたIT勉強記録, [radare2メモ書き](https://motojiroxx.hatenablog.com/entry/2018/09/13/014318), 2018/09/13
- pancake, [「radare2」トーク/ワークショップAVTokyo 2017](https://www.slideshare.net/unixfreaxjp/20171102radare2avtokyo-2017), 2017/11/02
- 拾い物のコンパス, [使えれば良いやradare2(静的解析編)](http://poppycompass.hatenablog.jp/entry/2016/10/26/164034), 2016/10/26
- 電気通信大学MMA, [CTF/Toolkit/Radare](https://wiki.mma.club.uec.ac.jp/CTF/Toolkit/Radare)

# Walkthrough
- NEERANJAN MURUGAN, [Advent of Cyber 2 ~ Try Hack Me](https://neeranjan.com/advent-of-cyber-2-try-hack-me/)
- tocto, [Day 17 | Advent of Cyber 2](https://medium.com/advent-of-cyber-2-write-up-try-hack-me/day-17-advent-of-cyber-2-d5d925962247)
- John V, [Advent of Cyber Day 17: ReverseELFneering with Assembly](https://hackofalltrades.dev/advent-of-cyber-day-17-reverseelfneering-with-assembly/)