ごちゃごちゃしたIT勉強記録

自分用メモ。主にセキュリティで、その他色々書きたい。

【あとで追加予定】radare2メモ書き

CTF界隈では非常に使われているradare2ですが、コマンドとかよくわからないし、どう処理を進めていけばいいのかが全然わからんちんなので、まとめておく。

radare2とは

Reverse Engineering Framework。バイナリの解析とかに便利なツール、コマンドが色々入っている。
いろんなアーキテクチャ、ファイルフォーマットに対応している。フリーでさまざまなアーキテクチャ・ファイルフォーマットに対応している点は非常に強いと思う(ただし、x86には対応しているがx86-64には対応していない様子)。詳しい情報は以下を参照。
github.com

解析で基本的にやりたいこと

コードの逆アセンブル

アセンブルで個人的にやりたいのは以下のような作業。

  • 特定のアドレスから何行分かのアセンブリコードを表示するなどの操作
  • import, exportの一覧、しょっぱなから見れるstring情報を表示
  • まぁ、ざっくりアセンブリコードを眺めるとかそんな感じ

デバッグ

デバッグでやりたい基本的なことは以下のようなこと。

  • セキュリティの機構の有無(ASLRなど)
  • メモリマップの表示
  • ブレークポイントの設置
  • ステップ実行(ステップイン、ステップアウト)
  • レジスタの状態
  • 特定のメモリアドレスに格納されている値(hex, strings)

一番最初のコマンド

アセンブルするだけの場合とデバッグをする場合ではすこし違う。
ただ、dスイッチをつけるだけなのだが。

【逆アセンブル】最初のコマンド

r2 <elf binary file>

デバッグ】最初のコマンド

r2 -d <elf binary file>

dスイッチをつけることで、デバッグモードで起動することが可能。起動すると以下のような表示があった後、プロンプトが表示される。

$ r2 -d hello
Process with PID 9276 started...
= attach 9276 9276
bin.baddr 0x00400000
Using 0x400000
asm.bits 64
 -- Press 'C' in visual mode to toggle colors
[0x7f532faecc30]> 

ここで表示される画面がradare shellというものらしい。
まぁ、radareにおけるホーム画面みたいなもんとして今の所は理解しておけばいいかと。
で、最初のコマンドが違うだけで、後の操作は基本的に同じかと思われる。

radare shell起動後の操作

セキュリティ機構の有無

iI

実行するとこんな感じ。

[0x7f532faecc30]> iI
arch     x86
baddr    0x400000
binsz    6666
bintype  elf
bits     64
canary   false
class    ELF64
crypto   false
endian   little
havecode true
intrp    /lib64/ld-linux-x86-64.so.2
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
relro    partial
rpath    NONE
static   false
stripped false
subsys   linux
va       true

バイナリに関連する情報と、セキュリティ機構の有無に関する情報が出てくる。
checksec.shとかと似たようなもん。

初期段階の解析

aaa

上記のコマンド(analyzeコマンド)を行うと以下のような表示が出る。

