From 5c95c28387a4a756e39fd5f2c984bb8b034aa485 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Mon, 23 Aug 2021 17:31:51 +0200 Subject: [PATCH] smb: midstream probing checks for netbios message type If it is available Bug: #4620. (cherry picked from commit f37240a3e2758756f345a237b6d348ab38fb758b) --- rust/src/smb/smb2_records.rs | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/rust/src/smb/smb2_records.rs b/rust/src/smb/smb2_records.rs index fa6d62eb89..54a5238963 100644 --- a/rust/src/smb/smb2_records.rs +++ b/rust/src/smb/smb2_records.rs @@ -20,6 +20,7 @@ use nom::IResult; use nom::combinator::rest; use nom::number::streaming::{le_u8, le_u16, le_u32, le_u64}; use crate::smb::smb::*; +use crate::smb::nbss_records::NBSS_MSGTYPE_SESSION_MESSAGE; #[derive(Debug,PartialEq)] pub struct Smb2SecBlobRecord<'a> { @@ -535,15 +536,34 @@ named!(pub parse_smb2_response_record, }) )); +fn smb_basic_search(d: &[u8]) -> usize { + let needle = b"SMB"; + let mut r = 0 as usize; + // this could be replaced by aho-corasick + let iter = d.windows(needle.len()); + for window in iter { + if window == needle { + return r; + } + r = r + 1; + } + return 0; +} + pub fn search_smb_record<'a>(i: &'a [u8]) -> nom::IResult<&'a [u8], &'a [u8]> { let mut d = i; while d.len() >= 4 { - if &d[1..4] == b"SMB" && - (d[0] == 0xfe || d[0] == 0xff || d[0] == 0xfd) - { - return Ok((&d[4..], d)); + let index = smb_basic_search(d); + if index == 0 { + return Err(nom::Err::Error((d, nom::error::ErrorKind::Eof))); + } + if d[index - 1] == 0xfe || d[index - 1] == 0xff || d[index - 1] == 0xfd { + // if we have enough data, check nbss + if index < 5 || d[index-5] == NBSS_MSGTYPE_SESSION_MESSAGE { + return Ok((&d[index + 3..], &d[index - 1..])); + } } - d = &d[1..]; + d = &d[index + 3..]; } Err(nom::Err::Incomplete(nom::Needed::Size(4 as usize - d.len()))) } -- 2.47.2