From: Jason Ish Date: Fri, 18 Feb 2022 04:57:30 +0000 (-0600) Subject: smb: handle records in the wrong direction X-Git-Tag: suricata-5.0.9~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b6df4564338d43c1cac7b1290b3a02a496b2d7a4;p=thirdparty%2Fsuricata.git smb: handle records in the wrong direction If an SMB record is seen in the wrong direction, set an event on the PDU frame and don't process the record in the state. No error is returned, so the next record will be processed. (cherry picked from commit 2341f47755c616f9ee3249cd28372eab45889e0d) --- diff --git a/rust/src/smb/events.rs b/rust/src/smb/events.rs index 1b29da7d43..a2540fdbcf 100644 --- a/rust/src/smb/events.rs +++ b/rust/src/smb/events.rs @@ -28,6 +28,8 @@ pub enum SMBEvent { DuplicateNegotiate = 5, NegotiateMalformedDialects = 6, FileOverlap = 7, + RequestToClient = 8, + ResponseToServer = 9, } impl SMBEvent { @@ -41,6 +43,8 @@ impl SMBEvent { 5 => Some(SMBEvent::DuplicateNegotiate), 6 => Some(SMBEvent::NegotiateMalformedDialects), 7 => Some(SMBEvent::FileOverlap), + 8 => Some(SMBEvent::RequestToClient), + 9 => Some(SMBEvent::ResponseToServer), _ => None, } } @@ -57,6 +61,8 @@ pub fn smb_str_to_event(instr: &str) -> i32 { "duplicate_negotiate" => SMBEvent::DuplicateNegotiate as i32, "negotiate_malformed_dialects" => SMBEvent::NegotiateMalformedDialects as i32, "file_overlap" => SMBEvent::FileOverlap as i32, + "request_to_client" => SMBEvent::RequestToClient as i32, + "response_to_server" => SMBEvent::ResponseToServer as i32, _ => -1, } } diff --git a/rust/src/smb/smb.rs b/rust/src/smb/smb.rs index 08ff8e51a1..2a1f7ef517 100644 --- a/rust/src/smb/smb.rs +++ b/rust/src/smb/smb.rs @@ -1442,7 +1442,13 @@ impl SMBState { SCLogDebug!("SMBv1 record"); match parse_smb_record(&nbss_hdr.data) { Ok((_, ref smb_record)) => { - smb1_request_record(self, smb_record); + if smb_record.is_request() { + smb1_request_record(self, smb_record); + } else { + // If we recevied a response when expecting a request, set an event. + SCLogDebug!("SMB1 reply seen from client to server"); + self.set_event(SMBEvent::ResponseToServer); + } }, _ => { self.set_event(SMBEvent::MalformedData); @@ -1456,8 +1462,13 @@ impl SMBState { match parse_smb2_request_record(&nbss_data) { Ok((nbss_data_rem, ref smb_record)) => { SCLogDebug!("nbss_data_rem {}", nbss_data_rem.len()); - - smb2_request_record(self, smb_record); + if smb_record.is_request() { + smb2_request_record(self, smb_record); + } else { + // If we recevied a response when expecting a request, set an event. + SCLogDebug!("SMB2 reply seen from client to server"); + self.set_event(SMBEvent::ResponseToServer); + } nbss_data = nbss_data_rem; }, _ => { @@ -1670,7 +1681,12 @@ impl SMBState { SCLogDebug!("SMBv1 record"); match parse_smb_record(&nbss_hdr.data) { Ok((_, ref smb_record)) => { - smb1_response_record(self, smb_record); + if smb_record.is_response() { + smb1_response_record(self, smb_record); + } else { + SCLogDebug!("SMB1 request seen from server to client"); + self.set_event(SMBEvent::RequestToClient); + } }, _ => { self.set_event(SMBEvent::MalformedData); @@ -1683,7 +1699,12 @@ impl SMBState { SCLogDebug!("SMBv2 record"); match parse_smb2_response_record(&nbss_data) { Ok((nbss_data_rem, ref smb_record)) => { - smb2_response_record(self, smb_record); + if smb_record.is_response() { + smb2_response_record(self, smb_record); + } else { + SCLogDebug!("SMB2 request seen from server to client"); + self.set_event(SMBEvent::RequestToClient); + } nbss_data = nbss_data_rem; }, _ => { @@ -2196,6 +2217,8 @@ pub extern "C" fn rs_smb_state_get_event_info_by_id(event_id: std::os::raw::c_in SMBEvent::DuplicateNegotiate => { "duplicate_negotiate\0" }, SMBEvent::NegotiateMalformedDialects => { "netogiate_malformed_dialects\0" }, SMBEvent::FileOverlap => { "file_overlap\0" }, + SMBEvent::RequestToClient => { "request_to_client\0" }, + SMBEvent::ResponseToServer => { "response_to_server\0" }, }; unsafe{ *event_name = estr.as_ptr() as *const std::os::raw::c_char; diff --git a/rust/src/smb/smb2_records.rs b/rust/src/smb/smb2_records.rs index d5f2afb0b7..9410e79af6 100644 --- a/rust/src/smb/smb2_records.rs +++ b/rust/src/smb/smb2_records.rs @@ -67,6 +67,14 @@ impl<'a> Smb2Record<'a> { pub fn is_async(&self) -> bool { self.async_id != 0 } + + pub fn is_request(&self) -> bool { + self.direction == 0 + } + + pub fn is_response(&self) -> bool { + self.direction == 1 + } } #[derive(Debug)]