System Hacking

Use-After-Free (UAF)

jir4vvit 2021. 1. 6. 18:06

예전에 봤는데.. 까먹은 것 같아서 정리해보려고 한다.


참고 : dreamhack.io
환경 : ubuntu 16.04.7

 

동적 메모리 관리에서 가장 자주 발생하는 문제는 해제된 메모리를 정확히 관리하지 않아 발생하는 문제이다.

 

Use-After-Free (UAF)

해제된 메모리에 접근해서 값을 쓸 수 있는 취약점이다. 

 

 

// uaf1.c
#include <stdio.h>
#include <string.h>
#include <malloc.h>
int main(void) {
    char *a = (char *)malloc(100);
    memset(a, 0, 100);
    
    strcpy(a, "Hello World!");
    printf("%s\n", a);
    free(a);
    
    char *b = (char *)malloc(100); 
    strcpy(b, "Hello Pwnable!");
    printf("%s\n", b);
    
    strcpy(a, "Hello World!");
    printf("%s\n", b);
}

100바이트 크기의 메모리 a를 동적할당한 후 "Hello World!" 문자열을 복사한다.

 

그 다음 free(a), 즉 메모리 a를 해제한다.

참고로 이미 해제된 영역을 여전히 가리키는 포인터를 Dangling Pointer라고 부르는데,  여기선 포인터 a가 될 수 있겠다.

 

그리고 새로운 100바이트 크기의 메모리 b를 동적할당한 후 "Hello Pwnable!" 문자열을 복사한다.

 

 

이때, 포인터 a에 저장된 메모리 주소값은 바뀌지 않는다.

그리고 메모리 a와 메모리 b는 같은 주소를 가리키고 있다. 

 

메모리 효율적으로 쓰기 위해.. 그렇다고 한다.

 

여기서 이제 해제된 메모리 a에 접근하면 의도치 않은 일이 발생할 수도 있다. 

 

 

마지막에 "Hello World!" 문자열을 다시 복사하는데, 해제된 메모리 포인터인 a에 복사하게 된다. 

이미 해제된 포인터 a와 새로이 할당한 포인터 b가 같은 메모리 영역을 가리키고 있기 때문에, 포인터 a에 "Hello World!" 문자열을 복사하고

 

포인터 b의 내용을 출력하면 "Hello World!" 문자열이 출력된다.

 

 

 

음.. 한마디로 UAF는 dangling pointer를 재사용함으로써 발생하는 것이다.

 

dangling pointer

How to exploit

free한 후 (방금 free한 메모리와 비슷한 크기로) malloc을 해주면 거의 동일한 메모리에 위치하게 된다.

이것을 이용하면 된다.