detect: add email.cc keyword

email.cc matches on MIME EMAIL Carbon Copy
This keyword maps to the EVE field email.cc[]
It is a sticky buffer
Supports prefiltering

Ticket: #7588
pull/12840/head
Alice Akaki 4 months ago committed by Victor Julien
parent 9c3c6cf4cc
commit 7ba4ebdc2c

@ -74,3 +74,27 @@ Example of a signature that would alert if a packet contains the MIME field ``to
.. container:: example-rule .. container:: example-rule
alert smtp any any -> any any (msg:"Test mime email to"; :example-rule-emphasis:`email.to; content:"172.16.92.2@linuxbox";` sid:1;) alert smtp any any -> any any (msg:"Test mime email to"; :example-rule-emphasis:`email.to; content:"172.16.92.2@linuxbox";` sid:1;)
email.cc
--------
Matches the MIME ``Cc`` field of an email.
Comparison is case-sensitive.
Syntax::
email.cc; content:"<content to match against>";
``email.cc`` is a 'sticky buffer' and can be used as a ``fast_pattern``.
This keyword maps to the EVE field ``email.cc[]``
Example
^^^^^^^
Example of a signature that would alert if a packet contains the MIME field ``cc`` with the value ``Emily <emily.roberts@example.com>, Ava <ava.johnson@example.com>, Sophia Wilson <sophia.wilson@example.com>``
.. container:: example-rule
alert smtp any any -> any any (msg:"Test mime email cc"; :example-rule-emphasis:`email.cc; content:"Emily <emily.roberts@example.com>, Ava <ava.johnson@example.com>, Sophia Wilson <sophia.wilson@example.com>";` sid:1;)

@ -47,7 +47,7 @@ Example rule:
The above rule will alert on a single dns query containing The above rule will alert on a single dns query containing
"example.net" or "example.domain.net" since the rule content "example.net" or "example.domain.net" since the rule content
matches are within a single ``dns.query`` buffer and all matches are within a single ``dns.query`` buffer and all
content match requirements of the rule are met. content match requirements of the rule are met.
@ -65,7 +65,7 @@ Using our example from above, the first query is for example.net
which matches content:"example"; but does not match content:".com"; which matches content:"example"; but does not match content:".com";
The second query is for something.com which would match on the The second query is for something.com which would match on the
content:".com"; but not the content:"example"; content:".com"; but not the content:"example";
So with the Suricata behavior prior to Suricata 7, the signature So with the Suricata behavior prior to Suricata 7, the signature
would not fire in this case since both content conditions will would not fire in this case since both content conditions will

@ -20,6 +20,8 @@ use super::smtp::MimeStateSMTP;
use std::ffi::CStr; use std::ffi::CStr;
use std::ptr; use std::ptr;
/// Intermediary function used in detect-email.c to access data from the MimeStateSMTP structure.
/// The hname parameter determines which data will be returned.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn SCDetectMimeEmailGetData( pub unsafe extern "C" fn SCDetectMimeEmailGetData(
ctx: &MimeStateSMTP, buffer: *mut *const u8, buffer_len: *mut u32, ctx: &MimeStateSMTP, buffer: *mut *const u8, buffer_len: *mut u32,

@ -25,6 +25,7 @@
static int g_mime_email_from_buffer_id = 0; static int g_mime_email_from_buffer_id = 0;
static int g_mime_email_subject_buffer_id = 0; static int g_mime_email_subject_buffer_id = 0;
static int g_mime_email_to_buffer_id = 0; static int g_mime_email_to_buffer_id = 0;
static int g_mime_email_cc_buffer_id = 0;
static int DetectMimeEmailFromSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg) static int DetectMimeEmailFromSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
{ {
@ -131,6 +132,40 @@ static InspectionBuffer *GetMimeEmailToData(DetectEngineThreadCtx *det_ctx,
return buffer; return buffer;
} }
static int DetectMimeEmailCcSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
{
if (DetectBufferSetActiveList(de_ctx, s, g_mime_email_cc_buffer_id) < 0)
return -1;
if (DetectSignatureSetAppProto(s, ALPROTO_SMTP) < 0)
return -1;
return 0;
}
static InspectionBuffer *GetMimeEmailCcData(DetectEngineThreadCtx *det_ctx,
const DetectEngineTransforms *transforms, Flow *f, const uint8_t _flow_flags, void *txv,
const int list_id)
{
InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
if (buffer->inspect == NULL) {
SMTPTransaction *tx = (SMTPTransaction *)txv;
const uint8_t *b_email_cc = NULL;
uint32_t b_email_cc_len = 0;
if (tx->mime_state == NULL)
return NULL;
if (SCDetectMimeEmailGetData(tx->mime_state, &b_email_cc, &b_email_cc_len, "cc") != 1)
return NULL;
InspectionBufferSetup(det_ctx, list_id, buffer, b_email_cc, b_email_cc_len);
InspectionBufferApplyTransforms(buffer, transforms);
}
return buffer;
}
void DetectEmailRegister(void) void DetectEmailRegister(void)
{ {
SCSigTableElmt kw = { 0 }; SCSigTableElmt kw = { 0 };
@ -167,4 +202,15 @@ void DetectEmailRegister(void)
DetectHelperBufferMpmRegister("email.to", "MIME EMAIL TO", ALPROTO_SMTP, false, DetectHelperBufferMpmRegister("email.to", "MIME EMAIL TO", ALPROTO_SMTP, false,
true, // to server true, // to server
GetMimeEmailToData); GetMimeEmailToData);
kw.name = "email.cc";
kw.desc = "'Cc' field from an email";
kw.url = "/rules/email-keywords.html#email.cc";
kw.Setup = (int (*)(void *, void *, const char *))DetectMimeEmailCcSetup;
kw.flags = SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER;
DetectHelperKeywordRegister(&kw);
g_mime_email_cc_buffer_id =
DetectHelperBufferMpmRegister("email.cc", "MIME EMAIL CC", ALPROTO_SMTP, false,
true, // to server
GetMimeEmailCcData);
} }

Loading…
Cancel
Save