Reversingカテゴリ。
200点。
このエントリ無駄に縦に長くなった。
crackme_d079a0af0b01789c01d5755c885da4f6を取得。
とりあえず file コマンド。
tkito@Ubuntu1204_x64:~$ file crackme_d079a0af0b01789c01d5755c885da4f6 crackme_d079a0af0b01789c01d5755c885da4f6: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=0xb300ef9227a8911db0d6aea538fe03fe4dfb20fe, stripped
64bit Linux用のバイナリらしい。ちょうど手元の環境が64bitだったので実行。
tkito@Ubuntu1204_x64:~$ chmod +x crackme_d079a0af0b01789c01d5755c885da4f6 tkito@Ubuntu1204_x64:~$ ./crackme_d079a0af0b01789c01d5755c885da4f6 root@localhost's password:
何か聞かれたので適当に入力する。
root@localhost's password: hogehoge Permission denied (password).
ですよねー。
このパターンは正解がKeyか、正解を入れるとKeyが出て来るかのどちらかだと推測。
では中で何やってるのか確認するためにstraceしてみる。
tkito@Ubuntu1204_x64:~$ strace -o output.txt ./crackme_d079a0af0b01789c01d5755c885da4f6 root@localhost's password: hogehoge Permission denied (password). tkito@Ubuntu1204_x64:~$ cat output.txt execve("./crackme_d079a0af0b01789c01d5755c885da4f6", ["./crackme_d079a0af0b01789c01d575"...], [/* 40 vars */]) = 0 mmap(NULL, 30000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f041f21e000 write(1, "r", 1) = 1 write(1, "o", 1) = 1 write(1, "o", 1) = 1 write(1, "t", 1) = 1 write(1, "@", 1) = 1 write(1, "l", 1) = 1 write(1, "o", 1) = 1 write(1, "c", 1) = 1 write(1, "a", 1) = 1 write(1, "l", 1) = 1 write(1, "h", 1) = 1 write(1, "o", 1) = 1 write(1, "s", 1) = 1 write(1, "t", 1) = 1 write(1, "'", 1) = 1 write(1, "s", 1) = 1 write(1, " ", 1) = 1 write(1, "p", 1) = 1 write(1, "a", 1) = 1 write(1, "s", 1) = 1 write(1, "s", 1) = 1 write(1, "w", 1) = 1 write(1, "o", 1) = 1 write(1, "r", 1) = 1 write(1, "d", 1) = 1 write(1, ":", 1) = 1 write(1, " ", 1) = 1 read(0, "h", 1) = 1 read(0, "o", 1) = 1 read(0, "g", 1) = 1 read(0, "e", 1) = 1 read(0, "h", 1) = 1 read(0, "o", 1) = 1 read(0, "g", 1) = 1 read(0, "e", 1) = 1 read(0, "\n", 1) = 1 write(1, "P", 1) = 1 write(1, "e", 1) = 1 write(1, "r", 1) = 1 write(1, "m", 1) = 1 write(1, "i", 1) = 1 write(1, "s", 1) = 1 write(1, "s", 1) = 1 write(1, "i", 1) = 1 write(1, "o", 1) = 1 write(1, "n", 1) = 1 write(1, " ", 1) = 1 write(1, "d", 1) = 1 write(1, "e", 1) = 1 write(1, "n", 1) = 1 write(1, "i", 1) = 1 write(1, "e", 1) = 1 write(1, "d", 1) = 1 write(1, " ", 1) = 1 write(1, "(", 1) = 1 write(1, "p", 1) = 1 write(1, "a", 1) = 1 write(1, "s", 1) = 1 write(1, "s", 1) = 1 write(1, "w", 1) = 1 write(1, "o", 1) = 1 write(1, "r", 1) = 1 write(1, "d", 1) = 1 write(1, ")", 1) = 1 write(1, ".", 1) = 1 write(1, "\n", 1) = 1 _exit(0) = ?
mmapしてメモリ領域確保した後は標準出力に出して標準入力から読んで結果を出力する、しかしていない。
ファイルアクセス一切なし。すべてはメモリ内で完結している。
バイナリを見てみる。手元に64bitバイナリ読めるIDAがなかったのでobjdumpで。
tkito@Ubuntu1204_x64:~$ objdump -M intel -d crackme_d079a0af0b01789c01d5755c885da4f6 crackme_d079a0af0b01789c01d5755c885da4f6: file format elf64-x86-64 Disassembly of section .text: 00000000004000e0 <.text>: 4000e0: b8 3c 00 00 00 mov eax,0x3c 4000e5: bf 00 00 00 00 mov edi,0x0 4000ea: 0f 05 syscall 4000ec: 41 b9 00 00 00 00 mov r9d,0x0 4000f2: 49 c7 c0 ff ff ff ff mov r8,0xffffffffffffffff 4000f9: 41 ba 22 00 00 00 mov r10d,0x22 4000ff: ba 03 00 00 00 mov edx,0x3 400104: be 30 75 00 00 mov esi,0x7530 400109: bf 00 00 00 00 mov edi,0x0 40010e: b8 09 00 00 00 mov eax,0x9 400113: 0f 05 syscall 400115: 48 83 f8 00 cmp rax,0x0 400119: 7e c5 jle 0x4000e0 40011b: 48 89 c5 mov rbp,rax 40011e: 48 81 c5 98 3a 00 00 add rbp,0x3a98 400125: 48 8d 0c 25 03 c3 40 lea rcx,ds:0x40c303 40012c: 00 40012d: 48 8d 14 25 0b c3 40 lea rdx,ds:0x40c30b 400134: 00 400135: 8a 45 00 mov al,BYTE PTR [rbp+0x0] 400138: 84 c0 test al,al 40013a: 74 1f je 0x40015b 40013c: eb 00 jmp 0x40013e
syscall命令は、eaxの値に応じたシステムコールを実行する。9はmmapである。0がreadで1がwrite。
少し下を見ると、rbpに8を足したり8を引いたりしつつ、rbpが指すメモリアドレスの値をインクリメントしたりデクリメントしたりしている。
なお、rbpの値はmmapで確保されたメモリ内部のアドレスになっている。
40015b: 48 8d 6d 08 lea rbp,[rbp+0x8] 40015f: fe 45 00 inc BYTE PTR [rbp+0x0] 400162: 48 8d 6d f8 lea rbp,[rbp-0x8] 400166: fe 45 00 inc BYTE PTR [rbp+0x0] 400169: 8a 45 00 mov al,BYTE PTR [rbp+0x0] 40016c: 84 c0 test al,al 40016e: 0f 84 8a c1 00 00 je 0x40c2fe 400174: eb 00 jmp 0x400176 400176: 48 8d 6d 08 lea rbp,[rbp+0x8] 40017a: 8a 45 00 mov al,BYTE PTR [rbp+0x0] 40017d: 84 c0 test al,al 40017f: 74 2e je 0x4001af 400181: eb 00 jmp 0x400183 400183: 48 8d 6d 08 lea rbp,[rbp+0x8] 400187: 8a 45 00 mov al,BYTE PTR [rbp+0x0] 40018a: 84 c0 test al,al 40018c: 74 0e je 0x40019c 40018e: eb 00 jmp 0x400190 400190: fe 4d 00 dec BYTE PTR [rbp+0x0] 400193: 8a 45 00 mov al,BYTE PTR [rbp+0x0] 400196: 84 c0 test al,al 400198: 74 02 je 0x40019c 40019a: eb f4 jmp 0x400190
この少し下でwriteを行って”root@localhost’s password:”を出力して、ひたすらインクリメントとデクリメントを繰り返している。
readを実行するのは大分下、アドレス0x4065aeである。
この処理をずっと追うのも大変なのでデバッガで実行する。
tkito@Ubuntu1204_x64:~$ gdb ./crackme_d079a0af0b01789c01d5755c885da4f6 GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04 Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". For bug reporting instructions, please see: <http://bugs.launchpad.net/gdb-linaro/>... Reading symbols from /home/tkito/crackme_d079a0af0b01789c01d5755c885da4f6...(no debugging symbols found)...done. (gdb) set pagination 0 (gdb) b *0x400125 Breakpoint 1 at 0x400125 (gdb) b *0x4065ae Breakpoint 2 at 0x4065ae (gdb) r Starting program: /home/tkito/crackme_d079a0af0b01789c01d5755c885da4f6 warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffd000 Breakpoint 1, 0x0000000000400125 in ?? () (gdb) i r rbp rbp 0x7ffff7ff8a98 0x7ffff7ff8a98 (gdb) c Continuing. root@localhost's password: Breakpoint 2, 0x00000000004065ae in ?? () (gdb) x/88xg 0x7ffff7ff8a98 0x7ffff7ff8a98: 0x0000000000000001 0x0000000000000001 0x7ffff7ff8aa8: 0x0000000000000001 0x0000000000000000 0x7ffff7ff8ab8: 0x0000000000000000 0x0000000000000000 0x7ffff7ff8ac8: 0x0000000000000000 0x0000000000000000 0x7ffff7ff8ad8: 0x0000000000000000 0x0000000000000000 0x7ffff7ff8ae8: 0x0000000000000000 0x0000000000000000 0x7ffff7ff8af8: 0x0000000000000000 0x0000000000000000 0x7ffff7ff8b08: 0x0000000000000000 0x0000000000000000 0x7ffff7ff8b18: 0x0000000000000000 0x0000000000000000 0x7ffff7ff8b28: 0x0000000000000000 0x0000000000000000 0x7ffff7ff8b38: 0x0000000000000000 0x0000000000000000 0x7ffff7ff8b48: 0x0000000000000000 0x0000000000000000 0x7ffff7ff8b58: 0x0000000000000048 0x0000000000000000 0x7ffff7ff8b68: 0x0000000000000034 0x0000000000000000 0x7ffff7ff8b78: 0x0000000000000050 0x0000000000000000 0x7ffff7ff8b88: 0x0000000000000050 0x0000000000000000 0x7ffff7ff8b98: 0x0000000000000059 0x0000000000000000 0x7ffff7ff8ba8: 0x000000000000005f 0x0000000000000000 0x7ffff7ff8bb8: 0x0000000000000043 0x0000000000000000 0x7ffff7ff8bc8: 0x0000000000000030 0x0000000000000000 0x7ffff7ff8bd8: 0x0000000000000044 0x0000000000000000 0x7ffff7ff8be8: 0x0000000000000045 0x0000000000000000 0x7ffff7ff8bf8: 0x0000000000000047 0x0000000000000000 0x7ffff7ff8c08: 0x0000000000000061 0x0000000000000000 0x7ffff7ff8c18: 0x0000000000000054 0x0000000000000000 0x7ffff7ff8c28: 0x0000000000000045 0x0000000000000000 0x7ffff7ff8c38: 0x000000000000005f 0x0000000000000000 0x7ffff7ff8c48: 0x0000000000000032 0x0000000000000000 0x7ffff7ff8c58: 0x0000000000000030 0x0000000000000000 0x7ffff7ff8c68: 0x0000000000000031 0x0000000000000000 0x7ffff7ff8c78: 0x0000000000000034 0x0000000000000000 0x7ffff7ff8c88: 0x000000000000005f 0x0000000000000000 0x7ffff7ff8c98: 0x0000000000000043 0x0000000000000000 0x7ffff7ff8ca8: 0x0000000000000055 0x0000000000000000 0x7ffff7ff8cb8: 0x000000000000005f 0x0000000000000000 0x7ffff7ff8cc8: 0x0000000000000031 0x0000000000000000 0x7ffff7ff8cd8: 0x000000000000004e 0x0000000000000000 0x7ffff7ff8ce8: 0x000000000000005f 0x0000000000000000 0x7ffff7ff8cf8: 0x000000000000004b 0x0000000000000000 0x7ffff7ff8d08: 0x0000000000000030 0x0000000000000000 0x7ffff7ff8d18: 0x0000000000000052 0x0000000000000000 0x7ffff7ff8d28: 0x0000000000000045 0x0000000000000000 0x7ffff7ff8d38: 0x0000000000000034 0x0000000000000000 0x7ffff7ff8d48: 0x0000000000000000 0x0000000000000000
0x400125まで実行してrbpの値をメモし、0x4065ae(readのところ)まで実行して先ほどメモした値周辺のメモリを表示する。
すると、0x7ffff7ff8b58あたりから文字っぽいデータが16バイトごとに1バイトずつ存在しているのが見える。
これを並べると、以下の文字列になる。
H4PPY_C0DEGaTE_2014_CU_1N_K0RE4
これをパスワードとして入力してみる。
tkito@Ubuntu1204_x64:~$ ./crackme_d079a0af0b01789c01d5755c885da4f6 root@localhost's password: H4PPY_C0DEGaTE_2014_CU_1N_K0RE4 SUCCESS
というわけでこれがKeyでした。