From: Philippe Antoine Date: Mon, 4 Apr 2022 20:51:01 +0000 (+0200) Subject: smb: ntlmssp domain_blob_offset underflow check X-Git-Tag: suricata-6.0.6~64 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9bc690897a4728a1bb292912a76c1c02dac15700;p=thirdparty%2Fsuricata.git smb: ntlmssp domain_blob_offset underflow check Ticket: 5246 (cherry picked from commit e72036f12f577fb37b985147c2c847d147e49db2) --- diff --git a/rust/src/smb/ntlmssp_records.rs b/rust/src/smb/ntlmssp_records.rs index e0fca25c8c..b252875665 100644 --- a/rust/src/smb/ntlmssp_records.rs +++ b/rust/src/smb/ntlmssp_records.rs @@ -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, - 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> {