
CVE-2026-98260용 Android 프런트엔드: Shizuku를 통한 root 셸 + KernelSU late-load
CVE-2026-98260(POSIX CPU 타이머 use-after-free)을 위한 Android 프런트 엔드로, CVE-2026-64560과 동일한 부류의 버그입니다. 한 번의 탭으로 루트 셸을 얻은 다음 KernelSU(u:r:ksu:s0)를 지연 로드합니다.
익스플로잇 자체는 여기에 포함되어 있지 않습니다. 이 저장소는 그 주변의 앱 셸입니다. 즉, UI, 상태 감지, 그리고 일반 앱에서 셸 도메인 익스플로잇을 실행하는 데 필요한 Shizuku 연결부입니다.
앱은 untrusted_app으로 실행되며 /sys/kernel/tracing을 읽을 수 없는데, 익스플로잇은 누출과 트리거를 위해 이 경로가 필요합니다. 따라서 TimerRoot는 Shizuku 사용자 서비스를 시작하며, Shizuku는 이를 셸 사용자(uid 2000, u:r:shell:s0)로 실행합니다. 익스플로잇 바이너리는 해당 프로세스 내부에서 실행되므로 adb shell에서 얻었을 것과 동일한 환경을 갖습니다.
MainActivity (untrusted_app)
└─ Shizuku user service (uid 2000, u:r:shell:s0)
├─ extracts assets/timer to /data/local/tmp/timer
└─ runs it; on success keeps /system/bin/sh alive
minSdk 30), arm64Load KernelSU 경로를 위해 KernelSU 매니저 설치됨6.12.69-android16-6-g242e1a07f878-ab15865446-4k를 대상으로 함; 아래 참조.TimerRoot는 컴파일된 익스플로잇을 app/src/main/assets/timer에서 찾습니다:
git clone https://github.com/YuKongA/CVE-2026-98260
cp CVE-2026-98260/timer/timer app/src/main/assets/timer
또는
scripts/fetch-timer.ps1
바이너리는 저자들에 의해 MIT 라이선스로 배포됩니다. 소유한 하드웨어에서만 사용하고, 커널이 포팅된 빌드와 일치할 때만 사용하십시오.
프로젝트를 열고 빌드하거나:
./gradlew assembleDebug
프로젝트에는 플랫폼 36과 빌드 도구 36이 포함된 Android SDK가 필요합니다. Shizuku API는 Maven(dev.rikka.shizuku:api)에서 가져옵니다.
scripts/build.ps1은 SDK, javac, d8, aapt2, apksigner만으로 APK를 빌드하고 서명합니다. 아무것도 벤더링하지 않습니다. 앱을 Shizuku API 소스와 함께 컴파일하므로, 먼저 해당 소스를 클론하세요:
git clone https://github.com/RikkaApps/Shizuku-API
scripts/build.ps1 -Sdk "C:\Users\<you>\AppData\Local\Android\Sdk"
TimerRoot가 어떤 작업이든 수행하려면 Shizuku가 먼저 실행 중이어야 합니다. Shizuku는 익스플로잇에 필요한 shell 사용자를 제공하는 프로세스입니다. Shizuku는 재부팅할 때마다 중지되므로, 매번 이 단계가 첫 번째 단계입니다.
무선 디버깅 (최초 페어링 이후 PC 불필요)
USB 사용
휴대전화를 연결하고 USB 디버깅을 승인한 상태에서:
adb shell sh /sdcard/Android/data/moe.shizuku.privileged.api/start.sh
최신 Shizuku 릴리스에서는 해당 스크립트가 더 이상 포함되지 않을 수 있습니다. 스크립트가 없는 경우에는 위의 무선 디버깅 경로를 사용하세요.
서버가 실행 중인지 확인하세요:
adb shell ps -A | grep shizuku_server
# shell 12345 1 ... shizuku_server
ps에 moe.shizuku.privileged.api만 표시된다면 매니저 앱은 열려 있지만
서버는 실행 중이 아니라는 뜻입니다. 서버가 실행되기 전까지는 익스플로잇을 시작할 수 없습니다.
연결되지 않음으로 표시되면 도구 행에서 Shizuku를 눌러 다시 요청합니다.Prepare는 assets/timer를 /data/local/tmp/timer로 추출합니다:
installed 307192 bytes
한 번의 탭. 앱이 권한을 상승시키고, 서비스 내부에 uid=0 셸을 유지한 다음,
KernelSU 지연 로드를 자동으로 시작합니다:
[child] woke uid=0
root shell ready - loading KernelSU...
Loading KernelSU... 12s
KSU_LOADED
카드는 Root shell -> Jailbreak mode(u:r:ksu:s0)로 전환됩니다. KernelSU 단계가 경쟁에서 지면 카드가 KernelSU failed와 함께 빨간색으로 바뀌며, 재시도하기 전에 재부팅해야 합니다.
Reboot 알약 버튼을 사용하세요. 이 버튼은 서비스(svc power reboot)를 거치므로 아직 root 셸이 열려 있지 않아도 작동합니다. 재부팅은 대기 중인 프로세스를 제거하고 KernelSU를 언로드하는 유일한 깔끔한 방법이기도 합니다.
재부팅 후에는 1단계부터 다시 시작하세요. Shizuku는 중지되고 KernelSU는 사라집니다.
상태 카드는 su -c id를 실행하고 u:r:ksu:s0를 확인하여 감지된, 실제로 활성 상태인 내용을 반영합니다:
| 카드 | 의미 |
|---|---|
| Not connected | Shizuku가 실행 중이 아님 / 바인딩되지 않음 |
| Ready | Shizuku 연결됨, 아직 root 없음 |
| Root shell | uid=0, u:r:shell:s0 |
| Jailbreak mode | KernelSU 로드됨, su가 u:r:ksu:s0에서 작동함 |
KernelSU failed 및 base calibration failed가 표시됨가짜 자격 증명 단계에는 커널 선형 매핑 베이스가 필요하며, 익스플로잇은 이를 페이지 할당 추적 이벤트에서 도출합니다. 이는 4 KB 페이지를 가정합니다:
[base] made=512 best=0 count=0
[-] base calibration failed
디바이스의 페이지 크기를 확인합니다:
adb shell getconf PAGE_SIZE
4096: 다른 이유로 레이아웃이 다릅니다. uname -r, 모델, 전체 로그를 수집하여 업스트림에 보고하세요.16384: 이 익스플로잇은 출하 상태 그대로는 이 기기에서 동작할 수 없습니다. 16 KB 페이지(페이지 시프트, 마스크, 오더 크기)에 맞게 재빌드해야 하며, 이는 앱 설정이 아니라 포팅 작업입니다.루트 셸은 이러한 기기에서도 여전히 성공할 수 있는데, 해당 경로는 선형 맵 베이스가 아니라 유출된 자격 증명 주소만 필요로 하기 때문입니다.
Not connected에 머무름Shizuku가 실행 중이 아닙니다. 다시 시작하고(재부팅할 때마다 중지됨) 1단계를 확인하세요.
Prepare가 아무것도 보고하지 않음시스템 대화상자가 앱을 가리고 있을 수 있습니다(Shizuku 페어링, OPPO 설치 프로그램 검사). 닫고 Prepare를 다시 누르세요.
이것은 커널 익스플로잇입니다. 아무것도 누르기 전에 읽어 보세요.
app/src/main/java/com/kpgc/timerroot/MainActivity.java UI and state
app/src/main/java/com/kpgc/timerroot/UserService.java runs as the shell user
app/src/main/aidl/com/kpgc/timerroot/IUserService.aidl service interface
app/src/main/assets/timer exploit binary (not in git)
scripts/build.ps1 Gradle-free build
이 저장소의 앱 코드는 MIT입니다. 익스플로잇 바이너리와 Shizuku API는 각자의 라이선스를 유지합니다.