The heap 2.
힙 오버플로우를 이용하는 방법.
일단 버퍼 오버플로우는 C or C++ 컴파일러가 배열의 경계 검사를 하지 않아 선언된 크기보다 더 큰 데이터를 기록함으로써 발생되는 현상.
운영체제가 스택 or 힙 영역에 임의의 데이터 기록 및 실행을 허용함으로써 발생되는 현상.
Heap buffer overflow?
힙 데이터 영역에서 일어나는 버퍼 오버플로우를 힙 오버플로우라 부르며, 스택 기반 오버플로우와는 다른 방법으로 볼 수 있다.
이 데이터를 특정한 방법으로 오염시켜 응용 프로그램이 연결 리스트 포인터 등과 같은 내부 자료 구조를 덮어쓰게 한다.
기본적인 힙 오버플로우 기술은 동적 메모리 할당 연결(malloc() 상위 수준 데이터)를 덮어씀으로써 프로그램 함수 포인터를 조작한다.
주로 root 소유의 setuid 프로그램이나 힙 영역 or bss에 할당된 인접한 버퍼를 사용한다.
인접한 주소에 할당된 낮은 주소에 위치한 버퍼를 오버플로우 시켜서 데이터나 포인터를 변경함으로써 임의의 파일에
접근하거나 임의의 코드를 실행한다.
Ex)
아래는 heap overflow한 C 코드다.
Ex)
nowinner의 함수가 default로 실행되는데 winner로 eip를 넘겨줘서 system("cat flag")를 실행시켜본다.
버퍼가 64개라고 더미 값을 64개 넣는 것이 아니라 name이 힙에 할당되었을 때의 esp의 위치와 fp()가 할당되었을 때의
esp의 위치를 파악하여 dummy가 들어갈 공간을 파악해야 된다.
호출되어서 할당되는 시점은 fp는 main+35(f ==>fp)다. data[]는 main+73(d=>name).
data[]의 시작 위치 ==> 0x804b008
fp()의 시작 위치 ==> 0x804b050
즉 0x804b050 - 0x804b008 = 72. 즉 더미의 크기는 72만큼 넣으면 된다.
주소를 확인하면 winner() ==> 0x080484db
다시 천천히 정리해보자.
힙 버퍼 오버플로우는 힙 영역에 할당된 버퍼의 크기를 초과하는 데이터를 기록하거나, 저장된 데이터 및 함수의 주소를
변경함으로써 임의의 코드를 실행한다. 특징적인 것은 벗어난 데이터는 인접 메모리를 덮어 쓰게 되는데 다른 데이터가
포함되어 있을 경우, 데이터의 손실 or 치명적인 오류를 발생할 수 있다.
공격 기법은 Heap Offset을 이용한 방법과 Argv[]를 이용한 방법이 있다.
해결 방법은 Return 주소 앞에 특정한 값을 삽입하고 이 값의 변경 여부를 확인하여 BOF 발생을 확인한다.
아니면 운영체제 커널 패치를 하거나 안전한 라이브러리 함수 사용을 한다.
'#Tip' 카테고리의 다른 글
Arena. (0) | 2018.04.07 |
---|---|
Process & Thread. (0) | 2018.04.07 |
The heap. (0) | 2018.04.07 |
PLT and GOT (0) | 2018.04.06 |
Function Prologue & Epilogue. (0) | 2018.04.06 |