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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-43499-S26 — Android GKI 6.12 기기에서 CVE-2026-43499를 악용: 결정적 임의 커널 읽기/쓰기, KASLR 우회, LD_PRELOAD 페이로드를 통한 전체 루트 권한 획득. | Kitploit
도구/GitHubGitHub/1ndevelopment/cve-2026-43499-s26
Android SecurityPrivilege EscalationVulnerability AnalysisExploitationPost-ExploitationPayload DevelopmentBinary Exploitation
GitHub1ndevelopment/cve-2026-43499-s26

CVE-2026-43499-S26

Android GKI 6.12 기기에서 CVE-2026-43499를 악용: 결정적 임의 커널 읽기/쓰기, KASLR 우회, LD_PRELOAD 페이로드를 통한 전체 루트 권한 획득.

저장소 보기
7110시간 43분 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-43499 — Android GKI 6.12 pselect / configfs 커널 익스플로잇

Android GKI 6.12 라인의 Linux 커널 익스플로잇(Samsung 및 Pixel 디바이스)으로, CVE-2026-43499를 대상으로 합니다: rt_mutex_start_proxy_lock()의 버그가 있는 remove_waiter() 롤백이 waiter::task 대신 current를 사용하여, waiter의 pi_blocked_on이 (이후에 pop되는) 커널 스택 rt_mutex_waiter를 가리키게 만듭니다. 여기에 pselect() fd_set 스택 오버라이트와 consumer sched_setattr 기반의 가짜 rb_tree 탐색을 결합하면 결정론적 커널 쓰기 프리미티브와 완전한 root 권한을 얻습니다.

이 익스플로잇은 LD_PRELOAD 공유 라이브러리(preload.so)로 실행되며, root su 데몬과 월페이퍼를 root 획득 후 아티팩트로 설치합니다.

상태: 활발한 개발 진행 중. 대상별 스택 깊이 오프셋(PSELECT_* 워드 시프트)과 슬라이드 동작은 디바이스마다 다르며 아직 기기에서 검증 중입니다. m1q (ZF1) 타깃이 현재 부팅(bring-up) 테스트의 초점입니다.

취약한 프리미티브 (CVE-2026-43499)

FUTEX_CMP_REQUEUE_PI가 waiter를 requeue하고 requeue의 교착 상태 감지 체인 탐색이 -EDEADLK를 반환하면, __rt_mutex_start_proxy_lock()은 remove_waiter()(rtmutex.c:1535)를 통해 롤백합니다. 롤백은 wait 트리에서 waiter를 올바르게 dequeue하지만 requeue 호출자의 pi_blocked_on을 클리어할 뿐 waiter->task->pi_blocked_on은 클리어하지 않습니다. WAITER의 pi_blocked_on은 스택의 rt_mutex_waiter에 매달린(dangling) 채로 남으며, futex가 타임아웃되면 해당 스택은 pop됩니다.

타임아웃 후 waiter의 커널 스택 영역은 재사용됩니다: core_sys_select()가 세 개의 fd_set을 그 스택 버퍼로 복사합니다(ZF1의 nfds < 344 스택 경로). 조작된 fd_set 워드 배열은 가짜 rt_mutex_waiter / 가짜 task / 가짜 rt_mutex(포인터가 제어되는 rb_tree 루트 포함)를 다시 구체화합니다. 그런 다음 consumer 스레드가 sched_setattr_tid(waiter) → rt_mutex_adjust_pi() → rb_erase_cached를 호출하여 제어된 값의 임의 주소 쓰기를 만들어냅니다.

이 프리미티브 전체는 PI 체인 사이클을 필요로 합니다: owner가 f_pi_target을 보유하면서 동시에 (waiter가 보유한) f_pi_chain에서 블록되므로, 체인 탐색은 owner → chain → waiter → target → owner에 도달하고 -EDEADLK로 실패합니다. 사이클을 제거하면 requeue가 커널 효과 없이 성공을 반환합니다.

익스플로잇 체인

  1. 슬라이드 (KASLR) — 커널 베이스 누출. 두 가지 경로:
    • tracefs sched_blocked_reason (m1q 기본): 차단된 kworker의 저장된 return PC(stack_trace_save_tsk)를 링 버퍼에서 읽어 컴파일 시 포함된 worker_thread 오프셋과 비교합니다.
    • boot_id pselect 경로 (대체, 슬라이드 무관): pselect 쓰기가 선형 맵 별칭을 통해 SLIDE_LOGGERS_0_1을 boot_id sysctl 데이터에 심고, 누출된 값으로 stext를 재구성합니다.
  2. KernelSnitch — mm_struct 크기의 객체를 스프레이하고 futex-hash 충돌을 이용해 힙에서 mm_struct를 찾아, 가짜 객체 스프레이 베이스로 사용되는 커널 힙 페이지 주소를 누출합니다.
  3. 메인 경로 — pselect 변조로 정적 .data ashmem file_operations의 write_iter 슬롯(+0x30)에 configfs_bin_write_iter를 씁니다. 그 후 ashmem을 열면 configfs 바이너리 fs 경로를 통한 임의 커널 읽기/쓰기가 가능해집니다.
  4. Pipe physrw — 스프레이된 커널 페이지에 파이프 버퍼 페이지를 위조하여 물리 읽기/쓰기를 수행합니다: cred 패치, SELinux 비활성화, 직접 커널 메모리 조작.

