Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

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

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

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-98937 — Android 비특권 태스크에 커널 콜체인 주소를 유출하여 KASLR 슬라이드 도출을 가능하게 하는 Linux perf/core 권한 검사 우회에 대한 검증된 PoC 및 분석입니다. | Kitploit
도구/GitHubGitHub/woshigenm/cve-2026-98937
Android SecurityPrivilege EscalationVulnerability AnalysisExploitationInformation GatheringPapers & Research
GitHubwoshigenm/cve-2026-98937

CVE-2026-98937

Android 비특권 태스크에 커널 콜체인 주소를 유출하여 KASLR 슬라이드 도출을 가능하게 하는 Linux perf/core 권한 검사 우회에 대한 검증된 PoC 및 분석입니다.

저장소 보기
424일 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-98937 — perf 커널 콜체인 권한 우회

한국어 | 简体中文

Linux perf/core 권한 검사 우회: 비특권 태스크가 exclude_kernel=1을 설정한 상태에서 커널 콜체인을 요청하여 perf_allow_kernel() 게이트를 건너뛰고 perf 링 버퍼를 통해 커널 스택 프레임을 노출할 수 있습니다. 이 저장소에는 분석 내용과 검증된 PoC가 포함되어 있으며, 이 버그는 정보 유출을 일으키는 것으로, 직접적인 권한 상승 프리미티브는 아닙니다.

상태

항목값
CVECVE-2026-98937
분류권한 우회 / 정보 노출 (CWE-284/CWE-269)
대상Android arm64 (HONOR YLP-W00 및 Redmi K70에서 검증됨)
커널YLP-W00: 6.12.38-android16-5-gfde7767f6ef6-abogki481467632-4k; K70: 5.15.178-android13-8-00021-g6f2f96be86b9-ab13729987
SELinuxEnforcing (u:r:shell:s0)
패치됨아니오; 6.12.113 / 6.18.56 / 7.2.10 / 7.3+에서 업스트림 수정됨
상태PoC 검증됨; KASLR 슬라이드 오라클이 6.12.38 및 5.15.178에서 검증됨
사전 검사src/vuln_precheck.h

영향을 받는 버전

아래 수정 이전의 커널이 영향을 받습니다. a4b016d0a29038a5b7c96bf62c054bf7832451d9 ("perf/core: Check kernel access when kernel callchains are requested", Dapeng Mi, 2026-06-30 병합) 및 해당 안정 브랜치 백포트로 수정되었습니다.

근본 원인

perf_event_open()은 이전에 !attr.exclude_kernel만을 기준으로 커널 프로파일링을 제한했습니다:

if (!attr.exclude_kernel) {
        err = perf_allow_kernel(&attr);
        if (err)
                return err;
}

perf_allow_kernel()에는 perf_event_paranoid > 1 검사와 SELinux perf_event { kernel } 훅이 모두 포함되어 있습니다. 태스크는 exclude_kernel=1을 설정하면서도 여전히 커널 콜체인을 요청할 수 있으며 (exclude_callchain_kernel=0인 PERF_SAMPLE_CALLCHAIN), 이때 perf_callchain()은 샘플링 필터와 무관하게 커널 부분을 수집합니다. 사용자 모드만 카운트하는 하드웨어 PMU 이벤트는 커널 컨텍스트에서 오버플로 인터럽트를 발생시킬 수 있으므로(skid), perf_callchain_kernel()은 커널 스택을 언와인드하고 커널 텍스트 주소를 링 버퍼에 기록합니다.

수정 사항은 커널 샘플링 또는 커널 콜체인이 요청될 때 perf_allow_kernel()을 호출합니다:

if (!attr.exclude_kernel ||
    ((attr.sample_type & PERF_SAMPLE_CALLCHAIN) &&
     !attr.exclude_callchain_kernel)) {
        err = perf_allow_kernel();
        if (err)
                return err;
}

위 스니펫은 6.12.113 stable-tree 형태로, 여기서는 perf_allow_kernel()이 더 이상 속성 포인터를 받지 않습니다; 업스트림 커밋은 perf_allow_kernel(&attr)와 함께 동일한 조건을 사용합니다.

전체 호출 경로, skid 메커니즘, SELinux 감사 증거 및 디바이스 측정값은 docs/analysis.md를 참조하십시오.

검증 설계

PoC는 비권한 셸 프로세스로 세 가지 케이스를 실행합니다:

