From 489bd75ea10bb351dd13418549dafbf784266ffd Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Thu, 23 Jul 2026 16:38:35 +0530 Subject: [PATCH] dcerpc: store unhandled packet types This allows to at least log unhandled packet types even if the parser does not do anything extra with them. All this information was already in the header but since transactions were only created for the supported PDU types, there was no way to log or have a possibility to match on these. Store the packet type information for all unhandled types in a new transaction. Note that one transaction is created for each unhandled type and there is no request-response pair matching done. Feature 8762 --- rust/src/dcerpc/dcerpc.rs | 44 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/rust/src/dcerpc/dcerpc.rs b/rust/src/dcerpc/dcerpc.rs index 2cd6cbb85c..7a6f206b49 100644 --- a/rust/src/dcerpc/dcerpc.rs +++ b/rust/src/dcerpc/dcerpc.rs @@ -801,6 +801,24 @@ impl DCERPCState { } } + fn save_unhandled_ptypes(&mut self, hdr: &DCERPCHdr, direction: Direction) { + /* Create tx even on unhandled PDU types to be able to + * at least issue a match on header only fields */ + let mut tx = self.create_tx(hdr); + if direction == Direction::ToServer { + tx.req_cmd = hdr.hdrtype; + tx.req_seen = true; + } else { + tx.resp_cmd = hdr.hdrtype; + tx.resp_seen = true; + } + tx.req_done = true; + tx.resp_done = true; + self.transactions.push_back(tx); + // recognized DCERPC PDU types that we do not process + SCLogDebug!("Unhandled packet type: {:?}", hdr.hdrtype); + } + pub fn handle_input_data( &mut self, stream_slice: StreamSlice, direction: Direction, ) -> AppLayerResult { @@ -893,6 +911,15 @@ impl DCERPCState { // input only consists of the header and that was consumed, so, return early cur_i = &cur_i[fraglen as usize..]; consumed += fraglen as u32; + // save header-only PDU types too + if matches!( + hdr.hdrtype, + DCERPC_TYPE_SHUTDOWN | DCERPC_TYPE_CO_CANCEL | DCERPC_TYPE_ORPHANED + ) { + self.save_unhandled_ptypes(&hdr, direction); + /* DCERPC_TYPE_CO_CANCEL and ORPHANED can optionally be more than header + * too so they're also handled later on the in the unrecognized branch */ + } continue; } cmp::Ordering::Greater => {} @@ -1006,9 +1033,24 @@ impl DCERPCState { return AppLayerResult::err(); } } + DCERPC_TYPE_PING + | DCERPC_TYPE_FAULT + | DCERPC_TYPE_WORKING + | DCERPC_TYPE_NOCALL + | DCERPC_TYPE_REJECT + | DCERPC_TYPE_ACK + | DCERPC_TYPE_CL_CANCEL + | DCERPC_TYPE_FACK + | DCERPC_TYPE_CANCEL_ACK + | DCERPC_TYPE_BINDNAK + | DCERPC_TYPE_AUTH3 + | DCERPC_TYPE_CO_CANCEL + | DCERPC_TYPE_ORPHANED + | DCERPC_TYPE_RTS => { + self.save_unhandled_ptypes(&hdr, direction); + } _ => { SCLogDebug!("Unrecognized packet type: {:?}", hdrtype); - // skip unrecognized packet types such as AUTH3 } } consumed += fraglen as u32;