]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
smb/ntlmssp: fix parsing of negotiate flags
authortianjinshan <tianjinshan@meituan.com>
Wed, 8 Mar 2023 07:38:55 +0000 (15:38 +0800)
committerVictor Julien <vjulien@oisf.net>
Fri, 5 May 2023 09:17:39 +0000 (11:17 +0200)
Ticket: #5783

rust/src/smb/ntlmssp_records.rs

index cde31cecc59ad0a053cdb6265fd7e3b3694b4de9..b99d74dc079cf4f63f22d91f9bfa4a76bab0742f 100644 (file)
  * 02110-1301, USA.
  */
 
-use crate::common::nom7::{bits, take_until_and_consume};
-use nom7::bits::streaming::take as take_bits;
+use crate::common::nom7::take_until_and_consume;
 use nom7::bytes::streaming::take;
 use nom7::combinator::{cond, rest, verify};
 use nom7::error::{make_error, ErrorKind};
 use nom7::number::streaming::{le_u16, le_u32, le_u8};
-use nom7::sequence::tuple;
 use nom7::Err;
 use nom7::IResult;
 use std::fmt;
@@ -68,8 +66,15 @@ pub struct NTLMSSPAuthRecord<'a> {
     pub warning: bool,
 }
 
-fn parse_ntlm_auth_nego_flags(i: &[u8]) -> IResult<&[u8], (u32, u8, u8)> {
-    bits(tuple((take_bits(25u8), take_bits(1u8), take_bits(6u32))))(i)
+#[derive(Debug, PartialEq, Eq)]
+pub struct NTLMSSPNegotiateFlags {
+    pub version: bool,
+    // others fields not done because not interesting yet
+}
+
+fn parse_ntlm_auth_nego_flags(i: &[u8]) -> IResult<&[u8], NTLMSSPNegotiateFlags> {
+    let (i, raw) = le_u32(i)?;
+    return Ok((i, NTLMSSPNegotiateFlags{version: (raw & 0x2000000) != 0}));
 }
 
 const NTLMSSP_IDTYPE_LEN: usize = 12;
@@ -115,7 +120,7 @@ pub fn parse_ntlm_auth_record(i: &[u8]) -> IResult<&[u8], NTLMSSPAuthRecord> {
     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 (_, version) = cond(nego_flags.1 == 1, parse_ntlm_auth_version)(i)?;
+    let (_, version) = cond(nego_flags.version, parse_ntlm_auth_version)(i)?;
 
     // Caller does not care about remaining input...
     let (_, domain_blob) = extract_ntlm_substring(orig_i, domain_blob_offset, domain_blob_len)?;
@@ -161,12 +166,30 @@ mod tests {
     use nom7::Err;
     #[test]
     fn test_parse_auth_nego_flags() {
-        // ntlmssp.negotiateflags
+        // ntlmssp.negotiateflags 1
         let blob = [0x15, 0x82, 0x88, 0xe2];
         let result = parse_ntlm_auth_nego_flags(&blob);
         match result {
-            Ok((remainder, (_, version_flag, _))) => {
-                assert_eq!(version_flag, 1);
+            Ok((remainder, flags)) => {
+                assert_eq!(flags.version, true);
+                assert_eq!(remainder.len(), 0);
+            }
+            Err(Err::Error(err)) => {
+                panic!("Result should not be an error: {:?}.", err.code);
+            }
+            Err(Err::Incomplete(_)) => {
+                panic!("Result should not have been incomplete.");
+            }
+            _ => {
+                panic!("Unexpected behavior!");
+            }
+        }
+        // ntlmssp.negotiateflags 0
+        let blob = [0x15, 0x82, 0x88, 0xe0];
+        let result = parse_ntlm_auth_nego_flags(&blob);
+        match result {
+            Ok((remainder, flags)) => {
+                assert_eq!(flags.version, false);
                 assert_eq!(remainder.len(), 0);
             }
             Err(Err::Error(err)) => {