둘둘리둘둘리둘둘리둘둘리둘둘리둘

[Hacker school FTZ] Level18 -> Level19 본문

War game/해커 스쿨 FTZ

[Hacker school FTZ] Level18 -> Level19

dool2ly 2015. 8. 20. 22:19

#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);                            //fdset 초기화

          FD_SET(STDIN_FILENO,&fds);   //fdset중 stdin에 해당하는 비트를 1로 세트


          if(select(FD_SETSIZE, &fds, NULL, NULL, NULL) >= 1)    //fdset선택

            {

              if(FD_ISSET(fileno(stdin),&fds))    //stdin가 세트되면 진행

                {

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

                  switch(x)

                    {

                      case '\r':

                      case '\n':

                        printf("\a");

                        break;

                      case 0x08:        //stdin이 0x08(Backspace)면 count감소

                        count--;

                        printf("\b \b");

                        break;

                      default:            //\r,\n,0x08이 아니면 string[count]에 stdin값을 입력

                        string[count] = x;

                        count++;

                        break;

                    }

                }

            }

        }

    }

}


void shellout(void)

{

  setreuid(3099,3099);

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

}


특별한 기술이 필요한게 아니라 쫄지 않고 차근차근 뜯어보면 해결할 수 있다.


소스를 풀어보면 while문으로 stdin에 입력이 있으면 string[count]에 차곡차곡 쌓고,

count가 100 이상이 되면 "what are you tring to do?\n"을 출력하고, 변수 check가 0xdeadbeef라면 함수 shellout을 출력해 준다.





함수 main을 디스어셈블 해서 <main+526>~<main+535>부분을 소스코드와 비교해보면서 뜯어보면 string이 ebp-100(ebp-252가 ebp-100의 주소를 가짐)임을 알 수 있다.

(직접 값 넣어가면서 디버깅해보는게 최고..)



이부분에서는 변수 check가 ebp-104에 위치한다는것을 알 수 있다.


스텍을 생각해보면 조작할 수 있는 string(ebp-100)의 주소가 check(ebp-104)보다 더 높은 주소에 있다.  string의 내용은 계속해서 더 높은 주소로 쌓이니 변수 check를 조작할 방법이 없어보이는데, 좀 더 생각해보면 그렇지 않다.


string에 stdin을 더해주는게 아니라 string주소 기준으로 count번째에 값을 입력하는것이다.


그렇다면 count값을 음수로 조작한다면 string보다 4byte낮은주소에 위치한 변수 check의 주소에 원하는 값을 입력할 수 있을 것이다.


count의 값을 음수로 만들 수 있는 방법을 소스코드에서 찾아보면 문제를 해결할 수 있다.




--풀이--


Comments