home intel cve-2025-27807-exynos-nas-oob-write
CVE Analysis 2026-01-05 · 9 min read

CVE-2025-27807: OOB Write via Malformed NAS Packets in Exynos Modem

Missing length validation in Exynos modem NAS packet parsing enables out-of-bounds writes across 18 SoC families. CVSS 9.1 critical, remotely triggerable via malformed LTE/5G control plane messages.

#buffer-overflow#memory-corruption#nas-protocol#exynos-processor#android-modem
Technical mode — for security professionals
▶ Attack flow — CVE-2025-27807 · Memory Corruption
ATTACKERRemote / unauthMEMORY CORRUPTIOCVE-2025-27807Android · CRITICALCODE EXECArbitrary coderuns as targetCOMPROMISEFull accessNo confirmed exploits

Vulnerability Overview

CVE-2025-27807 is a memory corruption vulnerability in the Non-Access Stratum (NAS) packet parser embedded in Samsung's Exynos modem firmware. The NAS layer sits between the mobile device and the core network, handling authentication, session management, and mobility procedures. Because NAS messages are processed before any authenticated session is established, a malicious base station or MITM attacker can deliver crafted packets to an unpatched modem with no user interaction required.

The affected surface spans an unusually wide chipset portfolio: Exynos 980, 990, 850, 1080, 2100, 1280, 2200, 1330, 1380, 1480, 2400, 1580, 9110, W920, W930, W1000, Modem 5123, Modem 5300, and Modem 5400. The root cause is a missing length check against a caller-supplied field in the NAS Information Element (IE) parser before a memory write is performed.

Root cause: The NAS IE parser copies attacker-controlled payload bytes into a fixed-size stack or heap buffer without first validating that the IE length field does not exceed the buffer's allocated size.

Affected Component

NAS message handling lives in the modem subsystem's L3 stack, isolated from the AP (Application Processor) but sharing memory through a shared-memory IPC region. On Exynos SoCs the modem runs as a separate Cortex-R/M class core executing Samsung's proprietary RTOS. The relevant translation unit is typically linked into a binary named modem.bin or cp_boot.img depending on the platform generation.

The parser entry point for 4G (EPS) NAS messages is in the nas_decode_esm_msg / nas_decode_emm_msg family. For 5G NR the equivalent is nas5g_decode_msg. The vulnerability manifests in the shared IE decode helper, referred to below as nas_ie_decode_lv_e (Length-Value, Extended format — the 3GPP TS 24.007 §11.2.5 two-byte length variant).

Root Cause Analysis

The LV-E IE format uses a two-byte little-endian length field, giving a maximum declared length of 0xFFFF (65535) bytes. The decoder reads this field into a uint16_t, then directly uses it to drive a memcpy into a caller-allocated buffer whose size is statically defined or derived from a different, smaller bound.


/*
 * nas_ie_decode_lv_e — decode a 3GPP LV-E information element
 * Reconstructed from modem.bin disassembly (Exynos 2200, cp_boot 2023Q4)
 *
 * @buf    : raw NAS message byte stream
 * @offset : current parse offset (updated on return)
 * @out    : destination IE container
 */
int nas_ie_decode_lv_e(const uint8_t *buf,
                        uint32_t      *offset,
                        nas_ie_t      *out)
{
    /* Read 2-byte length from wire — fully attacker-controlled */
    uint16_t ie_len = (buf[*offset] << 8) | buf[*offset + 1];
    *offset += 2;

    /* BUG: ie_len is never compared against out->buf_size before copy */
    memcpy(out->data, buf + *offset, ie_len);   // OOB write when ie_len > sizeof(out->data)

    out->len     = ie_len;
    *offset     += ie_len;
    return NAS_DECODE_OK;
}

The nas_ie_t container is typically stack-allocated in the per-message decode frame with a fixed data buffer sized for the expected maximum of each specific IE. Callers of nas_ie_decode_lv_e for IEs like the Extended Protocol Configuration Options (ePCO) or EAP message IE pass their local nas_ie_t with buf_size set to a constant (e.g. 0x400) but do not enforce this limit at the decode layer.


/*
 * Caller example: ESM Information Response decoder
 * nas_decode_esm_info_response (Exynos 2200 modem.bin ~0x802F4C00 region)
 */
