From 0ac5c5376a2a6e32ac0c12ff8bc483abf04c9cb8 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Tue, 23 Feb 2021 15:25:52 +0530 Subject: [PATCH] dcerpc: trigger raw assembly on record completion --- rust/src/dcerpc/dcerpc.rs | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/rust/src/dcerpc/dcerpc.rs b/rust/src/dcerpc/dcerpc.rs index 203d9377b8..356022ff97 100644 --- a/rust/src/dcerpc/dcerpc.rs +++ b/rust/src/dcerpc/dcerpc.rs @@ -17,7 +17,7 @@ use std::mem::transmute; use crate::applayer::*; -use crate::core::{self, sc_detect_engine_state_free}; +use crate::core::{self, *}; use crate::dcerpc::parser; use nom::error::ErrorKind; use nom::number::Endianness; @@ -350,6 +350,7 @@ pub struct DCERPCState { pub tc_ssn_gap: bool, pub ts_ssn_trunc: bool, /// true if Truncated in this direction pub tc_ssn_trunc: bool, + pub flow: Option<*const core::Flow>, } impl DCERPCState { @@ -376,6 +377,7 @@ impl DCERPCState { tc_ssn_gap: false, ts_ssn_trunc: false, tc_ssn_trunc: false, + flow: None, }; } @@ -618,6 +620,9 @@ impl DCERPCState { tx.req_lost = true; } tx.req_done = true; + if let Some(flow) = self.flow { + sc_app_layer_parser_trigger_raw_stream_reassembly(flow, dir.into()); + } } } else if self.tc_ssn_gap && dir == core::STREAM_TOCLIENT { for tx in &mut self.transactions { @@ -633,6 +638,9 @@ impl DCERPCState { } tx.req_done = true; tx.resp_done = true; + if let Some(flow) = self.flow { + sc_app_layer_parser_trigger_raw_stream_reassembly(flow, dir.into()); + } } } } @@ -745,6 +753,9 @@ impl DCERPCState { let mut tx = self.create_tx(call_id); tx.req_cmd = self.get_hdr_type().unwrap_or(0); tx.req_done = true; + if let Some(flow) = self.flow { + sc_app_layer_parser_trigger_raw_stream_reassembly(flow, core::STREAM_TOSERVER.into()); + } tx.frag_cnt_ts = 1; self.transactions.push(tx); // Bytes parsed with `parse_dcerpc_bind` + (bytes parsed per bindctxitem [44] * number @@ -827,6 +838,9 @@ impl DCERPCState { ); tx.req_done = true; tx.frag_cnt_ts = 1; + if let Some(flow) = self.flow { + sc_app_layer_parser_trigger_raw_stream_reassembly(flow, core::STREAM_TOSERVER.into()); + } } DCERPC_TYPE_RESPONSE => { retval = evaluate_stub_params( @@ -839,6 +853,9 @@ impl DCERPCState { ); tx.resp_done = true; tx.frag_cnt_tc = 1; + if let Some(flow) = self.flow { + sc_app_layer_parser_trigger_raw_stream_reassembly(flow, core::STREAM_TOCLIENT.into()); + } } _ => { SCLogDebug!("Unrecognized packet type"); @@ -1069,6 +1086,9 @@ impl DCERPCState { }; tx.resp_done = true; tx.frag_cnt_tc = 1; + if let Some(flow) = self.flow { + sc_app_layer_parser_trigger_raw_stream_reassembly(flow, core::STREAM_TOCLIENT.into()); + } self.handle_bind_cache(current_call_id, false); } DCERPC_TYPE_REQUEST => { @@ -1163,7 +1183,7 @@ pub extern "C" fn rs_parse_dcerpc_response_gap( #[no_mangle] pub extern "C" fn rs_dcerpc_parse_request( - _flow: *mut core::Flow, state: &mut DCERPCState, _pstate: *mut std::os::raw::c_void, + flow: *mut core::Flow, state: &mut DCERPCState, _pstate: *mut std::os::raw::c_void, input: *const u8, input_len: u32, _data: *mut std::os::raw::c_void, flags: u8, ) -> AppLayerResult { SCLogDebug!("Handling request: input {:p} input_len {} flags {:x} EOF {}", @@ -1177,6 +1197,7 @@ pub extern "C" fn rs_dcerpc_parse_request( } if input_len > 0 && input != std::ptr::null_mut() { let buf = build_slice!(input, input_len as usize); + state.flow = Some(flow); return state.handle_input_data(buf, core::STREAM_TOSERVER); } AppLayerResult::err() @@ -1184,7 +1205,7 @@ pub extern "C" fn rs_dcerpc_parse_request( #[no_mangle] pub extern "C" fn rs_dcerpc_parse_response( - _flow: *mut core::Flow, state: &mut DCERPCState, _pstate: *mut std::os::raw::c_void, + flow: *mut core::Flow, state: &mut DCERPCState, _pstate: *mut std::os::raw::c_void, input: *const u8, input_len: u32, _data: *mut std::os::raw::c_void, flags: u8, ) -> AppLayerResult { if flags & core::STREAM_EOF != 0 && input_len == 0 { @@ -1197,6 +1218,7 @@ pub extern "C" fn rs_dcerpc_parse_response( if input_len > 0 { if input != std::ptr::null_mut() { let buf = build_slice!(input, input_len as usize); + state.flow = Some(flow); return state.handle_input_data(buf, core::STREAM_TOCLIENT); } } @@ -1229,12 +1251,18 @@ pub extern "C" fn rs_dcerpc_state_trunc(state: *mut std::os::raw::c_void, direct dce_state.ts_ssn_trunc = true; for tx in &mut dce_state.transactions { tx.req_done = true; + if let Some(flow) = dce_state.flow { + sc_app_layer_parser_trigger_raw_stream_reassembly(flow, core::STREAM_TOSERVER.into()); + } } SCLogDebug!("dce_state.ts_ssn_trunc = true; txs {}", dce_state.transactions.len()); } else if direction & core::STREAM_TOCLIENT != 0 { dce_state.tc_ssn_trunc = true; for tx in &mut dce_state.transactions { tx.resp_done = true; + if let Some(flow) = dce_state.flow { + sc_app_layer_parser_trigger_raw_stream_reassembly(flow, core::STREAM_TOCLIENT.into()); + } } SCLogDebug!("dce_state.tc_ssn_trunc = true; txs {}", dce_state.transactions.len()); } -- 2.47.2