]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
quic: events and rules on them
authorPhilippe Antoine <contact@catenacyber.fr>
Wed, 16 Mar 2022 13:45:41 +0000 (14:45 +0100)
committerPhilippe Antoine <pantoine@oisf.net>
Tue, 2 Aug 2022 12:54:43 +0000 (14:54 +0200)
rules/Makefile.am
rules/quic-events.rules [new file with mode: 0644]
rust/src/quic/quic.rs

index e4d5635c51ae00271458945cfe9fedb78f24db5b..0eaf5be8906c4dd2eddd039198af7abb1f979549 100644 (file)
@@ -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 (file)
index 0000000..41e9628
--- /dev/null
@@ -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;)
index 573579209f5978386e8f3eca3f97771fb195fe95..01b46ad6c4bec954d0e281c41ec03e37fde8e5b3 100644 (file)
@@ -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,