Blog | Tag | Local | Media | Guest | Login  RSS
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 at 0x8048403
(gdb) r
Starting program: /levels/level01

Breakpoint 1, 0x08048403 in main ()
(gdb) x/s $0x80485c8
Value can't be converted to integer.
(gdb) x/s 0x80485c8
0x80485c8:  "omgpassword"


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 level3  (0) 2011.07.17
IO smashthestack level2  (0) 2011.07.17
IO smashthestack level1  (0) 2011.07.17

Name
Password
Homepage
비밀글 (Secret)

티스토리 툴바