SECCON:ダンプを追え!writeup

今回、同じサークルの人たちとSECCONのCTFに挑戦しました。 結論から言うと、40番第に入ることができました。 僕自身はソーシャルハッキング的なアレしか解けなかったですが… でもでも、いろいろな問題に取組めて楽しかったです。

ダンプを追え!も頑張りましたが、あと少しのところでタイムアップしてしまいました。

v850は全く触ったことなかったけど、disassembler.ioとかでアセンブリに直して、ネットで拾ったアーキテクチャの資料を見ながらCライクに戻してみました。

.data:0x00000000    401e0000    movhi   0, r0, sp       ; base addres is 0x1400
.data:0x00000004    231e8017    movea   6016, sp, sp
.data:0x00000008    40260000    movhi   0, r0, gp
.data:0x0000000c    24261616    movea   5654, gp, gp
.data:0x00000010    80ffbc00    jarl    0x000000cc, lp  ; char c = src[i]
.data:0x00000014    80ff8c01    jarl    0x000001a0, lp  ; dst[i] = c
.data:0x00000018    0a38        mov r10, r7     ; i++

.data:0x0000001a    0132        mov 1, r6           ; ___r_exit
.data:0x0000001c    ff070001    trap    31
.data:0x00000020    7f00        jmp [lp]

.data:0x00000022    0332        mov 3, r6           ; ___r_read
.data:0x00000024    ff070001    trap    31
.data:0x00000028    7f00        jmp [lp]

.data:0x0000002a    0432        mov 4, r6           ; ___r_write
.data:0x0000002c    ff070001    trap    31
.data:0x00000030    7f00        jmp [lp]

.data:0x00000032    0532        mov 5, r6           ; ___r_open
.data:0x00000034    ff070001    trap    31
.data:0x00000038    7f00        jmp [lp]

.data:0x0000003a    0632        mov 6, r6           ; ___r_close
.data:0x0000003c    ff070001    trap    31
.data:0x00000040    7f00        jmp [lp]

.data:0x00000042    031eecff    addi    -20, sp, sp ; _sys_exit
.data:0x00000046    0638        mov r6, r7
.data:0x00000048    63ff1100    st.w    lp, 16[sp]
.data:0x0000004c    0032        mov 0, r6
.data:0x0000004e    bfffccff    jarl    0x0000001a, lp

.data:0x00000052    0750        mov r7, r10     ; _sys_read
.data:0x00000054    031eecff    addi    -20, sp, sp
.data:0x00000058    0848        mov r8, r9
.data:0x0000005a    0638        mov r6, r7
.data:0x0000005c    63ff1100    st.w    lp, 16[sp]
.data:0x00000060    0a40        mov r10, r8
.data:0x00000062    0032        mov 0, r6
.data:0x00000064    bfffbeff    jarl    0x00000022, lp
.data:0x00000068    23ff1100    ld.w    16[sp], lp
.data:0x0000006c    031e1400    addi    20, sp, sp
.data:0x00000070    7f00        jmp [lp]

.data:0x00000072    0750        mov r7, r10     ; r10 = r7 //  _sys_write
.data:0x00000074    031eecff    addi    -20, sp, sp ; sp += -20
.data:0x00000078    0848        mov r8, r9          ; r9 = r8
.data:0x0000007a    0638        mov r6, r7          ; r7 = r6
.data:0x0000007c    63ff1100    st.w    lp, 16[sp]      ; sp[16] = lp
.data:0x00000080    0a40        mov r10, r8     ; r8 = r10
.data:0x00000082    0032        mov 0, r6           ; r6 = 0
.data:0x00000084    bfffa6ff    jarl    0x0000002a, lp  ; r10 = ___r_write()
.data:0x00000088    23ff1100    ld.w    16[sp], lp      ; lp = sp[16]
.data:0x0000008c    031e1400    addi    20, sp, sp      ; sp += 20
.data:0x00000090    7f00        jmp [lp]            ; return r10

