smb: log file FID/GUID as fuid

pull/3286/head
Victor Julien 7 years ago
parent 67f0e27ca4
commit fb986abe81

@ -26,7 +26,7 @@ use smb::smb::*;
#[derive(Debug)]
pub struct SMBTransactionFile {
pub direction: u8,
pub guid: Vec<u8>,
pub fuid: Vec<u8>,
pub file_name: Vec<u8>,
pub share_name: Vec<u8>,
pub file_tracker: FileTransferTracker,
@ -36,7 +36,7 @@ impl SMBTransactionFile {
pub fn new() -> SMBTransactionFile {
return SMBTransactionFile {
direction: 0,
guid: Vec::new(),
fuid: Vec::new(),
file_name: Vec::new(),
share_name: Vec::new(),
file_tracker: FileTransferTracker::new(),
@ -91,7 +91,7 @@ pub fn filetracker_newchunk(ft: &mut FileTransferTracker, files: &mut FileContai
}
impl SMBState {
pub fn new_file_tx(&mut self, file_guid: &Vec<u8>, file_name: &Vec<u8>, direction: u8)
pub fn new_file_tx(&mut self, fuid: &Vec<u8>, file_name: &Vec<u8>, direction: u8)
-> (&mut SMBTransaction, &mut FileContainer, u16)
{
let mut tx = self.new_tx();
@ -99,7 +99,7 @@ impl SMBState {
match tx.type_data {
Some(SMBTransactionTypeData::FILE(ref mut d)) => {
d.direction = direction;
d.guid = file_guid.to_vec();
d.fuid = fuid.to_vec();
d.file_name = file_name.to_vec();
d.file_tracker.tx_id = tx.id - 1;
},
@ -113,14 +113,14 @@ impl SMBState {
return (tx_ref.unwrap(), files, flags)
}
pub fn get_file_tx_by_guid(&mut self, guid: &Vec<u8>, direction: u8)
pub fn get_file_tx_by_fuid(&mut self, fuid: &Vec<u8>, direction: u8)
-> Option<(&mut SMBTransaction, &mut FileContainer, u16)>
{
let g = guid.to_vec();
let f = fuid.to_vec();
for tx in &mut self.transactions {
let found = match tx.type_data {
Some(SMBTransactionTypeData::FILE(ref mut d)) => {
direction == d.direction && g == d.guid
direction == d.direction && f == d.fuid
},
_ => { false },
};
@ -131,7 +131,7 @@ impl SMBState {
return Some((tx, files, flags));
}
}
SCLogDebug!("SMB: Failed to find SMB TX with GUID {:?}", guid);
SCLogDebug!("SMB: Failed to find SMB TX with FUID {:?}", fuid);
return None;
}
@ -190,7 +190,7 @@ impl SMBState {
let ssn_gap = self.ts_ssn_gap | self.tc_ssn_gap;
// get the tx and update it
let consumed = match self.get_file_tx_by_guid(&file_handle, direction) {
let consumed = match self.get_file_tx_by_fuid(&file_handle, direction) {
Some((tx, files, flags)) => {
if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
if ssn_gap {

@ -25,7 +25,6 @@ use smb::smb1::*;
use smb::smb2::*;
use smb::dcerpc::*;
use smb::funcs::*;
use nom;
#[cfg(not(feature = "debug"))]
fn debug_add_progress(_js: &Json, _tx: &SMBTransaction) { }
@ -36,6 +35,24 @@ fn debug_add_progress(js: &Json, tx: &SMBTransaction) {
js.set_boolean("response_done", tx.request_done);
}
/// take in a file GUID (16 bytes) or FID (2 bytes). Also deal
/// with our frankenFID (2 bytes + 4 user_id)
fn fuid_to_string(fuid: &Vec<u8>) -> String {
let fuid_len = fuid.len();
if fuid_len == 16 {
guid_to_string(fuid)
} else if fuid_len == 2 {
let o = format!("{:02x}{:02x}", fuid[1], fuid[0]);
o.to_string()
} else if fuid_len == 6 {
let pure_fid = &fuid[0..2];
let o = format!("{:02x}{:02x}", pure_fid[1], pure_fid[0]);
o.to_string()
} else {
"".to_string()
}
}
fn guid_to_string(guid: &Vec<u8>) -> String {
if guid.len() == 16 {
let output = format!("{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
@ -243,6 +260,9 @@ fn smb_common_header(state: &SMBState, tx: &SMBTransaction) -> Json
js.set_integer("modified", x.last_write_ts as u64);
js.set_integer("changed", x.last_change_ts as u64);
js.set_integer("size", x.size);
let gs = fuid_to_string(&x.guid);
js.set_string("fuid", &gs);
},
Some(SMBTransactionTypeData::NEGOTIATE(ref x)) => {
if x.smb_ver == 1 {
@ -304,21 +324,16 @@ fn smb_common_header(state: &SMBState, tx: &SMBTransaction) -> Json
Some(SMBTransactionTypeData::FILE(ref x)) => {
let file_name = String::from_utf8_lossy(&x.file_name);
js.set_string("filename", &file_name);
let share_name = String::from_utf8_lossy(&x.share_name);
js.set_string("share", &share_name);
if x.share_name.len() > 0 {
let share_name = String::from_utf8_lossy(&x.share_name);
js.set_string("share", &share_name);
} else {
// name suggestion from Bro
js.set_string("share", "<share_root>");
};
if x.guid.len() >= 2 {
let fid_s = &x.guid[0..2];
let fid_n = match nom::le_u16(&fid_s) {
nom::IResult::Done(_, x) => {
x as u16
}
_ => 0 as u16
};
let fid_hex_str = format!("0x{:00x}", fid_n);
js.set_string("fid", &fid_hex_str);
}
let gs = fuid_to_string(&x.fuid);
js.set_string("fuid", &gs);
},
Some(SMBTransactionTypeData::DCERPC(ref x)) => {
let jsd = Json::object();

@ -371,6 +371,7 @@ pub struct SMBTransactionCreate {
pub delete_on_close: bool,
pub directory: bool,
pub filename: Vec<u8>,
pub guid: Vec<u8>,
pub create_ts: u32,
pub last_access_ts: u32,
@ -387,6 +388,7 @@ impl SMBTransactionCreate {
delete_on_close: del,
directory: dir,
filename: filename,
guid: Vec::new(),
create_ts: 0,
last_access_ts: 0,
last_write_ts: 0,

@ -135,7 +135,7 @@ fn smb1_close_file(state: &mut SMBState, fid: &Vec<u8>)
{
// we can have created 2 txs for a FID: one for reads
// and one for writes. So close both.
match state.get_file_tx_by_guid(&fid, STREAM_TOSERVER) {
match state.get_file_tx_by_fuid(&fid, STREAM_TOSERVER) {
Some((tx, files, flags)) => {
SCLogDebug!("found tx {}", tx.id);
if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
@ -146,13 +146,11 @@ fn smb1_close_file(state: &mut SMBState, fid: &Vec<u8>)
tx.response_done = true;
SCLogDebug!("tx {} is done", tx.id);
}
// as a precaution, reset guid so it can be reused
tdf.guid.clear(); // TODO review
}
},
None => { },
}
match state.get_file_tx_by_guid(&fid, STREAM_TOCLIENT) {
match state.get_file_tx_by_fuid(&fid, STREAM_TOCLIENT) {
Some((tx, files, flags)) => {
SCLogDebug!("found tx {}", tx.id);
if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
@ -163,8 +161,6 @@ fn smb1_close_file(state: &mut SMBState, fid: &Vec<u8>)
tx.response_done = true;
SCLogDebug!("tx {} is done", tx.id);
}
// as a precaution, reset guid so it can be reused
tdf.guid.clear(); // TODO review now that fid is improved
}
},
None => { },
@ -513,6 +509,7 @@ pub fn smb1_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32
tdn.last_write_ts = cr.last_write_ts.as_unix();
tdn.last_change_ts = cr.last_change_ts.as_unix();
tdn.size = cr.file_size;
tdn.guid = cr.fid.to_vec();
}
}
true
@ -713,7 +710,7 @@ pub fn smb1_write_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>)
Some(n) => n.to_vec(),
None => Vec::new(),
};
let found = match state.get_file_tx_by_guid(&file_fid, STREAM_TOSERVER) {
let found = match state.get_file_tx_by_fuid(&file_fid, STREAM_TOSERVER) {
Some((tx, files, flags)) => {
let file_id : u32 = tx.id as u32;
if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
@ -797,7 +794,7 @@ pub fn smb1_read_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>)
Some(n) => n.to_vec(),
None => Vec::new(),
};
let found = match state.get_file_tx_by_guid(&file_fid, STREAM_TOCLIENT) {
let found = match state.get_file_tx_by_fuid(&file_fid, STREAM_TOCLIENT) {
Some((tx, files, flags)) => {
if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
let file_id : u32 = tx.id as u32;

@ -132,7 +132,7 @@ pub fn smb2_read_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
SCLogDebug!("SMBv2 READ: GUID {:?} offset {}", file_guid, offset);
// look up existing tracker and if we have it update it
let found = match state.get_file_tx_by_guid(&file_guid, STREAM_TOCLIENT) {
let found = match state.get_file_tx_by_fuid(&file_guid, STREAM_TOCLIENT) {
Some((tx, files, flags)) => {
if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
let file_id : u32 = tx.id as u32;
@ -209,7 +209,7 @@ pub fn smb2_write_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
None => Vec::new(),
};
let found = match state.get_file_tx_by_guid(&file_guid, STREAM_TOSERVER) {
let found = match state.get_file_tx_by_fuid(&file_guid, STREAM_TOSERVER) {
Some((tx, files, flags)) => {
if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
let file_id : u32 = tx.id as u32;
@ -385,7 +385,7 @@ pub fn smb2_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
SMB2_COMMAND_CLOSE => {
match parse_smb2_request_close(r.data) {
IResult::Done(_, cd) => {
let found_ts = match state.get_file_tx_by_guid(&cd.guid.to_vec(), STREAM_TOSERVER) {
let found_ts = match state.get_file_tx_by_fuid(&cd.guid.to_vec(), STREAM_TOSERVER) {
Some((tx, files, flags)) => {
if !tx.request_done {
if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
@ -399,7 +399,7 @@ pub fn smb2_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
},
None => { false },
};
let found_tc = match state.get_file_tx_by_guid(&cd.guid.to_vec(), STREAM_TOCLIENT) {
let found_tc = match state.get_file_tx_by_fuid(&cd.guid.to_vec(), STREAM_TOCLIENT) {
Some((tx, files, flags)) => {
if !tx.request_done {
if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
@ -498,7 +498,7 @@ pub fn smb2_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
Vec::new()
},
};
let found = match state.get_file_tx_by_guid(&file_guid, STREAM_TOCLIENT) {
let found = match state.get_file_tx_by_fuid(&file_guid, STREAM_TOCLIENT) {
Some((tx, files, flags)) => {
if !tx.request_done {
if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
@ -547,6 +547,7 @@ pub fn smb2_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
tdn.last_write_ts = cr.last_write_ts.as_unix();
tdn.last_change_ts = cr.last_change_ts.as_unix();
tdn.size = cr.size;
tdn.guid = cr.guid.to_vec();
}
}
}

Loading…
Cancel
Save