diff --git a/rust/src/smb/events.rs b/rust/src/smb/events.rs
index f8b3055ede..b2a49ca1aa 100644
--- a/rust/src/smb/events.rs
+++ b/rust/src/smb/events.rs
@@ -27,6 +27,10 @@ pub enum SMBEvent {
DuplicateNegotiate,
NegotiateMalformedDialects,
FileOverlap,
+ /// A request was seen in the to client direction.
+ RequestToClient,
+ /// A response was seen in the to server direction,
+ ResponseToServer,
}
impl SMBTransaction {
diff --git a/rust/src/smb/smb.rs b/rust/src/smb/smb.rs
index eaf886395c..d50bbd9050 100644
--- a/rust/src/smb/smb.rs
+++ b/rust/src/smb/smb.rs
@@ -1453,9 +1453,18 @@ impl SMBState {
SCLogDebug!("SMBv1 record");
match parse_smb_record(nbss_hdr.data) {
Ok((_, ref smb_record)) => {
- self.add_smb1_ts_pdu_frame(flow, stream_slice, nbss_hdr.data, nbss_hdr.length as i64);
+ let pdu_frame = self.add_smb1_ts_pdu_frame(flow, stream_slice, nbss_hdr.data, nbss_hdr.length as i64);
self.add_smb1_ts_hdr_data_frames(flow, stream_slice, nbss_hdr.data, nbss_hdr.length as i64);
- smb1_request_record(self, smb_record);
+ if smb_record.is_request() {
+ smb1_request_record(self, smb_record);
+ } else {
+ // If we recevied a response when expecting a request, set an event
+ // on the PDU frame instead of handling the response.
+ SCLogDebug!("SMB1 reply seen from client to server");
+ if let Some(frame) = pdu_frame {
+ frame.add_event(flow, 0, SMBEvent::ResponseToServer as u8);
+ }
+ }
},
_ => {
if let Some(frame) = nbss_data_frame {
@@ -1472,10 +1481,19 @@ impl SMBState {
match parse_smb2_request_record(nbss_data) {
Ok((nbss_data_rem, ref smb_record)) => {
let record_len = (nbss_data.len() - nbss_data_rem.len()) as i64;
- self.add_smb2_ts_pdu_frame(flow, stream_slice, nbss_data, record_len);
+ let pdu_frame = self.add_smb2_ts_pdu_frame(flow, stream_slice, nbss_data, record_len);
self.add_smb2_ts_hdr_data_frames(flow, stream_slice, nbss_data, record_len, smb_record.header_len as i64);
SCLogDebug!("nbss_data_rem {}", nbss_data_rem.len());
- smb2_request_record(self, smb_record);
+ if smb_record.is_request() {
+ smb2_request_record(self, smb_record);
+ } else {
+ // If we recevied a response when expecting a request, set an event
+ // on the PDU frame instead of handling the response.
+ SCLogDebug!("SMB2 reply seen from client to server");
+ if let Some(frame) = pdu_frame {
+ frame.add_event(flow, 0, SMBEvent::ResponseToServer as u8);
+ }
+ }
nbss_data = nbss_data_rem;
},
_ => {
@@ -1571,9 +1589,10 @@ impl SMBState {
(nbss_pdu, nbss_hdr_frame, nbss_data_frame)
}
- fn add_smb1_tc_pdu_frame(&mut self, flow: *const Flow, stream_slice: &StreamSlice, input: &[u8], nbss_len: i64) {
- let _smb_pdu = Frame::new_tc(flow, stream_slice, input, nbss_len, SMBFrameType::SMB1Pdu as u8);
- SCLogDebug!("SMB PDU frame {:?}", _smb_pdu);
+ fn add_smb1_tc_pdu_frame(&mut self, flow: *const Flow, stream_slice: &StreamSlice, input: &[u8], nbss_len: i64) -> Option {
+ let smb_pdu = Frame::new_tc(flow, stream_slice, input, nbss_len, SMBFrameType::SMB1Pdu as u8);
+ SCLogDebug!("SMB PDU frame {:?}", smb_pdu);
+ smb_pdu
}
fn add_smb1_tc_hdr_data_frames(&mut self, flow: *const Flow, stream_slice: &StreamSlice, input: &[u8], nbss_len: i64) {
let _smb1_hdr = Frame::new_tc(flow, stream_slice, input, SMB1_HEADER_SIZE as i64, SMBFrameType::SMB1Hdr as u8);
@@ -1585,9 +1604,10 @@ impl SMBState {
}
}
- fn add_smb2_tc_pdu_frame(&mut self, flow: *const Flow, stream_slice: &StreamSlice, input: &[u8], nbss_len: i64) {
- let _smb_pdu = Frame::new_tc(flow, stream_slice, input, nbss_len, SMBFrameType::SMB2Pdu as u8);
- SCLogDebug!("SMBv2 PDU frame {:?}", _smb_pdu);
+ fn add_smb2_tc_pdu_frame(&mut self, flow: *const Flow, stream_slice: &StreamSlice, input: &[u8], nbss_len: i64) -> Option {
+ let smb_pdu = Frame::new_tc(flow, stream_slice, input, nbss_len, SMBFrameType::SMB2Pdu as u8);
+ SCLogDebug!("SMBv2 PDU frame {:?}", smb_pdu);
+ smb_pdu
}
fn add_smb2_tc_hdr_data_frames(&mut self, flow: *const Flow, stream_slice: &StreamSlice, input: &[u8], nbss_len: i64, hdr_len: i64) {
let _smb2_hdr = Frame::new_tc(flow, stream_slice, input, hdr_len, SMBFrameType::SMB2Hdr as u8);
@@ -1764,9 +1784,16 @@ impl SMBState {
SCLogDebug!("SMBv1 record");
match parse_smb_record(nbss_hdr.data) {
Ok((_, ref smb_record)) => {
- self.add_smb1_tc_pdu_frame(flow, stream_slice, nbss_hdr.data, nbss_hdr.length as i64);
+ let pdu_frame = self.add_smb1_tc_pdu_frame(flow, stream_slice, nbss_hdr.data, nbss_hdr.length as i64);
self.add_smb1_tc_hdr_data_frames(flow, stream_slice, nbss_hdr.data, nbss_hdr.length as i64);
- smb1_response_record(self, smb_record);
+ if smb_record.is_response() {
+ smb1_response_record(self, smb_record);
+ } else {
+ SCLogDebug!("SMB1 request seen from server to client");
+ if let Some(frame) = pdu_frame {
+ frame.add_event(flow, 1, SMBEvent::RequestToClient as u8);
+ }
+ }
},
_ => {
self.set_event(SMBEvent::MalformedData);
@@ -1780,9 +1807,16 @@ impl SMBState {
match parse_smb2_response_record(nbss_data) {
Ok((nbss_data_rem, ref smb_record)) => {
let record_len = (nbss_data.len() - nbss_data_rem.len()) as i64;
- self.add_smb2_tc_pdu_frame(flow, stream_slice, nbss_data, record_len);
+ let pdu_frame = self.add_smb2_tc_pdu_frame(flow, stream_slice, nbss_data, record_len);
self.add_smb2_tc_hdr_data_frames(flow, stream_slice, nbss_data, record_len, smb_record.header_len as i64);
- smb2_response_record(self, smb_record);
+ if smb_record.is_response() {
+ smb2_response_record(self, smb_record);
+ } else {
+ SCLogDebug!("SMB2 request seen from server to client");
+ if let Some(frame) = pdu_frame {
+ frame.add_event(flow, 1, SMBEvent::RequestToClient as u8);
+ }
+ }
nbss_data = nbss_data_rem;
},
_ => {
diff --git a/rust/src/smb/smb2_records.rs b/rust/src/smb/smb2_records.rs
index 2d8950bcfc..d069ef0486 100644
--- a/rust/src/smb/smb2_records.rs
+++ b/rust/src/smb/smb2_records.rs
@@ -69,6 +69,14 @@ impl<'a> Smb2Record<'a> {
pub fn is_async(&self) -> bool {
self.async_id != 0
}
+
+ pub fn is_request(&self) -> bool {
+ self.direction == 0
+ }
+
+ pub fn is_response(&self) -> bool {
+ self.direction == 1
+ }
}
#[derive(Debug)]