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));
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)]
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
})
));
+#[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,