smb2: validate negotiate read/write max sizes

Raise event if they exceed the configured limit.

(cherry picked from commit fc9b65d8d3)
pull/7288/head
Victor Julien 4 years ago committed by Shivani Bhardwaj
parent 8510031e6c
commit 65f24b2e84

@ -31,16 +31,20 @@ pub enum SMBEvent {
RequestToClient = 8, RequestToClient = 8,
ResponseToServer = 9, ResponseToServer = 9,
/// Negotiated max sizes exceed our limit
NegotiateMaxReadSizeTooLarge = 10,
NegotiateMaxWriteSizeTooLarge = 11,
/// READ request asking for more than `max_read_size` /// READ request asking for more than `max_read_size`
ReadRequestTooLarge = 10, ReadRequestTooLarge = 12,
/// READ response bigger than `max_read_size` /// READ response bigger than `max_read_size`
ReadResponseTooLarge = 11, ReadResponseTooLarge = 13,
ReadResponseQueueSizeExceeded = 12, ReadResponseQueueSizeExceeded = 14,
ReadResponseQueueCntExceeded = 13, ReadResponseQueueCntExceeded = 15,
/// WRITE request for more than `max_write_size` /// WRITE request for more than `max_write_size`
WriteRequestTooLarge = 14, WriteRequestTooLarge = 16,
WriteQueueSizeExceeded = 15, WriteQueueSizeExceeded = 17,
WriteQueueCntExceeded = 16, WriteQueueCntExceeded = 18,
} }
impl SMBEvent { impl SMBEvent {
@ -56,13 +60,15 @@ impl SMBEvent {
7 => Some(SMBEvent::FileOverlap), 7 => Some(SMBEvent::FileOverlap),
8 => Some(SMBEvent::RequestToClient), 8 => Some(SMBEvent::RequestToClient),
9 => Some(SMBEvent::ResponseToServer), 9 => Some(SMBEvent::ResponseToServer),
10 => Some(SMBEvent::ReadRequestTooLarge), 10 => Some(SMBEvent::NegotiateMaxReadSizeTooLarge),
11 => Some(SMBEvent::ReadResponseTooLarge), 11 => Some(SMBEvent::NegotiateMaxWriteSizeTooLarge),
12 => Some(SMBEvent::ReadResponseQueueSizeExceeded), 12 => Some(SMBEvent::ReadRequestTooLarge),
13 => Some(SMBEvent::ReadResponseQueueCntExceeded), 13 => Some(SMBEvent::ReadResponseTooLarge),
14 => Some(SMBEvent::WriteRequestTooLarge), 14 => Some(SMBEvent::ReadResponseQueueSizeExceeded),
15 => Some(SMBEvent::WriteQueueSizeExceeded), 15 => Some(SMBEvent::ReadResponseQueueCntExceeded),
16 => Some(SMBEvent::WriteQueueCntExceeded), 16 => Some(SMBEvent::WriteRequestTooLarge),
17 => Some(SMBEvent::WriteQueueSizeExceeded),
18 => Some(SMBEvent::WriteQueueCntExceeded),
_ => None, _ => None,
} }
} }
@ -71,24 +77,26 @@ impl SMBEvent {
pub fn smb_str_to_event(instr: &str) -> i32 { pub fn smb_str_to_event(instr: &str) -> i32 {
SCLogDebug!("checking {}", instr); SCLogDebug!("checking {}", instr);
match instr { match instr {
"internal_error" => SMBEvent::InternalError as i32, "internal_error" => SMBEvent::InternalError as i32,
"malformed_data" => SMBEvent::MalformedData as i32, "malformed_data" => SMBEvent::MalformedData as i32,
"record_overflow" => SMBEvent::RecordOverflow as i32, "record_overflow" => SMBEvent::RecordOverflow as i32,
"malformed_ntlmssp_request" => SMBEvent::MalformedNtlmsspRequest as i32, "malformed_ntlmssp_request" => SMBEvent::MalformedNtlmsspRequest as i32,
"malformed_ntlmssp_response" => SMBEvent::MalformedNtlmsspResponse as i32, "malformed_ntlmssp_response" => SMBEvent::MalformedNtlmsspResponse as i32,
"duplicate_negotiate" => SMBEvent::DuplicateNegotiate as i32, "duplicate_negotiate" => SMBEvent::DuplicateNegotiate as i32,
"negotiate_malformed_dialects" => SMBEvent::NegotiateMalformedDialects as i32, "negotiate_malformed_dialects" => SMBEvent::NegotiateMalformedDialects as i32,
"file_overlap" => SMBEvent::FileOverlap as i32, "file_overlap" => SMBEvent::FileOverlap as i32,
"request_to_client" => SMBEvent::RequestToClient as i32, "request_to_client" => SMBEvent::RequestToClient as i32,
"response_to_server" => SMBEvent::ResponseToServer as i32, "response_to_server" => SMBEvent::ResponseToServer as i32,
"read_request_too_large" => SMBEvent::ReadRequestTooLarge as i32, "negotiate_max_read_size_too_large" => SMBEvent::NegotiateMaxReadSizeTooLarge as i32,
"read_response_too_large" => SMBEvent::ReadResponseTooLarge as i32, "negotiate_max_write_size_too_large" => SMBEvent::NegotiateMaxWriteSizeTooLarge as i32,
"read_response_queue_size_exceeded" => SMBEvent::ReadResponseQueueSizeExceeded as i32, "read_request_too_large" => SMBEvent::ReadRequestTooLarge as i32,
"read_response_queue_cnt_exceeded" => SMBEvent::ReadResponseQueueCntExceeded as i32, "read_response_too_large" => SMBEvent::ReadResponseTooLarge as i32,
"write_request_too_large" => SMBEvent::WriteRequestTooLarge as i32, "read_response_queue_size_exceeded" => SMBEvent::ReadResponseQueueSizeExceeded as i32,
"write_queue_size_exceeded" => SMBEvent::WriteQueueSizeExceeded as i32, "read_response_queue_cnt_exceeded" => SMBEvent::ReadResponseQueueCntExceeded as i32,
"write_queue_cnt_exceeded" => SMBEvent::WriteQueueCntExceeded as i32, "write_request_too_large" => SMBEvent::WriteRequestTooLarge as i32,
_ => -1, "write_queue_size_exceeded" => SMBEvent::WriteQueueSizeExceeded as i32,
"write_queue_cnt_exceeded" => SMBEvent::WriteQueueCntExceeded as i32,
_ => -1,
} }
} }

@ -2198,6 +2198,8 @@ pub extern "C" fn rs_smb_state_get_event_info_by_id(event_id: std::os::raw::c_in
SMBEvent::FileOverlap => { "file_overlap\0" }, SMBEvent::FileOverlap => { "file_overlap\0" },
SMBEvent::RequestToClient => { "request_to_client\0" }, SMBEvent::RequestToClient => { "request_to_client\0" },
SMBEvent::ResponseToServer => { "response_to_server\0" }, SMBEvent::ResponseToServer => { "response_to_server\0" },
SMBEvent::NegotiateMaxReadSizeTooLarge => { "negotiate_max_read_size_too_large\0" },
SMBEvent::NegotiateMaxWriteSizeTooLarge => { "negotiate_max_write_size_too_large\0" },
SMBEvent::ReadRequestTooLarge => { "read_request_too_large\0" }, SMBEvent::ReadRequestTooLarge => { "read_request_too_large\0" },
SMBEvent::ReadResponseTooLarge => { "read_response_too_large\0" }, SMBEvent::ReadResponseTooLarge => { "read_response_too_large\0" },
SMBEvent::ReadResponseQueueSizeExceeded => { "read_response_queue_size_exceeded\0" }, SMBEvent::ReadResponseQueueSizeExceeded => { "read_response_queue_size_exceeded\0" },

@ -806,6 +806,15 @@ pub fn smb2_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
Ok((_, rd)) => { Ok((_, rd)) => {
SCLogDebug!("SERVER dialect => {}", &smb2_dialect_string(rd.dialect)); SCLogDebug!("SERVER dialect => {}", &smb2_dialect_string(rd.dialect));
let smb_cfg_max_read_size = unsafe { SMB_CFG_MAX_READ_SIZE };
if smb_cfg_max_read_size != 0 && rd.max_read_size > smb_cfg_max_read_size {
state.set_event(SMBEvent::NegotiateMaxReadSizeTooLarge);
}
let smb_cfg_max_write_size = unsafe { SMB_CFG_MAX_WRITE_SIZE };
if smb_cfg_max_write_size != 0 && rd.max_write_size > smb_cfg_max_write_size {
state.set_event(SMBEvent::NegotiateMaxWriteSizeTooLarge);
}
state.dialect = rd.dialect; state.dialect = rd.dialect;
state.max_read_size = rd.max_read_size; state.max_read_size = rd.max_read_size;
state.max_write_size = rd.max_write_size; state.max_write_size = rd.max_write_size;

Loading…
Cancel
Save