1. Introduction
ptmalloc2를 이용해 메모리를 할당 혹은 해제를 한다.
하지만, 메모리에는 할당 또는 해제의 흔적들이 남아 있을 수 있다.
Use-After-Free(UAF)는
메모리 참조에 사용한 포인터를 메모리 해제 후에 적절히 초기화 하지않아서, 혹은 해제한 메모리를 초기화하지 않고 다음 청크에 재할당해주면서 발생하는 취약점이다.
2. Use After Free
2.1 Dangling Pointer
컴퓨터 과학에서, Dangling Pointer는 유효하지 않은 메모리 영역을 가리키는 포인터를 말한다.
메모리의 동적 할당에 사용되는 malloc 함수는 할당한 메모리의 주소를 반환한다.
일반적으로, 메모리를 동적 할당할 때는 포인터를 선언하고, 그 포인터에 malloc 함수가 할당한 메모리의 주소를 저장한다.
그 후 그 포인터를 참조하여 할당한 메모리에 접근한다.
메모리를 해제할 때는 free 함수를 호출한다.
그런데 free 함수는 청크를 ptmalloc에 반환하기만 하고, 청크의 주소를 담고 있던 포인터는 초기화 하지 않는다.
따라서 free의 호출 이후에 프로그래머가 포인터를 초기화하지 않으면, 포인터는 해제된 청크를 가리키는 Dangling Pointer가 된다.
Dangling Pointer가 생긴다고 해서 보안적으로 취약하진 않다.
하지만, Dangling Pointer는 프로그램이 예상치 못한 이슈를 발생시킬 수 있고, 공격자에게 공격 수단으로 활용될 수 있다.
2.2 Use After Free
UAF는 문자 그대로, 해제된 메모리에 접근할 수 있을 때 발생하는 취약점이다.
malloc과 free 함수는 할당 또는 해제할 메모리의 데이터들을 초기화하지 않는다.
그래서 새롭게 할당한 청크를 프로그래머가 명시적으로 초기화하지 않으면, 메모리에 남아있던 데이터가 유출되거나 사용될 수 있다.
2.2.1 PoC
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct NameTag {
char team_name[16];
char name[32];
void (*func)();
};
struct Secret {
char secret_name[16];
char secret_info[32];
long code;
};
int main() {
int idx;
struct NameTag *nametag;
struct Secret *secret;
secret = malloc(sizeof(struct Secret));
strcpy(secret->secret_name, "ADMIN PASSWORD");
strcpy(secret->secret_info, "P@ssw0rd!@#");
secret->code = 0x1337;
free(secret);
secret = NULL;
nametag = malloc(sizeof(struct NameTag));
strcpy(nametag->team_name, "security team");
memcpy(nametag->name, "S", 1);
printf("Team Name: %s\n", nametag->team_name);
printf("Name: %s\n", nametag->name);
if (nametag->func) {
printf("Nametag function: %p\n", nametag->func);
nametag->func();
}
}
2.2.2 실행
0x1337이 출력(secret에서 입력한 값)
2.2.3 설명
2.2.4 동적 분석
1. secret 해제
heap 명령어를 통해, secret 해제된 청크의 부분을 보자
secret 해제 전
secret 해제 후
해제 전, 후를 비교해 보면, fd와 bk의 값들은 (0x4052a0 부분) 값이 변경됨을 알 수 있다.
하지만 secret_info(0x4052b0)의 값은 그대로 남아 있다.
printf를 호출하는 부분에 breakpoint를 걸면, 어떤 값들이 할당되었는지 확인이 가능하다.
이렇게, 동적 할당한 청크를 해제한 뒤에는 해제된 메모리 영역의 이전 객체의 데이터가 남는 것을 알 수 있었다.
이런 특징을 공격자가 이용한다면 초기화되지 않은 메모리의 값을 읽어내거나, 새로운 객체가 악의적인 값을 사용하게 유도하여 프로그램의 정상적인 실행을 방해할 수 있다.
마치며
Dangling Pointer: 해제된 메모리를 가리키고 있는 포인터. UAF가 발생하는 원인이 될 수 있음.
Use-After-Free (UAF): 해제된 메모리에 접근할 수 있을 때 발생하는 취약점
Reference