ike: set event for multiple server proposals

pull/6101/head
frank honza 4 years ago committed by Victor Julien
parent 488d5fb342
commit f83d51d0cb

@ -1838,6 +1838,7 @@ Fields
* "ikev1.server.nonce_payload_length", "ikev1.client.nonce_payload_length": Length of the nonce payload. * "ikev1.server.nonce_payload_length", "ikev1.client.nonce_payload_length": Length of the nonce payload.
* "ikev1.client.client_proposals": List of the security associations proposed to the server. * "ikev1.client.client_proposals": List of the security associations proposed to the server.
* "ikev1.vendor_ids": List of the vendor IDs observed in the communication. * "ikev1.vendor_ids": List of the vendor IDs observed in the communication.
* "server_proposals": List of server proposals with parameters, if there are more than one. This is a non-standard case; this field is only present if such a situation was observed in the inspected traffic.

@ -47,6 +47,8 @@ Match on an attribute value of the chosen Security Association (SA) by the Respo
``sa_field_size``. ``sa_field_size``.
IKEv2 supports ``alg_enc``, ``alg_auth``, ``alg_prf`` and ``alg_dh``. IKEv2 supports ``alg_enc``, ``alg_auth``, ``alg_prf`` and ``alg_dh``.
If there is more than one chosen SA the event ``MultipleServerProposal`` is set. The attributes of the first SA are used for this keyword.
Examples:: Examples::

