LoginSignup
0
0

More than 5 years have passed since last update.

[Internetwache CTF 2016] ServerfARM write up

Posted at

Reversing Challenges List の問題。

ARMアーキテクチャのバイナリ。

ARMアーキテクチャについては、以下の2つの記事を見ればだいたい理解できた。

実行環境がないので、アセンブリ言語だけ見て解析する。

解析にはradare2を用いた。

radare2はまだ全然使い方が分かっていないので探り探り。

main

radare2 で aaaa -> aflmain があったのでそこから解析。

pdf @ main

関数のコールだけ追っていくと、malloc -> printf -> scanf -> handle_task 関数->free という感じ。

printf の出力を見てみる。

[0x00010580]> pv @ loc._d_15
0x00010e30
[0x00010580]> pvz @ 0x00010e30
Enter Solution for task %d:

%d で表示されるのは[fp-0x8] なので、これがtaskのIDを表しているらしい。

handle_task 関数を[fp-0x8]scanf の入力値を引数として呼び出している。

handle_task

[0x00010580]> pdf @ sym.handle_task
|           ;-- $a:
/ (fcn) sym.handle_task 40
|   sym.handle_task ();
|           ; var int local_1ch @ fp-0x1c
|           ; var int local_18h @ fp-0x18
|           ; var int local_10h @ fp-0x10
|           ; CALL XREF from main (0x106f8)
|           0x0001073c      10482de9       push {r4, fp, lr}
|           0x00010740      08b08de2       add fp, sp, 8
|           0x00010744      14d04de2       sub sp, sp, 0x14
|           0x00010748      18000be5       str r0, [local_18h]         ; 0x18 ; 24
|           0x0001074c      1c100be5       str r1, [local_1ch]         ; 0x1c ; 28
|           0x00010750      0030a0e3       mov r3, 0
|           0x00010754      10300be5       str r3, [local_10h]         ; 0x10 ; 16
|           0x00010758      18301be5       ldr r3, [local_18h]         ; 0x18 ; 24
|           0x0001075c      030053e3       cmp r3, 3                   ; 3
\           0x00010760      03f19f97       ldrls pc, [pc, r3, lsl 2]   ; loc._d_16 ; [0x10768:4]=0x10778 loc._a_12 ; "x\a\x01"

taskID が [local_18h]scanf 入力が[local_1ch] に格納され、taskIDが3以下の場合にtaskIDに合わせてpcを変動させている。

ここで、pcが評価させるときにpc + 8として扱われることに注意 (ももテク の記事に記載)。

結果としてはpc = [0x00010760 + 8 + 4 * taskID] となるので、そこらへんのアドレスを見てみる。

[0x00010580]> pd 6 @ 0x00010760
\           0x00010760      03f19f97       ldrls pc, [pc, r3, lsl 2] ; loc._d_16 ; [0x10768:4]=0x10778 loc._a_12 ; "x\a\x01"
        ,=< 0x00010764      6d0000ea       b 0x10920
        |   ;-- $d:
        |   ; CODE XREF from sym.handle_task (0x10760)
        |   0x00010768      .dword 0x00010778 ; loc._a_12
        |   0x0001076c      .dword 0x00010838 ; aav.0x00010838
        |   0x00010770      .dword 0x000108a8 ; aav.0x000108a8
        |   0x00010774      .dword 0x000108f0 ; aav.0x000108f0

それぞれ 0x00010778, 0x00010838, 0x000108a8, 0x000108f0 である。

task 1

