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)さんが解いてくれました!
@ABCanG1015 最終的なデコードプログラムです。 https://t.co/Yt3gBfsRS5
— XiPHiA (@alchemicalogic) 2014, 7月 19
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で学ぼう!情報を守るための戦い方
- 作者: 碓井利宣,竹迫良範,廣田一貴,保要隆明,前田優人,美濃圭佑,三村聡志,八木橋優
- 出版社/メーカー: マイナビ出版
- 発売日: 2015/09/30
- メディア: Kindle版
- この商品を含むブログを見る