Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Reversing基礎編 / Basics of Reversing - SECCON Beginners Live 2022

Hi120ki
September 11, 2022
1.2k

Reversing基礎編 / Basics of Reversing - SECCON Beginners Live 2022

SECCON Beginners Live 2022 発表スライド
https://connpass.com/event/258217/

Hi120ki

September 11, 2022
Tweet

Transcript

  1. SECCON Beginners Live 2022 Reversing基礎編 2022/09/11 @hi120ki

  2. 自己紹介 Hi120ki - Hiroki Akamatsu 大阪大学大学院 情報科学研究科 修士1年 大阪大学CTFサークル Wani

    Hackase 所属 Web・Reversing担当 【Web】Util, Ironhand 【Rev】Quiz, Recursive, Ransom WaniCTFのインフラ担当 CTF大会開催はいいぞ - 魔女のお茶会 2021冬 Reversing基礎編 - SECCON Beginners Live 2022 2
  3. 本演習の目的 バイナリ解析の基本ツールのインストールから使い方までを紹介し,バイナリ 解析の第一歩を踏み出してもらい,Beginners CTFのEasy問題を解けるよう になる Reversing基礎編 - SECCON Beginners Live

    2022 3
  4. 流れ 1. Reversingとは 2. ELFファイル解析の基本 3. ツールのインストール 4. ツールの使い方 Reversing基礎編

    - SECCON Beginners Live 2022 4
  5. 1. Reversingとは Reverse Engineeringとも言われ,機械や製品・プログラムの内部の構造や 動作を解析すること CTFではプログラムや特定の形式のファイルを解析します (例) 実行可能ファイル(Executable file) Linux

    ELF Windows PE モバイルアプリ APK(Android Application Package) スクリプトファイル pcapファイル ファームウェア Reversing基礎編 - SECCON Beginners Live 2022 5
  6. 出題傾向 Linux ELF 2020 : mask yakisoba sneaky 2021 :

    only_read children please_not_trace_me be_angry firmware 2022 : Quiz Recursive Ransom Windows PE 2022 : WinTLS APK 2020 : siblangs スクリプトファイル 2020 : ghost pcapファイル 2022 : Ransom ファームウェア 2021 : firmware 特にBeginner~Easy難易度はLinux ELFファイルの出題がほとんど Reversing基礎編 - SECCON Beginners Live 2022 6
  7. ELFファイルとは Executable and Linkable Formatの略 多くのLinux系やBSD系のOSで実行ファイル形式として採用されている C言語でソースコードを記述し,コンパイラのgccで作成できる gcc main.c -o

    a.out 実行権限を与えた上で実行すると,ソースコード main.c に記述された処理が実 行される chmod +x ./a.out # 実行権限を与える ./a.out # 実行する Reversing基礎編 - SECCON Beginners Live 2022 7
  8. なぜLinux ELFファイルの出題が多いのか C言語で作成されたLinux ELFファイルは ファイルサイズが小さい 配布しやすい 解析ツールが軽快に動作する アセンブリが簡潔 どんなプログラムであるか想像しやすい 問題の本質にすぐ気付くことができる

    問題を作りやすい C言語を多少扱えればある程度の難易度の問題が作れる Reversing基礎編 - SECCON Beginners Live 2022 8
  9. 2. ELFファイル解析の基本 CPUは機械語しか実行できないが機械語は人間にとって扱いづらいので,機械 語と1対1で対応するアセンブリ言語や,コンパイラでアセンブリコードを出力 できるソースコードで処理を記述する ソースコードに記述された処理は機械語に変換されるとどんな処理が行われて いるか分かりづらくなる・マルウェアでは処理を秘匿するために更に処理が分 かりづらくなるような工夫がされる → 機械語から処理を正確に把握する能力を養う

    Reversing基礎編 - SECCON Beginners Live 2022 9
  10. ELFファイル解析の流れ 1. 表層解析 ファイルの種類を調べる ファイルに含まれる文字列からファイルの種類や動作の手がかりを取得する 2. 静的解析 バイナリに含まれる機械語の命令からプログラムの動作を把握する 3. 動的解析

    ファイルを実行しながら処理を追うことでプログラムの動作を把握する Reversing基礎編 - SECCON Beginners Live 2022 10
  11. ELFファイル解析でよく使うツール 1. 表層解析 fileコマンド : ファイル形式を推測 stringsコマンド : ファイルに含まれる可読文字列を表示 2.

    静的解析 Ghidra : NSAによって開発されているOSSの解析ツール IDA : Hex Rays社によって開発されている有償(機能が制限された無償版もあ り)の解析ツール 3. 動的解析 GDB : GNU Project debugger 特にLinuxではデファクトスタンダードなデ バッグ&動的解析ツール Reversing基礎編 - SECCON Beginners Live 2022 11
  12. 4. ツールのインストール インストールにあたっての準備 fileとstringsはLinuxのコマンドで,GDBはLinux上で動作 → Linux環境が必要 CTFでは色々なツールをインストールしていくことになり,ライブラリのバー ジョンの衝突で動かなくなったり,動作が不安定になることがよくある → CTF環境は「リセットしやすいもの」を選び構築するのがおすすめ

    1つのアプローチ VirtualBoxとVagrantでいつでもCTF環境となるLinux仮想マシンを立ち上げ る・リセットできるようにする よく使うツールを自動インストールするAnsible Playbookやシェルスクリプ トを用意し自分のCTF環境を再現できるようにする ホストとの共有ディレクトリの中で作業しCTF環境が突然動かなくなってもフ ァイルは復元できるようにする Reversing基礎編 - SECCON Beginners Live 2022 12
  13. 4-1. 表層解析ツール fileコマンド, stringsコマンド POSIXコマンドなのでLinuxでは標準インストールされている (今回の資料はUbuntu 20.04.4 LTSで作成) $ file

    --help Usage: file [OPTION...] [FILE...] Determine type of FILEs. $ strings --help Usage: strings [option(s)] [file(s)] Display printable strings in [file(s)] (stdin by default) Reversing基礎編 - SECCON Beginners Live 2022 13
  14. 4-2. 静的解析ツール Ghidra https://ghidra-sre.org/ 1. https://jdk.java.net/やhttps://adoptium.net/からJDKをダウン ロードしインストールする 2. GithubのReleaseページから最新のバージョンのzipファイル ghidra_<

    バージョン >_PUBLIC_< 日付 >.zip をダウンロードし展開する 3. Windowsなら ghidraRun.bat をクリックし,MacOSとLinuxは Terminalから ./ghidraRun で実行する (Armプロセッサを搭載したMacについては公式のInstallation Guideを参照 してください) Reversing基礎編 - SECCON Beginners Live 2022 14
  15. 4-3. 動的解析ツール GDB aptからインストール $ sudo apt update $ sudo

    apt install gdb $ gdb --version GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2 (最新版はhttp://ftp.gnu.org/gnu/gdb/からソースコードを入手できます) Reversing基礎編 - SECCON Beginners Live 2022 15
  16. GDBプラグイン Peda GEF PwndbgといったGDBを拡張するプラグインが公開されている これらをまとめてインストールできるスクリプト https://github.com/apogiatzis/gdb-peda-pwndbg-gef が便利 $ gdb-peda $

    gdb-pwndbg $ gdb-gef これらのコマンドから各プラグインが適用された状態のGDBが起動する Reversing基礎編 - SECCON Beginners Live 2022 16
  17. 5. ツールの使い方 表層解析ツールでは2022年出題 Quiz https://github.com/SECCON/Beginners_CTF_2022/raw/main/reversi ng/quiz/files/quiz 静的解析ツールでは2021年出題 only_read (by n01e0)

    https://github.com/SECCON/Beginners_CTF_2021/raw/main/reversi ng/only_read/files/chall 動的解析ツールでは2021年出題 please_not_trace_me (by n01e0) https://github.com/SECCON/Beginners_CTF_2021/raw/main/reversi ng/please_not_trace_me/files/chall を実際に解きながら紹介します Reversing基礎編 - SECCON Beginners Live 2022 17
  18. 5-1. 表層解析ツール fileコマンド $ file quiz quiz: ELF 64-bit LSB

    shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=3c3ecb93f6ca813352964076835ff6712fe9554e, for GNU/Linux 3.2.0, not stripped x86-64環境で動作するELFファイル Reversing基礎編 - SECCON Beginners Live 2022 18
  19. stringsコマンド $ strings quiz /lib64/ld-linux-x86-64.so.2 ... ctf4b{w0w_d1d_y0u_ca7ch_7h3_fl4g_1n_0n3_sh07?} Welcome, it's time

    for the binary quiz! Q1. What is the executable file's format used in Linux called? Linux 1) ELM 2) ELF 3) ELR Answer : %2s%*[^ answer length must be 1. ... 本来クイズに答えないと表示されないフラグ文字列がそのままバイナリ内にあ るため,stringsコマンドで取得できる (難しい問題はそのままバイナリ内にフラグが埋め込まない工夫がされている) Reversing基礎編 - SECCON Beginners Live 2022 19
  20. 5-2. 静的解析ツール Ghidraの使い方を紹介 1. 起動後File→New Projectを選択 2. Non-shared projectを選択 3.

    適当なProject DirectoryとProject Nameを入力 4. Tool Chestの緑のアイコンをクリック 5. File→Import Fileから配布バイナリを選択 6. 「analyze now?」にYes 7. Analysis OptionはデフォルトでOK 8. 左の真ん中のSymbol TreeのFunctionsを展開しmainを選択 9. 真ん中に逆アセンブル結果,右に逆コンパイル結果が表示される Reversing基礎編 - SECCON Beginners Live 2022 20
  21. 1. 起動後File→New Projectを選択 Reversing基礎編 - SECCON Beginners Live 2022 21

  22. 2. Non-shared projectを選択 Reversing基礎編 - SECCON Beginners Live 2022 22

  23. 3. 適当なProject DirectoryとProject Nameを入力 Reversing基礎編 - SECCON Beginners Live 2022

    23
  24. 4. Tool Chestの緑のアイコンをクリック Reversing基礎編 - SECCON Beginners Live 2022 24

  25. 5. File→Import Fileから配布バイナリを選択 Reversing基礎編 - SECCON Beginners Live 2022 25

  26. 5. File→Import Fileから配布バイナリを選択 Reversing基礎編 - SECCON Beginners Live 2022 26

  27. 5. File→Import Fileから配布バイナリを選択 Reversing基礎編 - SECCON Beginners Live 2022 27

  28. 6. 「analyze now?」にYes Reversing基礎編 - SECCON Beginners Live 2022 28

  29. 7. Analysis OptionはデフォルトでOK Reversing基礎編 - SECCON Beginners Live 2022 29

  30. 8. 左の真ん中のSymbol TreeのFunctionsを展開しmainを選択 Reversing基礎編 - SECCON Beginners Live 2022 30

  31. 8. 左の真ん中のSymbol TreeのFunctionsを展開しmainを選択 Reversing基礎編 - SECCON Beginners Live 2022 31

  32. 8. 左の真ん中のSymbol TreeのFunctionsを展開しmainを選択 Reversing基礎編 - SECCON Beginners Live 2022 32

  33. 9. 真ん中に逆アセンブル結果,右に逆コンパイル結果が表示される Reversing基礎編 - SECCON Beginners Live 2022 33

  34. (解法1) 逆アセンブル結果を見る Reversing基礎編 - SECCON Beginners Live 2022 34

  35. (解法1) 逆アセンブル結果を見る アドレス バイナリ 命令 オペランド 001011c9 ba 17 00

    MOV EDX,0x17 00 00 001011ce 48 89 c6 MOV RSI,RAX アドレス : メモリの中で命令が格納される番地.メモリの中に格納された命令 は基本的に順番に実行されていくがJNZ命令などで任意のアドレスの命令を実 行していくようにすることもできる バイナリ : ELFファイルの中身で命令とオペランドに対応するものが表示され ている 命令 : メモリのアドレスや中身・レジスタ・固定の値を引数(オペランドと呼 ぶ)として行われる処理の名称.MOV命令は第2オペランドの値を第1オペラン ドにコピーする レジスタ : CPUと⾼速にデータのやり取りができる記憶素子.EDX, RSI, RAX はレジスタの1種 Reversing基礎編 - SECCON Beginners Live 2022 35
  36. 001011c5 48 8d 45 e0 LEA RAX=>local_28,[RBP + -0x20] 001011c9

    ba 17 00 MOV EDX,0x17 00 00 001011ce 48 89 c6 MOV RSI,RAX 001011d1 bf 00 00 MOV EDI,0x0 00 00 001011d6 e8 b5 fe CALL <EXTERNAL>::read ff ff (LEA命令は第2オペランドのアドレスを第1オペランドにコピーする) このとき 第1引数 EDIには読み込むデータの種類として標準入力を指定 第2引数 RSIには書き込み先メモリ領域のアドレス 第3引数 EDXには読み込む文字数の0x17 とし,関数を呼び出すCALL命令で read を指定することで,標準入力から 0x17(=23)文字読み込みメモリ内に保存する処理が実行される Reversing基礎編 - SECCON Beginners Live 2022 36
  37. 001011e0 0f b6 45 e0 MOVZX EAX,byte ptr [RBP +

    local_28] 001011e4 3c 63 CMP AL,0x63 001011e6 0f 85 da JNZ LAB_001012c6 00 00 00 001011ec 0f b6 45 e1 MOVZX EAX,byte ptr [RBP + local_28+0x1] 001011f0 3c 74 CMP AL,0x74 001011f2 0f 85 ce JNZ LAB_001012c6 00 00 00 ... そしてメモリ内に保存された入力文字列を1byteずつEAXにコピーして 0x63 や 0x74 と比較している 0x63 0x74 0x66 0x34 は文字コードの標準的な規格であるアスキー文字として c t f 4 と対応する → CMP命令で比較している数値を順番にアスキー文字として変換するとフラ グ文字列 ctf4b{c0n5t4nt_f0ld1ng} が得られる Reversing基礎編 - SECCON Beginners Live 2022 37
  38. (解法2) Ghidraの右のDecompile画面を見る Reversing基礎編 - SECCON Beginners Live 2022 38

  39. (解法2) Ghidraの右のDecompile画面を見る if (((((((char)local_28 == 'c') && (local_28._1_1_ == 't'))

    && (local_28._2_1_ == 'f')) && (((local_28._3_1_ == '4' && (local_28._4_1_ == 'b')) && ((local_28._5_1_ == '{' && ((local_28._6_1_ == 'c' && (local_28._7_1_ == '0')))))))) && (((char)local_20 == 'n' && ((((((local_20._1_1_ == '5' && (local_20._2_1_ == 't')) && (local_20._3_1_ == '4')) && ((local_20._4_1_ == 'n' && (local_20._5_1_ == 't')))) && ((local_20._6_1_ == '_' && ((local_20._7_1_ == 'f' && ((char)local_18 == '0')))))) && (local_18._1_1_ == 'l')))))) && ((((local_18._2_1_ == 'd' && (local_18._3_1_ == '1')) && ((char)local_14 == 'n')) && ((local_14._1_1_ == 'g' && (local_12 == '}')))))) { puts("Correct"); } Ghidraに付属する逆コンパイラにより,処理がC言語のような擬似的なコード で表示される → 一文字ずつ c t f 4 ...と比較してすべて一致すれば Correct と出力するコ ードなので文字をつなげることでフラグ文字列 ctf4b{c0n5t4nt_f0ld1ng} が得ら れる Reversing基礎編 - SECCON Beginners Live 2022 39
  40. 5-3. 動的解析ツール GDBの使い方を紹介 0. 表層解析・静的解析 1. バイナリの読み込み 2. 解析の始め方 3.

    Break Pointによる一時停止 4. レジスタの書き換え Reversing基礎編 - SECCON Beginners Live 2022 40
  41. 0. 表層解析・静的解析 $ file please_not_trace_me please_not_trace_me: ELF 64-bit LSB shared

    object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=23181ea7316f70cf887016337e4024aa643a9d7b, for GNU/Linux 3.2.0, not stripped $ strings please_not_trace_me /lib64/ld-linux-x86-64.so.2 ... flag decrypted. bye. prease not trace me... ... Reversing基礎編 - SECCON Beginners Live 2022 41
  42. 0. 表層解析・静的解析 Ghidraで動作を確認する local_30 = 9; do { switch(local_30) {

    case 8: fwrite("prease not trace me...\n",1,0x17,stderr); exit(1); ... case 0xb: local_38 = ptrace(PTRACE_TRACEME,0,1,0); ... case 0x16: local_40 = ptrace(PTRACE_TRACEME,0,1,0); } Reversing基礎編 - SECCON Beginners Live 2022 42
  43. ptraceシステムコールとは https://man7.org/linux/man-pages/man2/ptrace.2.html あるプロセス(実行されているプログラム)のデバッグを提供する機能 ptraceシステムコールはあるプロセスの中で2回呼び出すことができないとい う特徴があり,1回目の呼び出しでは返り値が 0 (実行に成功した)となるが2回 目の呼び出しでは返り値が -1 (実行に失敗した)となる

    GDBはptraceシステムコールによってデバッグを実現しているため,GDB上 でデバッグを行うプロセスはすでに1回ptraceシステムコールが呼ばれた状態 となる つまり,ptraceシステムコールをあらかじめプログラム内に記載しておくと プログラム内のptraceシステムコールの呼び出しの返り値が 0 とな るときはGDB(やptraceシステムコールによるデバッグ)で呼び出さ れていない プログラム内のptraceシステムコールの呼び出しの返り値が -1 とな る場合はデバッガー上で動作している と判定することができる Reversing基礎編 - SECCON Beginners Live 2022 43
  44. 2. 解析の始め方 please_not_trace_meをGDB上で動かす $ gdb-peda please_not_trace_me ... gdb-peda$ start #

    main 関数手前で一時停止 ... gdb-peda$ c # 実行を続ける Continuing. prease not trace me... [Inferior 1 (process 162338) exited with code 01] Reversing基礎編 - SECCON Beginners Live 2022 44
  45. please_not_trace_meをそのまま動かす $ ./please_not_trace_me flag decrypted. bye. GDB上で動かしたときと処理が変わっている → please_not_trace_meはptraceシステムコールでGDB上で動作している か検知し,GDB上で動作していないときのみフラグ文字列を復号する実装

    → フラグ文字列を取得するにはプログラム内のptraceシステムコールが呼ば れた直後でプログラムを一時停止させ,返り値が格納されている場所の値を書 き換える必要がある Reversing基礎編 - SECCON Beginners Live 2022 45
  46. 3. Break Pointによる一時停止 プログラムのアドレスを設定しておくことで,そのアドレスの命令を実行する 直前でプログラムを一時停止する機能 さらに停止中はレジスタやメモリの値を書き換えることができる → プログラム内のptraceシステムコールが呼ばれた直後にプログラムを一時 停止させ,返り値が格納されているレジスタの値を -1

    から 0 に書き換える Reversing基礎編 - SECCON Beginners Live 2022 46
  47. まずはGDB上でプログラム内のptraceシステムコールがどのアドレスで呼び 出されているか調査する $ gdb-peda please_not_trace_me ... gdb-peda$ start # main

    関数手前で一時停止 ... gdb-peda$ disas main # main 関数を逆アセンブルする Dump of assembler code for function main: 0x00005555555551ff <+0>: push rbp 0x0000555555555200 <+1>: mov rbp,rsp => 0x0000555555555203 <+4>: sub rsp,0x70 0x0000555555555207 <+8>: mov DWORD PTR [rbp-0x54],edi 0x000055555555520a <+11>: mov QWORD PTR [rbp-0x60],rsi 0x000055555555520e <+15>: mov QWORD PTR [rbp-0x68],rdx 0x0000555555555212 <+19>: call 0x55555555585e <megaInit> 0x0000555555555217 <+24>: mov eax,DWORD PTR [rbp-0x54] Reversing基礎編 - SECCON Beginners Live 2022 47
  48. ここから1回目に呼ばれるptraceシステムコールを探すと 0x00005555555552f3 <+244>: call 0x555555555080 <[email protected]> 0x00005555555552f8 <+249>: mov QWORD

    PTR [rbp-0x38],rax アドレス 0x00005555555552f3 で呼びだしており,返り値が格納されるレジスタ RAX をその直後にメモリ内にコピーし処理が行われていくことが分かる → ptraceシステムコールが呼ばれた直後にプログラムを一時停止させたいの でアドレス 0x00005555555552f8 にbreak pointを設定する Reversing基礎編 - SECCON Beginners Live 2022 48
  49. 4. レジスタの書き換え gdb-peda$ b *0x00005555555552f8 # break point を設定 Breakpoint

    2 at 0x5555555552f8 gdb-peda$ c # 実行を再開する Continuing. ... Breakpoint 2, 0x00005555555552f8 in main () gdb-peda$ set $rax=0 # RAX レジスタの値を0 にする gdb-peda$ c # 実行を再開する Continuing. flag decrypted. bye. → プログラム内で呼ばれたptraceシステムコールの返り値をsetコマンドで -1 から 0 に書き換えることで,please_not_trace_meをそのまま動かすと きと同じ処理をするようになった Reversing基礎編 - SECCON Beginners Live 2022 49
  50. フラグがメモリ内で復号されているようなのでさらに flag decrypted. bye. が 表示される箇所(GhidraのDecompile画面とGDBの逆アセンブル結果を見比 べることで 0x0000555555555330 のputs命令だとわかる)にbreak pointを設定

    する Reversing基礎編 - SECCON Beginners Live 2022 50
  51. gdb-peda$ b *0x0000555555555330 Breakpoint 3 at 0x555555555330 gdb-peda$ start #

    最初から実行し直す gdb-peda$ c # main 関数前で停止するので実行を再開する Breakpoint 2, 0x00005555555552f8 in main () # ptarace システムコールが呼ばれた直後に停止 gdb-peda$ set $rax=0 # RAX レジスタの値を0 にする gdb-peda$ c # 実行を再開する [----------------------------------registers-----------------------------------] R8 : 0x5555555592c0 ("ctf4b{d1d_y0u_d3crypt_rc4?}") R8 レジスタにフラグ文字列 ctf4b{d1d_y0u_d3crypt_rc4?} が格納されていた (特にGDBでのアドレスの値は実行環境ごとに異なるので,適宜 disas コマン ドでGDBでの逆アセンブル結果を見ながらbreak pointを設定してください) Reversing基礎編 - SECCON Beginners Live 2022 51
  52. 最後に 表層解析ではfileコマンド・stringsコマンド,静的解析ではGhidra,動的解 析ではGDBをインストール方法から基本的な使い方までを紹介しました 実はGhidraにはstringsコマンドに該当する機能があり,逆アセンブル結果の どこで使われているかを簡単に見つける方法があったり,GDBでは今回紹介し たbreak point以外にも様々なコマンドがGDB本体やGDBプラグインで提供 されています SECCON Beginners

    CTFの過去問は https://github.com/seccon から入手 でき,また他にも常設CTFや書籍や他のCTFの過去問から解答付きの問題を入 手することができます ぜひいろんな問題を今回紹介したツールたちで解いてみてください Reversing基礎編 - SECCON Beginners Live 2022 52