[0]

double-free는 동일한 heap 메모리 공간에 대해 메모리 해제(free)를 2번 시도하여 발생하는 취약점이다. 메모리 해제는 코드 상의 여러 곳에 분포되어 있는 경우가 많아, 디버깅이 굉장히 어렵다(리눅스 커널에서도 double-free가 종종 발견된다.) 언뜻 생각하기로, 메모리 해제는 몇번을 해도 문제가 되지 않을 것 같다. 하지만 이는 심각한 취약점이 발생하게 되는데, 이를 이해하기 위해선 heap 메모리의 할당/해제에 대한 이해가 필요하다.

 

[1]

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;
};

[2]

위의 chunk 자료구조에서 double-free에 대해 중요한 자료구조는 fd와 bk이다. 이 포인터들은 이름에서 유추할 수 있듯이, 더블 링크드리스트에 사용되는데, 이 리스트는 bin이라고 하는 free된 chunk들을 모아놓은 리스트이다. 어떤 메모리 chunk가 해제되게 되면, bin에 추가되어 다음에 같은 사이즈의 할당이 될 경우 빠르게 재할당할 수 있도록 한다. 즉 [2]에서 free(ptr)이 될 경우 해당 chunk가 bin 리스트에 추가된다. 그런데 만약 free(ptr)이 한 번 더 이루어진다면? 

 

[3]

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 리스트를 조작할 수가 있고, 이를 이용해 공격자가 원하는 메모리 공간을 할당하도록 강제할 수도 있다.

 

 

[참고]

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

 

[glibc] 동적 메모리 관리 (1)

glibc: 2.10.1arch: x86이번에는 GNU C library (이하 glibc)에서 동적 메모리를 관리하는 방식에 대해서 살펴볼 것이다.(여기서 설명하는 내용은 32비트 머신 환경에 해당하며 64비트 환경의 경우 차이가 있을 수 있다.)glibc 내에 포함된 동적 메모리 할당자 (malloc) 모듈은Doug Lea가 최초로 작성한 구현(이름의

egloos.zum.com

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

 

Double Free Bug(DFB)

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

nroses-taek.tistory.com

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

 

Heap Exploitation

This book on heap exploitation is a guide to understanding the internals of glibc's heap. It also describes, in detail, various attacks possible on the heap structure.

heap-exploitation.dhavalkapil.com

 

'Computer Science > Security' 카테고리의 다른 글

Confidential Computing이란  (0) 2020.03.24
Memory safety - 3  (0) 2019.12.02
Memory Safety - 2  (0) 2019.11.12
Memory Safety - 1  (0) 2019.10.30

+ Recent posts