.data:0x00000092    0750        mov r7, r10     ; r10 = r7  // _sys_open
.data:0x00000094    031eecff    addi    -20, sp, sp ; sp += -20
.data:0x00000098    0848        mov r8, r9          ; r9 = r8
.data:0x0000009a    0638        mov r6, r7          ; r7 = r6
.data:0x0000009c    63ff1100    st.w    lp, 16[sp]      ; sp[16] = lp
.data:0x000000a0    0a40        mov r10, r8     ; r8 = r10
.data:0x000000a2    0032        mov 0, r6           ; r6 = 0
.data:0x000000a4    bfff8eff    jarl    0x00000032, lp  ; r10 = ___r_open()
.data:0x000000a8    23ff1100    ld.w    16[sp], lp      ; lp = sp[16]
.data:0x000000ac    031e1400    addi    20, sp, sp      ; sp += 20
.data:0x000000b0    7f00        jmp [lp]            ; return r10

.data:0x000000b2    031eecff    addi    -20, sp, sp ; _sys_close
.data:0x000000b6    0638        mov r6, r7
.data:0x000000b8    63ff1100    st.w    lp, 16[sp]
.data:0x000000bc    0032        mov 0, r6
.data:0x000000be    bfff7cff    jarl    0x0000003a, lp
.data:0x000000c2    23ff1100    ld.w    16[sp], lp
.data:0x000000c6    031e1400    addi    20, sp, sp
.data:0x000000ca    7f00        jmp [lp]

.data:0x000000cc    40560000    movhi   0, r0, r10      ; _init
.data:0x000000d0    405e0000    movhi   0, r0, r11
.data:0x000000d4    2a563c16    movea   5692, r10, r10
.data:0x000000d8    2b5e7c16    movea   5756, r11, r11
.data:0x000000dc    c505        br      0x000000e4
.data:0x000000de    4a070000    st.b    r0, 0[r10]
.data:0x000000e2    4152        add 1, r10
.data:0x000000e4    eb51        cmp r11, r10
.data:0x000000e6    c1fd        bl      0x000000de
.data:0x000000e8    7f00        jmp [lp]

.data:0x000000ea    031edcff    addi    -36, sp, sp ; sp += -36  //_read_data
.data:0x000000ee    1e08        mov ep, r1          ; r1 = ep
.data:0x000000f0    03f0        mov sp, ep          ; ep = sp
.data:0x000000f2    0fd5        sst.w   r26, 28[ep] ; ep[28] = r26
.data:0x000000f4    0ddd        sst.w   r27, 24[ep] ; ep[24] = r27
.data:0x000000f6    08d8        mov r8, r27     ; r27 = r8
.data:0x000000f8    07d0        mov r7, r26     ; r26 = r7
.data:0x000000fa    11fd        sst.w   lp, 32[ep]      ; ep[32] = lp
.data:0x000000fc    0be5        sst.w   r28, 20[ep] ; ep[20] = r28
.data:0x000000fe    01f0        mov r1, ep          ; ep = r1
.data:0x00000100    003a        mov 0, r7           ; r7 = 0
.data:0x00000102    0042        mov 0, r8           ; r8 = 0
.data:0x00000104    bfff8eff    jarl    0x00000092, lp  ; r10 = _sys_open(r6, r7, r8)
.data:0x00000108    0ae0        mov r10, r28        ; r28 = r10
.data:0x0000010a    033e1300    addi    19, sp, r7      ; r7 = sp + 19
.data:0x0000010e    0a30        mov r10, r6     ; r6 = r10
.data:0x00000110    0142        mov 1, r8           ; r8 = 1
.data:0x00000112    bfff40ff    jarl    0x00000052, lp  ; r10 = _sys_read(r6, r7, r8)
.data:0x00000116    3b470100    ld.w    0[r27], r8      ; r8 = r27[0]
.data:0x0000011a    1c30        mov r28, r6     ; r6 = r28
.data:0x0000011c    1a38        mov r26, r7     ; r7 = r26
.data:0x0000011e    bfff34ff    jarl    0x00000052, lp  ; r10 = _sys_read(r6, r7, r8)
.data:0x00000122    7b570100    st.w    r10, 0[r27] ; r27[0] = r10
.data:0x00000126    1c30        mov r28, r6     ; r6 = r28
.data:0x00000128    bfff8aff    jarl    0x000000b2, lp  ; r10 = _sys_close(r6)
.data:0x0000012c    1e08        mov ep, r1          ; r1 = ep
.data:0x0000012e    03f0        mov sp, ep          ; ep = sp
.data:0x00000130    1353        sld.b   19[ep], r10 ; r10 = ep[19] & 0xFF
.data:0x00000132    0ed5        sld.w   28[ep], r26 ; r26 = ep[28]
.data:0x00000134    0cdd        sld.w   24[ep], r27 ; r27 = sp[24]
.data:0x00000136    0ae5        sld.w   20[ep], r28 ; r28 = ep[20]
.data:0x00000138    10fd        sld.w   32[ep], lp      ; lp = ep[32]
.data:0x0000013a    01f0        mov r1, ep          ; ep = r1
.data:0x0000013c    ca56ff00    andi    255, r10, r1    ; r1 = r10 & 0xFF
.data:0x00000140    031e2400    addi    36, sp, sp      ; sp += 36
.data:0x00000144    7f00        jmp [lp]            ; return r10