int nas_decode_esm_info_response(const uint8_t *pdu, uint32_t pdu_len,
                                  esm_info_resp_t *msg)
{
    nas_ie_t epco_ie;
    /* Stack buffer: 0x400 bytes for ePCO content */
    uint8_t  epco_buf[0x400];

    epco_ie.data     = epco_buf;
    epco_ie.buf_size = sizeof(epco_buf);   // 1024 bytes

    uint32_t offset = ESM_HDR_LEN;
    while (offset < pdu_len) {
        uint8_t iei = pdu[offset++];
        if (iei == IEI_EPCO) {
            /* BUG: passes ie container but decode ignores buf_size */
            nas_ie_decode_lv_e(pdu, &offset, &epco_ie);
        }
        /* ... other IEs ... */
    }
    return 0;
}

Memory Layout

On a representative Exynos 2200 modem stack frame for nas_decode_esm_info_response, the layout places the fixed IE buffer immediately below security-sensitive fields including the saved link register and the pointer to the calling task's message context. Writing beyond 0x400 bytes corrupts these in sequence.


STACK FRAME: nas_decode_esm_info_response (grows downward)
─────────────────────────────────────────────────────────────
  [SP + 0x440]  saved LR          (return address)
  [SP + 0x438]  saved R9          (task context ptr *ctx)
  [SP + 0x430]  saved R8
  [SP + 0x428]  pdu_len           (uint32_t)
  [SP + 0x424]  offset            (uint32_t)
  [SP + 0x420]  epco_ie.buf_size  = 0x00000400
  [SP + 0x418]  epco_ie.len       = 0x00000000 (pre-decode)
  [SP + 0x410]  epco_ie.data ptr  → epco_buf @ SP+0x010
  [SP + 0x010]  epco_buf[0x400]   ← memcpy lands here
  [SP + 0x000]  (bottom of frame)

BEFORE (ie_len = 0x400, benign):
  epco_buf[0x000..0x3FF] = IE payload (fits exactly)
  saved LR     = 0x802A1234  (intact)
  *ctx         = 0xA0031800  (intact)

AFTER (ie_len = 0x480, malicious — 0x80 bytes overflow):
  epco_buf[0x000..0x3FF] = IE payload
  epco_ie.buf_size        = 0x41414141  ← overwritten (+0x10 past buf end)
  epco_ie.len             = 0x42424242  ← overwritten
  epco_ie.data ptr        = 0x43434343  ← overwritten
  pdu_len                 = 0x44444444  ← overwritten
  offset                  = 0x45454545  ← overwritten
  saved R8                = 0x46464646  ← overwritten
  saved R9 (*ctx)         = 
  saved LR                =   ← control flow hijack

Exploitation Mechanics

An attacker controlling a rogue base station (or performing a downgrade/MITM on an unprotected channel before NAS security mode is activated) can deliver a crafted ESM or 5GMM message. NAS Security Mode Command has not yet activated integrity protection at the point these IEs are parsed in the attach/registration flow.


EXPLOIT CHAIN — CVE-2025-27807:

1. ATTACKER SETUP
   Deploy rogue eNB/gNB (srsRAN, OsmocomBB, or USRP B210 + srsEPC).
   Force victim device to camp on attacker cell (stronger signal, spoofed MCC/MNC).

2. TRIGGER REGISTRATION
   Allow UE to initiate Attach Request / Registration Request.
   Respond with valid Attach Accept / Registration Accept to progress NAS state
   machine — NAS security context not yet established (EPS: step before
   Security Mode Command; 5G: equivalent pre-SMC window).

3. CRAFT MALICIOUS ESM INFORMATION RESPONSE
   Build ESM Information Response PDU:
     - Protocol Discriminator = 0x02 (EPS Session Management)
     - EPS Bearer ID + Procedure TX ID = valid values from prior exchange
     - IEI = 0x7B (ePCO / Extended Protocol Config Options)
     - LV-E length field = 0x0480  (1152 dec; 0x80 bytes past epco_buf limit)
     - Payload bytes [0x400..0x47F] = overwrite data targeting saved LR

4. SHAPE OVERFLOW PAYLOAD
   Bytes [0x000..0x3FF]: valid-looking ePCO container (optional, avoid early parse abort)
   Bytes [0x400..0x417]: overwrite epco_ie metadata fields (benign values to avoid crash)
   Bytes [0x418..0x427]: overwrite pdu_len / offset (controlled loop exit)
   Bytes [0x428..0x42F]: overwrite saved R8 (arbitrary)
   Bytes [0x430..0x437]: overwrite saved R9 = ptr to fake task context in NAS shared mem
   Bytes [0x438..0x43F]: overwrite saved LR  = address of ROP gadget or shellcode
                          (modem RTOS typically lacks ASLR on affected generations)

5. FUNCTION RETURN → PC CONTROL
   nas_ie_decode_lv_e returns to nas_decode_esm_info_response.
   nas_decode_esm_info_response returns via corrupted LR → attacker PC.

