From: Victor Julien Date: Mon, 11 Apr 2022 10:33:43 +0000 (+0200) Subject: smb/ntlmssp: add stricter len/offset validation X-Git-Tag: suricata-7.0.0-beta1~755 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=053a9d2e685abe7639e23b1c7fad5ae7d68630e3;p=thirdparty%2Fsuricata.git smb/ntlmssp: add stricter len/offset validation --- diff --git a/rust/src/smb/ntlmssp_records.rs b/rust/src/smb/ntlmssp_records.rs index 731af8ca9a..0fbdd1792c 100644 --- a/rust/src/smb/ntlmssp_records.rs +++ b/rust/src/smb/ntlmssp_records.rs @@ -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)?;