@ -17,3 +17,4 @@ alert ike any any -> any any (msg:"SURICATA IKE invalid proposal"; flow:to_serve
alert ike any any -> any any (msg:"SURICATA IKE invalid proposal selected"; flow:to_client; app-layer-event:ike.invalid_proposal; classtype:protocol-command-decode; sid:2224010; rev:2;) alert ike any any -> any any (msg:"SURICATA IKE invalid proposal selected"; flow:to_client; app-layer-event:ike.invalid_proposal; classtype:protocol-command-decode; sid:2224010; rev:2;)
alert ike any any -> any any (msg:"SURICATA IKE unknown proposal"; flow:to_server; app-layer-event:ike.unknown_proposal; classtype:protocol-command-decode; sid:2224011; rev:2;) alert ike any any -> any any (msg:"SURICATA IKE unknown proposal"; flow:to_server; app-layer-event:ike.unknown_proposal; classtype:protocol-command-decode; sid:2224011; rev:2;)
alert ike any any -> any any (msg:"SURICATA IKE unknown proposal selected"; flow:to_client; app-layer-event:ike.unknown_proposal; classtype:protocol-command-decode; sid:2224012; rev:2;) alert ike any any -> any any (msg:"SURICATA IKE unknown proposal selected"; flow:to_client; app-layer-event:ike.unknown_proposal; classtype:protocol-command-decode; sid:2224012; rev:2;)
alert ike any any -> any any (msg:"SURICATA IKE multiple server proposal"; flow:to_client; app-layer-event:ike.multiple_server_proposal; classtype:protocol-command-decode; sid:2224013; rev:1;)

@ -151,17 +151,16 @@ pub extern "C" fn rs_ike_state_get_sa_attribute(
if let Ok(sa) = sa_type_s { if let Ok(sa) = sa_type_s {
if tx.ike_version == 1 { if tx.ike_version == 1 {
'outer1: for (i, server_transform) in tx.hdr.ikev1_transforms.iter().enumerate() { if tx.hdr.ikev1_transforms.len() >= 1 {
if i >= 1 { // there should be only one chosen server_transform, check event
debug_validate_bug_on!(true); if let Some(server_transform) = tx.hdr.ikev1_transforms.first() {
break; for attr in server_transform {
} if attr.attribute_type.to_string() == sa {
for attr in server_transform { if let Some(numeric_value) = attr.numeric_value {
if attr.attribute_type.to_string() == sa { ret_val = numeric_value;
if let Some(numeric_value) = attr.numeric_value { ret_code = 1;
ret_val = numeric_value; break
ret_code = 1; }
break 'outer1;
} }
} }
} }

@ -47,6 +47,7 @@ pub enum IkeEvent {
InvalidProposal, InvalidProposal,
UnknownProposal, UnknownProposal,
PayloadExtraData, PayloadExtraData,
MultipleServerProposal,
} }
impl IkeEvent { impl IkeEvent {
@ -63,6 +64,7 @@ impl IkeEvent {
8 => Some(IkeEvent::InvalidProposal), 8 => Some(IkeEvent::InvalidProposal),
9 => Some(IkeEvent::UnknownProposal), 9 => Some(IkeEvent::UnknownProposal),
10 => Some(IkeEvent::PayloadExtraData), 10 => Some(IkeEvent::PayloadExtraData),
11 => Some(IkeEvent::MultipleServerProposal),
_ => None, _ => None,
} }
} }
@ -456,6 +458,7 @@ pub extern "C" fn rs_ike_state_get_event_info_by_id(
IkeEvent::InvalidProposal => "invalid_proposal\0", IkeEvent::InvalidProposal => "invalid_proposal\0",
IkeEvent::UnknownProposal => "unknown_proposal\0", IkeEvent::UnknownProposal => "unknown_proposal\0",
IkeEvent::PayloadExtraData => "payload_extra_data\0", IkeEvent::PayloadExtraData => "payload_extra_data\0",
IkeEvent::MultipleServerProposal => "multiple_server_proposal\0",
}; };
unsafe { unsafe {
*event_name = estr.as_ptr() as *const std::os::raw::c_char; *event_name = estr.as_ptr() as *const std::os::raw::c_char;
@ -490,6 +493,7 @@ pub extern "C" fn rs_ike_state_get_event_info(
"invalid_proposal" => IkeEvent::InvalidProposal as i32, "invalid_proposal" => IkeEvent::InvalidProposal as i32,
"unknown_proposal" => IkeEvent::UnknownProposal as i32, "unknown_proposal" => IkeEvent::UnknownProposal as i32,
"payload_extra_data" => IkeEvent::PayloadExtraData as i32, "payload_extra_data" => IkeEvent::PayloadExtraData as i32,
"multiple_server_proposal" => IkeEvent::MultipleServerProposal as i32,
_ => -1, // unknown event _ => -1, // unknown event
} }
} }

@ -130,6 +130,15 @@ pub fn handle_ikev1(
&tx.hdr.ikev1_transforms, &tx.hdr.ikev1_transforms,
); );
} else { } else {
if state.ikev1_container.server.transforms.len() <= 1
&& state.ikev1_container.server.transforms.len()
+ tx.hdr.ikev1_transforms.len()
> 1
{
SCLogDebug!("More than one chosen server proposal");
state.set_event(IkeEvent::MultipleServerProposal);
}
state.ikev1_container.server.update( state.ikev1_container.server.update(
&to_hex(tx.hdr.ikev1_header.key_exchange.as_ref()), &to_hex(tx.hdr.ikev1_header.key_exchange.as_ref()),
&to_hex(tx.hdr.ikev1_header.nonce.as_ref()), &to_hex(tx.hdr.ikev1_header.nonce.as_ref()),

@ -73,14 +73,19 @@ fn log_ike(
} }
if tx.ike_version == 1 { if tx.ike_version == 1 {
let mut index = 0; if state.ikev1_container.server.transforms.len() > 0 {
for server_transform in &state.ikev1_container.server.transforms { // log the first transform as the chosen one
if index >= 1 { add_attributes(&state.ikev1_container.server.transforms[0], jb)?;
debug_validate_bug_on!(true); }
break; if state.ikev1_container.server.transforms.len() > 1 {
// in case we have multiple server transforms log them in a list
jb.open_array("server_proposals")?;
for server_transform in &state.ikev1_container.server.transforms {
jb.start_object()?;
add_attributes(server_transform, jb)?;
jb.close()?;
} }
add_attributes(server_transform, jb)?; jb.close()?;
index += 1;
} }
} else if tx.ike_version == 2 { } else if tx.ike_version == 2 {
if tx.hdr.flags & IKEV2_FLAG_INITIATOR != 0 { if tx.hdr.flags & IKEV2_FLAG_INITIATOR != 0 {

Loading…
Cancel
Save