From: Victor Julien Date: Tue, 10 Jul 2018 15:22:53 +0000 (+0200) Subject: smb: log trans2 that enable delete on close X-Git-Tag: suricata-4.1.0-rc1~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b581cd6db63e090afd35376c39d82f58e21220f;p=thirdparty%2Fsuricata.git smb: log trans2 that enable delete on close --- diff --git a/rust/src/smb/log.rs b/rust/src/smb/log.rs index 734b13e57a..48c531feb1 100644 --- a/rust/src/smb/log.rs +++ b/rust/src/smb/log.rs @@ -362,6 +362,42 @@ fn smb_common_header(state: &SMBState, tx: &SMBTransaction) -> Json Some(SMBTransactionTypeData::IOCTL(ref x)) => { js.set_string("function", &fsctl_func_to_string(x.func)); }, + Some(SMBTransactionTypeData::SETFILEPATHINFO(ref x)) => { + let mut name_raw = x.filename.to_vec(); + name_raw.retain(|&i|i != 0x00); + if name_raw.len() > 0 { + let name = String::from_utf8_lossy(&name_raw); + js.set_string("filename", &name); + } else { + // name suggestion from Bro + js.set_string("filename", ""); + } + if x.delete_on_close { + js.set_string("access", "delete on close"); + } else { + js.set_string("access", "normal"); + } + + match x.subcmd { + 8 => { + js.set_string("subcmd", "SET_FILE_INFO"); + }, + 6 => { + js.set_string("subcmd", "SET_PATH_INFO"); + }, + _ => { }, + } + + match x.loi { + 1013 => { // Set Disposition Information + js.set_string("level_of_interest", "Set Disposition Information"); + }, + _ => { }, + } + + let gs = fuid_to_string(&x.fid); + js.set_string("fuid", &gs); + }, _ => { }, } return js; diff --git a/rust/src/smb/smb.rs b/rust/src/smb/smb.rs index 5af874c77a..874ff64c14 100644 --- a/rust/src/smb/smb.rs +++ b/rust/src/smb/smb.rs @@ -364,6 +364,69 @@ pub enum SMBTransactionTypeData { SESSIONSETUP(SMBTransactionSessionSetup), IOCTL(SMBTransactionIoctl), RENAME(SMBTransactionRename), + SETFILEPATHINFO(SMBTransactionSetFilePathInfo), +} + +// Used for Trans2 SET_PATH_INFO and SET_FILE_INFO +#[derive(Debug)] +pub struct SMBTransactionSetFilePathInfo { + pub subcmd: u16, + pub loi: u16, + pub delete_on_close: bool, + pub filename: Vec, + pub fid: Vec, +} + +impl SMBTransactionSetFilePathInfo { + pub fn new(filename: Vec, fid: Vec, subcmd: u16, loi: u16, delete_on_close: bool) + -> SMBTransactionSetFilePathInfo + { + return SMBTransactionSetFilePathInfo { + filename: filename, fid: fid, + subcmd: subcmd, + loi: loi, + delete_on_close: delete_on_close, + } + } +} + +impl SMBState { + pub fn new_setfileinfo_tx(&mut self, filename: Vec, fid: Vec, + subcmd: u16, loi: u16, delete_on_close: bool) + -> (&mut SMBTransaction) + { + let mut tx = self.new_tx(); + + tx.type_data = Some(SMBTransactionTypeData::SETFILEPATHINFO( + SMBTransactionSetFilePathInfo::new( + filename, fid, subcmd, loi, delete_on_close))); + tx.request_done = true; + tx.response_done = self.tc_trunc; // no response expected if tc is truncated + + SCLogDebug!("SMB: TX SETFILEPATHINFO created: ID {}", tx.id); + self.transactions.push(tx); + let tx_ref = self.transactions.last_mut(); + return tx_ref.unwrap(); + } + + pub fn new_setpathinfo_tx(&mut self, filename: Vec, + subcmd: u16, loi: u16, delete_on_close: bool) + -> (&mut SMBTransaction) + { + let mut tx = self.new_tx(); + + let fid : Vec = Vec::new(); + tx.type_data = Some(SMBTransactionTypeData::SETFILEPATHINFO( + SMBTransactionSetFilePathInfo::new(filename, fid, + subcmd, loi, delete_on_close))); + tx.request_done = true; + tx.response_done = self.tc_trunc; // no response expected if tc is truncated + + SCLogDebug!("SMB: TX SETFILEPATHINFO created: ID {}", tx.id); + self.transactions.push(tx); + let tx_ref = self.transactions.last_mut(); + return tx_ref.unwrap(); + } } #[derive(Debug)] diff --git a/rust/src/smb/smb1.rs b/rust/src/smb/smb1.rs index 67e88616eb..e51a03a30a 100644 --- a/rust/src/smb/smb1.rs +++ b/rust/src/smb/smb1.rs @@ -221,7 +221,32 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 { IResult::Done(_, pd) => { SCLogDebug!("TRANS2 SET_PATH_INFO PARAMS DONE {:?}", pd); - if pd.loi == 1010 { + if pd.loi == 1013 { // set disposition info + match parse_trans2_request_data_set_file_info_disposition(rd.data_blob) { + IResult::Done(_, disp) => { + SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION DONE {:?}", disp); + let tx_hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_GENERICTX); + + let tx = state.new_setpathinfo_tx(pd.oldname, + rd.subcmd, pd.loi, disp.delete); + tx.hdr = tx_hdr; + tx.request_done = true; + tx.vercmd.set_smb1_cmd(SMB1_COMMAND_TRANS2); + true + + }, + IResult::Incomplete(n) => { + SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION INCOMPLETE {:?}", n); + events.push(SMBEvent::MalformedData); + false + }, + IResult::Error(e) => { + SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION ERROR {:?}", e); + events.push(SMBEvent::MalformedData); + false + }, + } + } else if pd.loi == 1010 { match parse_trans2_request_data_set_path_info_rename(rd.data_blob) { IResult::Done(_, ren) => { SCLogDebug!("TRANS2 SET_PATH_INFO DATA RENAME DONE {:?}", ren); @@ -269,7 +294,39 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 { IResult::Done(_, pd) => { SCLogDebug!("TRANS2 SET_FILE_INFO PARAMS DONE {:?}", pd); - if pd.loi == 1010 { + if pd.loi == 1013 { // set disposition info + match parse_trans2_request_data_set_file_info_disposition(rd.data_blob) { + IResult::Done(_, disp) => { + SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION DONE {:?}", disp); + let tx_hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_GENERICTX); + + let mut frankenfid = pd.fid.to_vec(); + frankenfid.extend_from_slice(&u32_as_bytes(r.ssn_id)); + + let filename = match state.guid2name_map.get(&frankenfid) { + Some(n) => n.to_vec(), + None => b"".to_vec(), + }; + let tx = state.new_setfileinfo_tx(filename, pd.fid.to_vec(), + rd.subcmd, pd.loi, disp.delete); + tx.hdr = tx_hdr; + tx.request_done = true; + tx.vercmd.set_smb1_cmd(SMB1_COMMAND_TRANS2); + true + + }, + IResult::Incomplete(n) => { + SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION INCOMPLETE {:?}", n); + events.push(SMBEvent::MalformedData); + false + }, + IResult::Error(e) => { + SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION ERROR {:?}", e); + events.push(SMBEvent::MalformedData); + false + }, + } + } else if pd.loi == 1010 { match parse_trans2_request_data_set_file_info_rename(rd.data_blob) { IResult::Done(_, ren) => { SCLogDebug!("TRANS2 SET_FILE_INFO DATA RENAME DONE {:?}", ren); diff --git a/rust/src/smb/smb1_records.rs b/rust/src/smb/smb1_records.rs index 36b367470b..c0f1cf8307 100644 --- a/rust/src/smb/smb1_records.rs +++ b/rust/src/smb/smb1_records.rs @@ -562,6 +562,20 @@ named!(pub parse_smb_create_andx_request_record, })) ); +#[derive(Debug,PartialEq)] +pub struct Trans2RecordParamSetFileInfoDisposition<> { + pub delete: bool, +} + +named!(pub parse_trans2_request_data_set_file_info_disposition, + do_parse!( + delete: le_u8 + >> _reserved: take!(3) + >> (Trans2RecordParamSetFileInfoDisposition { + delete: delete & 1 == 1, + }) +)); + #[derive(Debug,PartialEq)] pub struct Trans2RecordParamSetFileInfo<'a> { pub fid: &'a[u8],