3단계 (pgd 스왑 브리지, 정적/빌드 전용)

선택적 STAGE3=1 단계로, 브리지 자식을 포크하여 mm->pgd를 스테이징된 가짜 페이지 테이블(3단계: PGD→L1→L2, RX 루프 리프 + RW 스택 리프)로 교체하고, 자식이 2MB 물리 스캔 윈도우를 통해 자신의 cred를 패치하는 레지스터 전용 어셈블리 블롭을 실행하게 합니다 — configfs/파이프 프리미티브 없이 전체 RAM 물리 R/W를 수행합니다. 현재 m1q 타깃에만 연결되어 있으며 아직 기기에서 실행되지 않았습니다.

지원 대상

src/targets/<코드네임>-<빌드>/에 41개 타깃이 있으며, 각각 최소한 target.h(커널 심볼 오프셋, KIMAGE_TEXT_BASE, 직접 맵 베이스, 구조체 오프셋)가 필요합니다. Pixel 타깃(comet, tokay, tegu, caiman, komodo, frankel, mustang, rango, stallion, blazer)은 공유 소스를 오버라이드하고, Samsung 타깃(m1q-*)은 디바이스별 로직을 추가합니다.

root@kitploit:~
make list-projects   # 전체 목록

커널 구조체 레이아웃은 디바이스마다 다릅니다 — 오프셋은 각 타깃의 실제 커널 바이너리 / kallsyms에 대해 검증해야 합니다.

빌드

출력: build/<PROJECT>/bin/preload.so (LD_PRELOAD로 로드되는 공유 라이브러리).

root@kitploit:~
# 기본 프로젝트
CC=clang make

# 특정 디바이스 타깃 (기본값: blazer-CP2A.260605.012)
CC=clang make PROJECT=m1q-BP4A.251205.006

# CC=clang 없이: NDK가 발견되면 사용 ($NDK_ROOT / $ANDROID_NDK_HOME /
# $ANDROID_NDK_ROOT), 그렇지 않으면 호스트 clang + Android sysroot 사용
make PROJECT=m1q-BP4A.251205.006

# 빌드 설정 표시
make info

# 정리
make clean

빌드는 PIE su_daemon 바이너리(src/su_daemon.c, build/embed/su_daemon_aarch64_pie로 빌드)와 assets/wallpaper.webp를 src/su_blob.S / src/wallpaper_blob.S를 통해 preload.so에 내장합니다.

기기에서 실행

빌드 출력물을 /data/local/tmp에 푸시한 후 LD_PRELOAD 상태로 익스플로잇을 실행합니다. 활성 bring-up 타깃에서는 tee 없이 실행하세요 — tee는 자체 stdio를 버퍼링하므로 커널 패닉 시 로그의 끝부분을 잃게 됩니다 (익스플로잇 stdout은 버퍼링되지 않으므로 파일로 직접 리다이렉트하면 모든 줄이 보존됩니다):

root@kitploit:~
adb push build/m1q-BP4A.251205.006/bin/preload.so /data/local/tmp/preload.so
adb push build/embed/su_daemon_aarch64_pie /data/local/tmp/su_daemon_aarch64_pie
adb shell "chmod 755 /data/local/tmp/preload.so /data/local/tmp/su_daemon_aarch64_pie"

adb shell "LD_PRELOAD=/data/local/tmp/preload.so \
  /data/local/tmp/su_daemon_aarch64_pie \
  > /data/local/tmp/output.log 2>&1"

성공 시 데몬은 /data/local/tmp/temp_su.sock에서 수신 대기하고 su가 /apex/com.android.virt/bin 아래에 설치됩니다.

런타임 구성 (환경 변수)

프로젝트 구조

