ii4gsp
[Heap] Buffer Overflow 본문
Heap?
프로그램이 실행되면, 실행에 필요한 정보들이 메모리 영역에 올라간다.
프로그램의 명령어가 올라가는 코드 영역
전역 변수와 정적 변수 등이 할당되는 데이터 영역
지역 변수와 매개 변수가 저장되는 스택 영역
필요에 의해 동적으로 메모리를 할당하는 힙 영역
특징
Heap의 메모리를 동적으로 할당한다.
Stack은 할당될 메모리의 크기를 컴파일 과정에서 알 수 있지만 Heap은 컴파일 과정에서는 크기를 알 수 없고, 프로그램 실행시 크기가 결정된다.
Stack은 높은 주소에서 낮은 주소로 할당되지만, Heap은 낮은 주소에서 높은 주소로 할당된다.
Heap overflow
힙 오버플로우는 스택 오버플로우처럼 직접적으로 RET조작은 불가능하다.
힙 오버플로우는 프로그램의 함수 포인터를 조작한다.
예제
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
struct data {
char name[64];
};
struct fp {
int (*fp)();
};
void winner()
{
printf("level passed\n");
}
void nowinner()
{
printf("level has not been passed\n");
}
int main(int argc, char **argv)
{
struct data *d;
struct fp *f;
d = malloc(sizeof(struct data));
f = malloc(sizeof(struct fp));
f->fp = nowinner;
printf("data is at %p, fp is at %p\n", d, f);
strcpy(d->name, argv[1]);
f->fp();
}
Protostar의 Heap0 문제이다.
구조체 포인터 d와 f에 각각의 구조체 크기만큼 malloc()함수로 메모리를 할당하고있다.
fp 구조체의 포인터 fp함수 포인터에 nowinner() 함수의 주소를 담고, 함수 포인터를 실행시킨다.
함수 포인터를 실행하기전 strcpy() 함수로 data구조체의 name멤버 변수에 argv[1]의 값을 복사하고있다.
strcpy() 함수에서 overflow가 일어나 nowinner() 함수가 아닌 winner() 함수를 실행시킬 수 있다.
gdb로 파일을 열어보면 malloc함수가 두 번 호출된다.
malloc() 함수의 반환값은 eax레지스터에 저장된다.
첫 번째 malloc() 함수의 할당 주소를 알아내기 위해 malloc() 함수 호출후<main+25>쯤 break point를 걸어주자
d는 0x804a008 - 0x8 주소부터 할당된다.
f는 0x804a050 주소부터 할당된다.
d와 f의 주소의 차이는 0x48 즉, 72만큼 차이가난다.
0x804a050에는 0x08048478이라는 주소를 가르키고있다.
d에서 f까지의 거리 72만큼 값을 채워주고 winner() 함수의 주소를 넣으면
0x08048478 주소가 winner()함수의 주소로 바뀌어 winner() 함수가 실행된다.
winner() 함수의 주소는 0x8048464 이다.
함수 포인터를 조작하여 winner()함수가 실행되었다.
'시스템 해킹 > Technique' 카테고리의 다른 글
[Heap] Double Free Bug (0) | 2020.01.20 |
---|---|
[Heap] Use After Free (0) | 2020.01.20 |
SEH Overwrite 기법 (0) | 2020.01.15 |
구조적 예외 처리 SEH (Structured Exception Handler) (0) | 2020.01.15 |
윈도우 실행 파일 구조 (0) | 2020.01.13 |