.data:0x00000146    031ee8ff    addi    -24, sp, sp ; sp += -24  // _proc
.data:0x0000014a    20564000    movea   64, r0, r10 ; r10 = r0 + 64
.data:0x0000014e    403e0000    movhi   0, r0, r7       ; r7 = ro << 16
.data:0x00000152    63ff1500    st.w    lp, 20[sp]      ; sp[20] = lp
.data:0x00000156    63571100    st.w    r10, 16[sp] ; sp[16] = r10
.data:0x0000015a    273e3c16    movea   5692, r7, r7    ; r7 += 0x163C
.data:0x0000015e    03461000    addi    16, sp, r8      ; r8 = sp + 16
.data:0x00000162    bfff88ff    jarl    0x000000ea, lp  ; r10 = _read_data(r6, r7, r8)
.data:0x00000166    23771100    ld.w    16[sp], r14 ; r14 = sp[16]
.data:0x0000016a    ca66ff00    andi    255, r10, r12   ; r12 = r10 & 0xFF
.data:0x0000016e    006a        mov 0, r13          ; r13 = 0
.data:0x00000170    9515        br      0x00000192      ; goto 0x00000192
.data:0x00000172    40560000    movhi   0, r0, r10      ; r10 = r0 << 16
.data:0x00000176    2a563c16    movea   5692, r10, r10  ; r10 +=  0x163C
.data:0x0000017a    cd51        add r13, r10        ; r10 += r13
.data:0x0000017c    0a5f0000    ld.b    0[r10], r11 ; r11 = r10[0] & 0xFF
.data:0x00000180    416a        add 1, r13          ; r13 ++
.data:0x00000182    2c59        xor r12, r11        ; r11 = r11 xor r12
.data:0x00000184    cc61        add r12, r12        ; r12 += r12
.data:0x00000186    0c661100    addi    17, r12, r12    ; r12 = r12 + 17
.data:0x0000018a    4a5f0000    st.b    r11, 0[r10] ; r10[0] = r11 & 0xFF
.data:0x0000018e    cc66ff00    andi    255, r12, r12   ; r12 = r12 & 0xFF
.data:0x00000192    ee69        cmp r14, r13        ; flag = r13 - r14 < 0
.data:0x00000194    f6ed        blt 0x00000172      ; if (flag == 1) goto 0x00000172
.data:0x00000196 23ff1500       ld.w    20[sp], lp      ; lp = sp[20]
.data:0x0000019a    031e1800    addi    24, sp, sp      ; sp += 24
.data:0x0000019e    7f00        jmp [lp]            ; return

