]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
smb/ntlmssp: add stricter len/offset validation
authorVictor Julien <vjulien@oisf.net>
Mon, 11 Apr 2022 10:33:43 +0000 (12:33 +0200)
committerVictor Julien <vjulien@oisf.net>
Mon, 11 Apr 2022 17:11:01 +0000 (19:11 +0200)
rust/src/smb/ntlmssp_records.rs

index 731af8ca9a86eaa9c2c468c48fe23ad4bf6de2cd..0fbdd1792cc68cb79d6019906784d8c0723a5847 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 Open Information Security Foundation
+/* Copyright (C) 2017-2022 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
@@ -19,7 +19,7 @@ use crate::common::nom7::{bits, take_until_and_consume};
 use std::fmt;
 use nom7::bits::streaming::take as take_bits;
 use nom7::bytes::streaming::take;
-use nom7::combinator::{cond, rest};
+use nom7::combinator::{cond, rest, verify};
 use nom7::number::streaming::{le_u8, le_u16, le_u32};
 use nom7::sequence::tuple;
 use nom7::IResult;
@@ -72,29 +72,31 @@ fn parse_ntlm_auth_nego_flags(i:&[u8]) -> IResult<&[u8],(u8,u8,u32)> {
 }
 
 pub fn parse_ntlm_auth_record(i: &[u8]) -> IResult<&[u8], NTLMSSPAuthRecord> {
-    let (i, _lm_blob_len) = le_u16(i)?;
+    let record_len = i.len() + 12; // idenfier (8) and type (4) are cut before we are called
+
+    let (i, _lm_blob_len) = verify(le_u16, |&v| (v as usize) < record_len)(i)?;
     let (i, _lm_blob_maxlen) = le_u16(i)?;
-    let (i, _lm_blob_offset) = le_u32(i)?;
+    let (i, _lm_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len)(i)?;
 
-    let (i, _ntlmresp_blob_len) = le_u16(i)?;
+    let (i, _ntlmresp_blob_len) = verify(le_u16, |&v| (v as usize) < record_len)(i)?;
     let (i, _ntlmresp_blob_maxlen) = le_u16(i)?;
-    let (i, _ntlmresp_blob_offset) = le_u32(i)?;
+    let (i, _ntlmresp_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len)(i)?;
 
-    let (i, domain_blob_len) = le_u16(i)?;
+    let (i, domain_blob_len) = verify(le_u16, |&v| (v as usize) < record_len)(i)?;
     let (i, _domain_blob_maxlen) = le_u16(i)?;
-    let (i, domain_blob_offset) = le_u32(i)?;
+    let (i, domain_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len)(i)?;
 
-    let (i, user_blob_len) = le_u16(i)?;
+    let (i, user_blob_len) = verify(le_u16, |&v| (v as usize) < record_len)(i)?;
     let (i, _user_blob_maxlen) = le_u16(i)?;
-    let (i, _user_blob_offset) = le_u32(i)?;
+    let (i, _user_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len)(i)?;
 
-    let (i, host_blob_len) = le_u16(i)?;
+    let (i, host_blob_len) = verify(le_u16, |&v| (v as usize) < record_len)(i)?;
     let (i, _host_blob_maxlen) = le_u16(i)?;
-    let (i, _host_blob_offset) = le_u32(i)?;
+    let (i, _host_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len)(i)?;
 
-    let (i, _ssnkey_blob_len) = le_u16(i)?;
+    let (i, _ssnkey_blob_len) = verify(le_u16, |&v| (v as usize) < record_len)(i)?;
     let (i, _ssnkey_blob_maxlen) = le_u16(i)?;
-    let (i, _ssnkey_blob_offset) = le_u32(i)?;
+    let (i, _ssnkey_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len)(i)?;
 
     let (i, nego_flags) = parse_ntlm_auth_nego_flags(i)?;
     let (i, version) = cond(nego_flags.1==1, parse_ntlm_auth_version)(i)?;