리눅스 커널, 패킷 소켓 UAF 취약점(CVE-2025-38617) 분석: 정교한 익스플로잇 기술 공개
리눅스 커널의 패킷 소켓(Packet Sockets)에서 발생하는 UAF 취약점(Use-After-Free, CVE-2025-38617) 분석
Race Condition을 활용한 익스플로잇(Exploit)은 현대 커널 완화 기법을 우회
Mutex 홀더(Mutex Holder)의 슬립(Sleep)을 통해 레이스 윈도우(Race Window)를 늘리는 기법 주목
CAP_NET_RAW 권한 획득을 통해 컨테이너 탈출 및 권한 상승 가능성 제시
취약점 개요 및 발생 원리
본 분석은 리눅스 커널의 패킷 소켓(Packet Sockets) 하위 시스템에서 발생하는 UAF(Use-After-Free) 취약점(CVE-2025-38617)을 다룬다. 특히, `packet_set_ring()`과 `packet_notifier()` 간의 Race Condition이 핵심 원인이다. 기술적으로 보면, 인터페이스가 DOWN된 상태에서 `packet_set_ring()`이 실행되는 동안 NETDEV_UP 이벤트가 발생하면, 소켓이 다시 연결되어 UAF가 발생한다. 이는 2005년 리눅스 2.6.12부터 존재했으며, 6.16 버전에서 수정되었다.
익스플로잇(Exploit)의 정교한 기술
익스플로잇은 현대 커널 완화 기법인 CONFIG_RANDOM_KMALLOC_CACHES 및 CONFIG_SLAB_VIRTUAL을 우회한다. 특히, 동일한 `alloc_pg_vec()` 함수를 사용하여 데이터 격리 아키텍처(Data Isolation Architecture)를 무력화한다. 또한, 4단계에 걸쳐 익스플로잇 프리미티브(Exploit Primitives)를 구축하며, 두 개의 레이스 컨디션을 결정적으로 제어하기 위한 정교한 타이밍 기술을 사용한다. 이는 공격자가 CAP_NET_RAW 권한만으로 전체 권한 상승을 가능하게 한다.
Mutex 홀더(Mutex Holder)의 슬립(Sleep) 활용
가장 주목할 만한 점은 Mutex 홀더(Mutex Holder)가 슬립(Sleep) 상태에 들어갈 때, 락 해제와 다음 중요 연산 사이의 시간 간격이 예측 가능해진다는 점이다. 기술적으로 보면, `tpacket_snd()` 함수 내에서 `wait_for_completion_interruptible_timeout()`을 통해 pg_vec_lock을 일정 시간 동안 유지함으로써 레이스 윈도우를 늘린다. 실제 사례로는, 이 기법을 통해 나노초 단위의 레이스 윈도우를 1초로 늘려 익스플로잇의 성공률을 높였다.
Heap Grooming 및 메모리 레이아웃(Memory Layout) 조작
익스플로잇은 UAF를 활용하기 위해 해프(Heap)를 정교하게 조작한다. 특히, 페이지 할당자(Page Allocator)와 슬랩 할당자(Slab Allocator)의 경계를 이용하여 메모리 레이아웃을 제어한다. 실제 사례로는, 2048개의 `simple_xattr` 객체를 스프레이(Spray)하여 데이터 격리 아키텍처(Data Isolation Architecture)를 우회하고, UAF 발생 지점과 인접한 메모리 영역에 공격 대상 객체를 배치한다. 이를 통해, 8바이트의 데이터 오버플로우(Overflow)를 통해 임의의 메모리 읽기/쓰기를 수행한다.
익스플로잇 단계별 분석
익스플로잇은 여러 단계를 거쳐 진행된다. 먼저, Race 1을 통해 `packet_set_ring()`과 `packet_notifier()` 간의 경쟁에서 승리한다. 그 후, Race 2를 통해 `tpacket_rcv()`가 해제된 메모리에 접근하도록 유도한다. 기술적으로 보면, BPF 필터(Filter)를 사용하여 실행 시간을 조절하고, 타이머 인터럽트(Timer Interrupt)를 활용하여 CPU 점유 시간을 늘린다. 최종적으로, 임의의 페이지 읽기/쓰기(Arbitrary Page Read/Write)를 통해 KASLR(Kernel Address Space Layout Randomization)을 우회하고, 시스템 콜 패칭(Syscall Patching)을 통해 권한 상승을 달성한다.