Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-46215-POC — CVE-2026-46215에 대한 개념 증명 익스플로잇으로, Linux DRM GEM change_handle ioctl에서 발생하는 use-after-free 취약점입니다. 슬랩 재활용(slab reclamation) 및 DirtyPipe 방식의 페이지 캐시 덮어쓰기를 통해 권한 없는 로컬 사용자에서 루트로의 권한 상승을 시연합니다. | Kitploit
도구/GitHubGitHub/0xcyberstan/cve-2026-46215-poc
Privilege EscalationMemory ForensicsVulnerability AnalysisExploitationCTFLearning & EducationBinary Exploitation
GitHub0xcyberstan/cve-2026-46215-poc

CVE-2026-46215-POC

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-46215에 대한 개념 증명 익스플로잇으로, Linux DRM GEM change_handle ioctl에서 발생하는 use-after-free 취약점입니다. 슬랩 재활용(slab reclamation) 및 DirtyPipe 방식의 페이지 캐시 덮어쓰기를 통해 권한 없는 로컬 사용자에서 루트로의 권한 상승을 시연합니다.

저장소 보기
1122개월 전아직 검토되지 않음

CVE-2026-46215: DRM GEM change_handle Use-After-Free (비특권 LPE)

DRM 코어 ioctl DRM_IOCTL_GEM_CHANGE_HANDLE(drm_gem_change_handle_ioctl, ioctl nr 0xD2)의 사용 후 해제(use-after-free)를 통한 로컬 권한 상승. 렌더 노드(/dev/dri/renderD*에 접근 가능한 모든 사용자에게 도달 가능하며, 모든 주요 데스크톱 배포판에서 systemd-logind가 활성 세션에 부여함). 이 저장소의 체인은 비특권 사용자로부터 암호 없는 root까지 UAF를 이끌어냅니다.

  • CVE: CVE-2026-46215 (HIGH, 7.8, AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)
  • 도입: v6.18-rc1, commit 53096728b891 ("drm: Add DRM prime interface to reassign GEM handle", David Francis / AMD), AMD의 CRIU 작업을 위해 추가됨
  • 수정: 6.18.32, 7.0.9, 7.1-rc3 (업스트림 5e28b7b94408). 이 ioctl은 이 버그 및 관련 경쟁 조건 때문에 7.1에서 업스트림에서 비활성화되고 있습니다.
  • 영향: v6.18-rc1부터 위의 수정된 릴리스까지

기여 (Attribution)

이 버그는 먼저 Puttimet Thammasaeng이 보고했으며, 그는 수정 사항에 대해 업스트림 Reported-by 크레딧을 보유합니다. 저는 2026-04-12에 [email protected]에 독립적으로 발견하여 보고했습니다. 제 보고는 인정되어 유지관리자에게 전달되었지만, 이전 보고가 업스트림에서 크레딧을 받았습니다. 이 저장소에는 제 분석과 익스플로잇이 포함되어 있습니다.

Writeup: https://cyberstan.co.uk

공개 상태

수정 사항은 안정적인 커널(6.18.32 및 7.0.9 이상)에 출시되었습니다. 이 저장소는 수정 사항이 널리 사용 가능해진 후 공개되었습니다.

버그

drm_gem_change_handle_ioctl()은 GEM 객체를 한 핸들에서 다른 핸들로 이동하지만 obj->handle_count를 조정하지 않습니다. 또한 drm_vma_node_allow/revoke와 드라이버 open/close 콜백을 건너뜁니다. handle_count가 1로 유지되기 때문에, 이전 핸들에 대한 동시 GEM_CLOSE는 이를 0으로 낮추고 객체를 해제하는 반면, 새 핸들은 여전히 IDR에서 객체를 참조합니다. 이 매달린 핸들은 나중에 drm_gem_object_release_handle()에서 역참조되는 use-after-free입니다.

익스플로잇 체인

  1. GEM_CHANGE_HANDLE을 GEM_CLOSE와 경쟁하여 매달린 핸들을 얻습니다.
  2. 해제된 객체의 슬랩 슬롯을 스프레이된 pipe_buffer 배열(kmalloc-512 조건을 맞추기 위한 msg_msg 펑수이, 그 다음 splice로 채워진 파이프)로 회수합니다.
  3. 드라이버 정보 ioctl을 통해 pipe_buf_ops를 누출합니다: obj->size(오프셋 216)가 pipe_buf[5].ops와 겹쳐 커널 포인터와 KASLR 베이스를 제공합니다.
  4. 매달린 핸들을 FLINK하여 obj->name(오프셋 224)이 pipe_buf[5].flags에 위치하고 PIPE_BUF_FLAG_CAN_MERGE(name = 16 = 0x10)를 설정하도록 합니다.
  5. 파이프에 쓰기를 하여 페이지 캐시에 병합하고 읽기 전용 파일(DirtyPipe 스타일)을 덮어씁니다. 대상은 /etc/passwd이며, root는 암호 없게 됩니다.

오프셋은 pahole을 통해 확인되었으며 6.18부터 7.0까지의 레이아웃에 특화되어 있습니다. 다른 커널의 경우 GEM_* / PIPEBUF_* 정의를 재정의하십시오.

파일

  • poc.c - 익스플로잇. -lpthread로 정적 빌드.
  • run_exploit.sh - PoC와 최소 initramfs를 빌드하고 QEMU에서 부팅합니다.

