본문 바로가기

WARGAME/hackerschool ftz,lob

[해커스쿨 ftz] level 18 -> level 19

hint

#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;

  printf("Enter your command: ");

  fflush(stdout);

  while(1)

    {

      if(count >= 100)

        printf("what are you trying to do?\n");

      if(check == 0xdeadbeef)

        shellout();

      else

        {

          FD_ZERO(&fds);

          FD_SET(STDIN_FILENO,&fds);


          if(select(FD_SETSIZE, &fds, NULL, NULL, NULL) >= 1)

            {

              if(FD_ISSET(fileno(stdin),&fds))

                {

                  read(fileno(stdin),&x,1);

                  switch(x)

                    {

                      case '\r':

                      case '\n':

                        printf("\a");

                        break;

                      case 0x08:

                        count--;

                        printf("\b \b");

                        break;

                      default:

                        string[count] = x;

                        count++;

                        break;

                    }

                }

            }

        }

    }

}


void shellout(void)

{

  setreuid(3099,3099);

  execl("/bin/sh","sh",NULL);

}



풀이

1. 간략하게 이해해 보면 count가 0부터 시작해서 100이 되면 프로그램을 끝낸다. 이 count는 밑에 switch문의 default에서 증가시켜 준다.

또, 아래쪽 분기문에는 파일 디스크립터와 표준 입력이 나오는데 뭔가 키보드 입력을 가지고 분기한다는 것을 알 수 있다.

switch문에는 세가지가 있는데, 0x08을 입력한 경우엔 카운트 값을 감소시키고 default에서는 string[count]의 위치에 표준 입력으로 입력한 값을 넣고 카운트를 증가시킨다.


마지막으로 check변수가 0xdeadbeef가 되면 shellout()이라는 함수로 이동시키며 level19의 쉘을 얻게 해준다.


gdb를 이용해서 스택 구조를 보면 다음과 같다.


low address ... fds | dummy | count | x | check | string[100] | dummy(20) | sfp | ret | ... high address





2. 처음에는 0x08을 12개 입력하고 다음으로 음수를 입력하여 count를 -200 정도로로 변경 하고 x값을 그대로 적어주고 check+string[100]+dummy(20)+sfp 만큼의 쓰레기값을 입력하고 마지막으로 shellout()의 주소를 ret에 적어주려고 삽을 준비했는데,

이럴바엔 0x08을 4개 입력하여 string[-4]에 0xdeadbeef를 차례대로 넣어주면 된다는걸 깨달았다.