From: Philippe Antoine Date: Wed, 16 Mar 2022 13:45:41 +0000 (+0100) Subject: quic: events and rules on them X-Git-Tag: suricata-7.0.0-beta1~330 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f242fb7f22a879db0af62a173fdf2d92ab6357a3;p=thirdparty%2Fsuricata.git quic: events and rules on them --- diff --git a/rules/Makefile.am b/rules/Makefile.am index e4d5635c51..0eaf5be890 100644 --- a/rules/Makefile.am +++ b/rules/Makefile.am @@ -15,6 +15,7 @@ modbus-events.rules \ mqtt-events.rules \ nfs-events.rules \ ntp-events.rules \ +quic-events.rules \ smb-events.rules \ smtp-events.rules \ ssh-events.rules \ diff --git a/rules/quic-events.rules b/rules/quic-events.rules new file mode 100644 index 0000000000..41e9628265 --- /dev/null +++ b/rules/quic-events.rules @@ -0,0 +1,8 @@ +# QUIC app-layer event rules. +# +# These SIDs fall in the 2231000+ range. See: +# http://doc.emergingthreats.net/bin/view/Main/SidAllocation and +# https://redmine.openinfosecfoundation.org/projects/suricata/wiki/AppLayer + +alert quic any any -> any any (msg:"SURICATA QUIC failed decrypt"; app-layer-event:quic.failed_decrypt; classtype:protocol-command-decode; sid:2231000; rev:1;) +alert quic any any -> any any (msg:"SURICATA QUIC error on data"; app-layer-event:quic.error_on_data; classtype:protocol-command-decode; sid:2231001; rev:1;) diff --git a/rust/src/quic/quic.rs b/rust/src/quic/quic.rs index 573579209f..01b46ad6c4 100644 --- a/rust/src/quic/quic.rs +++ b/rust/src/quic/quic.rs @@ -31,6 +31,13 @@ static mut ALPROTO_QUIC: AppProto = ALPROTO_UNKNOWN; const DEFAULT_DCID_LEN: usize = 16; const PKT_NUM_BUF_MAX_LEN: usize = 4; +#[derive(FromPrimitive, Debug, AppLayerEvent)] +pub enum QuicEvent { + FailedDecrypt, + ErrorOnData, + ErrorOnHeader, +} + #[derive(Debug)] pub struct QuicTransaction { tx_id: u64, @@ -62,6 +69,20 @@ impl QuicTransaction { tx_data: AppLayerTxData::new(), } } + + fn new_empty(client: bool, header: QuicHeader) -> Self { + QuicTransaction { + tx_id: 0, + header: header, + cyu: Vec::new(), + sni: None, + ua: None, + extv: Vec::new(), + ja3: None, + client: client, + tx_data: AppLayerTxData::new(), + } + } } pub struct QuicState { @@ -223,6 +244,14 @@ impl QuicState { self.new_tx(header, data, sni, ua, extv, ja3, to_server); } + fn set_event_notx(&mut self, event: QuicEvent, header: QuicHeader, client: bool) { + let mut tx = QuicTransaction::new_empty(client, header); + self.max_tx_id += 1; + tx.tx_id = self.max_tx_id; + tx.tx_data.set_event(event as u8); + self.transactions.push(tx); + } + fn parse(&mut self, input: &[u8], to_server: bool) -> bool { // so as to loop over multiple quic headers in one packet let mut buf = input; @@ -253,6 +282,7 @@ impl QuicState { { output.resize(dlen, 0); } else { + self.set_event_notx(QuicEvent::FailedDecrypt, header, to_server); return false; } framebuf = &output; @@ -278,11 +308,13 @@ impl QuicState { self.handle_frames(data, header, to_server); } Err(_e) => { + self.set_event_notx(QuicEvent::ErrorOnData, header, to_server); return false; } } } Err(_e) => { + // should we make an event with an empty header ? return false; } } @@ -434,8 +466,8 @@ pub unsafe extern "C" fn rs_quic_register_parser() { tx_comp_st_ts: 1, tx_comp_st_tc: 1, tx_get_progress: rs_quic_tx_get_alstate_progress, - get_eventinfo: None, - get_eventinfo_byid: None, + get_eventinfo: Some(QuicEvent::get_event_info), + get_eventinfo_byid: Some(QuicEvent::get_event_info_by_id), localstorage_new: None, localstorage_free: None, get_files: None,