
CVE-2026-68398 Ubuntu PPPoL2TP use-after-free 로컬 권한 상승

이 저장소는 CVE-2026-68398에 대한 특정 빌드 전용 로컬 권한 상승 익스플로잇을 포함합니다. 이 취약점은 PPPoL2TP 수신 처리와 연결되지 않은 PPP 채널 소멸 사이의 use-after-free 경쟁 조건입니다. QEMU에서 공식 Ubuntu 22.04 패키지 linux-image-5.15.0-187-generic(5.15.0-187.197)을 대상으로 검증되었습니다.
최종 테스트는 보충 그룹(supplementary groups), capabilities 및 sudo 접근 권한이 없는 전용 UID 1001 사용자로 시작하여 초기 네임스페이스(initial-namespace)에서 UID 0을 획득합니다. KASLR, SMEP, SMAP 및 AppArmor는 활성화된 상태로 유지됩니다. 게스트는 nokaslr, nopti, nosmep 또는 nosmap 없이 부팅됩니다.
경고
이 코드는 의도적으로 커널 힙 상태를 손상시키며 정확히 하나의 Ubuntu 커널 빌드에 맞춰져 있습니다. 실패한 경쟁 조건은 패닉(panic) 또는 시스템 손상을 유발할 수 있습니다. 소유한 격리된 일회용 VM에서만 실행하십시오.
pppol2tp_recv()는 RCU 읽기 측 임계 구역(read-side critical section) 아래의 L2TP UDP 수신 경로에서 실행되며 결국 ppp_input(&po->chan)을 호출합니다. PPPoX 소켓과 그에 포함된 ppp_channel은 RCU에 안전하지만, ppp_input()이 사용하는 내부 struct channel은 별도의 할당입니다.
PPPIOCGCHAN으로 바인딩되었지만 PPP 유닛에 연결(attach)되지도 않고 브리지되지도 않은 채널의 경우, 닫기 경로가 해당 내부 객체를 즉시 해제했습니다:
RX: l2tp_udp_encap_recv -> pppol2tp_recv -> ppp_input(channel)
CLOSE: pppol2tp_release -> pppox_unbind_sock
-> ppp_unregister_channel -> ppp_release_channel -> kfree(channel)
결과적으로 수신 경로는 해제된 채널의 skb 큐와 waitqueue에서 동작할 수 있습니다. 수정 사항은 struct channel에 RCU 콜백을 추가하고, RCU 유예 기간(grace period)이 경과할 때까지 큐 정리(purge)와 해제를 지연시킵니다.
이 취약점은 Doyensec의 Norbert Szetei가 상류(upstream)에서 발견하고 수정했습니다. 메인라인 수정 커밋은 ec4215683e47424c9c4762fd3c60f552a3119142입니다.
Linux CNA 기록은 취약한 계보가 Linux 4.15부터 시작되는 것으로 식별합니다. 벤더 커널은 다른 버전 번호로 수정 사항을 포함할 수 있으므로, 정확한 소스 또는 패키지 변경 로그(changelog)가 이 표보다 우선합니다.
이전의 지원되는 벤더 라인은 백포트(backport)가 필요합니다. 2026-08-12 기준으로 Ubuntu CVE 추적기는 Jammy의 linux 패키지를 needs-triage로 표시합니다. 수정된 Ubuntu Jammy 패키지는 확인되지 않았습니다. 테스트한 5.15.0-187.197 소스는 여전히 kfree(pch)를 직접 호출하며 취약합니다.
커널은 재컴파일되지 않았습니다. 최소 클라우드 이미지에는 linux-modules-extra-5.15.0-187-generic이 없어서 l2tp_ppp를 제공하기 위해 해당 공식 Ubuntu 패키지를 설치했습니다. linux-generic 메타패키지를 사용하는 일반적인 Jammy 설치 환경은 이미 해당하는 modules-extra 패키지에 의존합니다. 익스플로잇이 PPPoL2TP 소켓을 생성하면 프로토콜 모듈이 자동으로 로드됩니다.
자동 KASLR 탐지기는 x86 prefetch 타이밍 부채널(side channel)을 사용하며 KPTI가 비활성화된 상태에서 RDTSCP를 요구합니다. 테스트한 호스트 CPU는 rdtscp, smep, smap을 노출하며 Meltdown의 영향을 받지 않으므로, Ubuntu는 부팅 옵션 변경 없이 KPTI를 비활성 상태로 둡니다. /proc/cpuinfo가 pti 플래그를 보고하는 CPU에서는 탐지기가 실행을 거부합니다. 이는 익스플로잇 특유의 하드웨어 조건입니다. 기본 CVE는 여전히 도달 가능하지만, 이 릴리스는 KPTI 활성 시스템에서 KASLR 우회를 주장하지 않습니다. 수동으로 지정하는 slide는 통제된 진단 목적으로만 존재합니다.
struct channel을 재확보합니다. 계속 실행 중인 RX 경로는 제어된 키 바이트를 자신의 skb 큐 및 waitqueue로 취급합니다.core_pattern을 정보 노출용 임시 공간으로 사용하여 키 할당 포인터를 노출합니다.override_creds()를 호출합니다. UID/GID 필드, capabilities 및 필요한 user, namespace, ucount, group 포인터는 정확한 Ubuntu 빌드와 일치합니다./proc/self/exe를 /tmp의 고유 파일로 복사하고, root 소유의 mode 4755로 변경한 후 해당 속성을 검증합니다./usr/bin/id를 실행합니다.마지막 연결 단계가 필요한 이유는 override_creds()가 활성 커널 작업의 주관적 자격 증명(subjective credentials)만 변경하기 때문입니다. 검증된 SUID 복사본을 설치하고 실행함으로써 그 수명이 짧은 프리미티브를 일반 프로세스 자격 증명으로 전환합니다.
Makefile은 익스플로잇을 정적으로 링크합니다. 타이밍에 민감한 prefetch 오브젝트는 의도적으로 -O0으로 컴파일되며, 익스플로잇 자체는 -O2를 사용합니다.
make
동등한 명령:
gcc -O0 -Wall -Wextra -Werror -c -o build/kaslr_prefetch.o kaslr_prefetch.c
gcc -O2 -static -pthread -Wall -Wextra -Werror \
-o build/CVE-2026-68398 exploit.c build/kaslr_prefetch.o
정확히 검증된 커널의 일반 사용자 계정에서:
id
grep '^Cap' /proc/self/status
./CVE-2026-68398 auto 60
소스는 uname()을 확인하여 5.15.0-187-generic 이외의 릴리스에서는 실행을 거부합니다. 경쟁 조건은 확률적입니다. 실패하거나 크래시가 발생한 후 재시도하기 전에 일회용 스냅샷을 재부팅하십시오.
성공적인 실행은 다음과 같이 끝납니다:
[KASLR] image_base=0xffffffffb9200000 slide=0x38200000
CVE-2026-68398 Ubuntu local privilege-escalation exploit
uid=1001 euid=1001 slide=0x38200000
...
[9/9] invoking override_creds and installing the SUID transition...
override callback: uid=0 euid=0 gid=0 egid=0
installed root-owned mode 4755 helper: /tmp/.cve-2026-68398-root-948
SUID helper ready; executing it from the original unprivileged task...
SUID transition: uid=0 euid=0 gid=0 egid=0
uid=0(root) gid=0(root) groups=0(root),1001(poc)
해당 실제 QEMU 실행의 전체 간결 기록은 docs/example-output.txt에 있습니다.
이 체인은 무작위화가 정상적으로 적용된 세 번의 새로운 Ubuntu 부팅에서 완료되었습니다. 자동으로 복구된 이미지 베이스는 0xffffffff90800000, 0xffffffffa5a00000, 0xffffffffb9200000였습니다. 최종 실행은 위에서 설명한 전용 비관리자 UID 1001 계정을 사용했으며, 이후 임시 SUID 파일이 제거되었는지 검증했습니다.
동일한 최종 경쟁 조건은 KASAN을 활성화하고 동일한 4-vCPU 토폴로지로 정확한 상류 수정 커밋에서 60초 동안 실행되었습니다. 5,969회의 채널/키 사이클을 완료하고 stage 1: no controlled reclaim을 보고했으며, KASAN 보고나 익스플로잇 단계 전이는 발생하지 않았습니다.
이 비공개 저장소가 생성되기 전인 2026-08-12에 확인했습니다. SearchSploit/Exploit-DB는 익스플로잇을 반환하지 않았고, Packet Storm은 일치하는 파일을 반환하지 않았으며, GitHub 정확 코드 검색은 CVE/권고 미러 22개를 반환하고 PoC는 없었습니다. 정확한 웹 검색에서도 상류 수정 사항과 메타데이터만 발견되었습니다. 이는 특정 시점의 결과일 뿐, 나중에 다른 PoC가 나타나지 않을 것이라는 보장은 아닙니다.
kaslr_prefetch.c의 기반입니다.익스플로잇은 A. Ramos <[email protected]>(Twitter: @aramosf)이 작성했습니다. 취약점 발견 및 상류 수정은 **Norbert Szetei(Doyensec)**의 공로입니다.
exploit.c는 GPL-2.0-only입니다. kaslr_prefetch.c와 kaslr_prefetch.h는 MIT 라이선스이며 소스 파일에 KASLD 저자 표시와 전체 허가 고지를 유지합니다.
| 커널 라인 | 최초 수정 릴리스 | 수정 커밋 |
|---|
| 6.6.y | 6.6.148 | 4bb84e964ff0 |
| 6.12.y | 6.12.101 | 3ab32218d718 |
| 6.18.y | 6.18.42 | c9574b8a8ede |
| 7.1.y | 7.1.6 | 06213c85d8c0 |
| Mainline | 7.2-rc4 | ec4215683e47 |
| 속성 | 값 |
|---|
| 배포판 | Ubuntu 22.04.5 LTS (Jammy) |
| 커널 패키지 | linux-image-5.15.0-187-generic / 5.15.0-187.197 |
| 커널 릴리스 | 5.15.0-187-generic #197-Ubuntu |
| 아키텍처 | x86-64 |
| VM | QEMU/KVM, -cpu host, vCPU 4개, 5 GiB RAM |
| 초기 사용자 | uid=1001(poc) gid=1001(poc) groups=1001(poc) |
| 초기 capabilities | 상속(inheritable), 허용(permitted), 유효(effective), 주변(ambient) 모두 0 |
| 최종 사용자 | 초기 네임스페이스에서 uid=0(root) gid=0(root) |
| 부팅 변경 | 없음. 기본 커널 명령줄, KASLR 활성화 |
| 요구 사항 | Ubuntu 5.15.0-187 상태 | 익스플로잇 사용 |
|---|
| PPP | CONFIG_PPP=y | 커널 내장 |
| L2TP / PPPoL2TP | CONFIG_L2TP=m, CONFIG_PPPOL2TP=m | 공식 linux-modules-extra 모듈 |
| 사용자 키 | CONFIG_KEYS=y | 해제된 kmalloc-256 채널 재확보 |
| AppArmor | CONFIG_SECURITY_APPARMOR=y | 활성 상태 유지. 위조 cred에 유효한 unconfined 레이블 포함 |
| KASLR | CONFIG_RANDOMIZE_BASE=y | 활성 상태 유지. slide는 런타임에 복구됨 |
| SMAP | CONFIG_X86_SMAP=y | 활성 상태 유지 |
| 사용자/네트워크 네임스페이스 | Ubuntu에서 활성화되지만 사용되지 않음 | 네임스페이스 설정이나 capability 획득 불필요 |
/dev/ppp | 필요 없음 | 채널은 바인딩되지만 PPP 유닛에 연결되지 않음 |