본문 바로가기

취약점 분석/힙(Heap)

힙 손상 탐지(2-2) - 힙 오버런, 언더런 (Full PageHeap)

반응형

힙 손상 탐지(2-2) - 힙 오버런, 언더런 (Full PageHeap)

힙 손상 탐지(2-1) - 힙 오버런, 언더런 (Normal PageHeap) 를 먼저 읽고 보자.


gflags를 이용한 풀 페이지힙 적용 방법

gflags.exe /p /enable <프로그램> /full

/p : 페이지 힙

/enable : 특정 옵션을 킴

/full : 풀 옵션으로~!




[ 풀 페이지 힙 - 할당 ]

[시나리오]

1) 0x30 크기만큼의 힙을 할당 / 해제.

2) Full PageHeap 적용 후 windbg에서 분석


1) 0x30 크기의 힙을 요청에 성공하고

2) EAX에 유저 영역 시작 주소를 반환 받았다.


명령어 : !address <조사를 원하는 주소>

할당받은 0x30크기의 힙을 !address로 봤더니 Heap이 아닌 PageHeap으로 뜨는 것을 볼 수 있다.


구조는 Normal PageHeap과 크게 다르지 않다. 다만 접근불가영역이 추가 되었다. (?????로 표시되는 부분이다!)

구조 : 보호계층 / 유저 사용 영역 / 후위 채움 패턴 / 접근 불가 영역

0x30크기를 할당한 지금은 유저사용영역 뒤에 후위 채움 패턴이 존재하지 않는데, 정확하진 않지만 작은 크기의 힙 할당 시에는 단순히 접근 불가 영역만으로 대체 하는 듯하다.


1500bytes 할당 했을 때에는 뒤에 후위 채움 패턴이 위치한다.


Normal PageHeap에서는 PageHeap이 아닌 일반 Heap이었다. 따라서 맨 앞 8bytes에 일반 힙 엔트리 메타데이터가 존재했는데, Full PageHeap에서는 따로 일반 힙 엔트리 메타데이터는 존재하지 않는다.


 Normal PageHeap과 마찬가지로 아래 명령어로 페이지힙 보호계층 구조를 볼 수 있다.

역시나 주목할 부분은 메모리 할당 과정을 다 담는 StackTrace 부분이다.

명령어 : dt _DPH_BLOCK_INFORMATION <페이지힙 메타데이터 시작주소>


명령어 : dds <스택 트레이스 주소>

힙 할당까지의 모든 스택 트레이스를 담고있다. 심볼이 있다면 상당히 유추하기 쉬워진다.


구조를 정리하자.


풀 페이지 힙의 할당 시 구조는 위 그림과 같다.

노멀 페이지 힙과 비교했을 때 일단 채움 패턴의 내용이 다르다. 나머지는 아래 표로 정리함.

노멀 페이지 힙 

 풀 페이지 힙

 일반 힙 메타데이터 8bytes

: 존재

 X

 후위 채움 패턴 8bytes

 후위 채움 패턴 4bytes

 (크기가 작을 땐 없기도)

 X

 접근 불가 페이지

: 존재




[ 풀 페이지 힙 - 힙 오버런 탐지 ]


[시나리오]

1) 0x14 크기의 힙 할당

2) "ohl_world_is_my_world" 유니코드 문자열 복사

3) 10글자를 넘어가면 후위 채움 패턴덮어씀

4) 12글자를 넘어가면 접근 불가 영역도달

5) 접근 불가 영역에 쓰려고 하는 그 순간 바로 Access Violation 발생


0x14 만큼의 풀페이지 힙을 할당하였다.

[풀 페이지 힙 구조]


 사용자 영역 앞의 보호 계층

 사용자 영역

 사용자 영역 뒤의 후위 채움 패턴

 접근 불가 영역


문자열을 힙에 복사하는 도중, 후위 채움 패턴은 덮어쓰였지만 접근 불가 영역에 접근을 시도하는 그 순간에 바로 잡아버림.


du 명령어로 문자열로 다시 확인해 보면, 접근 불가 영역이라 덮어쓰이지 않은 모습이다.




[ 풀 페이지 힙 - 해제 ]

Free를 했더니 유저 사용 영역은 물론이거니와, 풀 페이지 힙의 메타데이터가지 전부 접근 불가 영역이 된다.

접근 불가 영역에 접근하면 바로 Access Violation 발생!



[노말 페이지 힙과 비교]

 

 노말 페이지 힙

 풀 페이지 힙

 앞 뒤로 보호계층 추가됨?

 O

 O

 추가 접근 불가 영역 존재?

 X

 O

 오류 발생 시점

 쓰인 후 나중에 잡긴 하지만, 페이지 힙 메타데이터에 쓰인 스택 트레이스를 이용하여 할당 루틴 추적이 가능하므로

 나름대로 수월하게 분석 가능.

 접근 불가 영역에 접근 하는 그 순간에 바로 잡아버림. 실제로 버퍼 오버플로우 문제가 발생하는 순간에서 잡히므로 분석이 훨씬 수월. 


그렇다면 무조건 풀 페이지 힙이 더 좋은 거 아닌가?

풀 페이지 힙의 단점은 자원을 많이 잡아먹는 다는 점.

따라서 처음에는 풀 페이지 힙으로 동작 시켜보고 너무 느리거나 쓰지 못하겠다 싶으면 노말 페이지 힙으로 분석하면 됨.

반응형