Headline
CVE-2023-23009: abnormal TS payload causes pluto daemon to restart in libreswan 4.9 · Issue #954 · libreswan/libreswan
Libreswan 4.9 allows remote attackers to cause a denial of service (assert failure and daemon restart) via crafted TS payload with an incorrect selector length.
Hi, I found a bug in libreswan-4.9 which caused the pluto daemon to restart by sending several crafted IKEv2 messages to the server.
process
first, send correct IKE_SA_INIT message and IKE_AUTH message so that the IPSEC_SA and CHILD_SA are established successfully.
then, send a REKEY_CHILD_SA message with an incorrect TSi payload. specifically, the Selector Length of the Traffic Selector need to be a different value from the real length(samller or larger, it doesn’t matter). This will cause a crash when the server trys to parse this payload.
my conf
conn ikev2_test
authby=secret
ike=aes128-sha1;modp1536
keyexchange=ike
phase2=esp
phase2alg=aes128-sha1
compress=no
pfs=no
auto=add
type=tunnel
left=192.168.100.31
leftnexthop=%defaultroute
right=192.168.100.30
rightnexthop=%defaultroute
my pluto.log for parsing the REKEY_CHILD_SA message
when parsing 1 traffic selectors , the pluto restart
Dec 20 06:04:47.516841: | *received 204 bytes from 192.168.100.30:36062 on ens33 192.168.100.31:500 using UDP
Dec 20 06:04:47.516901: | d8 ef b8 ef 3b 3a f8 a4 41 06 0f 82 7d 60 77 86
Dec 20 06:04:47.516904: | 2e 20 24 08 00 00 00 02 00 00 00 cc 29 00 00 b0
Dec 20 06:04:47.516906: | e6 8b 54 3f 30 cb cc 93 70 a6 79 47 ff c1 d3 7f
Dec 20 06:04:47.516908: | 83 6d d7 2b 44 b5 86 75 64 fb cb f0 f9 f3 e5 b7
Dec 20 06:04:47.516910: | 94 60 b4 26 3e 16 fc 6d 2d 76 9d 8e 82 11 59 c1
Dec 20 06:04:47.516911: | c3 5a 68 2c 01 5e 4f ed 8d b7 e7 56 b3 23 24 cc
Dec 20 06:04:47.516913: | dd bf e5 76 03 a3 33 36 83 5e 06 f2 71 bf 75 86
Dec 20 06:04:47.516915: | 07 f8 01 da 32 01 9e 89 9c aa a0 98 62 72 96 b8
Dec 20 06:04:47.516917: | 38 ef 32 31 1a 6f d2 50 d8 50 0f 92 49 cb 33 20
Dec 20 06:04:47.516919: | 4b 2c b0 7b f8 a4 8a ea 8f f8 ca 94 84 cf a7 ff
Dec 20 06:04:47.516921: | f1 e7 19 df c1 6b ae f9 6a c7 dc ca 3a dc ea 72
Dec 20 06:04:47.516923: | d5 08 2e 70 2f 79 15 52 a8 bf 07 ea fc 8b 3c 96
Dec 20 06:04:47.516925: | 26 0c cf 18 c3 44 f2 ea f2 09 af 5c
Dec 20 06:04:47.516933: | **parse ISAKMP Message:
Dec 20 06:04:47.516937: | initiator SPI: d8 ef b8 ef 3b 3a f8 a4
Dec 20 06:04:47.516940: | responder SPI: 41 06 0f 82 7d 60 77 86
Dec 20 06:04:47.516942: | next payload type: ISAKMP_NEXT_v2SK (0x2e)
Dec 20 06:04:47.516944: | ISAKMP version: IKEv2 version 2.0 (rfc4306/rfc5996) (0x20)
Dec 20 06:04:47.516946: | exchange type: ISAKMP_v2_CREATE_CHILD_SA (0x24)
Dec 20 06:04:47.516949: | flags: ISAKMP_FLAG_v2_IKE_INIT (0x8)
Dec 20 06:04:47.516952: | Message ID: 2 (00 00 00 02)
Dec 20 06:04:47.516955: | length: 204 (00 00 00 cc)
Dec 20 06:04:47.516957: | processing version=2.0 packet with exchange type=ISAKMP_v2_CREATE_CHILD_SA (36)
Dec 20 06:04:47.516960: | I am the IKE SA Original Responder receiving an IKEv2 CREATE_CHILD_SA request
Dec 20 06:04:47.516970: | State DB: found IKEv2 state #1 in ESTABLISHED_IKE_SA (find_v2_ike_sa)
Dec 20 06:04:47.516974: | #1 st.st_msgid_lastrecv 1 md.hdr.isa_msgid 00000002
Dec 20 06:04:47.516981: | Message ID: IKE #1 not a duplicate - message request 2 is new (SKEYSEED is known) (initiator: .sent=-1 .recv=-1 .recv_frags=0 .wip=-1 .last_sent=36587.248097 .last_recv=36587.248097 responder: .sent=1 .recv=1 .recv_frags=0 .wip=-1 .last_sent=36587.284336 .last_recv=36587.284331)
Dec 20 06:04:47.516983: | unpacking clear payload
Dec 20 06:04:47.516985: | Now let’s proceed with payload (ISAKMP_NEXT_v2SK)
Dec 20 06:04:47.516988: | ***parse IKEv2 Encryption Payload:
Dec 20 06:04:47.516991: | next payload type: ISAKMP_NEXT_v2N (0x29)
Dec 20 06:04:47.516993: | flags: none (0x0)
Dec 20 06:04:47.516995: | length: 176 (00 b0)
Dec 20 06:04:47.516998: | processing payload: ISAKMP_NEXT_v2SK (len=172)
Dec 20 06:04:47.517002: | looking for transition from ESTABLISHED_IKE_SA matching CREATE_CHILD_SA request: SK (ignoring secured payloads)
Dec 20 06:04:47.517026: | trying: process rekey IKE SA request (CREATE_CHILD_SA)
Dec 20 06:04:47.517028: | matching by ignoring secured payloads
Dec 20 06:04:47.517088: | authenticator matched
Dec 20 06:04:47.517102: | stripping 4 octets as pad
Dec 20 06:04:47.517105: | #1 ikev2 ISAKMP_v2_CREATE_CHILD_SA decrypt success
Dec 20 06:04:47.517108: | Now let’s proceed with payload (ISAKMP_NEXT_v2N)
Dec 20 06:04:47.517112: | **parse IKEv2 Notify Payload:
Dec 20 06:04:47.517114: | next payload type: ISAKMP_NEXT_v2SA (0x21)
Dec 20 06:04:47.517116: | flags: none (0x0)
Dec 20 06:04:47.517118: | length: 12 (00 0c)
Dec 20 06:04:47.517121: | Protocol ID: IKEv2_SEC_PROTO_ESP (0x3)
Dec 20 06:04:47.517123: | SPI size: 4 (04)
Dec 20 06:04:47.517126: | Notify Message Type: v2N_REKEY_SA (0x4009)
Dec 20 06:04:47.517128: | processing payload: ISAKMP_NEXT_v2N (len=4)
Dec 20 06:04:47.517130: | Now let’s proceed with payload (ISAKMP_NEXT_v2SA)
Dec 20 06:04:47.517133: | **parse IKEv2 Security Association Payload:
Dec 20 06:04:47.517135: | next payload type: ISAKMP_NEXT_v2Ni (0x28)
Dec 20 06:04:47.517137: | flags: none (0x0)
Dec 20 06:04:47.517140: | length: 44 (00 2c)
Dec 20 06:04:47.517142: | processing payload: ISAKMP_NEXT_v2SA (len=40)
Dec 20 06:04:47.517144: | Now let’s proceed with payload (ISAKMP_NEXT_v2Ni)
Dec 20 06:04:47.517146: | **parse IKEv2 Nonce Payload:
Dec 20 06:04:47.517148: | next payload type: ISAKMP_NEXT_v2TSi (0x2c)
Dec 20 06:04:47.517149: | flags: none (0x0)
Dec 20 06:04:47.517152: | length: 36 (00 24)
Dec 20 06:04:47.517154: | processing payload: ISAKMP_NEXT_v2Ni (len=32)
Dec 20 06:04:47.517156: | Now let’s proceed with payload (ISAKMP_NEXT_v2TSi)
Dec 20 06:04:47.517158: | **parse IKEv2 Traffic Selector - Initiator - Payload:
Dec 20 06:04:47.517160: | next payload type: ISAKMP_NEXT_v2TSr (0x2d)
Dec 20 06:04:47.517162: | flags: none (0x0)
Dec 20 06:04:47.517164: | length: 24 (00 18)
Dec 20 06:04:47.517166: | number of TS: 1 (01)
Dec 20 06:04:47.517168: | processing payload: ISAKMP_NEXT_v2TSi (len=16)
Dec 20 06:04:47.517170: | Now let’s proceed with payload (ISAKMP_NEXT_v2TSr)
Dec 20 06:04:47.517173: | **parse IKEv2 Traffic Selector - Responder - Payload:
Dec 20 06:04:47.517175: | next payload type: ISAKMP_NEXT_v2NONE (0x0)
Dec 20 06:04:47.517177: | flags: none (0x0)
Dec 20 06:04:47.517179: | length: 24 (00 18)
Dec 20 06:04:47.517181: | number of TS: 1 (01)
Dec 20 06:04:47.517183: | processing payload: ISAKMP_NEXT_v2TSr (len=16)
Dec 20 06:04:47.517187: | looking for transition from ESTABLISHED_IKE_SA matching CREATE_CHILD_SA request: SK{N(REKEY_SA),SA,Ni,TSi,TSr}
Dec 20 06:04:47.517189: | trying: process rekey IKE SA request (CREATE_CHILD_SA)
Dec 20 06:04:47.517191: | secured payloads do not match
Dec 20 06:04:47.517192: | trying: process rekey IKE SA response (CREATE_CHILD_SA)
Dec 20 06:04:47.517195: | message role does not match response
Dec 20 06:04:47.517197: | trying: process rekey Child SA request (CREATE_CHILD_SA)
Dec 20 06:04:47.517198: | secured message matched
Dec 20 06:04:47.517201: | selected state microcode process rekey Child SA request (CREATE_CHILD_SA)
Dec 20 06:04:47.517205: | #1 updating local interface from 192.168.100.31:500 to 192.168.100.31:500 using md->iface (update_ike_endpoints() +2598 /programs/pluto/state.c)
Dec 20 06:04:47.517210: | #1.st_v2_transition PARENT_R1->ESTABLISHED_IKE_SA -> ESTABLISHED_IKE_SA->ESTABLISHED_IKE_SA (v2_dispatch() +2292 /programs/pluto/ikev2.c)
Dec 20 06:04:47.517215: | Message ID: IKE #1 responder starting message request 2 (initiator: .sent=-1 .recv=-1 .recv_frags=0 .wip=-1 .last_sent=36587.248097 .last_recv=36587.248097 responder: .sent=1 .recv=1 .recv_frags=0 .wip=2 .last_sent=36587.284336 .last_recv=36587.284331)
Dec 20 06:04:47.517218: | calling processor process rekey Child SA request (CREATE_CHILD_SA)
Dec 20 06:04:47.517221: | CREATE_CHILD_SA IPsec SA rekey Protocol IKEv2_SEC_PROTO_ESP
Dec 20 06:04:47.517223: | parsing 4 raw bytes of IKEv2 Notify Payload into SPI
Dec 20 06:04:47.517229: | SPI
Dec 20 06:04:47.517232: | 0d bb 3a 00 …:.
Dec 20 06:04:47.517234: | CREATE_CHILD_S to rekey IPsec SA(0x0dbb3a00) Protocol IKEv2_SEC_PROTO_ESP
Dec 20 06:04:47.517237: | v2 CHILD SA #2 found using their inbound (our outbound) SPI, in STATE_V2_ESTABLISHED_CHILD_SA
Dec 20 06:04:47.517239: | State DB: found IKEv2 state #2 in ESTABLISHED_CHILD_SA (find_v2_child_sa_by_outbound_spi)
Dec 20 06:04:47.517242: | #1 hasa a rekey request for “ikev2_test” #2 TSi TSr
Dec 20 06:04:47.517246: | addref fd@NULL (duplicate_state() +1538 /programs/pluto/state.c)
Dec 20 06:04:47.517252: | entry state hash_table_entries.serialno@0x55a1f6e50ea8 “ikev2_test” #3 initialized
Dec 20 06:04:47.517255: | entry state hash_table_entries.connection_serialno@0x55a1f6e50ea8 $2 initialized
Dec 20 06:04:47.517257: | entry state hash_table_entries.reqid@0x55a1f6e50ea8 “ikev2_test” #3: reqid=0 initialized
Dec 20 06:04:47.517261: | entry state hash_table_entries.ike_initiator_spi@0x55a1f6e50ea8 “ikev2_test” #3: 00 00 00 00 00 00 00 00 initialized
Dec 20 06:04:47.517264: | entry state hash_table_entries.ike_spis@0x55a1f6e50ea8 “ikev2_test” #3: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 initialized
Dec 20 06:04:47.517266: | creating state object #3 at 0x55a1f6e50ea8
Dec 20 06:04:47.517283: | entry state hash_table_entries.serialno@0x55a1f6e50ea8 “ikev2_test” #3 added to hash table bucket 0x55a1f5778b20
Dec 20 06:04:47.517286: | entry state hash_table_entries.connection_serialno@0x55a1f6e50ea8 $2 added to hash table bucket 0x55a1f5774ea0
Dec 20 06:04:47.517289: | entry state hash_table_entries.reqid@0x55a1f6e50ea8 “ikev2_test” #3: reqid=0 added to hash table bucket 0x55a1f576e0a0
Dec 20 06:04:47.517292: | entry state hash_table_entries.ike_initiator_spi@0x55a1f6e50ea8 “ikev2_test” #3: d8 ef b8 ef 3b 3a f8 a4 added to hash table bucket 0x55a1f576dbc0
Dec 20 06:04:47.517295: | entry state hash_table_entries.ike_spis@0x55a1f6e50ea8 “ikev2_test” #3: d8 ef b8 ef 3b 3a f8 a4 41 06 0f 82 7d 60 77 86 added to hash table bucket 0x55a1f57671c0
Dec 20 06:04:47.517298: | pstats #3 ikev2.child started
Dec 20 06:04:47.517301: | duplicating state object #1 “ikev2_test” as #3 for IPSEC SA
Dec 20 06:04:47.517304: | #3 setting local endpoint to 192.168.100.31:500 from #1.st_localport (duplicate_state() +1553 /programs/pluto/state.c)
Dec 20 06:04:47.517310: | child state #3: UNDEFINED(ignore) => REKEY_CHILD_R0(established IKE SA)
Dec 20 06:04:47.517313: | #3.st_v2_transition NULL -> REKEY_CHILD_R0->ESTABLISHED_CHILD_SA (new_v2_child_state() +1636 /programs/pluto/state.c)
Dec 20 06:04:47.517317: | constructing ESP/AH proposals with default DH NONE for ikev2_test (Child SA proposals (initiating rekey))
Dec 20 06:04:47.517322: | converting proposal AES_CBC_128-HMAC_SHA1_96 to ikev2 …
Dec 20 06:04:47.517328: | … ikev2_proposal: 1:ESP=AES_CBC_128-HMAC_SHA1_96-NONE-ENABLED+DISABLED
Dec 20 06:04:47.517331: | TSi: parsing 1 traffic selectors
Dec 20 06:04:48.074282: | releasing whack fd@(nil) for (main() +1602 /programs/pluto/plutomain.c)
Dec 20 06:04:48.074334: | delref fd@NULL (main() +1602 /programs/pluto/plutomain.c)
Dec 20 06:04:48.074348: | delref fd@NULL (main() +1602 /programs/pluto/plutomain.c)
Dec 20 06:04:48.074360: | checking IKEv1 state table
related code in ikev2_ts.c
I think this is the code that causes the error. When parsing an incorrect TSi payload with wrong selecter length, pbs_in_struct return early, so the ts_body_pbs is not initialized.
struct ikev2_ts_header ts_h;
struct pbs_in ts_body_pbs;
d = pbs_in_struct(&ts_pd->pbs, &ikev2_ts_header_desc,
&ts_h, sizeof(ts_h), &ts_body_pbs);
switch (ts_h.isath_type) {
case IKEv2_TS_IPV4_ADDR_RANGE:
case IKEv2_TS_IPV6_ADDR_RANGE:
{
ts->ipprotoid = ts_h.isath_ipprotoid;
/* read and fill in port range */
struct ikev2_ts_portrange pr;
d = pbs_in_struct(&ts_body_pbs, &ikev2_ts_portrange_desc,
&pr, sizeof(pr), NULL);
I also tested several other versions, it seems to have the same problem in libreswan 4.5 - 4.8
Related news
An update for libreswan is now available for Red Hat Enterprise Linux 8. Red Hat Product Security has rated this update as having a security impact of Moderate. A Common Vulnerability Scoring System (CVSS) base score, which gives a detailed severity rating, is available for each vulnerability from the CVE link(s) in the References section.This content is licensed under the Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0/). If you distribute this content, or a modified version of it, you must provide attribution to Red Hat Inc. and provide a link to the original. Related CVEs: * CVE-2023-23009: A flaw was found in the Libreswan package. A crafted TS payload with an incorrect selector length may allow a remote attacker to cause a denial of service.
An update for libreswan is now available for Red Hat Enterprise Linux 9. Red Hat Product Security has rated this update as having a security impact of Moderate. A Common Vulnerability Scoring System (CVSS) base score, which gives a detailed severity rating, is available for each vulnerability from the CVE link(s) in the References section.This content is licensed under the Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0/). If you distribute this content, or a modified version of it, you must provide attribution to Red Hat Inc. and provide a link to the original. Related CVEs: * CVE-2023-23009: A flaw was found in the Libreswan package. A crafted TS payload with an incorrect selector length may allow a remote attacker to cause a denial of service.
Debian Linux Security Advisory 5368-1 - It was discovered that the libreswan IPsec implementation could be forced into a crash/restart via malformed IKEv2 packets after peer authentication, resulting in denial of service.