.data:0x000001a0    031ee0ff    addi    -32, sp, sp ; sp += -32  // _main
.data:0x000001a4    40360000    movhi   0, r0, r6       ; r6 = r0 << 16
.data:0x000001a8    1e08        mov ep, r1          ; r1 = ep
.data:0x000001aa    03f0        mov sp, ep          ; ep = sp
.data:0x000001ac    0ffd        sst.w   lp, 28[ep]      ; ep[28] = lp
.data:0x000001ae    0be5        sst.w   r28, 20[ep] ; ep[20] = r28
.data:0x000001b0    09ed        sst.w   r29, 16[ep] ; ep[16] = r29
.data:0x000001b2    26362416    movea   5668, r6, r6    ; r6 += 0x1624 // "flag.txt"
.data:0x000001b6    0ddd        sst.w   r27, 24[ep] ; sp[24] = r27
.data:0x000001b8    01f0        mov r1, ep          ; ep = r1
.data:0x000001ba    bfff8cff    jarl    0x00000146, lp  ; _proc(r6)
.data:0x000001be    40360000    movhi   0, r0, r6       ; r6 = r0 << 16
.data:0x000001c2    26362d16    movea   5677, r6, r6    ; r6 += 0x162D  // "dump.bin"
.data:0x000001c6    203e0206    movea   1538, r0, r7    ; r7 = r0 + 1538
.data:0x000001ca    2046a401    movea   420, r0, r8 ; r8 = r0 + 420
.data:0x000001ce    bfffc4fe    jarl    0x00000092, lp  ; r10 = _sys_open(r6, r7, r8)
.data:0x000001d2    0ae0        mov r10, r28        ; r28 = r10
.data:0x000001d4    40560000    movhi   0, r0, r10      ; r10 = r0 << 16
.data:0x000001d8    405e0000    movhi   0, r0, r11      ; r11 = r0 << 16
.data:0x000001dc    2aee0014    movea   5120, r10, r29  ; r29 = r10 + 0x1400
.data:0x000001e0    2b5e8017    movea   6016, r11, r11  ; r11 += 0x1780
.data:0x000001e4    ebe9        cmp r11, r29        ; CY = r29 < r11
.data:0x000001e6    a90d        bnl 0x000001fa      ; if(CY == 0) goto 0x000001fa
.data:0x000001e8    0bd8        mov r11, r27        ; r27 = r11
.data:0x000001ea    1d38        mov r29, r7     ; r7 = r29
.data:0x000001ec    1c30        mov r28, r6     ; r6 = r28
.data:0x000001ee    0142        mov 1, r8           ; r8 = 1
.data:0x000001f0    bfff82fe    jarl    0x00000072, lp  ; r10 = _sys_write(r6, r7, r8)  // fwrite(FILE *fp, const void *buf, size_t size);
.data:0x000001f4    41ea        add 1, r29          ; r29 += 1
.data:0x000001f6    fbe9        cmp r27, r29        ; CY = r29 < r27
.data:0x000001f8    91fd        bl      0x000001ea      ; if (CY ==1) goto 0x000001ea
.data:0x000001fa    1c30        mov r28, r6     ; r6 = r28
.data:0x000001fc    bfffb6fe    jarl    0x000000b2, lp  ; r10 = _sys_close(r6)
.data:0x00000200    1e08        mov ep, r1          ; r1 = ep
.data:0x00000202    03f0        mov sp, ep          ; ep = sp
.data:0x00000204    0cdd        sld.w   24[ep], r27 ; r27 = ep[24]
.data:0x00000206    0ae5        sld.w   20[ep], r28 ; r28 = ep[20]
.data:0x00000208    08ed        sld.w   16[ep], r29 ; r29 = ep[16]
.data:0x0000020a    0efd        sld.w   28[ep], lp      ; lp = ep[28]
.data:0x0000020c    01f0        mov r1, ep          ; ep = r1
.data:0x0000020e    0052        mov 0, r10          ; r10 = 0
.data:0x00000210    031e2000    addi    32, sp, sp      ; sp += 32
.data:0x00000214    7f00        jmp [lp]            ; return r10

ほとんどを直したけど、結局のところ答えはわからず… 上のソースでは0000から始まってるけど、encrypt.nmでは0x1400から始まってるって書いてたので、そう読み替えて進めました。 _read_dataでflag.txtを読み込んで、_procでxorして置換していくってのは分かった。 その保存先のデータも0x163Cにあることは分かったけど、どうしても元のデータに戻せず… writeup探してもダンプを追え!のものがないのですごくモヤモヤしてる。 誰かお願いします!

追記

XiPHiA (XiPHiA (@alchemicalogic) | Twitter)さんが解いてくれました!

twitter.com

/*
 * SECCON 2014
 * Chase the dump!
 */

#include <stdio.h>

unsigned char d[] = {0x63, 0x17, 0x86, 0xD8, 0x34, 0xF9, 0x06, 0x8C, 0x9B, 0x80, 0x9D, 0x96, 0xD7, 0xDA, 0xDF, 0x92};

int main(void) {
  int i;
  unsigned char r12 = 0x25;

  for(i = 0; i < 16; i++) {
    printf("%c", d[i] ^ r12);
    r12 = (unsigned char)((r12 + r12 + 17) & 0xFF);
  }
  printf("n");

  return 0;
}

r12の初期値は総当りで見つけたそうです。 結構面倒な問題でしたが、ようやく答えもわかってスッキリしました。 次回も時間があればこういったイベントに参加したいと思います。

セキュリティコンテストチャレンジブック CTFで学ぼう!情報を守るための戦い方

セキュリティコンテストチャレンジブック CTFで学ぼう!情報を守るための戦い方