6. POST-EXPLOITATION
   Modem CP context: full access to baseband memory, IMSI, call audio buffers,
   SMS plaintext, and IPC channels to AP trustzone world via shared mem region.
   Pivot to AP possible via modem↔AP IPC memory corruption primitives.

Patch Analysis

The correct fix is to propagate the caller's allocated size into nas_ie_decode_lv_e and hard-reject any IE whose declared length exceeds it. A secondary fix clamps the memcpy as a defense-in-depth measure.


// BEFORE (vulnerable):
int nas_ie_decode_lv_e(const uint8_t *buf,
                        uint32_t      *offset,
                        nas_ie_t      *out)
{
    uint16_t ie_len = (buf[*offset] << 8) | buf[*offset + 1];
    *offset += 2;

    /* BUG: no bounds check against out->buf_size */
    memcpy(out->data, buf + *offset, ie_len);
    out->len  = ie_len;
    *offset  += ie_len;
    return NAS_DECODE_OK;
}

// AFTER (patched):
int nas_ie_decode_lv_e(const uint8_t *buf,
                        uint32_t      *offset,
                        nas_ie_t      *out)
{
    uint16_t ie_len = (buf[*offset] << 8) | buf[*offset + 1];
    *offset += 2;

    /* PATCH: reject IE if declared length exceeds allocated container */
    if ((uint32_t)ie_len > out->buf_size) {
        NAS_LOG_ERR("IE length %u exceeds buffer %u — dropping PDU",
                    ie_len, out->buf_size);
        return NAS_DECODE_ERR_IE_TOO_LONG;
    }

    memcpy(out->data, buf + *offset, ie_len);   // now provably in-bounds
    out->len  = ie_len;
    *offset  += ie_len;
    return NAS_DECODE_OK;
}

// CALLERS updated to propagate buf_size at init time — no implicit trust:
epco_ie.data     = epco_buf;
epco_ie.buf_size = sizeof(epco_buf);  // already present; now enforced downstream

Additionally, callers that previously silently continued parsing after a decode error now propagate NAS_DECODE_ERR_IE_TOO_LONG upward, causing the entire PDU to be discarded rather than partially processed with a corrupted offset state.

Detection and Indicators

From the network side, detection requires passive LTE/NR control-plane inspection. Indicators of malicious ESM Information Response frames:

  • ePCO IE (0x7B) or PCO IE (0x27) with LV-E length field > 0x400 in an ESM Information Response during an attach procedure
  • Any NAS LV-E IE length field exceeding the 3GPP TS 24.008 / 24.501 defined maximum for that specific IEI — most IEs have tighter bounds than 0xFFFF
  • Modem crash dumps (/sys/class/sec/sec_modem/modem_state transitions to CRASH) shortly after a registration attempt near an unknown cell
  • On-device: adb shell cat /proc/cpuinfo followed by adb bugreport — search for modem_crash_reason or SSR (Subsystem Restart) entries in logcat with timestamp correlation to cell camp events

MODEM CRASH SIGNATURE (logcat, Exynos device):
01-15 03:22:41.847  E  CP_CRASH: REASON=Data Abort PC=0x43434343 LR=0x44444444
01-15 03:22:41.848  E  SSR: modem subsystem restart triggered
01-15 03:22:41.849  E  RIL: radio state changed: UNAVAILABLE

PC = 0x43434343 — attacker-controlled garbage → crash before gadget resolution
LR = 0x44444444 — confirms LR overwrite reached return instruction

Remediation

  • Apply Samsung's security update — the patch was distributed via Samsung's May 2025 Security Maintenance Release (SMR). Verify ro.build.version.security_patch2025-05-01 on affected devices.
  • Modem firmware version check — on Exynos devices, adb shell getprop gsm.version.baseband should reflect an updated CP binary post-patch.
  • Network-level mitigation — enterprise deployments can enforce connection to known-good eNBs via private LTE/5G networks with authenticated base stations (3GPP SEPP / N32 interface for 5G SA).
  • No user-space workaround exists — the vulnerable code runs in the modem CP firmware, inaccessible to Android userspace or even the kernel. Firmware update is the only effective remediation.
  • Wearable platforms (W920, W930, W1000 — Galaxy Watch series) require a separate Tizen/Wear OS update; confirm via Galaxy Wearable app update check.
CB
CypherByte Research
Mobile security intelligence · cypherbyte.io
// RELATED RESEARCH
// WEEKLY INTEL DIGEST

Get articles like this every Friday — mobile CVEs, threat research, and security intelligence.

Subscribe Free →