smb: improve request/response mapping

Only use ssn_id and msg_id for mapping a response to a request.

By not using the tree_id it can always be included in the tx.hdr which
means it can be logged properly in case of IOCTL and DCERPC.
pull/3593/head
Victor Julien 7 years ago
parent 6f5eb487a1
commit 8b570c0293

@ -232,7 +232,7 @@ impl SMBState {
SCLogDebug!("looking for {:?}", dce_hdr); SCLogDebug!("looking for {:?}", dce_hdr);
for tx in &mut self.transactions { for tx in &mut self.transactions {
let found = dce_hdr == tx.hdr.to_dcerpc(vercmd) && let found = dce_hdr.compare(&tx.hdr.to_dcerpc(vercmd)) &&
match tx.type_data { match tx.type_data {
Some(SMBTransactionTypeData::DCERPC(ref x)) => { Some(SMBTransactionTypeData::DCERPC(ref x)) => {
x.call_id == call_id x.call_id == call_id

@ -62,7 +62,7 @@ impl SMBState {
-> Option<&mut SMBTransaction> -> Option<&mut SMBTransaction>
{ {
for tx in &mut self.transactions { for tx in &mut self.transactions {
let hit = tx.hdr == hdr && match tx.type_data { let hit = tx.hdr.compare(&hdr) && match tx.type_data {
Some(SMBTransactionTypeData::SESSIONSETUP(_)) => { true }, Some(SMBTransactionTypeData::SESSIONSETUP(_)) => { true },
_ => { false }, _ => { false },
}; };

@ -701,6 +701,12 @@ impl SMBCommonHdr {
msg_id : msg_id, msg_id : msg_id,
} }
} }
// don't include tree id
pub fn compare(&self, hdr: &SMBCommonHdr) -> bool {
(self.rec_type == hdr.rec_type && self.ssn_id == hdr.ssn_id &&
self.msg_id == hdr.msg_id)
}
} }
#[derive(Hash, Eq, PartialEq, Debug)] #[derive(Hash, Eq, PartialEq, Debug)]
@ -973,10 +979,10 @@ impl SMBState {
let found = if tx.vercmd.get_version() == smb_ver { let found = if tx.vercmd.get_version() == smb_ver {
if smb_ver == 1 { if smb_ver == 1 {
let (_, cmd) = tx.vercmd.get_smb1_cmd(); let (_, cmd) = tx.vercmd.get_smb1_cmd();
cmd as u16 == smb_cmd && tx.hdr == *key cmd as u16 == smb_cmd && tx.hdr.compare(key)
} else if smb_ver == 2 { } else if smb_ver == 2 {
let (_, cmd) = tx.vercmd.get_smb2_cmd(); let (_, cmd) = tx.vercmd.get_smb2_cmd();
cmd == smb_cmd && tx.hdr == *key cmd == smb_cmd && tx.hdr.compare(key)
} else { } else {
false false
} }
@ -1054,7 +1060,7 @@ impl SMBState {
-> Option<&mut SMBTransaction> -> Option<&mut SMBTransaction>
{ {
for tx in &mut self.transactions { for tx in &mut self.transactions {
let hit = tx.hdr == hdr && match tx.type_data { let hit = tx.hdr.compare(&hdr) && match tx.type_data {
Some(SMBTransactionTypeData::TREECONNECT(_)) => { true }, Some(SMBTransactionTypeData::TREECONNECT(_)) => { true },
_ => { false }, _ => { false },
}; };
@ -1090,7 +1096,7 @@ impl SMBState {
for tx in &mut self.transactions { for tx in &mut self.transactions {
let found = match tx.type_data { let found = match tx.type_data {
Some(SMBTransactionTypeData::CREATE(ref _d)) => { Some(SMBTransactionTypeData::CREATE(ref _d)) => {
*hdr == tx.hdr tx.hdr.compare(&hdr)
}, },
_ => { false }, _ => { false },
}; };

@ -59,14 +59,13 @@ impl SMBState {
// IOCTL responses ASYNC don't set the tree id // IOCTL responses ASYNC don't set the tree id
pub fn smb2_ioctl_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>) pub fn smb2_ioctl_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
{ {
let hdr = SMBCommonHdr::from2(r, SMBHDR_TYPE_HEADER);
match parse_smb2_request_ioctl(r.data) { match parse_smb2_request_ioctl(r.data) {
IResult::Done(_, rd) => { IResult::Done(_, rd) => {
SCLogDebug!("IOCTL request data: {:?}", rd); SCLogDebug!("IOCTL request data: {:?}", rd);
let is_dcerpc = rd.is_pipe && match state.get_service_for_guid(&rd.guid) { let is_dcerpc = rd.is_pipe && match state.get_service_for_guid(&rd.guid) {
(_, x) => x, (_, x) => x,
}; };
let hdr = SMBCommonHdr::new(SMBHDR_TYPE_HEADER,
r.session_id, 0, r.message_id);
if is_dcerpc { if is_dcerpc {
SCLogDebug!("IOCTL request data is_pipe. Calling smb_write_dcerpc_record"); SCLogDebug!("IOCTL request data is_pipe. Calling smb_write_dcerpc_record");
let vercmd = SMBVerCmdStat::new2(SMB2_COMMAND_IOCTL); let vercmd = SMBVerCmdStat::new2(SMB2_COMMAND_IOCTL);
@ -78,8 +77,6 @@ pub fn smb2_ioctl_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
} }
}, },
_ => { _ => {
let hdr = SMBCommonHdr::new(SMBHDR_TYPE_HEADER,
r.session_id, 0, r.message_id);
let tx = state.new_generic_tx(2, r.command, hdr); let tx = state.new_generic_tx(2, r.command, hdr);
tx.set_event(SMBEvent::MalformedData); tx.set_event(SMBEvent::MalformedData);
}, },
@ -89,6 +86,7 @@ pub fn smb2_ioctl_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
// IOCTL responses ASYNC don't set the tree id // IOCTL responses ASYNC don't set the tree id
pub fn smb2_ioctl_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>) pub fn smb2_ioctl_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
{ {
let hdr = SMBCommonHdr::from2(r, SMBHDR_TYPE_HEADER);
match parse_smb2_response_ioctl(r.data) { match parse_smb2_response_ioctl(r.data) {
IResult::Done(_, rd) => { IResult::Done(_, rd) => {
SCLogDebug!("IOCTL response data: {:?}", rd); SCLogDebug!("IOCTL response data: {:?}", rd);
@ -98,16 +96,12 @@ pub fn smb2_ioctl_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
}; };
if is_dcerpc { if is_dcerpc {
SCLogDebug!("IOCTL response data is_pipe. Calling smb_read_dcerpc_record"); SCLogDebug!("IOCTL response data is_pipe. Calling smb_read_dcerpc_record");
let hdr = SMBCommonHdr::new(SMBHDR_TYPE_HEADER,
r.session_id, 0, r.message_id);
let vercmd = SMBVerCmdStat::new2_with_ntstatus(SMB2_COMMAND_IOCTL, r.nt_status); let vercmd = SMBVerCmdStat::new2_with_ntstatus(SMB2_COMMAND_IOCTL, r.nt_status);
SCLogDebug!("TODO passing empty GUID"); SCLogDebug!("TODO passing empty GUID");
smb_read_dcerpc_record(state, vercmd, hdr, &[],rd.data); smb_read_dcerpc_record(state, vercmd, hdr, &[],rd.data);
} else { } else {
let tx_key = SMBCommonHdr::new(SMBHDR_TYPE_HEADER, SCLogDebug!("SMB2_COMMAND_IOCTL/SMB_NTSTATUS_PENDING looking for {:?}", hdr);
r.session_id, 0, r.message_id); match state.get_generic_tx(2, SMB2_COMMAND_IOCTL, &hdr) {
SCLogDebug!("SMB2_COMMAND_IOCTL/SMB_NTSTATUS_PENDING looking for {:?}", tx_key);
match state.get_generic_tx(2, SMB2_COMMAND_IOCTL, &tx_key) {
Some(tx) => { Some(tx) => {
tx.set_status(r.nt_status, false); tx.set_status(r.nt_status, false);
if r.nt_status != SMB_NTSTATUS_PENDING { if r.nt_status != SMB_NTSTATUS_PENDING {
@ -119,10 +113,8 @@ pub fn smb2_ioctl_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
} }
}, },
_ => { _ => {
let tx_key = SMBCommonHdr::new(SMBHDR_TYPE_HEADER, SCLogDebug!("SMB2_COMMAND_IOCTL/SMB_NTSTATUS_PENDING looking for {:?}", hdr);
r.session_id, 0, r.message_id); match state.get_generic_tx(2, SMB2_COMMAND_IOCTL, &hdr) {
SCLogDebug!("SMB2_COMMAND_IOCTL/SMB_NTSTATUS_PENDING looking for {:?}", tx_key);
match state.get_generic_tx(2, SMB2_COMMAND_IOCTL, &tx_key) {
Some(tx) => { Some(tx) => {
SCLogDebug!("updated status of tx {}", tx.id); SCLogDebug!("updated status of tx {}", tx.id);
tx.set_status(r.nt_status, false); tx.set_status(r.nt_status, false);

Loading…
Cancel
Save