/*

        The Lord of the BOF : The Fellowship of the BOF 

- evil_wizard

- Local BOF on Fedora Core 3 

- hint : GOT overwriting

*/


// magic potion for you

void pop_pop_ret(void)

{

asm("pop %eax");

asm("pop %eax");

asm("ret");

}

 

int main(int argc, char *argv[])

{

char buffer[256];

char saved_sfp[4];

int length; 


if(argc < 2){

printf("argv error\n");

exit(0);

}


// for disturbance RET sleding

length = strlen(argv[1]);

   

        // healing potion for you

        setreuid(geteuid(), geteuid());

        setregid(getegid(), getegid());


// save sfp 

memcpy(saved_sfp, buffer+264, 4);

 

// overflow!!

strcpy(buffer, argv[1]);


// restore sfp 

memcpy(buffer+264, saved_sfp, 4);


        // disturbance RET sleding

        memset(buffer+length, 0, (int)0xff000000 - (int)(buffer+length));


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

}

 




위 소스를 봐보면 스택을 0으로 초기화 해줌으로써 RET Sled를 방지해줬고

문제 해결의 실마리로 pop pop ret 코드를 제공해줍니다.

pop pop ret를 이용해 함수를 연쇄적으로 호출 할수가 있는데


[ func1 ][ ret ][ arg1 ][ arg2 ][ func2 ][ ret ][ ...]


위 스택구조에서 ret에다가 pop pop ret을 넣어줌으로써 esp를 8바이트 위로 올려주고 그 다음위치에 있는

값이 ret로 가는 형식으로 함수 연쇄 호출이 가능합니다. 



ASCII Armor 때문에 system함수를 호출할 때 인자구성을 해줄수가 없으므로 ASCII Armor의 영향을 받지않는

PLT를 이용해 주면 됩니다. GOT와 PLT 관련 사이트들은 아래를 참조해주시면 될꺼 같네요


http://lapislazull.tistory.com/54

http://ezbeat.tistory.com/374

http://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html



그럼 GOT Overwrite가 정확히 무엇인지 알아보겠습니다.

GOT Overwrite란 실제 함수의 주소를 저장하고 있는 GOT 테이블을 변조해서 원하는 함수를 호출하는 방법입니다.


예를들어 memcpy함수를 호출할때 GOT Overwrite를 통해 memcpy의 주소가 저장된 GOT 테이블을 system함수의 주소로 변조한 후 memcpy의 plt를 호출하면 system함수가 호출됩니다

그럼 최종적으로 pop pop ret 가젯을 이용해 chaining rtl로 strcpy를 불러와 memory got에 system주소를 넣어주면 될꺼 같네요


[hell_fire@Fedora_1stFloor ~]$ objdump -d evil_wizard | grep pop -A1


--

 804854f: 58                   pop    %eax

 8048550: 58                   pop    %eax

 8048551: c3                   ret    

--


[hell_fire@Fedora_1stFloor ~]$ objdump -h evil_wizard | grep .got.plt

 20 .got.plt      00000038  0804986c  0804986c  0000086c  2**2


[hell_fire@Fedora_1stFloor ~]$ gdb -q wizard_evil


(gdb) b *main+319

Breakpoint 1 at 0x8048693


(gdb) r a

Starting program: /home/hell_fire/wizard_evil a

(no debugging symbols found)...(no debugging symbols found)...a


Breakpoint 1, 0x08048693 in main ()


(gdb) print memcpy

$1 = {<text variable, no debug info>} 0x7854c0 <memcpy>


(gdb) print system

$2 = {<text variable, no debug info>} 0x7507c0 <system>


(gdb) print strcpy

$3 = {<text variable, no debug info>} 0x783880 <strcpy>


(gdb) x/10x 0x804986c

0x804986c <_GLOBAL_OFFSET_TABLE_>: 0x080497a0 0x007194f8 0x0070e9e0 0x00783d70

0x804987c <_GLOBAL_OFFSET_TABLE_+16>: 0x007d98f0 0x00730d50 0x0075e660 0x007854c0

0x804988c <_GLOBAL_OFFSET_TABLE_+32>: 0x007d9860 0x0804845a


system함수의 인자로 넣어줄 /bin/sh도 구성해줘야 되는데 

어떤 분의 블로그를 보고 아이디어를 얻었다. bss영역을 이용해 거기다가 /bin/sh 문자열을 

구성해주면 될까 싶어서 시도해봤더니 됬습니다.


[hell_fire@Fedora_1stFloor ~]$ objdump -h evil_wizard | grep bss

 22 .bss          00000004  080498b0  080498b0  000008b0  2**2


[hell_fire@Fedora_1stFloor ~]$ gdb -q wizard_evil

(no debugging symbols found)...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) b *main

Breakpoint 1 at 0x8048554

(gdb) r a

Starting program: /home/hell_fire/wizard_evil a

(no debugging symbols found)...(no debugging symbols found)...

Breakpoint 1, 0x08048554 in main ()

(gdb) x/10x 0x080498b0

0x80498b0 <completed.1>: 0x00000000 0x00000000 0x00000000 0x00000000

0x80498c0: 0x00000000 0x00000000 0x00000000 0x00000000

0x80498d0: 0x00000000 0x00000000


저기 공간중에서 적절한 주소값을 찾아서 /bin/sh를 넣어주면 됩니다.

대충 구상도 다 했으니 이제 필요한 문자열들을 찾아내줘야되는데

/, b, i, n, s, h, \xc0, \x07, \x75, \x00 를 찾아주면 되겠습니다.


이제 익스플로잇을 짜주면 되는데 시험 끝나고 마무리 해야될꺼 같네요


'Wargame > LOB[FC]' 카테고리의 다른 글

[BOF원정대/FC3] evil_wizard -> dark_stone  (0) 2013.10.14
Posted by xer0s :