]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
smb: log trans2 that enable delete on close 3421/head
authorVictor Julien <victor@inliniac.net>
Tue, 10 Jul 2018 15:22:53 +0000 (17:22 +0200)
committerVictor Julien <victor@inliniac.net>
Fri, 13 Jul 2018 11:37:35 +0000 (13:37 +0200)
rust/src/smb/log.rs
rust/src/smb/smb.rs
rust/src/smb/smb1.rs
rust/src/smb/smb1_records.rs

index 734b13e57ae7e940c50d940aeeef2991c330f5b3..48c531feb155d1f23fc88c45237de577a22edda2 100644 (file)
@@ -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", "<share_root>");
+            }
+            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;
index 5af874c77aa2b9fcee3679c850c2b691aec266ae..874ff64c14369b2eecab30260d2a23bb577eb36b 100644 (file)
@@ -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<u8>,
+    pub fid: Vec<u8>,
+}
+
+impl SMBTransactionSetFilePathInfo {
+    pub fn new(filename: Vec<u8>, fid: Vec<u8>, 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<u8>, fid: Vec<u8>,
+            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<u8>,
+            subcmd: u16, loi: u16, delete_on_close: bool)
+        -> (&mut SMBTransaction)
+    {
+        let mut tx = self.new_tx();
+
+        let fid : Vec<u8> = 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)]
index 67e88616eb2f960385474532451c910732cfc92f..e51a03a30af9b432b6939f9e4d7e9663db613b11 100644 (file)
@@ -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"<unknown>".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);
index 36b367470b05b6305cba62c12dd0f8040ea76a8d..c0f1cf83078e20ddec1bd3b9a6338746a904f2e4 100644 (file)
@@ -562,6 +562,20 @@ named!(pub parse_smb_create_andx_request_record<SmbRequestCreateAndXRecord>,
            }))
 );
 
+#[derive(Debug,PartialEq)]
+pub struct Trans2RecordParamSetFileInfoDisposition<> {
+    pub delete: bool,
+}
+
+named!(pub parse_trans2_request_data_set_file_info_disposition<Trans2RecordParamSetFileInfoDisposition>,
+    do_parse!(
+            delete: le_u8
+        >>  _reserved: take!(3)
+        >> (Trans2RecordParamSetFileInfoDisposition {
+                delete: delete & 1 == 1,
+            })
+));
+
 #[derive(Debug,PartialEq)]
 pub struct Trans2RecordParamSetFileInfo<'a> {
     pub fid: &'a[u8],