DVLには色々なソフトウェアが収録されているので飽きずに遊べます。
今日やったのはcrackmeというソフトをリバースエンジニアリングしてパスワードを当てるといったものです。
まずはどんなものか確認
bt Cyrex_LinuxCrackme1 # ./crackme -[ Linux CrackMe (Level:2) by cyrex ]- -[ TODO: You have to get the valid Password ]- Enter Password: aaa -[ Ohhhh, your skills are bad try again later ]-
いつもながらgdbを使って実行していく。
bt Cyrex_LinuxCrackme1 # gdb crackme GNU gdb 6.5 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1". 一旦main()に入ったところにブレークポイントを張る。 gdb $ b main Breakpoint 1 at 0x8048456 gdb $ r -------------------------------------------------------------------------[ regs] eax:BF8FE0EC ebx:B7FC9FFC ecx:B7FCC19C edx:00000001 eflags:00000286 esi:BF8FE0E4 edi:BF8FE070 esp:BF8FE030 ebp:BF8FE058 eip:08048456 cs:0073 ds:007B es:007B fs:0000 gs:0033 ss:007B o d I t S z a P c [007B:BF8FE030]---------------------------------------------------------[stack] BF8FE060 : 01 00 00 00 E4 E0 8F BF - EC E0 8F BF 6C 1B FF B7 ............l... BF8FE050 : 00 00 00 00 E0 CC FF B7 - B8 E0 8F BF 14 3E EB B7 .............>.. BF8FE040 : FC 9F FC B7 FC 9F FC B7 - 50 85 04 08 FC 9F FC B7 ........P....... BF8FE030 : 00 00 00 00 00 00 00 00 - 58 E0 8F BF 0B 85 04 08 ........X....... [007B:BF8FE0E4]---------------------------------------------------------[ data] BF8FE0E4 : 64 E6 8F BF 00 00 00 00 - 9F E6 8F BF ED E6 8F BF d............... BF8FE0F4 : F4 E6 8F BF 01 E7 8F BF - 0C E7 8F BF 1C E7 8F BF ................ [0073:08048456]---------------------------------------------------------[ code] 0x8048456 <main+6>: add esp,0xfffffff4 0x8048459 <main+9>: push 0x8048620 0x804845e <main+14>: call 0x804835c <printf@plt> 0x8048463 <main+19>: add esp,0x10 0x8048466 <main+22>: add esp,0xfffffff4 0x8048469 <main+25>: push 0x8048660 ------------------------------------------------------------------------------- ブレークポイントで止まったらeipを表示。iを使うことでアセンブラコードを表示できる。 文字列比較にはstrcmp/strncmp辺りを使っていると思うのでそれらしい所を探す。 Breakpoint 1, 0x08048456 in main () gdb $ x/50i $eip 0x8048456 <main+6>: add esp,0xfffffff4 0x8048459 <main+9>: push 0x8048620 0x804845e <main+14>: call 0x804835c <printf@plt> 0x8048463 <main+19>: add esp,0x10 0x8048466 <main+22>: add esp,0xfffffff4 0x8048469 <main+25>: push 0x8048660 0x804846e <main+30>: call 0x804835c <printf@plt> 0x8048473 <main+35>: add esp,0x10 0x8048476 <main+38>: add esp,0xfffffff4 0x8048479 <main+41>: push 0x8048690 0x804847e <main+46>: call 0x804835c <printf@plt> 0x8048483 <main+51>: add esp,0x10 0x8048486 <main+54>: add esp,0xfffffff8 0x8048489 <main+57>: lea eax,[ebp-32] 0x804848c <main+60>: push eax 0x804848d <main+61>: push 0x80486a1 0x8048492 <main+66>: call 0x804832c <scanf@plt> 0x8048497 <main+71>: add esp,0x10 0x804849a <main+74>: add esp,0xfffffff8 0x804849d <main+77>: push 0x80486a4 <---- ここはstrcmpに渡している引数っぽい(こっちは期待するパスワードの文字列のアドレス) 0x80484a2 <main+82>: lea eax,[ebp-32] 0x80484a5 <main+85>: push eax <---- ここはstrcmpに渡している引数っぽい(こっちは入力された文字列) 0x80484a6 <main+86>: call 0x804831c <strcmp@plt> <---- ここがパスワードを比較している箇所だろう。 0x80484ab <main+91>: add esp,0x10 0x80484ae <main+94>: mov eax,eax 0x80484b0 <main+96>: test eax,eax 0x80484b2 <main+98>: jne 0x80484c6 <main+118> 0x80484b4 <main+100>: add esp,0xfffffff4 0x80484b7 <main+103>: push 0x80486c0 0x80484bc <main+108>: call 0x804835c <printf@plt> 0x80484c1 <main+113>: add esp,0x10 0x80484c4 <main+116>: jmp 0x80484d6 <main+134> 0x80484c6 <main+118>: add esp,0xfffffff4 0x80484c9 <main+121>: push 0x8048700 0x80484ce <main+126>: call 0x804835c <printf@plt> 0x80484d3 <main+131>: add esp,0x10 0x80484d6 <main+134>: xor eax,eax 0x80484d8 <main+136>: jmp 0x80484e0 <main+144> 0x80484da <main+138>: lea esi,[esi] 0x80484e0 <main+144>: leave 0x80484e1 <main+145>: ret 0x80484e2 <main+146>: lea esi,[esi] 0x80484e9 <main+153>: lea edi,[edi] 0x80484f0 <__libc_csu_init>: push ebp 0x80484f1 <__libc_csu_init+1>: mov ebp,esp 0x80484f3 <__libc_csu_init+3>: push edi 0x80484f4 <__libc_csu_init+4>: push esi 0x80484f5 <__libc_csu_init+5>: xor esi,esi 0x80484f7 <__libc_csu_init+7>: push ebx 0x80484f8 <__libc_csu_init+8>: sub esp,0xc ではスタックにpushしているアドレスの内容を表示してみる。 gdb $ x/s 0x80486a4 0x80486a4 <_IO_stdin_used+160>: "47ghf6fh37fbgbgj" あー。なにやら怪しい文字列が見えたのでこれをパスワードとして入力してみる。 gdb $ c -[ Linux CrackMe (Level:2) by cyrex ]- -[ TODO: You have to get the valid Password ]- Enter Password: 47ghf6fh37fbgbgj -[ Good, You're ready to begin linux reversing ]- Program exited normally. -------------------------------------------------------------------------[ regs] Error while running hook_stop: No registers. gdb $ q bt Cyrex_LinuxCrackme1 #
というわけで、0x80486a4のアドレスの内容が見事にパスワードだったというわけです。