[0x00010580]> pd 48 @ 0x00010778
            ;-- $a:
            ; UNKNOWN XREF from loc._d_16 ()
            0x00010778      0030a0e3       mov r3, 0
            0x0001077c      14300be5       str r3, [fp, -0x14]         ; 20
        ,=< 0x00010780      0a0000ea       b 0x107b0
        |   ; CODE XREF from loc._a_12 (+0x4c)
       .--> 0x00010784      14301be5       ldr r3, [fp, -0x14]         ; 20
       :|   0x00010788      1c201be5       ldr r2, [fp, -0x1c]         ; 28
       :|   0x0001078c      033082e0       add r3, r2, r3
       :|   0x00010790      0030d3e5       ldrb r3, [r3]
       :|   0x00010794      0320a0e1       mov r2, r3
       :|   0x00010798      10301be5       ldr r3, [fp, -0x10]         ; 16
       :|   0x0001079c      023083e0       add r3, r3, r2
       :|   0x000107a0      10300be5       str r3, [fp, -0x10]         ; 16
       :|   0x000107a4      14301be5       ldr r3, [fp, -0x14]         ; 20
       :|   0x000107a8      013083e2       add r3, r3, 1
       :|   0x000107ac      14300be5       str r3, [fp, -0x14]         ; 20
       :|   ; CODE XREF from loc._a_12 (+0x8)
       :`-> 0x000107b0      1c001be5       ldr r0, [fp, -0x1c]         ; 28
       :    0x000107b4      65ffffeb       bl sym.imp.strlen           ; size_t strlen(const char *s)
       :    0x000107b8      0020a0e1       mov r2, r0
       :    0x000107bc      14301be5       ldr r3, [fp, -0x14]         ; 20
       :    0x000107c0      030052e1       cmp r2, r3
       `==< 0x000107c4      eeffff8a       bhi 0x10784
            0x000107c8      10401be5       ldr r4, [fp, -0x10]         ; 16
            0x000107cc      1c001be5       ldr r0, [fp, -0x1c]         ; 28
            0x000107d0      5effffeb       bl sym.imp.strlen           ; size_t strlen(const char *s)
            0x000107d4      0030a0e1       mov r3, r0
            0x000107d8      0310a0e1       mov r1, r3
            0x000107dc      0400a0e1       mov r0, r4
            0x000107e0      5f0000eb       bl sym.__aeabi_uidiv
            0x000107e4      0030a0e1       mov r3, r0
            0x000107e8      10300be5       str r3, [fp, -0x10]         ; 16
            0x000107ec      38119fe5       ldr r1, loc._d_17           ; [0x1092c:4]=0x10e50 str.Here_s_your_1._block: ; "P\x0e\x01"
            0x000107f0      38019fe5       ldr r0, aav.0x00010e4c      ; [0x10930:4]=0x10e4c aav.0x00010e4c
            0x000107f4      43ffffeb       bl sym.imp.printf           ; int printf(const char *format)
            0x000107f8      10301be5       ldr r3, [fp, -0x10]         ; 16
            0x000107fc      230053e3       cmp r3, 0x23                ; '#' ; 35
        ,=< 0x00010800      020000da       ble 0x10810
        |   0x00010804      28019fe5       ldr r0, str.I_WAQ3          ; [0x10934:4]=0x10e68 str.I_WAQ3
        |   0x00010808      44ffffeb       bl sym.imp.puts             ; int puts(const char *s)
       ,==< 0x0001080c      440000ea       b 0x10924
       ||   ; CODE XREF from loc._a_12 (+0x88)
       |`-> 0x00010810      20119fe5       ldr r1, aav.0x00010e70      ; [0x10938:4]=0x10e70 aav.0x00010e70
       |    0x00010814      14019fe5       ldr r0, aav.0x00010e4c      ; [0x10930:4]=0x10e4c aav.0x00010e4c
       |    0x00010818      3affffeb       bl sym.imp.printf           ; int printf(const char *format)
       |    0x0001081c      5300a0e3       mov r0, 0x53                ; 'S'
       |    0x00010820      4dffffeb       bl sym.imp.putchar          ; int putchar(int c)
       |    0x00010824      4520a0e3       mov r2, 0x45                ; 'E'
       |    0x00010828      2e10a0e3       mov r1, 0x2e                ; '.'
       |    0x0001082c      08019fe5       ldr r0, str.c_c             ; [0x1093c:4]=0x10e74 str.c_c
       |    0x00010830      34ffffeb       bl sym.imp.printf           ; int printf(const char *format)
       |,=< 0x00010834      370000ea       b 0x10918

色々やっているが、Here's your 1. block: と出力し、

条件分岐で IW{S.E と出力ているのみ。

task 2

[0x00010580]> pd 28 @ 0x00010838
            ;-- aav.0x00010838:
            ; UNKNOWN XREF from loc._d_16 (+0x4)
            0x00010838      00119fe5       ldr r1, str.Here_s_your_2._block: ; [0x10940:4]=0x10e7c str.Here_s_your_2._block:
            0x0001083c      ec009fe5       ldr r0, aav.0x00010e4c      ; [0x10930:4]=0x10e4c aav.0x00010e4c
            0x00010840      30ffffeb       bl sym.imp.printf           ; int printf(const char *format)
            0x00010844      1c301be5       ldr r3, [fp, -0x1c]         ; 28
            0x00010848      0030d3e5       ldrb r3, [r3]
            0x0001084c      0320a0e1       mov r2, r3
            0x00010850      1c301be5       ldr r3, [fp, -0x1c]         ; 28
            0x00010854      013083e2       add r3, r3, 1
            0x00010858      0030d3e5       ldrb r3, [r3]
            0x0001085c      0310a0e1       mov r1, r3
            0x00010860      0200a0e1       mov r0, r2
            0x00010864      490100eb       bl sym.__aeabi_idivmod
            0x00010868      0130a0e1       mov r3, r1
            0x0001086c      410053e3       cmp r3, 0x41                ; 'A' ; 65
        ,=< 0x00010870      0900001a       bne 0x1089c
        |   0x00010874      c8109fe5       ldr r1, aav.0x00010e94      ; [0x10944:4]=0x10e94 aav.0x00010e94
        |   0x00010878      b0009fe5       ldr r0, aav.0x00010e4c      ; [0x10930:4]=0x10e4c aav.0x00010e4c
        |   0x0001087c      21ffffeb       bl sym.imp.printf           ; int printf(const char *format)
        |   0x00010880      5600a0e3       mov r0, 0x56                ; 'V'
        |   0x00010884      34ffffeb       bl sym.imp.putchar          ; int putchar(int c)
        |   0x00010888      4520a0e3       mov r2, 0x45                ; 'E'
        |   0x0001088c      2e10a0e3       mov r1, 0x2e                ; '.'
        |   0x00010890      a4009fe5       ldr r0, str.c_c             ; [0x1093c:4]=0x10e74 str.c_c
        |   0x00010894      1bffffeb       bl sym.imp.printf           ; int printf(const char *format)
       ,==< 0x00010898      1e0000ea       b 0x10918
       ||   ; CODE XREF from aav.0x00010838 (+0x38)
       |`-> 0x0001089c      a4009fe5       ldr r0, str.WI_QA3          ; [0x10948:4]=0x10e98 str.WI_QA3
       |    0x000108a0      1effffeb       bl sym.imp.puts             ; int puts(const char *s)
       |,=< 0x000108a4      1b0000ea       b 0x10918

