/* 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 |
---|