From: Philippe Antoine Date: Fri, 24 Jan 2025 12:54:39 +0000 (+0100) Subject: detect/smtp: smtp.rcpt_to keyword X-Git-Tag: suricata-8.0.0-beta1~514 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c5f3d33e51418b3c4bc3805ed51bb7d92660ef87;p=thirdparty%2Fsuricata.git detect/smtp: smtp.rcpt_to keyword Ticket: 7516 It is a sticky buffer mapping to the smtp.rcpt_to[] log field It is a multi-buffer --- diff --git a/doc/userguide/rules/smtp-keywords.rst b/doc/userguide/rules/smtp-keywords.rst index bbc12a515c..ecedd436ef 100644 --- a/doc/userguide/rules/smtp-keywords.rst +++ b/doc/userguide/rules/smtp-keywords.rst @@ -59,6 +59,27 @@ Signature example:: This keyword maps to the eve.json log field ``smtp.mail_from`` +smtp.rcpt_to +------------ + +SMTP rcpt to is the one of the parameters passed to one RCPT TO command from the client. + +Syntax:: + + smtp.rcpt_to; content:"sensitive@target"; + +Signature example:: + + alert smtp any any -> any any (msg:"SMTP rcpt to sensitive"; smtp.rcpt_to; content:"sensitive@target"; sid:2; rev:1;) + +``smtp.rcpt_to`` is a 'sticky buffer'. + +``smtp.rcpt_to`` is a 'multi buffer'. + +``smtp.rcpt_to`` can be used as ``fast_pattern``. + +This keyword maps to the eve.json log field ``smtp.rcpt_to[]`` + Frames ------ diff --git a/src/detect-smtp.c b/src/detect-smtp.c index 7ebdc21ac6..0c3e46150d 100644 --- a/src/detect-smtp.c +++ b/src/detect-smtp.c @@ -25,6 +25,7 @@ #include "suricata-common.h" #include "detect-smtp.h" #include "detect-engine.h" +#include "detect-engine-content-inspection.h" #include "detect-engine-helper.h" #include "detect-parse.h" #include "app-layer-smtp.h" @@ -32,6 +33,7 @@ static int g_smtp_helo_buffer_id = 0; static int g_smtp_mail_from_buffer_id = 0; +static int g_smtp_rcpt_to_buffer_id = 0; static int DetectSmtpHeloSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg) { @@ -87,6 +89,51 @@ static InspectionBuffer *GetSmtpMailFromData(DetectEngineThreadCtx *det_ctx, return buffer; } +static int DetectSmtpRcptToSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg) +{ + if (DetectBufferSetActiveList(de_ctx, s, g_smtp_rcpt_to_buffer_id) < 0) + return -1; + + if (DetectSignatureSetAppProto(s, ALPROTO_SMTP) < 0) + return -1; + + return 0; +} + +static InspectionBuffer *GetSmtpRcptToData(DetectEngineThreadCtx *det_ctx, + const DetectEngineTransforms *transforms, Flow *f, const uint8_t _flow_flags, void *txv, + const int list_id, uint32_t idx) +{ + InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, idx); + if (buffer == NULL || buffer->initialized) + return buffer; + + SMTPTransaction *tx = (SMTPTransaction *)txv; + if (TAILQ_EMPTY(&tx->rcpt_to_list)) { + InspectionBufferSetupMultiEmpty(buffer); + return NULL; + } + + SMTPString *s; + if (idx == 0) { + s = TAILQ_FIRST(&tx->rcpt_to_list); + } else { + // TODO optimize ? + s = TAILQ_FIRST(&tx->rcpt_to_list); + for (uint32_t i = 0; i < idx; i++) { + s = TAILQ_NEXT(s, next); + } + } + if (s == NULL) { + InspectionBufferSetupMultiEmpty(buffer); + return NULL; + } + + InspectionBufferSetupMulti(buffer, transforms, s->str, s->len); + buffer->flags = DETECT_CI_FLAGS_SINGLE; + return buffer; +} + void SCDetectSMTPRegister(void) { SCSigTableElmt kw = { 0 }; @@ -111,4 +158,15 @@ void SCDetectSMTPRegister(void) DetectHelperBufferMpmRegister("smtp.mail_from", "SMTP MAIL FROM", ALPROTO_SMTP, false, true, // to server GetSmtpMailFromData); + + kw.name = "smtp.rcpt_to"; + kw.desc = "SMTP rcpt to buffer"; + kw.url = "/rules/smtp-keywords.html#smtp-rcpt-to"; + kw.Setup = (int (*)(void *, void *, const char *))DetectSmtpRcptToSetup; + kw.flags = SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER; + DetectHelperKeywordRegister(&kw); + g_smtp_rcpt_to_buffer_id = + DetectHelperMultiBufferMpmRegister("smtp.rcpt_to", "SMTP RCPT TO", ALPROTO_SMTP, false, + true, // to server + GetSmtpRcptToData); }