일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- h4ckinggame
- 뮤텍스
- 프로그래머스
- 정보기
- 디포전 2급
- BoB 12기 최종합격 후기
- Active Directory
- BoB 12기
- cve-2024-6387
- DLL 사이드로딩
- CodeEngn
- race condition
- 리버싱
- cve-2022-26923
- 디지털 포렌식 트랙
- 디지털 포렌식 전문가 2급
- 정보보안기사
- malware
- 필기
- 논문리뷰
- bob
- 코드엔진
- 세마포어
- dll side-loading
- Best of the Best
- 디포전
- Today
- Total
SEO
[heap exploit] Use-After-Free (UAF) 취약점 본문
Use-After-Free(UAF) 취약점 개념 정리
Use-After-Free(UAF)는 프로그램이 메모리에서 해제된 객체를 참조하려고 시도할 때 발생하는 심각한 메모리 취약점 중 하나입니다. 이 문제는 메모리 관리 오류에서 비롯되며, 주로 C와 같은 수동 메모리 관리 언어에서 발생합니다. UAF 취약점은 악의적인 공격자가 이를 악용해 임의 코드를 실행하거나 시스템을 손상시킬 수 있는 가능성을 제공합니다.
UAF 취약점의 동작 원리
UAF 취약점은 일반적으로 다음 단계를 통해 발생합니다:
- 메모리 할당: 프로그램이 객체를 생성하고 메모리를 할당합니다.
- 메모리 해제: 해당 객체가 더 이상 필요하지 않을 때 메모리를 해제합니다.
- 해제된 메모리 접근: 해제된 메모리 주소를 여전히 참조하거나 사용하려는 시도가 발생합니다.
#include <iostream>
#include <cstdlib>
class Example {
public:
void sayHello() { std::cout << "Hello, world!" << std::endl; }
};
int main() {
Example* obj = new Example(); // 메모리 할당
delete obj; // 메모리 해제
obj->sayHello(); // 해제된 메모리 접근
return 0;
}
위 코드에서 obj는 메모리에서 해제되었지만, sayHello() 메서드를 호출하려고 시도합니다. 이로 인해 정의되지 않은 동작이 발생하며, 공격자가 이를 악용할 수 있습니다.
UAF 취약점의 주요 원인
- 부적절한 메모리 관리: 메모리를 올바르게 해제하지 않거나, 해제 후 참조를 제거하지 않는 경우
- 다중 스레드 환경: 한 스레드가 메모리를 해제하는 동안 다른 스레드가 여전히 해당 메모리를 사용하려는 경우
- 복잡한 객체 참조 구조: 객체 간의 순환 참조나 다중 참조로 인해 메모리 해제가 복잡해질 때
공격자가 UAF를 악용하는 방법
공격자는 다음과 같은 방식으로 UAF 취약점을 악용할 수 있습니다.
- 코드 실행: 해제된 메모리 영역을 재할당하고, 해당 영역에 악성 코드를 주입하여 프로그램 흐름을 제어합니다. 예를 들어, 공격자는 해제된 메모리 공간에 쉘코드(shellcode)를 삽입하여 이를 실행할 수 있습니다. 프로그램이 해제된 메모리를 참조하면 공격자의 코드가 실행됩니다.
- 정보 유출: 해제된 메모리에 저장된 민감한 정보를 읽어냅니다.
- 프로그램 충돌: 프로그램을 의도적으로 충돌시켜 서비스 거부(DoS) 상태를 유발합니다.
ptmalloc2의 동작 원리
ptmalloc2는 GNU C 라이브러리(glibc)에서 사용하는 동적 메모리 할당기입니다. 이 메모리 할당기는 효율성과 확장성을 고려하여 설계되었으며, 멀티스레드 환경에서도 동작할 수 있도록 최적화되어 있습니다. ptmalloc2의 주요 동작 원리는 다음과 같습니다.
- Arena 기반 메모리 관리: ptmalloc2는 다중 스레드 환경에서 경쟁 조건을 줄이기 위해 독립적인 메모리 할당 영역(Arena)을 사용합니다. 각 Arena는 스레드별로 분리되며, 병렬 처리를 지원합니다.
- Free List 관리: 메모리를 해제하면, 해당 메모리 블록은 Free List에 추가됩니다. Free List는 재사용 가능한 메모리 블록들의 목록으로, 이후의 메모리 할당 요청에 활용됩니다.
- Chunk 구조: 메모리 블록은 Chunk라는 구조로 관리되며, 각 Chunk는 크기와 상태(사용 중인지, 해제되었는지)에 대한 메타데이터를 포함합니다.
- Consolidation: 인접한 Free Chunk는 합쳐져 더 큰 Chunk로 통합될 수 있습니다. 이를 통해 메모리 단편화를 줄이고 할당 효율성을 높입니다.
ptmalloc2 관련 주요 개념
- Chunk
- ptmalloc2는 메모리를 Chunk 단위로 관리합니다.
- 각각의 Chunk는 사용 가능한 메모리 블록과 Chunk 메타데이터로 구성됩니다.
- 사용 블록: 사용자가 요청한 데이터가 저장되는 부분.
- 메타데이터: Chunk의 크기, 상태(할당 여부), 이전/다음 Chunk와의 관계 정보를 포함.
- Bin
- 크기가 유사한 Chunk를 효율적으로 관리하기 위해 ptmalloc2는 Bin이라는 데이터 구조를 사용합니다.
- Bin은 Chunk를 크기에 따라 분류하며, 다음과 같은 종류가 있습니다:
- Fast Bins: 매우 작은 크기의 Chunk를 빠르게 할당/해제.
- Small Bins: 중간 크기의 Chunk 관리.
- Large Bins: 큰 크기의 Chunk 관리.
- Unsorted Bin: 해제된 Chunk가 정리되기 전에 임시 저장.
- Thread Cache (Tcache)
- 멀티스레드 환경에서의 성능을 개선하기 위해 glibc 2.26 이후에는 Tcache가 도입되었습니다.
- Tcache는 스레드별로 독립적인 Chunk 목록을 유지하여, 잠금(lock) 없이 빠르게 메모리를 재사용할 수 있게 합니다.
- Memory Arena
- ptmalloc2는 멀티스레드 환경에서 병목 현상을 줄이기 위해 Arena라는 독립적인 메모리 공간을 사용합니다.
- 각 Arena는 독립적으로 관리되며, 기본적으로 메인 Arena(싱글스레드 전용)와 서브 Arena(멀티스레드 전용)가 존재합니다.
ptmalloc2와 UAF 취약점의 관련성
ptmalloc2의 동작 방식은 UAF 취약점과 밀접한 관련이 있습니다. 해제된 메모리 블록(Free Chunk)은 Free List에 보관되며, 재할당될 때까지 유지됩니다. 공격자는 이를 악용하여 다음과 같은 방식으로 UAF 취약점을 활용할 수 있습니다:
- Use-After-Free와 Free List 오염: 공격자는 해제된 메모리 블록에 악성 데이터를 삽입하거나 Free List의 포인터를 조작하여 임의의 메모리 주소를 참조하게 만듭니다. 이를 통해 메모리 손상을 유발하거나 임의 코드를 실행할 수 있습니다.
- Fake Chunk 생성: 공격자는 메모리 할당 요청이 이루어질 때, 공격에 필요한 Fake Chunk를 설정하여 해당 Chunk를 재활용하게 유도할 수 있습니다.
- Heap Spraying 기법: 공격자는 대량의 데이터를 할당하여 메모리 공간을 예측 가능한 상태로 조작합니다. 이후, UAF를 통해 해당 메모리 영역을 악용할 수 있습니다.
Dangling Pointer란?
Dangling Pointer는 해제된 메모리 공간을 참조하는 포인터를 의미합니다. 이는 메모리 관리가 잘못된 경우에 발생하며, 프로그램의 동작이 예기치 못한 결과를 초래할 수 있습니다.
Dangling Pointer가 발생하는 시나리오
1. 메모리 해제 후 참조
메모리를 free() 또는 delete로 해제한 뒤에도 포인터가 해당 메모리 위치를 가리키고 있을 때 발생합니다.
int* ptr = (int*)malloc(sizeof(int));
free(ptr);
*ptr = 10; // Dangling Pointer 사용
2. 범위를 벗어난 객체 접근
지역 변수가 함수 종료 후에도 참조될 경우, 해당 메모리는 더 이상 유효하지 않지만 포인터는 이를 참조할 수 있습니다.
int* danglingPointer() {
int localVar = 42;
return &localVar; // 함수 종료 후 localVar는 무효
}
3. Double-Free
동일한 메모리를 두 번 해제하는 경우에도 Dangling Pointer가 발생할 수 있습니다.
int* ptr = (int*)malloc(sizeof(int));
free(ptr);
free(ptr); // Double-Free로 인한 Dangling Pointer
Dangling Pointer와 UAF의 연관성
Dangling Pointer는 UAF 취약점의 핵심적인 원인입니다. 해제된 메모리를 참조하는 포인터가 남아 있는 상태에서 공격자가 이를 악용하면, 메모리를 재할당하거나 악성 데이터를 주입해 프로그램의 동작을 조작할 수 있습니다.
- UAF 취약점 발생 메커니즘
- Dangling Pointer로 인해 해제된 메모리에 접근하면, 정의되지 않은 동작이 발생합니다.
- 공격자는 이를 이용해 해제된 메모리를 덮어쓰고 악성 코드를 삽입하거나, 프로그램 흐름을 제어할 수 있습니다.
- Chunk 메타데이터 오염
- ptmalloc2와 같은 메모리 할당자는 Chunk 메타데이터를 사용하여 메모리를 관리합니다.
- Dangling Pointer를 통해 메타데이터를 조작하면, 할당/해제 동작을 왜곡시킬 수 있습니다.
UAF 취약점의 방어 기법
- 스마트 포인터 사용: C++의 std::shared_ptr 및 std::unique_ptr과 같은 스마트 포인터를 사용하여 메모리를 자동으로 관리합니다.
- 메모리 초기화: 메모리를 해제한 후 해당 포인터를 nullptr로 초기화하여 접근을 방지합니다.
Example* obj = new Example(); delete obj; obj = nullptr; // 포인터 초기화
- Static Analysis 도구 활용: 정적 분석 도구를 사용하여 코드에서 잠재적인 UAF 취약점을 탐지합니다.
- 주소 공간 레이아웃 난수화(ASLR): 메모리 주소를 난수화하여 공격자가 예측하기 어렵게 만듭니다.
- Pointer Sanitization: 포인터를 무효화하거나 유효성을 주기적으로 검사합니다.
'Security > System' 카테고리의 다른 글
[OS] Race Condition과 세마포어/뮤텍스 (0) | 2025.03.24 |
---|---|
[heap basics] Tcache와 멀티스레딩 환경 속 Heap 메모리 관리 (1) | 2025.01.18 |
[heap exploit] ptmalloc2의 unsorted bin과 Top Chunk (0) | 2025.01.12 |