From: Victor Julien Date: Wed, 7 Mar 2018 14:29:49 +0000 (+0100) Subject: smb: generic event per trans/read/write for tx events X-Git-Tag: suricata-4.1.0-beta1~88 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=78cd92a933cc280951a846eed6e4db5b7ddf034e;p=thirdparty%2Fsuricata.git smb: generic event per trans/read/write for tx events --- diff --git a/rust/src/smb/smb1.rs b/rust/src/smb/smb1.rs index 33c41a9f68..5554cb87d0 100644 --- a/rust/src/smb/smb1.rs +++ b/rust/src/smb/smb1.rs @@ -561,6 +561,8 @@ pub fn get_service_for_nameslice(nameslice: &[u8]) -> (&'static str, bool) pub fn smb1_trans_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) { + let mut events : Vec = Vec::new(); + match parse_smb_trans_request_record(r.data, r) { IResult::Done(_, rd) => { SCLogDebug!("TRANS request {:?}", rd); @@ -597,64 +599,73 @@ pub fn smb1_trans_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) } }, _ => { - state.set_event(SMBEvent::MalformedData); + events.push(SMBEvent::MalformedData); }, } + smb1_request_record_generic(state, r, events); } pub fn smb1_trans_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) { - match parse_smb_trans_response_record(r.data) { - IResult::Done(_, rd) => { - SCLogDebug!("TRANS response {:?}", rd); + let mut events : Vec = Vec::new(); - // see if we have a stored fid - let fid = match state.ssn2vec_map.remove( - &SMBCommonHdr::from1(r, SMBHDR_TYPE_GUID)) { - Some(f) => f, - None => Vec::new(), - }; - SCLogDebug!("FID {:?}", fid); + if r.nt_status == SMB_NTSTATUS_SUCCESS || r.nt_status == SMB_NTSTATUS_BUFFER_OVERFLOW { + match parse_smb_trans_response_record(r.data) { + IResult::Done(_, rd) => { + SCLogDebug!("TRANS response {:?}", rd); - // if we get status 'BUFFER_OVERFLOW' this is only a part of - // the data. Store it in the ssn/tree for later use. - if r.nt_status == SMB_NTSTATUS_BUFFER_OVERFLOW { - state.ssnguid2vec_map.insert(SMBHashKeyHdrGuid::new( - SMBCommonHdr::from1(r, SMBHDR_TYPE_TRANS_FRAG), fid), - rd.data.to_vec()); - } else { - let txn_hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_TXNAME); - let is_dcerpc = match state.ssn2vec_map.remove(&txn_hdr) { - None => false, - Some(s) => { - let (sername, is_dcerpc) = get_service_for_nameslice(&s); - SCLogDebug!("service: {} dcerpc {}", sername, is_dcerpc); - is_dcerpc - }, + // see if we have a stored fid + let fid = match state.ssn2vec_map.remove( + &SMBCommonHdr::from1(r, SMBHDR_TYPE_GUID)) { + Some(f) => f, + None => Vec::new(), }; - if is_dcerpc { - SCLogDebug!("SMBv1 TRANS TO PIPE"); - let hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_HEADER); - let vercmd = SMBVerCmdStat::new1_with_ntstatus(r.command, r.nt_status); - smb_read_dcerpc_record(state, vercmd, hdr, &fid, &rd.data); + SCLogDebug!("FID {:?}", fid); + + // if we get status 'BUFFER_OVERFLOW' this is only a part of + // the data. Store it in the ssn/tree for later use. + if r.nt_status == SMB_NTSTATUS_BUFFER_OVERFLOW { + state.ssnguid2vec_map.insert(SMBHashKeyHdrGuid::new( + SMBCommonHdr::from1(r, SMBHDR_TYPE_TRANS_FRAG), fid), + rd.data.to_vec()); + } else { + let txn_hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_TXNAME); + let is_dcerpc = match state.ssn2vec_map.remove(&txn_hdr) { + None => false, + Some(s) => { + let (sername, is_dcerpc) = get_service_for_nameslice(&s); + SCLogDebug!("service: {} dcerpc {}", sername, is_dcerpc); + is_dcerpc + }, + }; + if is_dcerpc { + SCLogDebug!("SMBv1 TRANS TO PIPE"); + let hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_HEADER); + let vercmd = SMBVerCmdStat::new1_with_ntstatus(r.command, r.nt_status); + smb_read_dcerpc_record(state, vercmd, hdr, &fid, &rd.data); + } } - } - }, - _ => { - state.set_event(SMBEvent::MalformedData); - }, + }, + _ => { + events.push(SMBEvent::MalformedData); + }, + } } + // generic tx as well. Set events if needed. + smb1_response_record_generic(state, r, events); } -fn smb1_write_request_record_generic_error<'b>(state: &mut SMBState, r: &SmbRecord<'b>, event: SMBEvent) { +fn smb1_request_record_generic<'b>(state: &mut SMBState, r: &SmbRecord<'b>, events: Vec) { let tx_key = SMBCommonHdr::from1(r, SMBHDR_TYPE_GENERICTX); let tx = state.new_generic_tx(1, r.command as u16, tx_key); - tx.set_event(event); + tx.set_events(events); } /// Handle WRITE, WRITE_ANDX, WRITE_AND_CLOSE request records pub fn smb1_write_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) { + let mut events : Vec = Vec::new(); + let result = if r.command == SMB1_COMMAND_WRITE_ANDX { parse_smb1_write_andx_request_record(r.data) } else if r.command == SMB1_COMMAND_WRITE { @@ -722,12 +733,13 @@ pub fn smb1_write_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) } }, _ => { - smb1_write_request_record_generic_error(state, r, SMBEvent::MalformedData); + events.push(SMBEvent::MalformedData); }, } + smb1_request_record_generic(state, r, events); } -fn smb1_read_response_record_generic<'b>(state: &mut SMBState, r: &SmbRecord<'b>, events: Vec) { +fn smb1_response_record_generic<'b>(state: &mut SMBState, r: &SmbRecord<'b>, events: Vec) { // see if we want a tx per READ command if smb1_create_new_tx(r.command) { let tx_key = SMBCommonHdr::from1(r, SMBHDR_TYPE_GENERICTX); @@ -820,5 +832,5 @@ pub fn smb1_read_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) } // generic tx as well. Set events if needed. - smb1_read_response_record_generic(state, r, events); + smb1_response_record_generic(state, r, events); }