LoginSignup
1
5

More than 5 years have passed since last update.

初心者によるバイナリ解析(CTF2017 Write UP)

Last updated at Posted at 2018-06-28

はじめに

CTFの過去問に挑戦してみました。解いた問題はALEXCTFのre2です。使ったツールはgdbとradare2,rabin2です。かなり雑です・・。

それではさっそく...

$ ./re2
Usage: ./re2 flag

$ ./re2 aaaa
Better luck next time

引数として文字列を読み込んでそれによって応答を変えてくるタイプですかね

rabin2による文字列解析
$ rabin2 -z ./re2
000 0x00000e58 0x00400e58 119 120 (.rodata) ascii L3t_ME_T3ll_Y0u_S0m3th1ng_1mp0rtant_A_{FL4G}_W0nt_b3_3X4ctly_th4t_345y_t0_c4ptur3_H0wev3r_1T_w1ll_b3_C00l_1F_Y0u_g0t_1t
001 0x00000ed0 0x00400ed0  22  23 (.rodata) ascii Better luck next time
002 0x00000ee8 0x00400ee8  32  33 (.rodata) ascii You should have the flag by now
003 0x00000f09 0x00400f09   7   8 (.rodata) ascii Usage: 
004 0x00000f11 0x00400f11   6   7 (.rodata) ascii  flag
    :

Better luck next time のアドレスは0x00400ed0であることがわかりました。次にradare2を用いてこのアドレスにアクセスする関数を見つけ出します。

radare2による解析
$ r2 ./re2
>aa
>aac
>afl
>axt 0x00400ed0
fcn.00400b56 0x400b5a [DATA] mov esi, str.Better_luck_next_time

fcn.0x400b56であることがわかりました
main関数を見ていきます。

