]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
smb2: validate negotiate read/write max sizes
authorVictor Julien <vjulien@oisf.net>
Tue, 19 Apr 2022 06:13:48 +0000 (08:13 +0200)
committerShivani Bhardwaj <shivanib134@gmail.com>
Wed, 20 Apr 2022 13:04:08 +0000 (18:34 +0530)
Raise event if they exceed the configured limit.

(cherry picked from commit fc9b65d8d3188c57016635aef8d7cdfe4552324e)

rust/src/smb/events.rs
rust/src/smb/smb.rs
rust/src/smb/smb2.rs

index 601d4e76c53e1bbe13b4a637fb568cfb344d19c2..504e302698375906295a077f4e1f4f8425411aff 100644 (file)
@@ -31,16 +31,20 @@ pub enum SMBEvent {
     RequestToClient = 8,
     ResponseToServer = 9,
 
+    /// Negotiated max sizes exceed our limit
+    NegotiateMaxReadSizeTooLarge = 10,
+    NegotiateMaxWriteSizeTooLarge = 11,
+
     /// READ request asking for more than `max_read_size`
-    ReadRequestTooLarge = 10,
+    ReadRequestTooLarge = 12,
     /// READ response bigger than `max_read_size`
-    ReadResponseTooLarge = 11,
-    ReadResponseQueueSizeExceeded = 12,
-    ReadResponseQueueCntExceeded = 13,
+    ReadResponseTooLarge = 13,
+    ReadResponseQueueSizeExceeded = 14,
+    ReadResponseQueueCntExceeded = 15,
     /// WRITE request for more than `max_write_size`
-    WriteRequestTooLarge = 14,
-    WriteQueueSizeExceeded = 15,
-    WriteQueueCntExceeded = 16,
+    WriteRequestTooLarge = 16,
+    WriteQueueSizeExceeded = 17,
+    WriteQueueCntExceeded = 18,
 }
 
 impl SMBEvent {
@@ -56,13 +60,15 @@ impl SMBEvent {
             7 => Some(SMBEvent::FileOverlap),
             8 => Some(SMBEvent::RequestToClient),
             9 => Some(SMBEvent::ResponseToServer),
-            10 => Some(SMBEvent::ReadRequestTooLarge),
-            11 => Some(SMBEvent::ReadResponseTooLarge),
-            12 => Some(SMBEvent::ReadResponseQueueSizeExceeded),
-            13 => Some(SMBEvent::ReadResponseQueueCntExceeded),
-            14 => Some(SMBEvent::WriteRequestTooLarge),
-            15 => Some(SMBEvent::WriteQueueSizeExceeded),
-            16 => Some(SMBEvent::WriteQueueCntExceeded),
+            10 => Some(SMBEvent::NegotiateMaxReadSizeTooLarge),
+            11 => Some(SMBEvent::NegotiateMaxWriteSizeTooLarge),
+            12 => Some(SMBEvent::ReadRequestTooLarge),
+            13 => Some(SMBEvent::ReadResponseTooLarge),
+            14 => Some(SMBEvent::ReadResponseQueueSizeExceeded),
+            15 => Some(SMBEvent::ReadResponseQueueCntExceeded),
+            16 => Some(SMBEvent::WriteRequestTooLarge),
+            17 => Some(SMBEvent::WriteQueueSizeExceeded),
+            18 => Some(SMBEvent::WriteQueueCntExceeded),
             _ => None,
         }
     }
@@ -71,24 +77,26 @@ impl SMBEvent {
 pub fn smb_str_to_event(instr: &str) -> i32 {
     SCLogDebug!("checking {}", instr);
     match instr {
-        "internal_error"                    => SMBEvent::InternalError as i32,
-        "malformed_data"                    => SMBEvent::MalformedData as i32,
-        "record_overflow"                   => SMBEvent::RecordOverflow as i32,
-        "malformed_ntlmssp_request"         => SMBEvent::MalformedNtlmsspRequest as i32,
-        "malformed_ntlmssp_response"        => SMBEvent::MalformedNtlmsspResponse as 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,
-        "read_request_too_large"            => SMBEvent::ReadRequestTooLarge as i32,
-        "read_response_too_large"           => SMBEvent::ReadResponseTooLarge as i32,
-        "read_response_queue_size_exceeded" => SMBEvent::ReadResponseQueueSizeExceeded as i32,
-        "read_response_queue_cnt_exceeded"  => SMBEvent::ReadResponseQueueCntExceeded as i32,
-        "write_request_too_large"           => SMBEvent::WriteRequestTooLarge as i32,
-        "write_queue_size_exceeded"         => SMBEvent::WriteQueueSizeExceeded as i32,
-        "write_queue_cnt_exceeded"          => SMBEvent::WriteQueueCntExceeded as i32,
-        _ => -1,
+        "internal_error"                     => SMBEvent::InternalError as i32,
+        "malformed_data"                     => SMBEvent::MalformedData as i32,
+        "record_overflow"                    => SMBEvent::RecordOverflow as i32,
+        "malformed_ntlmssp_request"          => SMBEvent::MalformedNtlmsspRequest as i32,
+        "malformed_ntlmssp_response"         => SMBEvent::MalformedNtlmsspResponse as 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,
+        "negotiate_max_read_size_too_large"  => SMBEvent::NegotiateMaxReadSizeTooLarge as i32,
+        "negotiate_max_write_size_too_large" => SMBEvent::NegotiateMaxWriteSizeTooLarge as i32,
+        "read_request_too_large"             => SMBEvent::ReadRequestTooLarge as i32,
+        "read_response_too_large"            => SMBEvent::ReadResponseTooLarge as i32,
+        "read_response_queue_size_exceeded"  => SMBEvent::ReadResponseQueueSizeExceeded as i32,
+        "read_response_queue_cnt_exceeded"   => SMBEvent::ReadResponseQueueCntExceeded as i32,
+        "write_request_too_large"            => SMBEvent::WriteRequestTooLarge as i32,
+        "write_queue_size_exceeded"          => SMBEvent::WriteQueueSizeExceeded as i32,
+        "write_queue_cnt_exceeded"           => SMBEvent::WriteQueueCntExceeded as i32,
+        _                                    => -1,
     }
 }
 
index d350609ac814cab94e5a37a6e325f05169220c53..abfda7fbbab4eb92a84984830320b8f59b7a9d17 100644 (file)
@@ -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::RequestToClient => { "request_to_client\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::ReadResponseTooLarge => { "read_response_too_large\0" },
             SMBEvent::ReadResponseQueueSizeExceeded => { "read_response_queue_size_exceeded\0" },
index 9824900f52f15ae5baa20ccd246356ee91658058..d4ad1bb95a19fa8d9d49987fa650d794e43e621d 100644 (file)
@@ -806,6 +806,15 @@ pub fn smb2_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
                 Ok((_, rd)) => {
                     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.max_read_size = rd.max_read_size;
                     state.max_write_size = rd.max_write_size;