]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
smb: handle records in the wrong direction
authorJason Ish <jason.ish@oisf.net>
Fri, 18 Feb 2022 04:57:30 +0000 (22:57 -0600)
committerVictor Julien <vjulien@oisf.net>
Tue, 19 Apr 2022 11:50:42 +0000 (13:50 +0200)
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)

rust/src/smb/events.rs
rust/src/smb/smb.rs
rust/src/smb/smb2_records.rs

index 1b29da7d4394b3a7d295a10a17708a1ba8f6cc5f..a2540fdbcff637933fe7a1ace3a97532f39a2fbb 100644 (file)
@@ -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,
     }
 }
index c470bc140b9a427521ab631ff369d46e3ed5b588..f479ded2091d4003a5e952d860afbfd01cf98696 100644 (file)
@@ -1426,7 +1426,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);
@@ -1440,8 +1446,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;
                                             },
                                             _ => {
@@ -1665,7 +1676,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);
@@ -1678,7 +1694,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;
                                             },
                                             _ => {
@@ -2163,6 +2184,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;
index 44deb0ffc96a935a68e331699d424326a3b54a3b..13df0bac970370f2405b119a0037185a3ef5dde5 100644 (file)
@@ -69,6 +69,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)]