>pdf @ main
          :
          :
       0x00400c20      488945a0       mov qword [local_60h], rax
   .-> 0x00400c24      488d45b0       lea rax, [local_50h]
   :   0x00400c28      4889c7         mov rdi, rax
   :   0x00400c2b      e8c0fdffff     call sym.std::__cxx11::basic_string_char_std::char_traits_char__std::allocator_char__::end
   :   0x00400c30      488945e0       mov qword [local_20h], rax
   :   0x00400c34      488d55e0       lea rdx, [local_20h]
   :   0x00400c38      488d45a0       lea rax, [local_60h]
   :   0x00400c3c      4889d6         mov rsi, rdx
   :   0x00400c3f      4889c7         mov rdi, rax
   :   0x00400c42      e8f6000000     call fcn.00400d3d
   :   0x00400c47      84c0           test al, al
  ,==< 0x00400c49      744a           je 0x400c95
  |:   0x00400c4b      488d45a0       lea rax, [local_60h]
  |:   0x00400c4f      4889c7         mov rdi, rax
  |:   0x00400c52      e843010000     call fcn.00400d9a
  |:   0x00400c57      0fb610         movzx edx, byte [rax]
  |:   0x00400c5a      488b0d3f1420.  mov rcx, qword str.L3t_ME_T3ll_Y0u_S0m3th1ng_1mp0rtant_A__FL4G__W0nt_b3_3X4ctly_th4t_345y_t0_c4ptur3_H0wev3r_1T_w1ll_b3_C00l_1F_Y0u_g0t_1t ; [0x6020a0:8]=0x400e58 str.L3t_ME_T3ll_Y0u_S0m3th1ng_1mp0rtant_A__FL4G__W0nt_b3_3X4ctly_th4t_345y_t0_c4ptur3_H0wev3r_1T_w1ll_b3_C00l_1F_Y0u_g0t_1t
  |:   0x00400c61      8b45ec         mov eax, dword [local_14h]
  |:   0x00400c64      4898           cdqe
  |:   0x00400c66      8b0485c02060.  mov eax, dword [rax*4 + 0x6020c0] ; [0x6020c0:4]=36
  |:   0x00400c6d      4898           cdqe
  |:   0x00400c6f      4801c8         add rax, rcx                ; '&'
  |:   0x00400c72      0fb600         movzx eax, byte [rax]
  |:   0x00400c75      38c2           cmp dl, al
  |:   0x00400c77      0f95c0         setne al
  |:   0x00400c7a      84c0           test al, al
 ,===< 0x00400c7c      7405           je 0x400c83
 ||:   0x00400c7e      e8d3feffff     call fcn.00400b56
 `---> 0x00400c83      8345ec01       add dword [local_14h], 1
  |:   0x00400c87      488d45a0       lea rax, [local_60h]
  |:   0x00400c8b      4889c7         mov rdi, rax
  |:   0x00400c8e      e8e7000000     call fcn.00400d7a
  |`=< 0x00400c93      eb8f           jmp 0x400c24
  `--> 0x00400c95      e8d9feffff     call fcn.00400b73
         :
         :

「Better luck next time」なんて煽り文句はもう見たくないのでfcn.00400b56を通らないルートを探します。命令文0x00400c7e周辺に注目すると直前の処理から、ループを行い何か(コマンドライン引数とFlag?)を比較していることがわかります。もとをたどるとal(Flag?)は、rax*4+0x6020c0の値とアドレス0x6020a0を足したアドレスに格納された値である。ここから、gdbに対してバッチ処理を行い、答えを明らかにしていく次第です。

gdbで0x6020c0周辺の値を調べる
gdb-peda$ x/40w 0x6020c0
0x6020c0:   0x00000024  0x00000000  0x00000005  0x00000036
0x6020d0:   0x00000065  0x00000007  0x00000027  0x00000026
0x6020e0:   0x0000002d  0x00000001  0x00000003  0x00000000
0x6020f0:   0x0000000d  0x00000056  0x00000001  0x00000003
0x602100:   0x00000065  0x00000003  0x0000002d  0x00000016
0x602110:   0x00000002  0x00000015  0x00000003  0x00000065
0x602120:   0x00000000  0x00000029  0x00000044  0x00000044
0x602130:   0x00000001  0x00000044  0x0000002b  0x00000000
add.py
offset=[
    0x00000024,0x00000000,0x00000005,0x00000036,
    0x00000065,0x00000007,0x00000027,0x00000026,
    0x0000002d,0x00000001,0x00000003,0x00000000,
    0x0000000d,0x00000056,0x00000001,0x00000003,
    0x00000065,0x00000003,0x0000002d,0x00000016,
    0x00000002,0x00000015,0x00000003,0x00000065,
    0x00000000,0x00000029,0x00000044,0x00000044,
    0x00000001,0x00000044,0x0000002b,0x00000000]

for i in offset:
    address = i+0x400e58
    print "x/s "+ hex(address)
add.pyの実行結果をgdbへ
$python add.py | gdb re2

$gdb-peda$ 0x400e7c:    "A_{FL4G}_W0nt_b"...
$gdb-peda$ 0x400e58:    "L3t_ME_T3ll_Y0u"...
$gdb-peda$ 0x400e5d:    "E_T3ll_Y0u_S0m3"...
$gdb-peda$ 0x400e8e:    "X4ctly_th4t_345"...
$gdb-peda$ 0x400ebd:    "C00l_1F_Y0u_g0t"...
$gdb-peda$ 0x400e5f:    "T3ll_Y0u_S0m3th"...
$gdb-peda$ 0x400e7f:    "FL4G}_W0nt_b3_3"...
$gdb-peda$ 0x400e7e:    "{FL4G}_W0nt_b3_"...
$gdb-peda$ 0x400e85:    "W0nt_b3_3X4ctly"...
$gdb-peda$ 0x400e59:    "3t_ME_T3ll_Y0u_"...
$gdb-peda$ 0x400e5b:    "_ME_T3ll_Y0u_S0"...
$gdb-peda$ 0x400e58:    "L3t_ME_T3ll_Y0u"...
$gdb-peda$ 0x400e65:    "0u_S0m3th1ng_1m"...
$gdb-peda$ 0x400eae:    "v3r_1T_w1ll_b3_"...
$gdb-peda$ 0x400e59:    "3t_ME_T3ll_Y0u_"...
$gdb-peda$ 0x400e5b:    "_ME_T3ll_Y0u_S0"...
$gdb-peda$ 0x400ebd:    "C00l_1F_Y0u_g0t"...
$gdb-peda$ 0x400e5b:    "_ME_T3ll_Y0u_S0"...
$gdb-peda$ 0x400e85:    "W0nt_b3_3X4ctly"...
$gdb-peda$ 0x400e6e:    "1ng_1mp0rtant_A"...
$gdb-peda$ 0x400e5a:    "t_ME_T3ll_Y0u_S"...
$gdb-peda$ 0x400e6d:    "h1ng_1mp0rtant_"...
$gdb-peda$ 0x400e5b:    "_ME_T3ll_Y0u_S0"...
$gdb-peda$ 0x400ebd:    "C00l_1F_Y0u_g0t"...
$gdb-peda$ 0x400e58:    "L3t_ME_T3ll_Y0u"...
$gdb-peda$ 0x400e81:    "4G}_W0nt_b3_3X4"...
$gdb-peda$ 0x400e9c:    "5y_t0_c4ptur3_H"...
$gdb-peda$ 0x400e9c:    "5y_t0_c4ptur3_H"...
$gdb-peda$ 0x400e59:    "3t_ME_T3ll_Y0u_"...
$gdb-peda$ 0x400e9c:    "5y_t0_c4ptur3_H"...
$gdb-peda$ 0x400e83:    "}_W0nt_b3_3X4ct"...
$gdb-peda$ 0x400e58:    "L3t_ME_T3ll_Y0u"...
$gdb-peda$ quit

そして、縦読みにすると...
ようやくフラッグ「ALEXCTF{W3_L0v3_C_W1th_CL45535}」を手に入れました。

最後に

2日間の紆余曲折はなんだったのかと思うど雑な書き込みでしたが、CTFはやはり敷居が高いと感じさせてくれました。
最後のFLAGを手に入れるための処理をもっときれいな方法で行いたかったが、縦読みして答えを得るというおしゃれなことをしてしまった。
Flagの最後のLに関してはよくわかりません。

参考

1
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
5