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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
mt6985-CVE-2026-43499 — MT6985 MediaTek Dimensity 9300 (vivo PD2241)용 CVE-2026-43499 익스플로잇 어댑터 | Kitploit
도구/GitHubGitHub/233laoliu/mt6985-cve-2026-43499
Exploit FrameworksVulnerability AnalysisExploitationReverse EngineeringForensicsMobile SecurityFirmware AnalysisBinary Exploitation
GitHub233laoliu/mt6985-cve-2026-43499

mt6985-CVE-2026-43499

MT6985 MediaTek Dimensity 9300 (vivo PD2241)용 CVE-2026-43499 익스플로잇 어댑터

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-43499 실패 기록: MT6985 포팅 시도

결론: 68M 토큰을 썼지만 root를 얻지 못함.
원인: KernelSnitch 타이밍 공격이 MTK Dimensity 9200에서 신뢰할 수 없고, CONFIG_PANIC_ON_OOPS=y가 시행착오 여지를 주지 않음.
이 글은 전체 삽질 과정을 기록하여 후인들이 함정을 피하도록 돕기 위한 것.


배경

항목값
기기vivo PD2241 (Dimensity 9200 / MT6985), Android 15
펌웨어PD2241_A_15.2.10.2.W10.V000L1
커널5.15.178-android13-8-gfb31f5bdd612-dirty
Bootloader잠김 (ro.boot.flash.locked=1)
SELinuxEnforcing
panic_on_oops켜짐 → 모든 커널 OOPS = 즉시 재부팅
ExploitCyberMeowfia — CVE-2026-43499 (IonStack)
소스 트리android_15.0_kernel_MT6985 (5.15.178) — 기기 버전과 불일치 (소스는 android15 GKI, 기기는 android13 GKI)

수행한 작업

1. 소스 분석 → 구조체 오프셋 추출

arch/arm64/include/asm/memory.h + include/linux/fs.h + android/abi_gki_aarch64.xml에서 추출:

  • 메모리 레이아웃: KIMAGE_TEXT_BASE = 0xffffffc008000000, VA_BITS=39, DIRECT_MAP=256GB
  • task_struct: 36864 bits, 완전 파싱 (ABI XML layout-offset-in-bits)
  • file_operations: iopoll 없음 (android13 GKI), IOCTL=0x48, open=0x68
  • cred: atomic_t usage = 4 바이트, uid=0x04
  • struct page: 64 바이트, slab_cache=0x18

핵심 발견: 소스는 android15 GKI, 기기는 android13 GKI — task_struct 오프셋이 0x40~0x88 바이트 차이 나므로 소스를 그대로 참조할 수 없음.

2. 펌웨어 언패킹 → 심볼 추출

root@kitploit:~
OTA zip (8.3GB)
  → payload.bin (8.2GB)
    → payload_dumper → boot.img (96MB, v4 header)
      → LZ4 압축 해제 → Image (50MB ARM64)
        → kallsyms-finder → 187810 심볼

두 펌웨어 버전 (15.2.7.6 / 15.2.10.2)에서 심볼 추출 — 같은 심볼이 두 버전 간 10KB~200KB 차이, 반드시 올바른 버전을 사용해야 함.

3. 디스어셈블리 검증 → capstone으로 핵심 오프셋 확인