Here's your 2. block:printf

-> 先のscanf の入力と何かを比較

-> 一致していれば .R.V.E と出力

task 3

[0x00010580]> pd 18 @ 0x000108a8
            ;-- aav.0x000108a8:
            ; UNKNOWN XREF from loc._d_16 (+0x8)
            0x000108a8      9c109fe5       ldr r1, str.Here_s_your_3._block: ; [0x1094c:4]=0x10ea0 str.Here_s_your_3._block:
            0x000108ac      7c009fe5       ldr r0, aav.0x00010e4c      ; [0x10930:4]=0x10e4c aav.0x00010e4c
            0x000108b0      14ffffeb       bl sym.imp.printf           ; int printf(const char *format)
            0x000108b4      94109fe5       ldr r1, str.1337            ; [0x10950:4]=0x10eb8 str.1337
            0x000108b8      1c001be5       ldr r0, [fp, -0x1c]         ; 28
            0x000108bc      0effffeb       bl sym.imp.strcmp           ; int strcmp(const char *s1, const char *s2)
            0x000108c0      0030a0e1       mov r3, r0
            0x000108c4      000053e3       cmp r3, 0
        ,=< 0x000108c8      0200001a       bne 0x108d8
        |   0x000108cc      80009fe5       ldr r0, str..R__F:          ; [0x10954:4]=0x10ec0 str..R__F:
        |   0x000108d0      12ffffeb       bl sym.imp.puts             ; int puts(const char *s)
       ,==< 0x000108d4      0f0000ea       b 0x10918
       ||   ; CODE XREF from aav.0x000108a8 (+0x20)
       |`-> 0x000108d8      2130a0e3       mov r3, 0x21                ; '!'
       |    0x000108dc      74209fe5       ldr r2, str.Q.D.Q           ; [0x10958:4]=0x10ec8 str.Q.D.Q
       |    0x000108e0      2e10a0e3       mov r1, 0x2e                ; '.'
       |    0x000108e4      70009fe5       ldr r0, str.c_s_c           ; [0x1095c:4]=0x10ed0 str.c_s_c
       |    0x000108e8      06ffffeb       bl sym.imp.printf           ; int printf(const char *format)
       |,=< 0x000108ec      090000ea       b 0x10918

Here's your 3. block: と出力

-> scanf の入力値と1337 を比較

-> 一致していれば .R>=F: と出力

task 4

[0x00010580]> pd 15 @ 0x000108f0
            ;-- aav.0x000108f0:
            ; UNKNOWN XREF from loc._d_16 (+0xc)
            0x000108f0      1c301be5       ldr r3, [fp, -0x1c]         ; 28
            0x000108f4      0030d3e5       ldrb r3, [r3]
            0x000108f8      000053e3       cmp r3, 0
        ,=< 0x000108fc      0400000a       beq 0x10914
        |   0x00010900      7d30a0e3       mov r3, 0x7d                ; '}'
        |   0x00010904      54209fe5       ldr r2, str.:R:M            ; [0x10960:4]=0x10ed8 str.:R:M
        |   0x00010908      4110a0e3       mov r1, 0x41                ; 'A'
        |   0x0001090c      48009fe5       ldr r0, str.c_s_c           ; [0x1095c:4]=0x10ed0 str.c_s_c
        |   0x00010910      fcfeffeb       bl sym.imp.printf           ; int printf(const char *format)
        |   ; CODE XREF from aav.0x000108f0 (+0xc)
        `-> 0x00010914      0000a0e1       mov r0, r0
            ; CODE XREF from loc._a_12 (+0xbc)
            ; CODE XREFS from aav.0x00010838 (+0x60, +0x6c)
            ; CODE XREFS from aav.0x000108a8 (+0x2c, +0x44)
            0x00010918      0000a0e1       mov r0, r0
        ,=< 0x0001091c      000000ea       b 0x10924
        |   ; CODE XREF from loc._a_11 (+0x28)
        |   0x00010920      0000a0e1       mov r0, r0
        |   ; CODE XREF from loc._a_12 (+0x94)
        |   ; CODE XREF from aav.0x000108f0 (+0x2c)
        `-> 0x00010924      08d04be2       sub sp, fp, 8
            0x00010928      1088bde8       pop {r4, fp, pc}

条件分岐の後、 A:R:M} を出力している。

全て繋げて、IW{S.E.R.V.E.R>=F:A:R:M}

0
0
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
0
0