워게임/Root Me

[Root Me] ELF x86 - Stack buffer overflow basic 1 - 포너블 / 버퍼오버플로우

SecurityMan 2022. 9. 3. 11:00

 

Root Me 에서 처음 풀어보는 포너블 문제

 

가장 기본적인 스택 버퍼오버플로우 문제이다.

 

반응형

 

문제 환경을 살펴보면 아무런 보호기법도 적용되지 않은것이 보인다.

 

그냥 편하게 풀 수 있는 수준이다.

 

#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
 
int main()
{
 
  int var;
  int check = 0x04030201;
  char buf[40];
 
  fgets(buf,45,stdin);
 
  printf("\n[buf]: %s\n", buf);
  printf("[check] %p\n", check);
 
  if ((check != 0x04030201) && (check != 0xdeadbeef))
    printf ("\nYou are on the right way!\n");
 
  if (check == 0xdeadbeef)
   {
     printf("Yeah dude! You win!\nOpening your shell...\n");
     setreuid(geteuid(), geteuid());
     system("/bin/bash");
     printf("Shell closed! Bye.\n");
   }
   return 0;
}

 

문제 아래쪽에 문제파일의 소스코드가 같이 주어진다.

 

코드를 살펴보면

 

check 변수에 0x04030201 이라는 값이 저장되어 있고,

 

40바이트 크기의 buf 배열을 선언하고 있다.

 

그런 다음 fgets 함수를 이용해 buf 변수에 사용자의 입력을 받아 저장하는데,

 

45 바이트를 저장하고 있다.

 

40바이트인 buf 변수에 45바이트를 저장하기 때문에

 

당연히 버퍼오버플로우 취약점이 발생한다.

 

그런다음 뒤에 따라오는 조건문에서

 

check 변수의 값이 0x04030201 또는 0xdeadbeef 가 아니면

 

You are on the right way! 라는 값을 프린트 하고

 

check 변수의 값이 0xdeadbeef 가 되면,

 

Yeah dude! You win!\nOpening your shell... 라는 문구가 출력되면서

 

/bin/bash 쉘을 실행시킨다.

 

기본적으로 문제의 목표는 buf 배열을 오버플로우 시켜 check 변수의 값을 0xdeadbeef 으로 만드는 것이다.

 

 

 

SSH 를 이용해 문제 서버에 접속해 문제를 풀면 되는데

 

귀찮다면 오른쪽에 있는 WebSSH 버튼을 누르면 된다.

 

 

해당 기능을 이용하면 이렇게

 

웹을 이용해서 SSH 접속을 할 수 있다.

 

 

먼저 터미널에서 ls -al 명령어로 

 

어떤 파일들이 있는지 살펴본다.

 

플래그가 숨어있을거 같은 .passwd 파일이 보이고,

 

문제파일인 ch13 / 소스파일은 ch13.c 파일이 보인다.

 

 

시험삼아 ch13 파일을 실행시켜 본다.

 

hello 라고 입력해봤는데, 값을 입력하면

 

buf 변수와 check 변수에 어떤 값이 현재 들어있는지 보여준다.

 

 

이번엔 a를 무작정 많이 입력해봤다.

 

그랬더니 check 변수의 값이 0x61616161 로 바뀌었는데,

 

0x61은 ASCII 코드로 소문자 a 를 의미한다.

 

buf 배열이 꽉 차서 오버플로우 되면서, 바로 뒤에있던 check 변수에 저장되어있던

 

0x04030201 을 덮어 써버린 것이다.

 

아래쪽에 보면 check 변수의 값이 변해서 You are on the right way! 가 출력되어있는게 보인다.

 

이제 check 변수의 값을 0xdeadbeef 으로 바꿀 방법을 생각하면 된다.

 

 

python 을 이용하면 된다.

 

python -c "print 'a'*40 + '\xef\xbe\xad\xde'" | ./ch13

 

먼저 a 를 buf 배열의 길이만큼 넣어서 buf 배열을 꽉 채워주고(40개)

 

그다음 0xdeadbeef 값을 더해주면 되는데,

 

리틀 엔디안 방식으로 저장되기 때문에 맨 뒤부터 두 바이트씩 끊어서 입력해줘야 한다.

 

de ad be ef  →  ef be ad de

 

이렇게 입력하면

 

check 변수에 0xdeadbeef 라는 값이 들어가게 되고,

 

You Win 이 출력되면서 shell 을 실행하는데

 

바로 Shell closed! Bye 가 나오면서 종료가 되어버린다.

 

Shell 이 바로 종료되지 않도록 추가적인 작업이 필요한듯 하다.

 

 

이건 간단하게 python 으로 print 한 뒤에 cat 명령어를 붙여주면 된다.

 

이렇게 하면 shell이 바로 종료되지 않고, 정지상태가 되는데

 

그때 cat .passwd 를 이용해 .passwd 파일의 내용을 읽어주면

 

그안에 숨어있던 플래그를 찾을 수 있다.

반응형