케이스perf_event 속성취약한 커널에서의 예상 결과
Aexclude_kernel=0EACCES (kernel-perf 게이트 활성)
Bexclude_kernel=1, exclude_callchain_kernel=1이벤트 허용, 커널 콜체인 프레임 없음
Cexclude_kernel=1, exclude_callchain_kernel=0이벤트 허용, 커널 콜체인 프레임 노출

검증된 YLP-W00 (커널 6.12.38, SELinux Enforcing)에서:

  • 케이스 A: EACCES, 감사 로그에 avc: denied { kernel } ... tclass=perf_event 기록.
  • 케이스 B: 이벤트 열림, 커널 콜체인 항목 0개.
  • 케이스 C: 이벤트 열림, 커널 컨텍스트를 가진 약 179k 샘플과 약 537k 커널 콜체인 주소(샘플당 3 프레임), 모두 0xffffffde... 커널 범위 내.

검증된 Redmi K70 (커널 5.15.178, 서드파티 Android 17 ROM, SELinux Enforcing)에서도 동일한 패턴이 관찰되었습니다:

  • 케이스 A: EACCES, 동일한 SELinux { kernel } 감사 라인.
  • 케이스 B: 이벤트 열림, 커널 콜체인 항목 0개.
  • 케이스 C: 이벤트 열림; period 1000에서 2,432개 샘플 내 커널 콜체인 주소 14,090개, period 5000에서 876개 샘플 내 5,049개, 모두 0xffffffdd... 커널 범위 내.

검증된 디바이스에서 수정된 커널은 커널 콜체인 요청이 이제 perf_allow_kernel()에 도달하므로 perf_event_open()에서 케이스 C를 EACCES로 거부할 것입니다.

KASLR 슬라이드 도출

일치하는 vmlinux가 있으면, 유출된 콜체인 프레임은 부팅별 KASLR 슬라이드 오라클이 됩니다. arm64 가상 슬라이드는 2 MiB 정렬이며, 유출된 모든 텍스트 주소는 _stext <= addr - slide < _etext를 만족해야 합니다; 이 구간들을 교집합하면 일반적으로 정확히 하나의 슬라이드만 남습니다.

make slide \
  SLIDE_VMLINUX=/path/to/vmlinux-6.12.38.elf \
  SLIDE_LINK_BASE=0xffffffc080000000 \
  SLIDE_LOG=logs/poc-ylp-w00-20261027-020133-period1000.log

검증된 YLP-W00 6.12.38 부팅에서 세 개의 프레임이 고유한 slide=0x1DCFC00000(런타임 _text=0xffffffde4fc00000)을 제공합니다:

유출된 주소링크 시점 주소심볼
0xffffffde50748c780xffffffc080b48c78local_daif_restore+0x4 (msr DAIF, x0; ret)
0xffffffde50d406e00xffffffc0811406e0el0t_64_sync_handler+0x70 (bl el0_svc 이후)
0xffffffde4fc115880xffffffc080011588el0t_64_sync+0x1a8 (bl el0t_64_sync_handler 이후)

이는 모듈이 아닌 코어 커널 텍스트 프레임입니다: 대기 중인 PMU 인터럽트가 시스템 콜 진입 경로의 msr DAIF, x0 이후 ret에서 정확히 전달됩니다. KASLR 하에서는 원시 주소를 직접 심볼화할 수 없으며, 먼저 slide를 빼야 합니다. 프레임이 모듈 주소인 경우, 모든 주소를 [_stext, _etext)에 위치시키는 slide가 존재하지 않으므로 스크립트는 추측하는 대신 이를 보고합니다. slide는 부팅할 때마다 변경되며 재부팅 간에 캐시되어서는 안 됩니다.

Redmi K70(5.15.178)도 검증되었습니다. 일치하는 이미지는 /sdcard/boot.img(boot v4; 내장된 버전 문자열이 실행 중인 커널과 일치)에서 가져왔으며 vmlinux-to-elf가 158,668개의 심볼을 복구했습니다. period-1000 실행 한 번에서 나온 일곱 개의 고유 프레임이 slide=0x1D93800000(런타임 _text=0xffffffdd9b800000)을 제공하며, 이는 syscall_trace_enter, el0_svc_common, do_el0_svc, el0_svc, el0t_64_sync_handler, el0t_64_sync, syscall_trace_exit에 매핑됩니다.

링크 시점 베이스는 브랜치별로 다릅니다 — 6.12 값을 5.15에서 재사용하지 마십시오:

커널 브랜치KIMAGE_VADDR
Android 13-5.15 (K70)0xffffffc008000000
Android 16-6.12 (YLP-W00)0xffffffc080000000
업스트림 v5.15 (다른 레이아웃)0xffffffc010000000

vmlinux-to-elf는 K70 이미지에 대해 0xffffffc008000000을 자동 감지했으며, 이는 AOSP android13-5.15와 일치합니다. 자동 감지된 ELF 베이스가 브랜치의 KIMAGE_VADDR와 다르면 --link-base(또는 SLIDE_LINK_BASE=)를 전달하십시오: 심볼화는 ELF 공간에 유지되고, 보고되는 slide는 실제 베이스에 상대적으로 계산되며, 런타임 _text는 일정한 베이스 이동에 대해 불변입니다. K70 유출을 6.12.38 이미지에 입력하는 것은 의도적인 부정 테스트로 남아 있으며 어떤 후보도 산출하지 않습니다.

빌드

요구 사항:

  • /opt/android-ndk-r29에 위치한 Android NDK r29 (NDK=로 재정의)
  • GNU make
  • adb
make                 # PoC, arm64, API 24
make ARCH=arm API=29 # other ABI / API level
make host            # static build for qemu-aarch64
make emu             # build and run the static PoC locally
make help

아티팩트는 build/에 기록되며 git에서 무시됩니다.

사용법

make check                         # push + read-only environment pre-check
make run                           # push + full three-case verification

# directly
adb push build/poc /data/local/tmp/poc
adb shell chmod 755 /data/local/tmp/poc
adb shell /data/local/tmp/poc --check
adb shell /data/local/tmp/poc --duration 2 --period 1000

옵션:

--check         pre-check only, no perf event is opened
--force         run on an unlisted kernel release
--duration N    sampling seconds per case (default 2)
--period N      sample period in cycles (default 1000)

종료 코드:

코드의미
0취약: 게이트 우회 및 커널 호출 체인 프레임 관찰됨
2사전 검사 거부됨 (알 수 없는 커널 릴리스 또는 환경 게이트 실패)
3판정 불가: 이벤트는 열렸으나 커널 프레임이 샘플링되지 않음
4열기 단계에서 거부됨 (수정됨 또는 강제 적용됨)
5우회할 커널 perf 제한 없음
6설정 오류 (사용 가능한 하드웨어 PMU 이벤트 없음, 예기치 않은 errno)

--check 사용 시, 종료 코드 0은 프로파일 게이트가 진행됨을 의미하고 2는 거부됨을 의미하며, perf 이벤트는 열리지 않습니다.

PoC는 하드웨어 샘플링 데이터만 읽으며, 커널 상태를 쓰거나, sysctl을 수정하거나, 기기를 재부팅하지 않습니다.

요구 사항 및 제한 사항

  • 하드웨어 PMU 이벤트(cycles/instructions)가 필요합니다. exclude_kernel=1인 소프트웨어 이벤트는 커널 컨텍스트에서 필터링되어 skid 경로에 도달하지 않습니다.
  • shell 도메인(uid 2000)에 대해서만 검증되었습니다. untrusted_app에 perf_event { open }이 허용되는지는 벤더 정책에 따라 다릅니다. 이 테스트를 위해 APK는 빌드되지 않았습니다.
  • 검증된 두 기기 모두에서 kptr_restrict=2이므로 기기 측 심볼화가 불가능합니다. 유출된 주소는 심볼화 대신 범위와 커널 컨텍스트 플래그로 검증됩니다.
  • PoC는 perf_event_paranoid를 수정하지 않습니다. 검증된 두 기기 모두에서 실효 게이트는 SELinux입니다. 건너뛴 함수에는 paranoid 검사도 포함되어 있으므로, perf_event_paranoid >= 2인 경우에도 동일한 우회가 적용됩니다.
  • K70 커널은 수정 이전인 2025-07-02에 빌드되었으며, 백포트를 포함하는 정확한 5.15 안정 릴리스는 열거되지 않았습니다.
  • 슬라이드 도출에는 python3, nm, 정확히 일치하는 vmlinux, 그리고 브랜치의 실제 KIMAGE_VADDR가 필요합니다. 슬라이드는 부팅마다 다릅니다. 6.12.38과 5.15.178 모두 검증되었습니다. 6.12.58 릴리스는 버전 기준으로 사전 검사 프로파일에 포함되어 있으나, 기기 측 런타임 검증은 아직 대기 중입니다.

저장소 구조

도구 다운로드