]> git.ipfire.org Git - people/ms/suricata.git/commitdiff
smb2: log renames
authorVictor Julien <victor@inliniac.net>
Thu, 15 Mar 2018 10:11:07 +0000 (11:11 +0100)
committerVictor Julien <victor@inliniac.net>
Thu, 15 Mar 2018 16:20:30 +0000 (17:20 +0100)
rust/src/smb/log.rs
rust/src/smb/smb.rs
rust/src/smb/smb2.rs
rust/src/smb/smb2_records.rs

index 0a277566be232c27b984b962d234b095905a0128..e3d9aa0cee3512964aa881bafaf27a26aba92964 100644 (file)
@@ -329,6 +329,18 @@ fn smb_common_header(state: &SMBState, tx: &SMBTransaction) -> Json
             let gs = fuid_to_string(&x.fuid);
             js.set_string("fuid", &gs);
         },
+        Some(SMBTransactionTypeData::RENAME(ref x)) => {
+            let jsd = Json::object();
+            jsd.set_string("class", "FILE_INFO");
+            jsd.set_string("info_level", "SMB2_FILE_RENAME_INFO");
+            let file_name = String::from_utf8_lossy(&x.oldname);
+            jsd.set_string("from", &file_name);
+            let file_name = String::from_utf8_lossy(&x.newname);
+            jsd.set_string("to", &file_name);
+            js.set("set_info", jsd);
+            let gs = fuid_to_string(&x.fuid);
+            js.set_string("fuid", &gs);
+        },
         Some(SMBTransactionTypeData::DCERPC(ref x)) => {
             let jsd = Json::object();
             jsd.set_string("request", &dcerpc_type_string(x.req_cmd));
index 9fcf4ba8080131f3d05103be49aaf29887bc56d9..5a57188c0bbf08ef3cd97b1fe17f6bee26a8d2e9 100644 (file)
@@ -363,6 +363,40 @@ pub enum SMBTransactionTypeData {
     CREATE(SMBTransactionCreate),
     SESSIONSETUP(SMBTransactionSessionSetup),
     IOCTL(SMBTransactionIoctl),
+    RENAME(SMBTransactionRename),
+}
+
+#[derive(Debug)]
+pub struct SMBTransactionRename {
+    pub oldname: Vec<u8>,
+    pub newname: Vec<u8>,
+    pub fuid: Vec<u8>,
+}
+
+impl SMBTransactionRename {
+    pub fn new(fuid: Vec<u8>, oldname: Vec<u8>, newname: Vec<u8>) -> SMBTransactionRename {
+        return SMBTransactionRename {
+            fuid: fuid, oldname: oldname, newname: newname,
+        }
+    }
+}
+
+impl SMBState {
+    pub fn new_rename_tx(&mut self, fuid: Vec<u8>, oldname: Vec<u8>, newname: Vec<u8>)
+        -> (&mut SMBTransaction)
+    {
+        let mut tx = self.new_tx();
+
+        tx.type_data = Some(SMBTransactionTypeData::RENAME(
+                    SMBTransactionRename::new(fuid, oldname, newname)));
+        tx.request_done = true;
+        tx.response_done = self.tc_trunc; // no response expected if tc is truncated
+
+        SCLogNotice!("SMB: TX RENAME created: ID {}", tx.id);
+        self.transactions.push(tx);
+        let tx_ref = self.transactions.last_mut();
+        return tx_ref.unwrap();
+    }
 }
 
 #[derive(Debug)]
index 83094ddf9476efa0fc27ce987814e6dcc2194ec6..3c2cd9142e674e502ab05948572c22824e0c16fb 100644 (file)
@@ -276,6 +276,42 @@ pub fn smb2_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
     let mut events : Vec<SMBEvent> = Vec::new();
 
     let have_tx = match r.command {
+        SMB2_COMMAND_SET_INFO => {
+            SCLogDebug!("SMB2_COMMAND_SET_INFO: {:?}", r);
+            let have_si_tx = match parse_smb2_request_setinfo(r.data) {
+                IResult::Done(_, rd) => {
+                    SCLogDebug!("SMB2_COMMAND_SET_INFO: {:?}", rd);
+
+                    if let Some(ref ren) = rd.rename {
+                        let tx_hdr = SMBCommonHdr::from2(r, SMBHDR_TYPE_GENERICTX);
+                        let mut newname = ren.name.to_vec();
+                        newname.retain(|&i|i != 0x00);
+                        let oldname = match state.guid2name_map.get(rd.guid) {
+                            Some(n) => { n.to_vec() },
+                            None => { b"<unknown>".to_vec() },
+                        };
+                        let tx = state.new_rename_tx(rd.guid.to_vec(), oldname, newname);
+                        tx.hdr = tx_hdr;
+                        tx.request_done = true;
+                        tx.vercmd.set_smb2_cmd(SMB2_COMMAND_SET_INFO);
+                        true
+                    } else {
+                        false
+                    }
+                },
+                IResult::Incomplete(_n) => {
+                    SCLogDebug!("SMB2_COMMAND_SET_INFO: {:?}", _n);
+                    events.push(SMBEvent::MalformedData);
+                    false
+                },
+                IResult::Error(_e) => {
+                    SCLogDebug!("SMB2_COMMAND_SET_INFO: {:?}", _e);
+                    events.push(SMBEvent::MalformedData);
+                    false
+                },
+            };
+            have_si_tx
+        },
         SMB2_COMMAND_IOCTL => {
             smb2_ioctl_request_record(state, r);
             true
index 3b299e4901352da6d5456c3397e5c6fbbc2b955c..ce0fac97b08e584bc58319d2ddedd00da2868c68 100644 (file)
@@ -300,6 +300,50 @@ named!(pub parse_smb2_request_close<Smb2CloseRequestRecord>,
             })
 ));
 
+#[derive(Debug)]
+pub struct Smb2SetInfoRequestRenameRecord<'a> {
+    pub name: &'a[u8],
+}
+
+named!(pub parse_smb2_request_setinfo_rename<Smb2SetInfoRequestRenameRecord>,
+    do_parse!(
+            replace: le_u8
+        >>  _reserved: take!(7)
+        >>  _root_handle: take!(8)
+        >>  name_len: le_u32
+        >>  name: take!(name_len)
+        >> (Smb2SetInfoRequestRenameRecord {
+                name: name,
+            })
+));
+
+#[derive(Debug)]
+pub struct Smb2SetInfoRequestRecord<'a> {
+    pub guid: &'a[u8],
+    pub class: u8,
+    pub infolvl: u8,
+    pub rename: Option<Smb2SetInfoRequestRenameRecord<'a>>,
+}
+
+named!(pub parse_smb2_request_setinfo<Smb2SetInfoRequestRecord>,
+    do_parse!(
+            struct_size: le_u16
+        >>  class: le_u8
+        >>  infolvl: le_u8
+        >>  setinfo_size: le_u32
+        >>  setinfo_offset: le_u16
+        >>  _reserved: take!(2)
+        >>  additional_info: le_u32
+        >>  guid: take!(16)
+        >>  rename: cond!(class == 1 && infolvl == 10, flat_map!(take!(setinfo_size),parse_smb2_request_setinfo_rename))
+        >> (Smb2SetInfoRequestRecord {
+                guid: guid,
+                class: class,
+                infolvl: infolvl,
+                rename: rename,
+            })
+));
+
 #[derive(Debug,PartialEq)]
 pub struct Smb2WriteRequestRecord<'a> {
     pub wr_len: u32,