]> 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 18:53:40 +0000 (20:53 +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 08ff8e51a18b410c1b4142daa99f77e85a685fa1..2a1f7ef5170d640d39a3f296443f1aacb8e7219e 100644 (file)
@@ -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;
index d5f2afb0b75cef79a902a99e11c4b77150e22d38..9410e79af6a3eeb39f55654a5c2053cb56e4aa3a 100644 (file)
@@ -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)]