Category : System hacking
ssh://io.smashthestack.org:2224 id : level1 pw : level1 |
Summary : strings , ltrace , basic debugging
서버에 접속하여 /levels에 있는 문제 바이너리를 확인한다.
level1@io:/levels$ ls -l level01 -r-sr-x--- 1 level2 level1 7500 Nov 16 2007 level01 level1@io:/levels$ file level01 level01: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.4.1, not stripped |
문제 바이너리인 level01인 실행파일로 excute권한과 read 권한이 있어서 디버깅도 가능하다.
실행파일이므로 실행시켜본다.
level1@io:/levels$ ./level01 Usage: ./level01 <password> level1@io:/levels$ ./level01 pwn3r Fail. |
level01은 argv[1]에 password를 입력받는다. 임의의 문자열을 넣었더니 "Fail."이라고 출력된다.
실행으로 더이상의 정보를 얻을 수 없으므로 디버깅을 한다.
(gdb) disas main Dump of assembler code for function main: 0x080483f4 <main+0>: lea 0x4(%esp),%ecx 0x080483f8 <main+4>: and $0xfffffff0,%esp 0x080483fb <main+7>: pushl -0x4(%ecx) 0x080483fe <main+10>: push %ebp 0x080483ff <main+11>: mov %esp,%ebp 0x08048401 <main+13>: push %edi 0x08048402 <main+14>: push %ecx 0x08048403 <main+15>: sub $0x30,%esp 0x08048406 <main+18>: mov %ecx,-0x20(%ebp) 0x08048409 <main+21>: movl $0x80485c8,-0xc(%ebp) 0x08048410 <main+28>: mov -0x20(%ebp),%eax 0x08048413 <main+31>: cmpl $0x2,(%eax) 0x08048416 <main+34>: je 0x8048439 <main+69> 0x08048418 <main+36>: mov -0x20(%ebp),%edx 0x0804841b <main+39>: mov 0x4(%edx),%eax 0x0804841e <main+42>: mov (%eax),%eax 0x08048420 <main+44>: mov %eax,0x4(%esp) 0x08048424 <main+48>: movl $0x80485d4,(%esp) ---Type <return> to continue, or q <return> to quit--- 0x0804842b <main+55>: call 0x804832c <printf@plt> 0x08048430 <main+60>: movl $0x1,-0x1c(%ebp) 0x08048437 <main+67>: jmp 0x80484b2 <main+190> 0x08048439 <main+69>: mov -0xc(%ebp),%eax 0x0804843c <main+72>: mov $0xffffffff,%ecx 0x08048441 <main+77>: mov %eax,-0x24(%ebp) 0x08048444 <main+80>: mov $0x0,%al 0x08048446 <main+82>: cld 0x08048447 <main+83>: mov -0x24(%ebp),%edi 0x0804844a <main+86>: repnz scas %es:(%edi),%al 0x0804844c <main+88>: mov %ecx,%eax 0x0804844e <main+90>: not %eax 0x08048450 <main+92>: lea -0x1(%eax),%edx 0x08048453 <main+95>: mov -0x20(%ebp),%ecx 0x08048456 <main+98>: mov 0x4(%ecx),%eax 0x08048459 <main+101>: add $0x4,%eax 0x0804845c <main+104>: mov (%eax),%ecx 0x0804845e <main+106>: mov %edx,0x8(%esp) 0x08048462 <main+110>: mov -0xc(%ebp),%eax ---Type <return> to continue, or q <return> to quit--- 0x08048465 <main+113>: mov %eax,0x4(%esp) 0x08048469 <main+117>: mov %ecx,(%esp) 0x0804846c <main+120>: call 0x804830c <strncmp@plt> 0x08048471 <main+125>: test %eax,%eax 0x08048473 <main+127>: jne 0x804849f <main+171> 0x08048475 <main+129>: movl $0x80485ea,(%esp) 0x0804847c <main+136>: call 0x80482fc <puts@plt> 0x08048481 <main+141>: movl $0x0,0x8(%esp) 0x08048489 <main+149>: movl $0x80485ef,0x4(%esp) 0x08048491 <main+157>: movl $0x80485f2,(%esp) 0x08048498 <main+164>: call 0x80482ec <execl@plt> 0x0804849d <main+169>: jmp 0x80484ab <main+183> 0x0804849f <main+171>: movl $0x80485fa,(%esp) 0x080484a6 <main+178>: call 0x80482fc <puts@plt> 0x080484ab <main+183>: movl $0x0,-0x1c(%ebp) 0x080484b2 <main+190>: mov -0x1c(%ebp),%eax 0x080484b5 <main+193>: add $0x30,%esp 0x080484b8 <main+196>: pop %ecx 0x080484b9 <main+197>: pop %edi ---Type <return> to continue, or q <return> to quit--- 0x080484ba <main+198>: pop %ebp 0x080484bb <main+199>: lea -0x4(%ecx),%esp 0x080484be <main+202>: ret End of assemble |
코드가 상당히 길지만 정리하면 argv[1]과 0x80485c8에 있는 값을 비교하여 같으면 "Win"을 출력한 후 쉘을 실행해주고 , 다르면 "Fail"을 출력한 후 종료된다.
0x08048453 <main+95>: mov -0x20(%ebp),%ecx 0x08048456 <main+98>: mov 0x4(%ecx),%eax 0x08048459 <main+101>: add $0x4,%eax 0x0804845c <main+104>: mov (%eax),%ecx 0x0804845e <main+106>: mov %edx,0x8(%esp) 0x08048462 <main+110>: mov -0xc(%ebp),%eax 0x08048465 <main+113>: mov %eax,0x4(%esp) 0x08048469 <main+117>: mov %ecx,(%esp) 0x0804846c <main+120>: call 0x804830c <strncmp@plt> |
< strncmp로 두 문자열을 비교하는 부분 >
0x80485c8에 있는 값은 디버깅을 통해 쉽게 알아낼 수 있다.
(gdb) b main Breakpoint 1, 0x08048403 in main () |
argv[1] 과 비교되는 문자열은 "omgpassword"이다
그러므로 argv[1]에 위 문자열을 넘겨주면 "Win"이 출력되고 level2의 쉘을 얻을 수 있을 것이다.
level1@io:/levels$ ./level01 omgpassword Win. sh-3.2$ id uid=1001(level1) gid=1001(level1) euid=1002(level2) groups=1001(level1),1029(nosu) sh-3.2$ cat /home/level2/.pass WE5aVWRwYPhX |
level2의 쉘을 얻고 password를 획득했다.
p.s 사실 디버깅을 할필요없이 strings나 ltrace 같은 유틸리티를 이용하면 편리하게 풀 수 있다.
level1@io:/levels$ strings level01 /lib/ld-linux.so.2 __gmon_start__ libc.so.6 printf execl puts strncmp _IO_stdin_used __libc_start_main GLIBC_2.0 PTRh 0Y_] [^_] [^_] omgpassword Usage: %s <password> Win. /bin/sh Fail. |
level1@io:/levels$ ltrace ./level01 hi __libc_start_main(0x80483f4, 2, 0xbfffdda4, 0x8048510, 0x80484c0 <unfinished ...> strncmp("hi", "omgpassword", 11) = -7 puts("Fail."Fail. ) = 6 +++ exited (status 0) +++ |
'Wargame > IO.smashthestack.org' 카테고리의 다른 글
IO smashthestack level5 (0) | 2011.07.25 |
---|---|
IO smashthestack level4 (0) | 2011.07.25 |
IO smashthestack level3 (0) | 2011.07.17 |
IO smashthestack level2 (0) | 2011.07.17 |