root@kitploit:~
exploit/
  Makefile
  assets/                     # wallpaper.webp (내장된 root 획득 후 아티팩트)
  src/
    main.c                    # run_exploit() 엔트리 포인트 (공유)
    preload.c                 # LD_PRELOAD 생성자, su/월페이퍼 설치
    util.c                    # 주소 변환, 페이지 준비, configfs 헬퍼
    pipe.c                    # 파이프 기반 물리 읽기/쓰기
    root.c                    # cred 패치 / task 탐색
    slide.c                   # KASLR 슬라이드 (tracefs + boot_id 경로)
    fops.c                    # pselect 변조 + fops 조작
    faketables.c              # 3단계 가짜 페이지 테이블 빌더 (3-레벨)
    stage3.c                  # pgd-스왑 브리지 자식 (구성 시에만 작동)
    stage3_loop.S, stage3_poll.S  # 브리지 블롭 + 진입 트램펄린
    su_daemon.c               # root 데몬 (별도 PIE로 컴파일)
    su_blob.S, wallpaper_blob.S   # 내장 바이너리
    offset.h                  # -DTARGET_CONFIG_H로 대상별 target.h를 가져옴
    kernelsnitch/             # mm_struct futex-hash 누출 라이브러리
    targets/<코드네임>-<빌드>/    # 디바이스별 target.h + 선택적 오버라이드
poc/poc.c                     # 독립형 POC (익스플로잇과 분리)

타깃은 Makefile pick_src 메커니즘을 통해 공유 소스를 오버라이드합니다: src/targets/<PROJECT>/<file>.c가 존재하면 공유 src/<file>.c 대신 사용되고, 그렇지 않으면 공유 버전이 사용됩니다.

참고 사항 및 주의점

  • PI 체인 사이클을 절대 제거하지 마세요. 쓰기 프리미티브는 requeue가 -EDEADLK(errno 35)로 실패하는 것에 의존합니다. 사이클이 없으면 커널 효과 없이 success=1로 나타납니다.
  • waiter는 pselect 동안 PI 체인 잠금을 계속 보유해야 합니다. 먼저 해제하면 owner가 깨어나 가짜 rb_tree 탐색과 경쟁하여 패닉이 발생합니다.
  • m1q: PSELECT_WAITER_WORD_SHIFT는 0이어야 합니다 (ZF1 스택 깊이는 ELF에서 검증됨). 다른 타깃은 여전히 기본값 1을 사용합니다 — 신뢰하기 전에 디바이스별로 검증하세요.
  • p0_data_alias()는 DIRECT_MAP_BASE(선형 맵)를 사용합니다 — 이는 ZF1의 P0_PAGE_OFFSET과 다릅니다. 역참조되는 커널 객체의 데이터 별칭은 선형 맵을 사용해야 합니다.
  • pr_error()는 치명적입니다 (exit(-1)), 경고/정보 매크로와 다릅니다.
  • 슬라이드 재구성은 SLIDE_LOGGERS_0_1을 사용하며, SLIDE_NFULNL_LOGGER가 아닙니다; 해당 워드는 무작위화되지 않은 선형 맵 별칭이므로 boot_id 경로는 슬라이드와 무관합니다 (slide=0에서만 사용하세요 — 먼저 tracefs 누출을 실행).

면책 조항

이것은 Android 디바이스용 익스플로잇 코드이며, 보안 연구, 승인된 취약점 테스트, 그리고 본인이 소유하거나 명시적 테스트 허가를 받은 하드웨어에 대한 방어 작업을 위한 것입니다. 본인이 소유하지 않은 디바이스에서의 오용은 불법입니다. 저자는 벽돌된 디바이스, 벽돌된 커널, 또는 보증 상실에 대해 책임을 지지 않습니다.

도구 다운로드
  • Root — root 자식의 cred(uid/gid/caps/SELinux SID)를 패치한 다음, preload.c가 내장된 su 데몬(/apex/com.android.virt/bin에 tmpfs 마운트, adbd 네임스페이스 및 로컬 변형 포함)을 설치하고 월페이퍼를 교체합니다.
  • 변수기본값용도
    PSELECT_ROUTE_SHIFT컴파일 시메인 경로용 A/B fd_set 워드 시프트 (m1q)
    SLIDE_SHIFT컴파일 시슬라이드 경로용 A/B fd_set 워드 시프트
    PSELECT_ROUTE_DELAY_USEC50000sched_setattr 전 consumer 지연 (> 0이어야 함)
    SLIDE_CONSUME_USEC, SLIDE_ENTER_DELAY_USEC, SLIDE_CONSUMER_CORE—슬라이드 경로 타이밍/핀 고정
    SKIP_SLIDE0직접 맵 폴백 사용 (slide = 0)
    SLIDE_ONLY0KASLR 슬라이드만 실행 후 종료
    SLIDE_P0_OFFSET, SLIDE_BOOTID_OFF—슬라이드 p0-별칭 / boot_id 오프셋 오버라이드
    KSNITCH_COLLISIONS4KernelSnitch 충돌 횟수
    STAGE30pgd-스왑 브리지 자식 단계 활성화 (m1q)
    STAGE3_DRYRUN0테이블 스테이징/검증 후 스왑 전 중단
    PAGE_RECLAIM_SENDS, PSELECT_SIMPLE_LAYOUT—스프레이/fd-set 레이아웃 조정
    TMP_PAGE_* / TMP_UNAME_*—tmp_page 실험 경로 (m1q)