
CVE-2026-46331 act_pedit page-cache corruption exploit, with Alpine PIE fix
net/sched act_pedit 부분 COW 페이지 캐시 손상 (범인 커밋 899ee91156e5, v5.18부터 v7.1-rc7에서 수정됨). packet_edit_meme.c는 이를 권한 없는 로컬 루트로 변환합니다: userns CAP_NET_ADMIN 자식 프로세스가 setuid-root 바이너리의 캐시된 ELF 메타데이터를 setgid(0)+setuid(0)+execve("/bin/sh") 셸코드로 덮어씁니다.
make
./packet_edit_meme
./packet_edit_meme --ubuntu # AppArmor-gated Ubuntu: aa-exec bypass first
| 배포판 | 커널 | 플래그 | 결과 |
|---|---|---|---|
| RHEL 10.0 | 6.12.0 | (none) | ROOT |
| Debian 13 trixie | 6.12.90+deb13.1 | (none) | ROOT |
| Ubuntu 24.04.4 | 6.17.0-22 | --ubuntu | ROOT |
| Alpine edge | 7.0.10-0-stable | (none) | ROOT |
Alpine Linux (musl)는 PIE 실행 파일을 컴파일하며, 여기서 실행 가능한 PT_LOAD 세그먼트는 파일 오프셋 0x1000 이상에서 시작합니다 — 이는 pedit TCP 헤더 오프셋 제한 511바이트를 초과합니다. ELF 헤더와 프로그램 헤더는 첫 번째 읽기 전용 PT_LOAD(파일 오프셋 0)를 차지합니다. 이에 적응된 익스플로잇은 다음과 같습니다:
페이지 0을 실행 가능하게 만듭니다 — 파일 오프셋 0xB4 (phdr[2] + 4)에 있는 첫 번째 PT_LOAD의 p_flags 필드에 PF_X를 추가하여.
셸코드를 분할하여 중요한 LOAD 프로그램 헤더 손상을 방지합니다:
e_entry → 0x28 (커널이 실행 시 확인하지 않는 e_shoff 필드).0x28: 5바이트 jmp 0x1C8.0x1C8, 커널이 실행 중 무시하는 PT_NOTE 프로그램 헤더를 덮어씁니다.대상을 자동으로 발견합니다 — 하드코딩된 경로 대신 런타임에 find / -xdev -type f -perm -4000 -user root를 사용합니다. 발견된 첫 번째 world-readable setuid-root ELF 바이너리가 사용됩니다 — Alpine의 /bin/su (-> /bin/bbsuid, ---s--x--x)는 열 수 없어 자동으로 건너뜁니다.
Ubuntu는 두 개의 sysctl을 통해 unconfined unprivileged userns를 차단합니다:
kernel.apparmor_restrict_unprivileged_userns # denies unconfined userns creation
kernel.apparmor_restrict_unprivileged_unconfined # forces unconfined change_profile to STACK,
# so an aa-exec permissive profile cannot
# shed the userns restriction
--ubuntu는 aa-exec -p {trinity,chrome,flatpak}을 통해 재실행됩니다 (해당 프로파일은 userns, 규칙을 가지고 있습니다).
| 우분투 | userns | unconfined | aa-exec 우회 |
|---|---|---|---|
| 24.04.4 | 1 | 0 | 작동 |
| 26.04 | 1 | 1 | 차단 |
정적 x86_64-linux-gnu 크로스 컴파일러:
# Debian / Ubuntu
apt install gcc-x86-64-linux-gnu
# Alpine
apk add gcc musl-dev