호스트 사전 요구 사항

qemu-system-x86_64, gcc, busybox (정적), fakeroot, cpio, gzip. KVM(/dev/kvm)이 권장되며, 경쟁 조건이 훨씬 더 신뢰할 수 있습니다.

테스트 커널 빌드

익스플로잇은 특정 옵션으로 빌드된 취약한 타겟이 필요합니다.

  • CONFIG_KASAN은 반드시 OFF여야 합니다. KASAN은 해제된 슬랩을 격리하고 파이프 스프레이 회수를 차단하므로, KASAN 빌드에서는 익스플로잇이 작동하지 않습니다.
  • 예상되는 오프셋에서 size/name 필드를 노출하는 DRM 드라이버: virtio_gpu(데모에서 사용) 또는 nouveau.
  • CONFIG_DRM=y, CONFIG_DRM_VIRTIO_GPU=y, CONFIG_DEVTMPFS=y, CONFIG_BLK_DEV_INITRD=y.

단계:

  1. 6.18부터 7.0까지의 소스 트리(또는 아래 패치된 검사에 실패하는 모든 트리)를 체크아웃합니다.
  2. 위의 구성 옵션을 설정하고 CONFIG_KASAN이 설정되지 않았는지 확인합니다.
  3. make -j"$(nproc)" bzImage, arch/x86/boot/bzImage 생성.

데모는 nokaslr로 부팅되므로 누출된 포인터가 결정적입니다. 누출 자체가 KASLR을 무력화하므로 KASLR이 켜져 있어도 작동하며, 주소는 부팅마다 다릅니다.

트리가 취약한지 패치되었는지 확인

drivers/gpu/drm/drm_gem.c 파일, drm_gem_change_handle_ioctl() 함수를 확인하십시오.

빠른 확인:

root@kitploit:~
awk '/^int drm_gem_change_handle_ioctl/,/^}/' \
    drivers/gpu/drm/drm_gem.c | grep -c handle_count
  • 0 = 취약 (참조 카운트 처리 없음).
  • 0이 아님 = 패치됨.

구조별:

  • 취약: file_priv->prime.lock 획득, 단일 idr_alloc(&file_priv->object_idr, obj, ...), 그 다음 이전 핸들에 대해 idr_remove(). drm_gem_object_handle_get 없음.
  • 패치됨: 2단계 삽입 (idr_alloc 후 idr_replace(NULL)로 이전 핸들 분리), 프라임 연산이 성공한 후에야 실제 객체가 교체됨.

익스플로잇 실행

root@kitploit:~
./run_exploit.sh /path/to/bzImage

이 명령은 poc.c를 빌드하고 initramfs로 감싼 후 QEMU를 -device virtio-gpu-pci 및 nokaslr로 부팅합니다. PoC는 uid 1000(비특권)으로 실행되며, 스크립트는 이전과 이후의 /etc/passwd를 출력하고 셸로 떨어뜨립니다. poweroff -f 또는 Ctrl-A X로 VM을 종료합니다.

예상 출력

root@kitploit:~
[!] Race won (iter 977): handle=132049
[!] KASLR: pipe_buf_ops = 0xffffffff82428400
[!] EXPLOIT SUCCESSFUL
[!] FLINK: 16 = 0x10
[*] /etc/passwd:
    root::0:0:pwned:/root:/bin/sh
[!] LPE CONFIRMED
[!] root account is now passwordless

root 소유의 읽기 전용(chmod 444) /etc/passwd가 비특권 프로세스에 의해 덮어써집니다. root: 행에서 암호 필드가 사라집니다.

신뢰성

  • 테스트에서 부팅당 약 99%(100회 신규 부팅 중 99/100, 이전 실행에서 53/53). PoC는 내부적으로 재시도합니다: 잘못된 누출 시 죽은 슬롯을 다시 스프레이하는 대신 새로운 매달린 객체를 위해 다시 경쟁하며, 최대 200라운드, 각 라운드는 수십 밀리초입니다. 대부분의 부팅은 첫 번째 경쟁에서 승리하며, 최악의 경우 200라운드 중 11라운드를 사용했습니다.
  • 드문(약 1%) 실패 모드: 패배한 경쟁 인터리빙이 커널 상태를 손상시키고 VM을 중단시킵니다(무음 정지, 평결 출력 없음). 이는 커널 경쟁 UAF의 본질적인 특성입니다. 약 30초 이내에 평결이 출력되지 않으면 전원을 껐다 켜고 다시 실행하십시오.

수정 확인

패치된 트리(6.18.32, 7.0.9, 7.1-rc3 이상, 또는 위의 패치된 검사를 통과하는 모든 트리)로 다시 빌드하고 다시 실행:

root@kitploit:~
./run_exploit.sh /path/to/patched-bzImage

패치된 커널에서는 익스플로잇이 "EXPLOIT SUCCESSFUL"에 도달하지 않아야 합니다: 경쟁 조건이 더 이상 새 핸들 아래에서 객체를 해제하지 않으므로 누출이 유효한 커널 포인터를 반환하지 않습니다.

면책 조항

업스트림 수정 사항이 출시된 후 연구 및 방어 목적으로 공개되었습니다. 있는 그대로 제공됩니다. 본인이 제어하는 VM에서만 실행하십시오.

도구 다운로드