root@kitploit:~
# rt_mutex_adjust_pi 내부:
LDR x21, [x19, #0x8b0]  → pi_blocked_on = 0x8b0 (android15 값, frankel 아님)

이로써 task_struct 레이아웃이 frankel의 android13이 아닌 android15 브랜치임을 확인.

4. 컴파일 → 성공

NDK r29, make PROJECT=android_15.0_kernel_MT6985 → preload.so (150KB).

5. 실행 → 반복적 크래시

root@kitploit:~
[+] preload starting pid=25414
[+] p0 profile ... 모든 심볼 정상 로드
[-] KernelSnitch mm_struct leak failed     ← 가끔 이 줄 없음 (드물게 성공)
[+] slide child context route=pselect      ← slide KASLR leak 자식 프로세스 시작
[커널 panic]                                ← rt_mutex_adjust_prio_chain+0x1b0

크래시 명령어 (capstone):

root@kitploit:~
ldar w8, [x27]    ; x27 = waiter->lock ([x28, #0x38]에서 로드)
                  ; x27 값이 쓰레기 → 페이지 테이블 매핑 없음 → translation fault
                  ; → die() → panic → 재부팅

실패 원인

근본 원인 1: KernelSnitch가 MTK에서 신뢰할 수 없음

KernelSnitch는 전체 exploit의 진입점 — futex 해시 버킷의 타이밍 차이로 mm_struct 주소를 유출:

  1. 충돌 감지 성공 — 낮은 임계값에서 충돌 5개 발견
  2. bruteforce 매칭은 거의 항상 실패 — 핵심 문제:
root@kitploit:~
MT6985는 CONFIG_KASAN_HW_TAGS=y → 커널이 MTE 태그로 slab 할당을 표시
mm_struct의 포인터에 KASAN tag 포함 → futex_hash가 tagged pointer 기반으로 계산

하지만 bruteforce는 direct map (untagged 주소)을 스캔 → 계산된 hash가 불일치
MTE tag 순회 (0-14 총 15종)를 추가해도 VA_BITS=39 시스템에서
tag 비트 (bit56-59)가 부호 확장 비트와 겹침 → 일부 tag 조합이 유효하지 않은 주소 생성 → 누락

Pixel 기기는 KASAN_HW_TAGS가 없어 이 메커니즘이 동작. MTK는 불가.

근본 원인 2: CONFIG_PANIC_ON_OOPS가 결정타

root@kitploit:~
Pixel:  커널 OOPS → dump_stack → 계속 실행 → exploit 재시도 가능
MT6985: 커널 OOPS → die() → panic() → 즉시 재부팅 → 시행착오 여지 없음
π 체인 파괴가 조금만 어긋나도 전체 붕괴, Pixel에서는 어긋나도 "이번엔 실패, 다른 주소로 재시도"일 뿐.

또한 bootloader가 잠겨 있음 (flash.locked=1) → 이 옵션을 제거한 커스텀 커널을 플래시할 수 없음.

근본 원인 3: 커널 버전 드리프트

root@kitploit:~
소스 트리: 5.15.178 android15 GKI
기기:      5.15.178-android13 (vivo vendor)

메이저 버전 번호가 모두 5.15.178이지만 GKI 브랜치가 다름 (android13 vs android15), task_struct/cred 등 핵심 구조체 레이아웃이 불일치. frankel/android15 두 오프셋 세트 사이를 반복 전환하다가 결국 디스어셈블리로 확정.


시도한 조정 (전부 무효)

변경목적결과
THRESHOLD_MULT 10→5→3충돌 감지 임계값 낮춤<5는 오탐 과다
APPENDED_FUTEXES 4096→8192hash 체인 차이 확대효과 없음
REPEAT_MEASUREMENT/AVERAGE샘플링 정밀도 증가효과 없음
MTE=1bruteforce가 태그 순회더 느려지고 오히려 크래시 감소
MM_STRUCT_SZ 0x500→0x400mm_struct 스텝 수정필수, ABI 실제 992 바이트
IDENTITY_END 64GB→256GB스캔 범위 확대너무 느림 (MTE 순회), 여전히 불일치
TASK offsets: android15↔frankel올바른 오프셋 확정디스어셈블리로 android15 확인
FOPS offsets: android15↔frankelandroid13에 iopoll 없음frankel 사용

target.h 현황

exploit/targets/android_15.0_kernel_MT6985/target.h 내:

카테고리신뢰도검증 방식
메모리 레이아웃정확memory.h 계산 + kallsyms _text 검증
심볼 오프셋 (22개)정확15.2.10.2 boot.img에서 추출
task_struct 오프셋정확ABI XML + capstone 디스어셈블리 (pi_blocked_on=0x8b0)
FOPS 오프셋오류 (2026-07-31 수정됨)원래 frankel에서 복사 (android13에 iopoll 없음); 소스 트리 ABI에는 실제로 iopoll@0x30, ioctl=0x50, open=0x70 — VERIFICATION.md 참조
CRED 오프셋정확 (검증됨)ABI XML: uid=0x04, securebits=0x24, caps=0x28, security=0x78

어셈블리는 통과, 실행도 됨, 마지막 1km에서 패배.


계속하려면

필수 조건 (하나라도 빠지면 안 됨)

  1. CONFIG_PANIC_ON_OOPS 제거 — 커스텀 커널 플래시 (bootloader 잠금 해제 필요) 또는 기본적으로 이 옵션이 꺼진 MT6985 기기 확보
  2. KernelSnitch 해결 — MTK Dimensity 9200의 캐시 타이밍 교정 필요, 또는 exploit에서 KernelSnitch를 다른 mm_struct 유출 방식으로 완전 대체

가능한 대안 아이디어

  • /proc/self/pagemap — 본 기기에서 제한됨 (전부 0 반환)
  • MTK 전용 디버그 인터페이스 (/proc/mtk_*) — 존재하나 추가 분석 필요
  • MTK 카메라/GPU 드라이버 ioctl 취약점 — 더 간단한 권한 상승 경로
  • 커뮤니티의 MTK 변종 포팅 대기

본 저장소의 잔존 가치

  • symbols/kallsyms_PD2241_15.2.10.2.txt — 완전한 15.2.10.2 심볼 테이블, 후인이 바로 사용 가능
  • device_config.txt — 기기 실제 커널 설정, vendor가 무엇을 변경했는지 확인 가능
  • exploit/targets/android_15.0_kernel_MT6985/target.h — 구조체 오프셋 검증 완료
  • scripts/server_compile.py — 자동 컴파일, 파라미터 변경 후 재컴파일 빠름

삽질 체크리스트 (후인용)

  1. Windows에서 파일 압축 해제: tar -xf는 대용량 zip에서 실패할 수 있음, Python zipfile 또는 수동 압축 해제 사용
  2. payload_dumper의 protobuf 버전 충돌: 생성된 update_metadata_pb2.py가 protobuf 5.x를 요구, runtime_version import 줄을 수동으로 삭제해야 함
  3. ./preload.so 직접 실행 시 segfault: 반드시 /system/bin/linker64 /data/local/tmp/preload.so 사용
  4. ABI XML이 소스보다 정확: layout-offset-in-bits는 컴파일러가 계산한 값, 수동으로 5000바이트 세는 것보다 100배 정확
  5. GKI 브랜치가 레이아웃에 영향: android13/14/15의 task_struct가 다름, 브랜치 간 오프셋 복사 금지
  6. 펌웨어 버전이 다르면 심볼 오프셋도 다름: 15.2.7.6과 15.2.10.2는 10KB~200KB 차이
  7. vivo vendor가 대량의 OEM 필드 추가: CONFIG_ANDROID_VENDOR_OEM_DATA=y, CONFIG_SCHED_INFO=y, CONFIG_RSC_* → 표준 GKI에서 이탈
  8. 전후방 심볼 추출 툴체인: boot.img → kernel.bin → LZ4 압축 해제 → Image → kallsyms-finder → 심볼 테이블

타임라인

root@kitploit:~
07/28  CyberMeowfia 저장소 + MT6985 소스 다운로드
07/29  소스 분석 (memory.h, fs.h, ABI XML, 각종 struct)
       펌웨어 언패킹 (payload.bin → boot.img → Image)
       심볼 추출 (kallsyms-finder → 187810 심볼)
       다회 컴파일 + 다회 크래시 + 디스어셈블리 검증
       자동 재시도 5회 → 전부 실패
       본 글 작성
-------------------------------------------
총계: ~68M 토큰, root 셸 0개

2026-07-29, 살아서 이야기를 전하다


2026-07-31 속편: 소스 확보 후 검증과 수정

android_15.0_kernel_MT6985.tar.gz(5.15.178 소스 트리 + ABI XML) 확보 후 전량 교차 검증 수행, 상세 내용은 VERIFICATION.md 참조. 요약:

  1. MT6985 = 디멘시티 9200(MT6989가 9300), 위 본문에서 정정함.
  2. 심볼 오프셋 23/23 정확(kallsyms 검증), task_struct / cred / waiter / page / pipe / configfs 오프셋 모두 소스 트리 ABI와 일치.
  3. FOPS 오프셋은 오류: 원래 frankel에서 복사(android13 GKI, iopoll 없음, ioctl=0x48); 하지만 기기 task_struct 레이아웃(pi_blocked_on=0x8b0, 런타임 디스어셈블리로 확인)이 이 소스 트리와 일치하므로, 같은 커널의 file_operations에는 iopoll@0x30, ioctl=0x50, open=0x70 등이 있어야 함 — target.h 수정 완료, exploit 내장 leak_kernel_base() 실기기 자체 검증으로 폴백.
  4. KernelSnitch의 MTK 호환성 패치(patches/kernelsnitch_mtk_fixes.patch):
    • 사용자 공간 futex 해시 테이블 크기를 커널과 일치시킴(possible CPU + 2의 거듭제곱 반올림), possible≠online일 때 bruteforce가 반드시 실패하는 문제 방지;
    • MTE tag 순회에 0xf(untagged) 추가, KSNITCH_MTE_ENABLED=1이 실제로 동작하도록 수정(기존 util.c는 mte=0 하드코딩);
    • 비 MTK target에는 영향 없음.
  5. 크래시 지점 rt_mutex_adjust_prio_chain+0x1b0은 pselect/pi 체인 단계에 위치하며 FOPS 자체 검증보다 앞섬; 위 수정 후 재실기 검증 가치 있음.

2026-07-31 실기기 테스트: KernelSnitch 통과, slide 단계가 여전히 벽

기기(PD2241, compiler251203103903) 실기 8+회 테스트:

  • KernelSnitch 수정 및 검증 완료: MM_STRUCT_SZ=0x400(기존 0x500은 스캔 그리드 오정렬로 오탐만 발생) + MTE tag 0..15 순회(기기 mm 포인터 tag가 변함) + 위조 주소 untag. 이제 실제 mm_struct를 안정적으로 찾음.
  • 매회 여전히 rt_mutex_adjust_prio_chain+0x1b0에서 크래시: pselect/pi 체인 타이밍 레이스(위조 waiter가 커널 스택의 올바른 오프셋에 안착하지 못함). vivo RSC 스케줄러가 futex/pi 경로를 변경하여 해당 레이스를 근본적으로 깨뜨렸을 가능성. slide 스택 정렬은 SLIDE_SHIFT 환경 변수로 파라미터화했으나 스캔 완료 못함.
  • FOPS/pipe/cred 단계는 아직 도달 못함, 실기 검증은 계속 진행 중.

최종 선택: 유료 bootloader 잠금 해제로 하향(더 이상 이 경로에 의존하지 않음).

도구 다운로드