/*

        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 :

몇일 전에 알아낸 사실인데

RTL을 하거나 ROP등을 하기 위해 exit함수 또는 가젯등을 이용할때 그게 어떤 원리로 돌아가는지 궁금해서 

연구해봤는데

RTL을 예로 들어보면 스택구조가 [ buffer ][ sfp ][ ret ] 대충이런식으로 있다고 가정했을때

ret에 system함수 주소를 넣어주면 정상적으로 (call로 호출) system함수를 호출 했을때 함수 호출 이후 

코드 실행을 위해 saved eip를 스택에 푸쉬하는데 ret로 함수를 호출하면 이 push eip가 안된 상태에서 

함수 내부에서 함수를 빠져나올때 원래 push eip가 되있어야 될위치의 값을 호출하기 때문에 

[ &system ][ &exit ][ /bin/sh ] 와 같은 구성이 가능한 것이다. 함수 인자를 ebp + 8부터 참조하는것도

이 이유 때문이다.

이런 원리를 이용해 chaining rtl을 할때도 pop pop ret과 같은 가젯을 이용해 계속 ret로 함수를 호출하면서

구성을 해줄수가 있다.

'Security' 카테고리의 다른 글

허..  (0) 2013.10.17
php extract vulnerability  (0) 2013.10.13
[Ollydbg 1.x] OllyMSDN plugin  (0) 2013.07.11
유용한 자료들..  (0) 2013.04.22
Duelist crackme #1 풀이  (0) 2013.03.10
Posted by xer0s :

으..

2013. 9. 5. 23:53 from General News/Life story

항상 블로그를 꾸준히 관리하겠다고 다짐하지만 보름을 못가 그 다짐이 무너지네요 ㅠㅠ

이놈의 귀차니즘이 문제지..


요즘 주식이랑 심리학도 공부하고 있는데 언제한번 그 포스팅이나 할깨요


그나저나 곧있으면 중간고사고 또 금방 디미고 원서 접수기간인데..

포스팅 할수는 있으련지 ㄷㄷ..


'General News > Life story' 카테고리의 다른 글

2014 순천향대 청소년 정보보호 페스티벌 예선  (0) 2014.08.14
2014 코드게이트 주니어 세미나 발표자료 및 후기  (2) 2014.04.03
근황..  (3) 2013.12.31
합격!  (0) 2013.11.27
Things to do..  (0) 2013.07.09
Posted by xer0s :