FTZ WriteUp

Level18


#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

void shellout(void);

int main()
{
    char string[100];
    int check;
    int x = 0;
    int count = 0;

    fd_set fds;          //fd_set 구조체 fds 선언

    printf("Enter your command: ");

    fflush(stdout);     //출력버퍼를 비움

    while(1)
    {
        if(count >= 100)
            printf("what are you trying to do?\n");

        if(check == 0xdeadbeef) // check안에  0xdeadbeef가 입력되어 있을 시 shelldout()함수 실행
            shellout();
        else
        {
            FD_ZERO(&fds);  // fds의 소켓셋을 비움
            FD_SET(STDIN_FILENO,&fds); //소켓셋에 표준입력 fd number 추가

            if(select(FD_SETSIZE, &fds, NULL, NULL, NULL) >= 1)           // 이 부분에서 입력이 되는것으로 추정...
            {
                if(FD_ISSET(fileno(stdin),&fds))
                {
                    read(fileno(stdin),&x,1);
                    switch(x)
                    {
                        case '\r':                      //carrage return이나 이걸뭐라하더라 에....암튼 띄어쓰기 문자가 나오면 \a를 출력함
                        case '\n':
                            printf("\a");
                            break;
                        case 0x08:                     //0x8이 입력되면 count는 -1이 되고 아래 \b을 두번 출력
                            count--;
                            printf("\b \b");
                            break;
                        default:             //그게아닌 남은 모든것은 string의 count인덱스가 가리키는곳에 x의 값을 집어넣고 count증가
                            string[count] = x;
                            count++;
                            break;
                    }
                }
            }
        }
    }
}

void shellout(void)
{
    setreuid(3099,3099);
    execl("/bin/sh","sh",NULL);
}

 

소스가 참 길고 어렵네요 저에겐 조금 많이 어려운 소스였습니다.

 

분명 입력은 이루어지고 check 0xdeadbeef가 들어있으면 shellout함수를 실행해 권한이상승되고 쉘을 얻을 수 있습니다.

 

이 문제는 음코드 이해력을 가장 많이 필요로 하네요 삽질을 쫌 했습니다

Check 0xdeadbeef만 있음 되니 이제 디버깅을 하며 메모리에 변수 위치들을 파악만 하면 될거같습니다..

 

 

Ebp-0x6cebp-0x70부분에 0이 들어가고 0xfc eax만큼 공간을 할당합니다 아마 string dummy일것입니다

중요한 건 가장 아래에 ebp-0x68부분에 0xdeadbeef와 비교를 하는건데요 그렇다면 추측을 해보면 스택의 위치는 대강 이렇게 나옵니다.

그렇다면 우리는 string count의 위치만큼 입력을 받으니 이것과 0x08을 이용해 string의 인덱스를 “ –4”만큼 이동하여 string[-4]부터 0xdeadbeef를 입력받으면 check 0xdeadbeef가 들어가게 되는 셈입니다. 어차피 -4부터 switch문으로 count1씩 증가할 테니 -4 -3 -2 -1에 입력이 될것입니다.

 

이제 입력을 받게 되면 그만이겠네요, 그리고 select gets함수와 비슷한 방식으로 입력을 받더군요

 

./attackme $(perl –e ‘print )…이런 식이 아니라

(perl –e ‘print….”’;cat)|./attackme 이런식으로 입력을 받아야 합니다

 

그럼 이렇게 입력을 하게 된다면 쉘이 떠오를 것입니다

 

 

이렇게 level18을 클리어 했지만 좀 가장 많이 아쉬움이 남는 문제였습니다.

소스 분석력이 많이 떨어진다고 느끼는 단계였습니다

Phantom@TeamH4C

댓글

댓글 본문