smb1: extract rename info from TRANS2

Exclude TRANS2 from generic TX lookup bypass.
pull/3289/head
Victor Julien 8 years ago
parent 8eeda113c8
commit 0dfb3f0e7f

@ -133,6 +133,18 @@ pub fn smb1_create_new_tx(cmd: u8) -> bool {
}
}
// see if we're going to do a lookup for a TX.
// related to smb1_create_new_tx(), however it
// excludes the 'maybe' commands like TRANS2
pub fn smb1_check_tx(cmd: u8) -> bool {
match cmd {
SMB1_COMMAND_READ_ANDX |
SMB1_COMMAND_WRITE_ANDX |
SMB1_COMMAND_TRANS => { false },
_ => { true },
}
}
fn smb1_close_file(state: &mut SMBState, fid: &Vec<u8>)
{
// we can have created 2 txs for a FID: one for reads
@ -199,7 +211,79 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
},
}
},
SMB1_COMMAND_TRANS2 => {
match parse_smb_trans2_request_record(r.data) {
IResult::Done(_, rd) => {
SCLogDebug!("TRANS2 DONE {:?}", rd);
if rd.subcmd == 8 {
match parse_trans2_request_params_set_file_info(rd.setup_blob) {
IResult::Done(_, pd) => {
SCLogDebug!("TRANS2 SET_FILE_INFO PARAMS DONE {:?}", pd);
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);
let tx_hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_GENERICTX);
let mut newname = ren.newname.to_vec();
newname.retain(|&i|i != 0x00);
let mut frankenfid = pd.fid.to_vec();
frankenfid.extend_from_slice(&u32_as_bytes(r.ssn_id));
let oldname = match state.guid2name_map.get(&frankenfid) {
Some(n) => n.to_vec(),
None => b"<unknown>".to_vec(),
};
let tx = state.new_rename_tx(pd.fid.to_vec(), oldname, newname);
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 RENAME INCOMPLETE {:?}", n);
events.push(SMBEvent::MalformedData);
false
},
IResult::Error(e) => {
SCLogDebug!("TRANS2 SET_FILE_INFO DATA RENAME ERROR {:?}", e);
events.push(SMBEvent::MalformedData);
false
},
}
} else {
false
}
},
IResult::Incomplete(n) => {
SCLogDebug!("TRANS2 SET_FILE_INFO PARAMS INCOMPLETE {:?}", n);
events.push(SMBEvent::MalformedData);
false
},
IResult::Error(e) => {
SCLogDebug!("TRANS2 SET_FILE_INFO PARAMS ERROR {:?}", e);
events.push(SMBEvent::MalformedData);
false
},
}
} else {
false
}
},
IResult::Incomplete(n) => {
SCLogDebug!("TRANS2 INCOMPLETE {:?}", n);
events.push(SMBEvent::MalformedData);
false
},
IResult::Error(e) => {
SCLogDebug!("TRANS2 ERROR {:?}", e);
events.push(SMBEvent::MalformedData);
false
},
}
},
SMB1_COMMAND_READ_ANDX => {
match parse_smb_read_andx_request_record(r.data) {
IResult::Done(_, rr) => {
@ -355,8 +439,7 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
false
},
_ => {
if r.command == SMB1_COMMAND_TRANS2 ||
r.command == SMB1_COMMAND_LOGOFF_ANDX ||
if r.command == SMB1_COMMAND_LOGOFF_ANDX ||
r.command == SMB1_COMMAND_TREE_DISCONNECT ||
r.command == SMB1_COMMAND_NT_TRANS ||
r.command == SMB1_COMMAND_NT_CANCEL ||
@ -577,7 +660,7 @@ pub fn smb1_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32
},
_ => {},
}
} else if !have_tx && smb1_create_new_tx(r.command) {
} else if !have_tx && smb1_check_tx(r.command) {
let tx_key = SMBCommonHdr::new(SMBHDR_TYPE_GENERICTX,
key_ssn_id as u64, key_tree_id as u32, key_multiplex_id as u64);
let _have_tx2 = match state.get_generic_tx(1, r.command as u16, &tx_key) {

@ -564,6 +564,79 @@ named!(pub parse_smb_create_andx_request_record<SmbRequestCreateAndXRecord>,
}))
);
#[derive(Debug,PartialEq)]
pub struct Trans2RecordParamSetFileInfo<'a> {
pub fid: &'a[u8],
pub loi: u16,
}
named!(pub parse_trans2_request_params_set_file_info<Trans2RecordParamSetFileInfo>,
do_parse!(
fid: take!(2)
>> loi: le_u16
>> (Trans2RecordParamSetFileInfo {
fid:fid,
loi:loi,
})
));
#[derive(Debug,PartialEq)]
pub struct Trans2RecordParamSetFileInfoRename<'a> {
pub replace: bool,
pub newname: &'a[u8],
}
named!(pub parse_trans2_request_data_set_file_info_rename<Trans2RecordParamSetFileInfoRename>,
do_parse!(
replace: le_u8
>> _reserved: take!(3)
>> root_dir: take!(4)
>> newname_len: le_u32
>> newname: take!(newname_len)
>> (Trans2RecordParamSetFileInfoRename {
replace: replace==1,
newname: newname,
})
));
#[derive(Debug,PartialEq)]
pub struct SmbRequestTrans2Record<'a> {
pub subcmd: u16,
pub setup_blob: &'a[u8],
pub data_blob: &'a[u8],
}
named!(pub parse_smb_trans2_request_record<SmbRequestTrans2Record>,
do_parse!(
wct: le_u8
>> total_param_cnt: le_u16
>> total_data_cnt: le_u16
>> max_param_cnt: le_u16
>> max_data_cnt: le_u16
>> max_setup_cnt: le_u8
>> _reserved1: take!(1)
>> flags: le_u16
>> timeout: le_u32
>> _reserved2: take!(2)
>> param_cnt: le_u16
>> param_offset: le_u16
>> data_cnt: le_u16
>> data_offset: le_u16
>> setup_cnt: le_u8
>> _reserved3: take!(1)
>> subcmd: le_u16
>> bcc: le_u16
>> _padding: take!(3)
>> setup_blob: take!(param_cnt)
>> data_blob: take!(data_cnt)
>> (SmbRequestTrans2Record {
subcmd: subcmd,
setup_blob: setup_blob,
data_blob: data_blob,
}))
);
#[derive(Debug,PartialEq)]
pub struct SmbResponseCreateAndXRecord<'a> {
pub fid: &'a[u8],

Loading…
Cancel
Save