]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
smb: ntlmssp domain_blob_offset underflow check
authorPhilippe Antoine <contact@catenacyber.fr>
Mon, 4 Apr 2022 20:51:01 +0000 (22:51 +0200)
committerJeff Lucovsky <jeff@lucovsky.org>
Sun, 29 May 2022 19:23:24 +0000 (15:23 -0400)
Ticket: 5246
(cherry picked from commit e72036f12f577fb37b985147c2c847d147e49db2)

rust/src/smb/ntlmssp_records.rs

index e0fca25c8ca7985c82f00dc092a3102c0084eeba..b2528756654c55c88e7f5aa33dbc5d7f977276a4 100644 (file)
@@ -16,8 +16,9 @@
  */
 
 use nom::IResult;
-use nom::combinator::rest;
+use nom::combinator::{cond, rest};
 use nom::number::streaming::{le_u8, le_u16, le_u32};
+use nom::bytes::streaming:: take;
 
 #[derive(Debug,PartialEq)]
 pub struct NTLMSSPVersion {
@@ -62,53 +63,53 @@ fn parse_ntlm_auth_nego_flags(i:&[u8]) -> IResult<&[u8],(u8,u8,u32)> {
     bits!(i, tuple!(take_bits!(6u8),take_bits!(1u8),take_bits!(25u32)))
 }
 
-named!(pub parse_ntlm_auth_record<NTLMSSPAuthRecord>,
-    do_parse!(
-            _lm_blob_len: le_u16
-         >> _lm_blob_maxlen: le_u16
-         >> _lm_blob_offset: le_u32
+pub fn parse_ntlm_auth_record(i: &[u8]) -> IResult<&[u8], NTLMSSPAuthRecord> {
+    let (i, _lm_blob_len) = le_u16(i)?;
+    let (i, _lm_blob_maxlen) = le_u16(i)?;
+    let (i, _lm_blob_offset) = le_u32(i)?;
 
-         >> _ntlmresp_blob_len: le_u16
-         >> _ntlmresp_blob_maxlen: le_u16
-         >> _ntlmresp_blob_offset: le_u32
+    let (i, _ntlmresp_blob_len) = le_u16(i)?;
+    let (i, _ntlmresp_blob_maxlen) = le_u16(i)?;
+    let (i, _ntlmresp_blob_offset) = le_u32(i)?;
 
-         >> domain_blob_len: le_u16
-         >> _domain_blob_maxlen: le_u16
-         >> domain_blob_offset: le_u32
+    let (i, domain_blob_len) = le_u16(i)?;
+    let (i, _domain_blob_maxlen) = le_u16(i)?;
+    let (i, domain_blob_offset) = le_u32(i)?;
 
-         >> user_blob_len: le_u16
-         >> _user_blob_maxlen: le_u16
-         >> _user_blob_offset: le_u32
+    let (i, user_blob_len) = le_u16(i)?;
+    let (i, _user_blob_maxlen) = le_u16(i)?;
+    let (i, _user_blob_offset) = le_u32(i)?;
 
-         >> host_blob_len: le_u16
-         >> _host_blob_maxlen: le_u16
-         >> _host_blob_offset: le_u32
+    let (i, host_blob_len) = le_u16(i)?;
+    let (i, _host_blob_maxlen) = le_u16(i)?;
+    let (i, _host_blob_offset) = le_u32(i)?;
 
-         >> _ssnkey_blob_len: le_u16
-         >> _ssnkey_blob_maxlen: le_u16
-         >> _ssnkey_blob_offset: le_u32
+    let (i, _ssnkey_blob_len) = le_u16(i)?;
+    let (i, _ssnkey_blob_maxlen) = le_u16(i)?;
+    let (i, _ssnkey_blob_offset) = le_u32(i)?;
 
-         >> nego_flags: parse_ntlm_auth_nego_flags
-         >> version: cond!(nego_flags.1==1, parse_ntlm_auth_version)
+    let (i, nego_flags) = parse_ntlm_auth_nego_flags(i)?;
+    let (i, version) = cond(nego_flags.1==1, parse_ntlm_auth_version)(i)?;
 
-         // subtrack 12 as idenfier (8) and type (4) are cut before we are called
-         // subtract 60 for the len/offset/maxlen fields above
-         >> cond!(nego_flags.1==1, take!(domain_blob_offset - (12 + 60)))
-         // or 52 if we have no version
-         >> cond!(nego_flags.1==0, take!(domain_blob_offset - (12 + 52)))
+    // subtrack 12 as idenfier (8) and type (4) are cut before we are called
+    // subtract 60 for the len/offset/maxlen fields above
+    let (i, _) = cond(nego_flags.1==1 && domain_blob_offset > 72, |b| take(domain_blob_offset - (12 + 60))(b))(i)?;
+    // or 52 if we have no version
+    let (i, _) = cond(nego_flags.1==0 && domain_blob_offset > 64, |b| take(domain_blob_offset - (12 + 52))(b))(i)?;
 
-         >> domain_blob: take!(domain_blob_len)
-         >> user_blob: take!(user_blob_len)
-         >> host_blob: take!(host_blob_len)
+    let (i, domain_blob) = take(domain_blob_len)(i)?;
+    let (i, user_blob) = take(user_blob_len)(i)?;
+    let (i, host_blob) = take(host_blob_len)(i)?;
 
-         >> ( NTLMSSPAuthRecord {
-                domain: domain_blob,
-                user: user_blob,
-                host: host_blob,
+    let record = NTLMSSPAuthRecord {
+        domain: domain_blob,
+        user: user_blob,
+        host: host_blob,
 
-                version: version,
-            })
-));
+        version,
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct NTLMSSPRecord<'a> {