본문 바로가기
UnrealEngine5/C++

double-free 취약점 재정리(미완, 검토 필요)

by 개발의 묘미(GaeMyo) 2025. 8. 24.
SMALL

double-free는 동일한 heap 메모리 공간에 대해 free(메모리 해제)를 2번 시도하여 발생하는 취약점.

당연히 메모리 해제는 코드 상의 여러 곳에 분포되어 있는 경우가 많으니

디버깅이 굉장히 어려움.

 

여기서 메모리 해제를 여러 번 하면 왜 문제가 생기는가에 대해

이해하기 위해서는 heap메모리의 할당과 해제에 대한 이해가 필요함.

 

void* Ptr = malloc(10);
free(Ptr);

 

여기서 Ptr이 가리키는 메모리 공간을 해제하려고 하는데

메모리 해제 시점에서 Ptr이 가리키는 메모리 공간이 정확히 10바이트라는걸 어떻게 알 수 있을까?

 

Ptr은 주소값만을 가지고 있을 뿐이니 해당 주소에서의 메모리 크기는 알 수가 없다.

그래서 이에 대한 정보를 표시하기 위해 heap메모리가 할당될 때마다

chunk라고 하는 메타데이터 영역도 생성하여 할당한다.

따라서 위의 메모리 할당에서는 실제로 10바이트가 아닌,

chunk가 포함된 더 큰 메모리가 할당됨.

 

chunk의 메타데이터 정보는 아래와 같음.

struct malloc_chunk {
  INTERNAL_SIZE_T      prev_size;  /* Size of previous chunk (if free).  */
  INTERNAL_SIZE_T      size;       /* Size in bytes, including overhead. */

  struct malloc_chunk* fd;         /* double links -- used only if free. */
  struct malloc_chunk* bk;

  /* Only used for large blocks: pointer to next larger size.  */
  struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */
  struct malloc_chunk* bk_nextsize;
};

 

위의 chunk 자료구조에서 double-free에 대해 중요한 자료구조는 fd와 bk임.

// 2025-08-24/17:06 마크

이 포인터들은 이름에서 유추할 수 있듯이, 더블 링크드리스트에 사용되는데

이 리스트는 bin이라고 하는 free된 chunk들을 모아놓은 리스트임.

어떤 메모리 chunk가 해제되게 되면, bin에 추가되어 다음에 같은 사이즈의 할당이 될 경우

빠르게 재할당 할 수 있도록 함.

 

따라서 맨 위에서의 free(Ptr)이 될 경우, 해당 chunk가 bin 리스트에 추가됨.

여기서 만약 free(Ptr)이 한 번 더 실행된다면?

 

void * a = malloc(10);
void * b = malloc(10);

free(a);
free(b);
free(a);		//double free!

void * c = malloc(10);
void * d = malloc(10);
void * e = malooc(10);	//same as c

 

위 코드에서 a와 b가 할당되고, a,b,a순으로 free되었으므로 bin 리스트에는 a->b->a 순서가 된다.

즉 a는 하나의 메모리 chunk이지만 bin 리스트에서는 두 개의 chunk로 인식되어 버리는 것이다!

따라서 이 후 c,d,e 순으로 같은 크기의 10바이트 메모리 할당을 요청하게 되면, a, b, a를 각각 할당 받게 된다.

따라서 c와 e가 의도와 다르게 같은 메모리 공간을 점유하게 되어 버그가 발생한다.

만약 공격자가 c나 e중 하나를 컨트롤 할 수 있다면 핵심 데이터를 유출하거나(information leak),

함수 포인터 등을 덮어씌워서 공격자가 의도한 코드를 실행할 수 도 있다.(code execution)

 

그런데 double-free의 문제는 여기서 그치지 않는다.

위 코드에서 c,d까지만 할당되었다고 생각해보자.

그럼 c,d는 각각 이전의 a,b가 사용한 메모리 영역이 할당되었을 것이고,

bin 리스트에는 아직 a가 하나 남아 있게 된다.

만약 공격자가 c를 컨트롤할 수 있고, 런타임에 overflow체크가 되지 않는다면,

공격자는 overflow를 통해 a의 chunk 메타데이터를 조작할 수 있다.

즉 fd와 bk를 덮어씌워서 bin 리스트를 조작할 수가 있고,

이를 이용해 공격자가 원하는 메모리 공간을 할당하도록 강제할 수도 있다.

 

 

 

참고자료.

 

https://heap-exploitation.dhavalkapil.com/attacks/double_free.html

 

Double Free | heap-exploitation

'malloc' request for 'd'. head -> b -> a -> tail [ 'a' is returned ]

heap-exploitation.dhavalkapil.com

https://nroses-taek.tistory.com/161

 

Double Free Bug(DFB)

UAF 처럼 DFB도 말 그대로 2번 Free해서 나타나는 취약점입니다. 간단한 예시 0x20만큼 메모리를 세 번 할당했습니다. 하지만 주소에서 볼 수 있듯이 0x30만큼 차이가 납니다. 요청한 사이즈보다 크게

nroses-taek.tistory.com

http://egloos.zum.com/studyfoss/v/5206220

 
반응형
SMALL

'UnrealEngine5 > C++' 카테고리의 다른 글

TWeakPtr<T> 재정리  (0) 2025.08.24
TUniquePtr 재정리  (0) 2025.08.24
TWeakObjectPtr<T> 재정리  (0) 2025.08.24
TObjectPtr<T> 재정리  (0) 2025.08.24
TSharedRef<T> 재정리  (0) 2025.08.24
TSharedPtr<T> 재정리  (3) 2025.08.24
FName && FString && FText  (1) 2025.08.18
IsValid(), == nullptr, check의 차이  (0) 2025.08.18