UAF (Use After Free)
1. UAF ?
1. UAF
UAF (Use After Free)는 해제된 메모리에 접근할 수 있을 때 발생하는 취약점을 말한다
malloc 과 free 함수는 메모리의 데이터를 초기화 하지 않는다
그래서 새롭게 할당한 청크를 명시적으로 초기화 하지 않으면 메모리에 남아있던 데이터가 유출되거나 사용될 수 있다
2. 발생 조건
- 메모리 참조에 사용한 포인터를 메모리 해제 후에 적절히 초기화 하지 않는 경우
- 해제한 메모리를 초기화 하지 않고 다음 청크에 재할당 하는 경우
3. Dangling pointer
Dangling 포인터는 유효하지 않은 메모리 영역을 가리키는 포인터를 말한다
메모리를 동적 할당할 때는 포인터를 선언하고 그 포인터에 malloc 함수가 할당한 메모리의 주소를 저장한다
그리고 그 포인터를 잠조하여 할당한 메모리에 접근한다
free 함수는 청크를 ptmalloc 에 반환하기만 하고 청크의 주소를 담고 있던 포인터를 초기화 하진 않는다
→ free 호출 이후 포인터를 초기화 하지 않으면 포인터는 해제된 청크를 가리키는 Dangling pointer 가 된다
// Name: dangling_ptr.c
// Compile: gcc -o dangling dangling.c
#include <stdio.h>
#include <stdlib.h>
int main() {
char *ptr = NULL;
int idx;
while (1) {
printf("> ");
scanf("%d", &idx);
switch (idx) {
case 1:
if (ptr) {
printf("Already allocated\\n");
break;
}
ptr = malloc(256);
break;
case 2:
if (!ptr) {
printf("Empty\\n");
}
free(ptr);
break;
default:
break;
}
}
}
위의 코드를 컴파일 하고 실행해보자
청크를 해제한 뒤 청크를 가리키던 ptr 변수를 초기화 하지 않는다
확인해보면
ptr 은 이전에 할당한 청크의 주소를 가리키는 Dangling pointer 가 된다
ptr 이 해제된 청크의 주소를 가리키고 있기 때문에 한번 더 해제할 수 있다
→ 이를 Double Free Bug 라고 한다
2. 예제 코드
// Name: uaf.c
// Compile: gcc -o uaf uaf.c -no-pie
#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();
}
}
코드를 컴파일 한 뒤 실행해보면
입력한 적이 없는 Name 과 Nametag function 이 출력된다
1. 동적 분석
secret 이 free 된 이후의 heap 을 살펴보자
secret 은 fee 로 해제되었기 때문에 free chunk 에 해당한다
heap 영역을 확인해보면 size 0x41 다음 16 byte 가 fd 와 bk 로 덮어씌워진 것을 볼 수 있다
하지만 secret_info 의 값과 code 의 값은 남아있는 것을 확인할 수 있다
name_tag 에 메모리를 할당하고 출력하기 전에 heap 영역을 확인해보자
name_tag 의 team_name 에는 값이 잘 들어간 것을 볼 수 있다
하지만 name_tag 의 name 과 func 부분에는 이전 값인 secret_info 와 code 가 남아있게 된다
name_tag 의 name 을 확인해보면 남아있던 secret_info 의 값에 덮어씌워진 것을 볼 수 있다
위와 같이 초기화 되지 않은 메모리의 값을 읽어내거나 새로운 객체가 악의적인 값을 사용하도록 유도하여
프로그램의 정상적인 실행을 방해할 수 있다
'Hacking > Pwnable' 카테고리의 다른 글
Tcache dup (0) | 2025.05.20 |
---|---|
DFB(Double Free Bug) (0) | 2025.05.19 |
Heap - ptmalloc2 (glibc) (0) | 2025.04.03 |
Stack Pivoting (0) | 2025.04.02 |
SROP (x64) (0) | 2025.03.26 |