From 816bd022a6996267e72d7d73fda3fc277074f9a1 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Tue, 13 Mar 2018 17:34:00 +0100 Subject: [PATCH] smb1: improve non nt-status handling Support SRV error, with a couple of codes. Rename statux field to status_code. --- rust/src/smb/log.rs | 26 +++++++++++++++++++------- rust/src/smb/smb.rs | 27 +++++++++++++++++++++++++-- rust/src/smb/smb1_records.rs | 5 ++++- 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/rust/src/smb/log.rs b/rust/src/smb/log.rs index 330550e1ed..87c612e478 100644 --- a/rust/src/smb/log.rs +++ b/rust/src/smb/log.rs @@ -91,17 +91,29 @@ fn smb_common_header(state: &SMBState, tx: &SMBTransaction) -> Json let status = smb_ntstatus_string(ntstatus); js.set_string("status", &status); let status_hex = format!("0x{:x}", ntstatus); - js.set_string("statux", &status_hex); + js.set_string("status_code", &status_hex); }, (false, _) => { match tx.vercmd.get_dos_error() { - (true, doserr) => { - let status = smb_dos_error_string(doserr); - js.set_string("status", &status); - let status_hex = format!("0x{:x}", doserr); - js.set_string("statux", &status_hex); + (true, errclass, errcode) => { + match errclass { + 1 => { // DOSERR + let status = smb_dos_error_string(errcode); + js.set_string("status", &status); + }, + 2 => { // SRVERR + let status = smb_srv_error_string(errcode); + js.set_string("status", &status); + } + _ => { + let s = format!("UNKNOWN_{:02x}_{:04x}", errclass, errcode); + js.set_string("status", &s); + }, + } + let status_hex = format!("0x{:04x}", errcode); + js.set_string("status_code", &status_hex); }, - (_, _) => { + (_, _, _) => { }, } }, diff --git a/rust/src/smb/smb.rs b/rust/src/smb/smb.rs index a48501f996..c6ada4429b 100644 --- a/rust/src/smb/smb.rs +++ b/rust/src/smb/smb.rs @@ -142,6 +142,22 @@ pub fn smb_ntstatus_string(c: u32) -> String { }.to_string() } +pub const SMB_SRV_ERROR: u16 = 1; +pub const SMB_SRV_BADPW: u16 = 2; +pub const SMB_SRV_BADTYPE: u16 = 3; +pub const SMB_SRV_ACCESS: u16 = 4; +pub const SMB_SRV_BADUID: u16 = 91; + +pub fn smb_srv_error_string(c: u16) -> String { + match c { + SMB_SRV_ERROR => "SRV_ERROR", + SMB_SRV_BADPW => "SRV_BADPW", + SMB_SRV_BADTYPE => "SRV_BADTYPE", + SMB_SRV_ACCESS => "SRV_ACCESS", + SMB_SRV_BADUID => "SRV_BADUID", + _ => { return (c).to_string(); }, + }.to_string() +} pub const SMB_DOS_SUCCESS: u16 = 0; pub const SMB_DOS_BAD_FUNC: u16 = 1; @@ -183,6 +199,7 @@ pub struct SMBVerCmdStat { status_set: bool, status_is_dos_error: bool, + status_error_class: u8, status: u32, } @@ -194,6 +211,7 @@ impl SMBVerCmdStat { smb2_cmd: 0, status_set: false, status_is_dos_error: false, + status_error_class: 0, status: 0, } } @@ -204,6 +222,7 @@ impl SMBVerCmdStat { smb2_cmd: 0, status_set: false, status_is_dos_error: false, + status_error_class: 0, status: 0, } } @@ -214,6 +233,7 @@ impl SMBVerCmdStat { smb2_cmd: 0, status_set: true, status_is_dos_error: false, + status_error_class: 0, status: status, } } @@ -224,6 +244,7 @@ impl SMBVerCmdStat { smb2_cmd: cmd, status_set: false, status_is_dos_error: false, + status_error_class: 0, status: 0, } } @@ -235,6 +256,7 @@ impl SMBVerCmdStat { smb2_cmd: cmd, status_set: true, status_is_dos_error: false, + status_error_class: 0, status: status, } } @@ -279,14 +301,15 @@ impl SMBVerCmdStat { (self.status_set && !self.status_is_dos_error, self.status) } - pub fn get_dos_error(&self) -> (bool, u16) { - (self.status_set && self.status_is_dos_error, self.status as u16) + pub fn get_dos_error(&self) -> (bool, u8, u16) { + (self.status_set && self.status_is_dos_error, self.status_error_class, self.status as u16) } fn set_status(&mut self, status: u32, is_dos_error: bool) { if is_dos_error { self.status_is_dos_error = true; + self.status_error_class = (status & 0x0000_00ff) as u8; self.status = (status & 0xffff_0000) >> 16; } else { self.status = status; diff --git a/rust/src/smb/smb1_records.rs b/rust/src/smb/smb1_records.rs index 46e75020a9..6e4def7c3c 100644 --- a/rust/src/smb/smb1_records.rs +++ b/rust/src/smb/smb1_records.rs @@ -632,6 +632,9 @@ impl<'a> SmbRecord<'a> { pub fn has_unicode_support(&self) -> bool { self.flags2 & 0x8000_u16 != 0 } + pub fn is_dos_error(&self) -> bool { + self.flags2 & 0x4000_u16 != 0 + } } named!(pub parse_smb_record, @@ -655,7 +658,7 @@ named!(pub parse_smb_record, nt_status:nt_status, flags:flags, flags2:flags2, - is_dos_error: ((flags2 & 0x4000 == 0) && nt_status != 0), + is_dos_error: (flags2 & 0x4000_u16 == 0),// && nt_status != 0), tree_id:tree_id, user_id:user_id, multiplex_id:multiplex_id,