[0x7f532faecc30]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Constructing a function name for fcn.* and sym.func.* functions (aan)
[TOFIX: afta can't run in debugger mode.ions (afta)
[x] Type matching analysis for all functions (afta)
[x] Use -AA or aaaa to perform additional experimental analysis.
= attach 9276 9276
9276

複数の解析をいっぺんにやっているという感じ。
複数の解析というのは、各行のカッコ内に記述されているコマンド。
なので、aa, aac, aar, aan, aftaをaaaというコマンドでいっぺんにやっているという感じでしょうか。
各コマンドの意味は、上の出力から判断できるかと。

関数名の調査

afl

バイナリに含まれているシンボルの一覧を出す(analyze function list?)ようなものでしょうか。
表示されるものは以下のようなもの

[0x7f532faecc30]> afl
0x00400400    3 26           sym._init
0x00400430    1 6            sym.imp.puts
0x00400440    1 6            sym.imp.__libc_start_main
0x00400450    1 6            sym.imp.exit
0x00400460    1 6            sub.__gmon_start_460
0x00400470    1 41           entry0
0x004004a0    4 50   -> 41   sym.deregister_tm_clones
0x004004e0    4 58   -> 55   sym.register_tm_clones
0x00400520    3 28           sym.__do_global_dtors_aux
0x00400540    4 38   -> 35   entry1.init
0x00400566    1 24           sym.main
0x00400580    4 101          sym.__libc_csu_init
0x004005f0    1 2            sym.__libc_csu_fini
0x004005f4    1 9            sym._fini

特定の関数またはアドレスへの移動

s <symbol or address>

sはseekコマンド。特定のシンボルがさす関数の先頭または任意のアドレスへの移動を行う。
例えば、aflで

[0x7f532faecc30]> afl
0x00400400    3 26           sym._init
0x00400430    1 6            sym.imp.puts
0x00400440    1 6            sym.imp.__libc_start_main
0x00400450    1 6            sym.imp.exit
0x00400460    1 6            sub.__gmon_start_460
0x00400470    1 41           entry0
0x004004a0    4 50   -> 41   sym.deregister_tm_clones
0x004004e0    4 58   -> 55   sym.register_tm_clones
0x00400520    3 28           sym.__do_global_dtors_aux
0x00400540    4 38   -> 35   entry1.init
0x00400566    1 24           sym.main
0x00400580    4 101          sym.__libc_csu_init
0x004005f0    1 2            sym.__libc_csu_fini
0x004005f4    1 9            sym._fini

sym.mainに移動したいのであれば、

s sym.main

とする。そうすると、プロンプトのアドレスがseekした後のアドレスに変化する。

[0x7f532faecc30]> s sym.main
[0x00400566]>

ビジュアルモードへの移行

Vコマンドをベースとして、次にくる文字によって表示方法を変更する。
表示方法としてはおもにfncgraphとpanelがある。

その1:fncgraph(function graph?)

[0040055a]> VV

これを実行すると、現在のアドレスを開始地点としてIDAのGraph Viewっぽい画面が出る。

[0x00400566]> VV @ sym.main (nodes 1 edges 0 zoom 100%) BB-NORM mouse:canvas-y mov-speed:5

                 .---------------------------------------------------.                                                                                       
                 | [0x400566]                                        |                                                                                       
                 | ;-- main:                                         |                                                                                       
                 | (fcn) sym.main 24                                 |                                                                                       
                 |   sym.main (int argc, char **argv, char **envp);  |                                                                                       
                 | ; DATA XREF from entry0 (0x40048d)                |                                                                                       
                 | push rbp                                          |                                                                                       
                 | mov rbp, rsp                                      |                                                                                       
                 | ; 0x400604                                        |                                                                                       
                 | ; "Hello world!"                                  |                                                                                       
                 | mov edi, str.Hello_world                          |                                                                                       
                 | call sym.imp.puts;[ga]                            |                                                                                       
                 | mov edi, 0                                        |                                                                                       
                 | call sym.imp.exit;[gb]                            |                                                                                       
                 `---------------------------------------------------'  

画面の移動はvimと同じようにhjklキーを使って行う。
で、この画面上でできることは

入力キー 操作
shift+/キー 使用可能なコマンド一覧を表示(ヘルプ機能)
xキー 今いるサブルーチンの呼び出し元(xref)のアセンブリコードを表示する
スペース hexダンプの表示
shift+dキー アセンブリコードとアドレスを同時に表示するモード

あとfncgraphの画面で
xキー -> vキー
という順番でやると、左側に関数のシンボル名、右側に左側で選択した関数のアドレスから何行分かのアセンブリコードが表示される画面が出てくる。
f:id:motojiroxx:20180912154800p:plain


その2:Panel表示

[0040055a]> V!

上記のコマンドを入力すると、以下のような画面が表示される。
f:id:motojiroxx:20180912150339p:plain
それぞれのパネルへ、tabキーを使うことで移動することが可能。
また、上にあるCUI版メニューバーへもtabキーで移動可能。
メニューバーには結構色々な機能があって、非常に使える。
(ただ、string検索はなぜか引っかかるはずの文字列が引っかからなかったのだが....)

いつものデバッグ操作

基本的なデバッグ操作はだいたい

  1. ブレークポイントの設置
  2. continue操作(現在位置から直近のブレークポイントまでpcを進める)
  3. ブレークポイントからステップ実行

という感じが多い。なので、それをradareでやる場合のコマンドなどを下にまとめる。基本的にはradare shell上でdコマンド(debug command)を使っていくことになる。

ブレークポイントの設置

radare shellでdbコマンド(debug breakpoint)を使う。

db <address>

これでブレークポイントを仕掛けることができる。

直近のブレークポイントまで移動(continue)

dc

このコマンドを実行すると、radare shellのプロンプトが表示するアドレスが設定したブレークポイントのところまでいっているはずである。

ステップ実行

ds

デバッグ操作の基本はだいたいこんな感じかと。


ここまでで把握できたもの

大まかなコマンド体系としては、いくつかの1文字で表現されるメインコマンドがあり、1文字で表現されるサブコマンド・オプションを合体させて1つの実行コマンドとしている。(メインコマンドの一覧は、radare shell上で'?'コマンドを実行するとみることが可能)
メインコマンドのうち主要なものを以下に列挙。

a : analyze command
aの次にくる文字で「何を解析(analyze)の対象とするか」を指定する
(例として、関数名を調べたい場合には' af 'とする)
で、その次にくる文字で「解析した結果をどのように処理したいか」というオプションがくる。
(例としては、リストとして画面出力したい場合であれば' afl 'とする)

p : print command
pの次にくる文字で「どういった形式で出力(print)を行うか」を指定する
(例として、逆アセンブルしたコードを出力する場合には' pd 'とする)
で、その次にくる文字で「何を対象とするか:を指定する
(例として、関数を出力する場合には' pdf@function_name 'とする)

i : information command
iの次にくる文字で「どういった情報を出力するか」を指定する
(例として、importされた関数の情報が欲しい場合には' ii 'とする)

V : Visual mode command
vの次にくる文字で「どういったモードで表示を行うか」を指定する
(例として、上記のようにpanelで表示する場合には' V! 'とする)

d : debug command
dの次にくる文字で「デバッグモードでどのような操作を行うか」を指定