From dfcb4295240f5b5fe33cc985857be2dba77c884f Mon Sep 17 00:00:00 2001 From: Jeff Lucovsky Date: Mon, 19 Dec 2022 08:51:31 -0500 Subject: [PATCH] detect/cert: Use client side certs Issue: 5516 This commit modifies the detect logic to choose the certificate based on the flow direction -- to server or to client. --- src/detect-tls-cert-fingerprint.c | 21 +++++++++++++++++---- src/detect-tls-cert-issuer.c | 20 ++++++++++++++++---- src/detect-tls-cert-serial.c | 21 +++++++++++++++++---- src/detect-tls-cert-subject.c | 26 +++++++++++++++++++------- src/detect-tls-certs.c | 17 +++++++++++++++-- src/detect-tls.c | 13 ++++++++++++- 6 files changed, 96 insertions(+), 22 deletions(-) diff --git a/src/detect-tls-cert-fingerprint.c b/src/detect-tls-cert-fingerprint.c index 49ffc930a2..83e802b065 100644 --- a/src/detect-tls-cert-fingerprint.c +++ b/src/detect-tls-cert-fingerprint.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Open Information Security Foundation +/* Copyright (C) 2017-2022 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -91,6 +91,12 @@ void DetectTlsFingerprintRegister(void) PrefilterGenericMpmRegister, GetData, ALPROTO_TLS, TLS_STATE_CERT_READY); + DetectAppLayerInspectEngineRegister2("tls.cert_fingerprint", ALPROTO_TLS, SIG_FLAG_TOSERVER, + TLS_STATE_CERT_READY, DetectEngineInspectBufferGeneric, GetData); + + DetectAppLayerMpmRegister2("tls.cert_fingerprint", SIG_FLAG_TOSERVER, 2, + PrefilterGenericMpmRegister, GetData, ALPROTO_TLS, TLS_STATE_CERT_READY); + DetectBufferTypeSetDescriptionByName("tls.cert_fingerprint", "TLS certificate fingerprint"); @@ -132,13 +138,20 @@ static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); if (buffer->inspect == NULL) { const SSLState *ssl_state = (SSLState *)f->alstate; + const SSLStateConnp *connp; + + if (flow_flags & STREAM_TOSERVER) { + connp = &ssl_state->client_connp; + } else { + connp = &ssl_state->server_connp; + } - if (ssl_state->server_connp.cert0_fingerprint == NULL) { + if (connp->cert0_fingerprint == NULL) { return NULL; } - const uint32_t data_len = strlen(ssl_state->server_connp.cert0_fingerprint); - const uint8_t *data = (uint8_t *)ssl_state->server_connp.cert0_fingerprint; + const uint32_t data_len = strlen(connp->cert0_fingerprint); + const uint8_t *data = (uint8_t *)connp->cert0_fingerprint; InspectionBufferSetup(det_ctx, list_id, buffer, data, data_len); InspectionBufferApplyTransforms(buffer, transforms); diff --git a/src/detect-tls-cert-issuer.c b/src/detect-tls-cert-issuer.c index c39ed95c9d..73044f7411 100644 --- a/src/detect-tls-cert-issuer.c +++ b/src/detect-tls-cert-issuer.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2016 Open Information Security Foundation +/* Copyright (C) 2007-2022 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -79,6 +79,12 @@ void DetectTlsIssuerRegister(void) sigmatch_table[DETECT_AL_TLS_CERT_ISSUER].flags |= SIGMATCH_NOOPT; sigmatch_table[DETECT_AL_TLS_CERT_ISSUER].flags |= SIGMATCH_INFO_STICKY_BUFFER; + DetectAppLayerInspectEngineRegister2("tls.cert_issuer", ALPROTO_TLS, SIG_FLAG_TOSERVER, + TLS_STATE_CERT_READY, DetectEngineInspectBufferGeneric, GetData); + + DetectAppLayerMpmRegister2("tls.cert_issuer", SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister, + GetData, ALPROTO_TLS, TLS_STATE_CERT_READY); + DetectAppLayerInspectEngineRegister2("tls.cert_issuer", ALPROTO_TLS, SIG_FLAG_TOCLIENT, TLS_STATE_CERT_READY, DetectEngineInspectBufferGeneric, GetData); @@ -122,13 +128,19 @@ static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); if (buffer->inspect == NULL) { const SSLState *ssl_state = (SSLState *)f->alstate; + const SSLStateConnp *connp; + if (flow_flags & STREAM_TOSERVER) { + connp = &ssl_state->client_connp; + } else { + connp = &ssl_state->server_connp; + } - if (ssl_state->server_connp.cert0_issuerdn == NULL) { + if (connp->cert0_issuerdn == NULL) { return NULL; } - const uint32_t data_len = strlen(ssl_state->server_connp.cert0_issuerdn); - const uint8_t *data = (uint8_t *)ssl_state->server_connp.cert0_issuerdn; + const uint32_t data_len = strlen(connp->cert0_issuerdn); + const uint8_t *data = (uint8_t *)connp->cert0_issuerdn; InspectionBufferSetup(det_ctx, list_id, buffer, data, data_len); InspectionBufferApplyTransforms(buffer, transforms); diff --git a/src/detect-tls-cert-serial.c b/src/detect-tls-cert-serial.c index 816f7e4db9..51c61dbf0e 100644 --- a/src/detect-tls-cert-serial.c +++ b/src/detect-tls-cert-serial.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Open Information Security Foundation +/* Copyright (C) 2017-2022 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -91,6 +91,12 @@ void DetectTlsSerialRegister(void) PrefilterGenericMpmRegister, GetData, ALPROTO_TLS, TLS_STATE_CERT_READY); + DetectAppLayerInspectEngineRegister2("tls.cert_serial", ALPROTO_TLS, SIG_FLAG_TOSERVER, + TLS_STATE_CERT_READY, DetectEngineInspectBufferGeneric, GetData); + + DetectAppLayerMpmRegister2("tls.cert_serial", SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister, + GetData, ALPROTO_TLS, TLS_STATE_CERT_READY); + DetectBufferTypeSetDescriptionByName("tls.cert_serial", "TLS certificate serial number"); @@ -131,13 +137,20 @@ static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); if (buffer->inspect == NULL) { const SSLState *ssl_state = (SSLState *)f->alstate; + const SSLStateConnp *connp; + + if (flow_flags & STREAM_TOSERVER) { + connp = &ssl_state->client_connp; + } else { + connp = &ssl_state->server_connp; + } - if (ssl_state->server_connp.cert0_serial == NULL) { + if (connp->cert0_serial == NULL) { return NULL; } - const uint32_t data_len = strlen(ssl_state->server_connp.cert0_serial); - const uint8_t *data = (uint8_t *)ssl_state->server_connp.cert0_serial; + const uint32_t data_len = strlen(connp->cert0_serial); + const uint8_t *data = (uint8_t *)connp->cert0_serial; InspectionBufferSetup(det_ctx, list_id, buffer, data, data_len); InspectionBufferApplyTransforms(buffer, transforms); diff --git a/src/detect-tls-cert-subject.c b/src/detect-tls-cert-subject.c index 0cb4ee981b..ee6a13d345 100644 --- a/src/detect-tls-cert-subject.c +++ b/src/detect-tls-cert-subject.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2016 Open Information Security Foundation +/* Copyright (C) 2007-2022 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -79,9 +79,14 @@ void DetectTlsSubjectRegister(void) sigmatch_table[DETECT_AL_TLS_CERT_SUBJECT].flags |= SIGMATCH_NOOPT; sigmatch_table[DETECT_AL_TLS_CERT_SUBJECT].flags |= SIGMATCH_INFO_STICKY_BUFFER; - DetectAppLayerInspectEngineRegister2("tls.cert_subject", ALPROTO_TLS, - SIG_FLAG_TOCLIENT, TLS_STATE_CERT_READY, - DetectEngineInspectBufferGeneric, GetData); + DetectAppLayerInspectEngineRegister2("tls.cert_subject", ALPROTO_TLS, SIG_FLAG_TOSERVER, + TLS_STATE_CERT_READY, DetectEngineInspectBufferGeneric, GetData); + + DetectAppLayerMpmRegister2("tls.cert_subject", SIG_FLAG_TOSERVER, 2, + PrefilterGenericMpmRegister, GetData, ALPROTO_TLS, TLS_STATE_CERT_READY); + + DetectAppLayerInspectEngineRegister2("tls.cert_subject", ALPROTO_TLS, SIG_FLAG_TOCLIENT, + TLS_STATE_CERT_READY, DetectEngineInspectBufferGeneric, GetData); DetectAppLayerMpmRegister2("tls.cert_subject", SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister, GetData, ALPROTO_TLS, @@ -121,13 +126,20 @@ static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); if (buffer->inspect == NULL) { const SSLState *ssl_state = (SSLState *)f->alstate; + const SSLStateConnp *connp; + + if (flow_flags & STREAM_TOSERVER) { + connp = &ssl_state->client_connp; + } else { + connp = &ssl_state->server_connp; + } - if (ssl_state->server_connp.cert0_subject == NULL) { + if (connp->cert0_subject == NULL) { return NULL; } - const uint32_t data_len = strlen(ssl_state->server_connp.cert0_subject); - const uint8_t *data = (uint8_t *)ssl_state->server_connp.cert0_subject; + const uint32_t data_len = strlen(connp->cert0_subject); + const uint8_t *data = (uint8_t *)connp->cert0_subject; InspectionBufferSetup(det_ctx, list_id, buffer, data, data_len); InspectionBufferApplyTransforms(buffer, transforms); diff --git a/src/detect-tls-certs.c b/src/detect-tls-certs.c index 7c028f1037..c4088222c8 100644 --- a/src/detect-tls-certs.c +++ b/src/detect-tls-certs.c @@ -102,6 +102,12 @@ void DetectTlsCertsRegister(void) PrefilterMpmTlsCertsRegister, NULL, ALPROTO_TLS, TLS_STATE_CERT_READY); + DetectAppLayerInspectEngineRegister2("tls.certs", ALPROTO_TLS, SIG_FLAG_TOSERVER, + TLS_STATE_CERT_READY, DetectEngineInspectTlsCerts, NULL); + + DetectAppLayerMpmRegister2("tls.certs", SIG_FLAG_TOSERVER, 2, PrefilterMpmTlsCertsRegister, + NULL, ALPROTO_TLS, TLS_STATE_CERT_READY); + DetectBufferTypeSetDescriptionByName("tls.certs", "TLS certificate"); g_tls_certs_buffer_id = DetectBufferTypeGetByName("tls.certs"); @@ -141,13 +147,20 @@ static InspectionBuffer *TlsCertsGetData(DetectEngineThreadCtx *det_ctx, return NULL; const SSLState *ssl_state = (SSLState *)f->alstate; + const SSLStateConnp *connp; + + if (f->flags & STREAM_TOSERVER) { + connp = &ssl_state->client_connp; + } else { + connp = &ssl_state->server_connp; + } - if (TAILQ_EMPTY(&ssl_state->server_connp.certs)) { + if (TAILQ_EMPTY(&connp->certs)) { return NULL; } if (cbdata->cert == NULL) { - cbdata->cert = TAILQ_FIRST(&ssl_state->server_connp.certs); + cbdata->cert = TAILQ_FIRST(&connp->certs); } else { cbdata->cert = TAILQ_NEXT(cbdata->cert, next); } diff --git a/src/detect-tls.c b/src/detect-tls.c index c9a1c259c7..2d338d41fb 100644 --- a/src/detect-tls.c +++ b/src/detect-tls.c @@ -143,6 +143,9 @@ void DetectTlsRegister (void) DetectAppLayerInspectEngineRegister2("tls_cert", ALPROTO_TLS, SIG_FLAG_TOCLIENT, TLS_STATE_CERT_READY, DetectEngineInspectGenericList, NULL); + + DetectAppLayerInspectEngineRegister2("tls_cert", ALPROTO_TLS, SIG_FLAG_TOSERVER, + TLS_STATE_CERT_READY, DetectEngineInspectGenericList, NULL); } /** @@ -619,6 +622,14 @@ static int DetectTlsStorePostMatch (DetectEngineThreadCtx *det_ctx, SCReturnInt(0); } - ssl_state->server_connp.cert_log_flag |= SSL_TLS_LOG_PEM; + SSLStateConnp *connp; + + if (p->flow->flags & STREAM_TOSERVER) { + connp = &ssl_state->client_connp; + } else { + connp = &ssl_state->server_connp; + } + + connp->cert_log_flag |= SSL_TLS_LOG_PEM; SCReturnInt(1); }