본문 바로가기

취약점 분석/힙(Heap)

힙 손상 탐지(1) - 초기화 안 된 상태로 사용

반응형

힙 손상 탐지(1) - 초기화 안 된 상태로 사용


공간을 할당했으면 초기화를 하고 사용해야함.

포인터 변수를 다뤄봤다면 알겠지만, 뭐가 들었을 지 알고 초기화도 안하고 사용하나?!


1) 할당만 받고 초기화 하지 않은 채 사용한다면 문제가 발생할 수 있으므로 잡아야한다.

2) Free 한 이후에도 사용하는 것은 문제를 야기할 수 있고 정상적인 사용방법이 아니다.

  • 스택은 문제를 야기하는 원인 근처에서 크래시가 발생하므로 추적이 쉬움.
  • 힙 문제는 원인과 결과가 한참 차이나는 경우가 많음 (변조는 이미 되었으나 오류 발생은 실제 사용 시점에서 발생하므로)
  • Crash 시점부터 백트레이스는 너무 많은 비용 소모, 힙 손상이 발생 시점에 트랩하자.

대안

: 디버깅 하에서 실행 시 채움 패턴 사용.

(디버거 하에서 프로세스를 시작한다면 분석을 한다고 간주. 이 때 힙 관리자로 하여금 어느 정도의 보호를 제공하는 채움패턴을 사용하도록 함.)


채움 패턴이란?

힙 메모리를 할당만 받은 경우와(초기화 전) Free 이후 / 힙 메타데이터를 제외한 사용자 영역을 특정 값으로 채움.

(패턴은 힙 블록의 상태에 따라 다르게)


- 할당만 받은 상태 : baadf00d 로 쭉 채워짐


- Free한 상태 : feeefeee 로 쭉 채워짐


채움 패턴을 사용하는 이유는?

비정상적 상황임을 인지할 수 있도록 특정 값들로 쭉 채운 후 값이 바뀐다면 비정상적 사용으로 판단할 수 있음.

값이 변조된다면 비정상적인 사용임돠 하면서 알려줌.


어떤 경우가 있을까?

메모리 할당을 비롯한 각가지 함수들은 in-out 인자 혹은 결과 eax로 성공/실패 여부를 항상 반환한다.

이 성공/실패 여부를 확인하는 루틴이 있어야하는데, 잘 돌아가는지만 확인하고 체크루틴을 빼먹는 경우가 종종 있다.

예를 들어보자.


scanf(문자열 입력 받음)

문자열 크기 측정

HeapAlloc // 힙 할당.

if( 반환 값이 NULL이 아니라면)

{

Init // 힙 초기화

사용 (문자열 복사 후 변조 등등)

Free //힙 해제

}

힙 할당 됐는지 확인도 했고, 초기화 안하고 쓰면 안된대서 초기화도 했다. 사용 후에 해제까지 해줬다.

여기서 문제가 뭘까?


초기화 루틴이 항상 정상적으로 완료된다고 장담할 수 있나?

초기화 루틴이 실패했을 경우에도 검사 루틴이 없으므로 다음 명령을 수행할텐데 문제 없을 거라 장담할 수 있나?


즤야~


반응형