]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
output/ja4: Restrict ja4 hashes to alerts
authorJeff Lucovsky <jlucovsky@oisf.net>
Sat, 1 Jun 2024 12:52:27 +0000 (08:52 -0400)
committerJeff Lucovsky <jlucovsky@oisf.net>
Sat, 8 Jun 2024 13:36:46 +0000 (09:36 -0400)
This commit restricts ja4 hash output to alerts; ja4 hashes will not be
in tls or quic events.

Issue: 7010

rust/src/quic/logger.rs
src/detect-ja4-hash.c
src/detect.h
src/output-json-alert.c
src/output-json-quic.c
src/output-json-quic.h
src/output-json-tls.c
src/output-json-tls.h

index fc2e85c88a75e344aedb8c4a11561df8be568084..0acc9841e706490291b6420f47e24f1c82f3a0bb 100644 (file)
@@ -88,7 +88,7 @@ fn quic_tls_extension_name(e: u16) -> Option<String> {
     }
 }
 
-fn log_template(tx: &QuicTransaction, js: &mut JsonBuilder) -> Result<(), JsonError> {
+fn log_template(tx: &QuicTransaction, log_ja4: bool, js: &mut JsonBuilder) -> Result<(), JsonError> {
     js.open_object("quic")?;
     if tx.header.ty != QuicType::Short {
         js.set_string("version", String::from(tx.header.version).as_str())?;
@@ -123,8 +123,10 @@ fn log_template(tx: &QuicTransaction, js: &mut JsonBuilder) -> Result<(), JsonEr
         js.close()?;
     }
 
-    if let Some(ref ja4) = &tx.ja4 {
-        js.set_string("ja4", ja4)?;
+    if log_ja4 {
+        if let Some(ref ja4) = &tx.ja4 {
+            js.set_string("ja4", ja4)?;
+        }
     }
 
     if !tx.extv.is_empty() {
@@ -155,8 +157,8 @@ fn log_template(tx: &QuicTransaction, js: &mut JsonBuilder) -> Result<(), JsonEr
 
 #[no_mangle]
 pub unsafe extern "C" fn rs_quic_to_json(
-    tx: *mut std::os::raw::c_void, js: &mut JsonBuilder,
+    tx: *mut std::os::raw::c_void, log_ja4: bool, js: &mut JsonBuilder,
 ) -> bool {
     let tx = cast_pointer!(tx, QuicTransaction);
-    log_template(tx, js).is_ok()
+    log_template(tx, log_ja4, js).is_ok()
 }
index 2d3f908bf605ce986837912adea7bdc05dc41a49..e1d285264da030564fdc262255cbf5d16e1c9919 100644 (file)
@@ -130,6 +130,7 @@ static int DetectJa4HashSetup(DetectEngineCtx *de_ctx, Signature *s, const char
         }
     }
     s->init_data->init_flags |= SIG_FLAG_INIT_JA;
+    s->flags |= SIG_FLAG_JA4;
 
     return 0;
 }
index 4ea495b254ea1f2072199acdb9e46126cae1e2ad..3ec38d3006b52931b17eeba00c8d03ec24595473 100644 (file)
@@ -275,6 +275,8 @@ typedef struct DetectPort_ {
 /** Info for Source and Target identification */
 #define SIG_FLAG_DEST_IS_TARGET         BIT_U32(26)
 
+#define SIG_FLAG_JA4 BIT_U32(27) /**< signature uses JA4 */
+
 #define SIG_FLAG_HAS_TARGET             (SIG_FLAG_DEST_IS_TARGET|SIG_FLAG_SRC_IS_TARGET)
 
 /* signature init flags */
index 1ce4366e896419cd5b955f03761f4d2c2896d8ee..072e54b61638598e478460d884b83fd639934bcb 100644 (file)
@@ -137,13 +137,13 @@ static int AlertJsonDumpStreamSegmentCallback(
     return 1;
 }
 
-static void AlertJsonTls(const Flow *f, JsonBuilder *js)
+static void AlertJsonTls(const Flow *f, const uint32_t sig_flags, JsonBuilder *js)
 {
     SSLState *ssl_state = (SSLState *)FlowGetAppState(f);
     if (ssl_state) {
         jb_open_object(js, "tls");
 
-        JsonTlsLogJSONExtended(js, ssl_state);
+        JsonTlsLogJSONExtended(js, ssl_state, sig_flags & SIG_FLAG_JA4);
 
         jb_close(js);
     }
@@ -467,8 +467,8 @@ static void AlertAddPayload(AlertJsonOutputCtx *json_output_ctx, JsonBuilder *js
     }
 }
 
-static void AlertAddAppLayer(const Packet *p, JsonBuilder *jb,
-        const uint64_t tx_id, const uint16_t option_flags)
+static void AlertAddAppLayer(const Packet *p, JsonBuilder *jb, const uint64_t tx_id,
+        const uint32_t sig_flags, const uint16_t option_flags)
 {
     const AppProto proto = FlowGetAppProtocol(p->flow);
     JsonBuilderMark mark = { 0, 0, 0 };
@@ -487,7 +487,7 @@ static void AlertAddAppLayer(const Packet *p, JsonBuilder *jb,
             jb_close(jb);
             break;
         case ALPROTO_TLS:
-            AlertJsonTls(p->flow, jb);
+            AlertJsonTls(p->flow, sig_flags, jb);
             break;
         case ALPROTO_SSH:
             AlertJsonSsh(p->flow, jb);
@@ -573,7 +573,7 @@ static void AlertAddAppLayer(const Packet *p, JsonBuilder *jb,
             break;
         case ALPROTO_QUIC:
             jb_get_mark(jb, &mark);
-            if (!JsonQuicAddMetadata(p->flow, tx_id, jb)) {
+            if (!JsonQuicAddMetadata(p->flow, sig_flags, tx_id, jb)) {
                 jb_restore_mark(jb, &mark);
             }
             break;
@@ -784,7 +784,7 @@ static int AlertJson(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p)
         if (p->flow != NULL) {
             if (pa->flags & PACKET_ALERT_FLAG_TX) {
                 if (json_output_ctx->flags & LOG_JSON_APP_LAYER) {
-                    AlertAddAppLayer(p, jb, pa->tx_id, json_output_ctx->flags);
+                    AlertAddAppLayer(p, jb, pa->tx_id, pa->s->flags, json_output_ctx->flags);
                 }
                 /* including fileinfo data is configured by the metadata setting */
                 if (json_output_ctx->flags & LOG_JSON_RULE_METADATA) {
index fdf2d0f09340d208a0d4c7ba84ff711dd22db2b1..4970c31defa0fe58250638dbb374baa3806e45e4 100644 (file)
@@ -59,7 +59,7 @@ static int JsonQuicLogger(ThreadVars *tv, void *thread_data, const Packet *p, Fl
     if (unlikely(js == NULL)) {
         return TM_ECODE_OK;
     }
-    if (!rs_quic_to_json(tx, js)) {
+    if (!rs_quic_to_json(tx, false, js)) {
         jb_free(js);
         return TM_ECODE_FAILED;
     }
@@ -140,13 +140,13 @@ static TmEcode JsonQuicLogThreadDeinit(ThreadVars *t, void *data)
     return TM_ECODE_OK;
 }
 
-bool JsonQuicAddMetadata(const Flow *f, uint64_t tx_id, JsonBuilder *js)
+bool JsonQuicAddMetadata(const Flow *f, const uint32_t sig_flags, uint64_t tx_id, JsonBuilder *js)
 {
     void *state = FlowGetAppState(f);
     if (state) {
         void *tx = AppLayerParserGetTx(f->proto, ALPROTO_QUIC, state, tx_id);
         if (tx) {
-            return rs_quic_to_json(tx, js);
+            return rs_quic_to_json(tx, sig_flags & SIG_FLAG_JA4, js);
         }
     }
 
index 2448d5063a349c9fa3cea653b1425934762f6504..71b434e114025ce3587547653d6839d1bfb5e185 100644 (file)
@@ -22,7 +22,7 @@
 #ifndef __OUTPUT_JSON_QUIC_H__
 #define __OUTPUT_JSON_QUIC_H__
 
-bool JsonQuicAddMetadata(const Flow *f, uint64_t tx_id, JsonBuilder *js);
+bool JsonQuicAddMetadata(const Flow *f, const uint32_t sig_flags, uint64_t tx_id, JsonBuilder *js);
 void JsonQuicLogRegister(void);
 
 #endif /* __OUTPUT_JSON_QUIC_H__ */
index f1134633c394a05994f938f2fc118084684c2cb7..4f5d07d49c9dc12e7bd91d0656ca5178567a1a62 100644 (file)
@@ -408,7 +408,7 @@ static void JsonTlsLogJSONCustom(OutputTlsCtx *tls_ctx, JsonBuilder *js,
     }
 }
 
-void JsonTlsLogJSONExtended(JsonBuilder *tjs, SSLState * state)
+void JsonTlsLogJSONExtended(JsonBuilder *tjs, SSLState *state, const bool log_ja4)
 {
     JsonTlsLogJSONBasic(tjs, state);
 
@@ -437,7 +437,8 @@ void JsonTlsLogJSONExtended(JsonBuilder *tjs, SSLState * state)
     JsonTlsLogJa3S(tjs, state);
 
     /* tls ja4 */
-    JsonTlsLogSCJA4(tjs, state);
+    if (log_ja4)
+        JsonTlsLogSCJA4(tjs, state);
 
     if (HasClientCert(&state->client_connp)) {
         jb_open_object(tjs, "client");
@@ -478,7 +479,7 @@ static int JsonTlsLogger(ThreadVars *tv, void *thread_data, const Packet *p,
     }
     /* log extended */
     else if (tls_ctx->flags & LOG_TLS_EXTENDED) {
-        JsonTlsLogJSONExtended(js, ssl_state);
+        JsonTlsLogJSONExtended(js, ssl_state, false);
     }
     /* log basic */
     else {
index 737e6233ef10aa13796391801c6e34878cc9c138..76a1190c21470a9737b212dc83655ca8706a0ab6 100644 (file)
@@ -29,6 +29,6 @@ void JsonTlsLogRegister(void);
 #include "app-layer-ssl.h"
 
 void JsonTlsLogJSONBasic(JsonBuilder *js, SSLState *ssl_state);
-void JsonTlsLogJSONExtended(JsonBuilder *js, SSLState *ssl_state);
+void JsonTlsLogJSONExtended(JsonBuilder *js, SSLState *ssl_state, bool is_alert);
 
 #endif /* __OUTPUT_JSON_TLS_H__ */