Libc 보호
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
Chunk Alignment Enforcement
Malloc은 메모리를 8바이트(32-bit) 또는 16바이트(64-bit) 단위로 할당합니다. 이는 32-bit 시스템에서 청크의 끝이 0x8에 정렬되어야 하고, 64-bit 시스템에서는 0x0에 정렬되어야 함을 의미합니다. 이 보안 기능은 bin에서 포인터를 사용하기 전에 각 청크가 해당 위치에서 올바르게 정렬되어 있는지 확인합니다.
보안 이점
64-bit 시스템에서의 청크 정렬 강제는 Malloc 보안을 크게 향상시켜 위조 청크가 16개의 주소 중 1개 위치에만 놓일 수 있도록 제한합니다. 이는 사용자 입력값에 대한 제어가 제한된 상황에서 특히 공격을 복잡하게 만들며, 성공적으로 공격을 수행하기 어렵게 만듭니다.
- Fastbin Attack on
__malloc_hook
Malloc의 새로운 정렬 규칙은 또한 __malloc_hook을 이용한 전형적인 공격을 방해합니다. 이전에는 공격자가 청크 크기를 조작해 이 함수 포인터를 덮어쓰고 코드 실행을 획득할 수 있었습니다. 이제 엄격한 정렬 요구사항으로 인해 이러한 조작이 더 이상 실현 가능하지 않아 흔한 익스플로잇 경로가 차단되고 전반적인 보안이 향상됩니다.
Note: glibc 2.34 이후로 레거시 훅들(
__malloc_hook,__free_hook등)은 exported ABI에서 제거되었습니다. 현대 익스플로잇은 이제 다른 쓰기 가능한 함수 포인터(예: tcache per-thread struct, vtable-style callbacks)를 대상으로 하거나setcontext,_IO_list_all프리미티브 등에 의존합니다.
Pointer Mangling on fastbins and tcache
Pointer Mangling은 메모리 관리 작업에서 fastbin 및 tcache Fd 포인터를 보호하기 위해 사용되는 보안 개선 기법입니다. 이 기법은 특히 leaked 메모리 정보를 필요로 하지 않거나 알려진 위치에 상대적으로 직접 메모리를 조작하는(상대적 overwrites) 공격 전술을 방지하는 데 도움이 됩니다.
핵심 기법은 다음과 같은 난독화 수식입니다:
New_Ptr = (L >> 12) XOR P
- L은 포인터의 저장 위치(Storage Location) 입니다.
- P는 실제 fastbin/tcache Fd Pointer 입니다.
XOR 연산 전에 저장 위치(L)를 오른쪽으로 12비트 시프트하는 이유는 중요합니다. 이는 시스템 아키텍처 제약으로 인해 일반적으로 예측 가능한 메모리 주소의 최하위 12비트의 결정론적 성질에 존재하는 취약점을 해결하기 위한 조치입니다. 비트를 시프트함으로써 예측 가능한 부분을 식에서 제거하여 새로 생성된 mangled 포인터의 무작위성을 높이고, 이러한 비트 예측에 의존한 공격을 방지합니다.
이 mangled 포인터는 프로그램이 사용하는 주소를 무작위화하여 공격자가 프로세스의 메모리 레이아웃을 예측하기 어렵게 만드는 **Address Space Layout Randomization (ASLR)**이 제공하는 기존 무작위성을 활용합니다.
Demangling은 동일한 XOR 연산을 사용해 원래 주소를 복원합니다. 이때 mangled 포인터를 수식에서 P로 취급하고 변경되지 않은 저장 위치(L)와 XOR하면 원래 포인터가 드러납니다. mangling과 demangling의 대칭성 덕분에 시스템은 큰 오버헤드 없이 포인터를 인코딩/디코딩할 수 있으며, 포인터 조작 공격에 대한 보안을 크게 강화합니다.
보안 이점
Pointer mangling은 힙 관리에서의 부분적 및 전체 포인터 덮어쓰기 방지를 목표로 하여 보안을 크게 향상시킵니다. 이 기능은 여러 방식으로 익스플로잇 기법에 영향을 미칩니다:
- Prevention of Bye Byte Relative Overwrites: 이전에는 공격자가 포인터의 일부를 변경해 정확한 주소를 모른 채도 힙 청크를 다른 위치로 리다이렉트할 수 있었으며, 이는 leakless House of Roman 익스플로잇에서 볼 수 있는 기법입니다. Pointer mangling이 도입되면서 이러한 상대적 덮어쓰기는 heap leak 없이 이제 브루트 포싱이 필요하게 되어 성공 가능성이 크게 줄어듭니다.
- Increased Difficulty of Tcache Bin/Fastbin Attacks: fastbin 또는 tcache 항목을 조작해 함수 포인터(예:
__malloc_hook)를 덮어써 임의 코드 실행을 얻는 일반적인 공격이 어렵게 됩니다. 예를 들어, 공격자는 LibC 주소를 leak한 후 청크를 tcache에 free하고 Fd 포인터를 덮어써__malloc_hook로 리다이렉트하려 할 수 있습니다. Pointer mangling으로 인해 이러한 포인터들은 올바르게 mangled 되어야 하므로, 정확한 조작을 위해 heap leak이 필요해져 익스플로잇 난이도가 높아집니다. - Requirement for Heap Leaks in Non-Heap Locations: 스택, .bss 섹션, PLT/GOT 같은 non-heap 영역에 가짜 청크를 만드는 것도 이제 pointer mangling 때문에 heap leak을 필요로 합니다. 이는 LibC 주소 조작과 유사하게 이러한 영역을 익스플로잇하는 복잡성을 증가시킵니다.
- Leaking Heap Addresses Becomes More Challenging: Pointer mangling은 fastbin 및 tcache bin의 Fd 포인터를 힙 주소 leak 소스로 활용하는 것을 제한합니다. 그러나 unsorted, small, large bin의 포인터는 mangled 되지 않으므로 여전히 주소를 유출하는 데 사용될 수 있습니다. 이 변화는 공격자가 exploitable 정보를 얻기 위해 이러한 bin들을 더 탐색하도록 만들며, 일부 기법은 제약이 있으나 leak 전에 포인터를 demangle할 수 있도록 허용할 수도 있습니다.
Safe-Linking Bypass (page-aligned leak scenario)
Even with safe-linking enabled (glibc ≥ 2.32), if you can leak the mangled pointer and both the corrupted chunk and victim chunk share the same 4KB page, the original pointer can be recovered with just the page offset:
// leaked_fd is the mangled Fd read from the chunk on the same page
uintptr_t l = (uintptr_t)&chunk->fd; // storage location
uintptr_t original = (leaked_fd ^ (l >> 12)); // demangle
This restores the Fd and permits classic tcache/fastbin poisoning. If the chunks sit on different pages, brute-forcing the 12-bit page offset (0x1000 possibilities) is often feasible when allocation patterns are deterministic or when crashes are acceptable (e.g., CTF-style exploits).
Demangling Pointers with a Heap Leak
Caution
프로세스에 대한 더 나은 설명은 여기에서 원본 게시물을 확인하세요.
Algorithm Overview
The formula used for mangling and demangling pointers is:
New_Ptr = (L >> 12) XOR P
Where L is the storage location and P is the Fd pointer. When L is shifted right by 12 bits, it exposes the most significant bits of P, due to the nature of XOR, which outputs 0 when bits are XORed with themselves.
알고리즘의 주요 단계:
- 최상위 비트의 초기 leak: L을 오른쪽으로 12비트 시프트한 값과 P를 XOR하면, L의 시프트된 부분이 0이 되어 P의 상위 비트 12비트를 효과적으로 얻을 수 있습니다.
- 포인터 비트 복원: XOR는 가역적이므로, 결과와 한 오퍼랜드를 알고 있으면 다른 오퍼랜드를 계산할 수 있습니다. 이 성질을 이용해 알려진 비트 집합을 mangled 포인터의 일부와 연속적으로 XOR하여 P의 전체 비트들을 유추합니다.
- 반복적 디망글링: 이 과정을 반복하여 이전 단계에서 발견한 P의 비트를 사용해 mangled 포인터의 다음 세그먼트를 해독하고, 모든 비트를 복원할 때까지 계속합니다.
- 결정적 비트 처리: L의 마지막 12비트는 시프트로 인해 손실되지만, 이들은 결정적이므로 후처리로 재구성할 수 있습니다.
이 알고리즘의 구현은 다음에서 확인할 수 있습니다: https://github.com/mdulin2/mangle
Pointer Guard
Pointer Guard는 glibc에서 atexit()와 같은 라이브러리 호출로 등록된 저장된 함수 포인터를 보호하기 위해 사용되는 exploit mitigation 기법입니다. 이 보호는 포인터를 스레드 데이터(fs:0x30)에 저장된 비밀값과 XOR한 후 비트 회전을 적용하여 스크램블링합니다. 이 메커니즘은 공격자가 함수 포인터를 덮어써서 제어 흐름을 탈취하는 것을 방지하는 것을 목표로 합니다.
Bypassing Pointer Guard with a leak
- Pointer Guard 동작 이해: 포인터의 스크램블링(mangling)은 PTR_MANGLE 매크로를 사용하여 포인터를 64비트 비밀값과 XOR한 다음 0x11 비트만큼 왼쪽 회전(left rotation)합니다. 원래 포인터를 복구하는 역연산은 PTR_DEMANGLE에서 처리됩니다.
- 공격 전략: 공격은 알려진-평문(known-plaintext) 접근 방식에 기반합니다. 공격자는 mangling에 사용된 비밀을 유추하려면 포인터의 원래 값과 mangled 버전 둘 다를 알아야 합니다.
- 알려진 평문 이용:
- 고정된 함수 포인터 식별: glibc 소스 코드나 초기화된 함수 포인터 테이블(예: __libc_pthread_functions)을 검사하면 예측 가능한 함수 포인터를 찾을 수 있습니다.
- 비밀값 계산: __pthread_attr_destroy와 같은 알려진 함수 포인터와 함수 포인터 테이블에서의 해당 mangled 버전을 사용하여, mangled 포인터를 오른쪽으로 회전(reverse rotate)한 뒤 함수 주소와 XOR하면 비밀값을 계산할 수 있습니다.
- 대체 평문: 공격자는 0이나 -1과 같은 알려진 값으로 포인터를 mangling하여 메모리에서 식별 가능한 패턴이 생기는지 실험할 수도 있으며, 메모리 덤프에서 이러한 패턴이 발견되면 비밀값을 드러낼 수 있습니다.
- 실전 적용: 비밀값을 계산한 후에는 포인터를 제어된 방식으로 조작할 수 있어, libc 베이스 주소를 알고 임의의 메모리 읽기가 가능한 멀티스레드 애플리케이션에서 Pointer Guard 보호를 우회할 수 있습니다.
GLIBC Tunables & Recent Loader Bugs
동적 로더는 프로그램 시작 전에 GLIBC_TUNABLES를 파싱합니다. 여기서의 잘못된 파싱 버그는 대부분의 완화책이 동작하기 전에 libc에 직접 영향을 미칩니다. 2023년의 “Looney Tunables” 버그(CVE-2023-4911)가 그 예입니다: 지나치게 긴 GLIBC_TUNABLES 값이 ld.so 내부 버퍼를 오버플로우시켜, SUID 바이너리와 결합될 때 많은 배포판에서 privilege escalation을 가능하게 합니다. 익스플로잇은 환경을 조작하고 대상 바이너리를 반복 실행하는 것만으로도 가능하며, 포인터 가드(pointer guard)나 safe-linking은 로더에서의 손상이 힙 설정 이전에 발생하기 때문에 이를 막지 못합니다.
References
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.


