From 130b8d26e7e8e64ca42dc7e4db9890619d9730aa Mon Sep 17 00:00:00 2001 From: Jeff Lucovsky Date: Wed, 5 Feb 2020 09:20:29 -0500 Subject: [PATCH] smtp/mime: Set event when name exceeds limit --- rules/smtp-events.rules | 3 ++- src/app-layer-smtp.c | 7 ++++++- src/app-layer-smtp.h | 1 + src/util-decode-mime.c | 19 ++++++++++++++++--- src/util-decode-mime.h | 1 + 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/rules/smtp-events.rules b/rules/smtp-events.rules index 89c25acbc7..cc7eedcbbf 100644 --- a/rules/smtp-events.rules +++ b/rules/smtp-events.rules @@ -29,4 +29,5 @@ alert smtp any any -> any any (msg:"SURICATA SMTP Mime boundary length exceeded" alert smtp any any -> any any (msg:"SURICATA SMTP duplicate fields"; flow:established,to_server; app-layer-event:smtp.duplicate_fields; flowint:smtp.anomaly.count,+,1; classtype:protocol-command-decode; sid:2220018; rev:1;) alert smtp any any -> any any (msg:"SURICATA SMTP unparsable content"; flow:established,to_server; app-layer-event:smtp.unparsable_content; flowint:smtp.anomaly.count,+,1; classtype:protocol-command-decode; sid:2220019; rev:1;) -# next sid 2220020 +alert smtp any any -> any any (msg:"SURICATA SMTP filename truncated"; flow:established,to_server; app-layer-event:smtp.mime_long_filename; flowint:smtp.anomaly.count,+,1; classtype:protocol-command-decode; sid:2220020; rev:1;) +# next sid 2220021 diff --git a/src/app-layer-smtp.c b/src/app-layer-smtp.c index 347467b510..874b0b5d61 100644 --- a/src/app-layer-smtp.c +++ b/src/app-layer-smtp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation +/* Copyright (C) 2007-2020 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 @@ -147,6 +147,8 @@ SCEnumCharMap smtp_decoder_event_table[ ] = { SMTP_DECODER_EVENT_MIME_LONG_HEADER_VALUE }, { "MIME_LONG_BOUNDARY", SMTP_DECODER_EVENT_MIME_BOUNDARY_TOO_LONG }, + { "MIME_LONG_FILENAME", + SMTP_DECODER_EVENT_MIME_LONG_FILENAME }, /* Invalid behavior or content */ { "DUPLICATE_FIELDS", @@ -873,6 +875,9 @@ static void SetMimeEvents(SMTPState *state) if (msg->anomaly_flags & ANOM_LONG_BOUNDARY) { SMTPSetEvent(state, SMTP_DECODER_EVENT_MIME_BOUNDARY_TOO_LONG); } + if (msg->anomaly_flags & ANOM_LONG_FILENAME) { + SMTPSetEvent(state, SMTP_DECODER_EVENT_MIME_LONG_FILENAME); + } } /** diff --git a/src/app-layer-smtp.h b/src/app-layer-smtp.h index 59c9d5b9f0..66b28b5e83 100644 --- a/src/app-layer-smtp.h +++ b/src/app-layer-smtp.h @@ -50,6 +50,7 @@ enum { SMTP_DECODER_EVENT_MIME_LONG_HEADER_NAME, SMTP_DECODER_EVENT_MIME_LONG_HEADER_VALUE, SMTP_DECODER_EVENT_MIME_BOUNDARY_TOO_LONG, + SMTP_DECODER_EVENT_MIME_LONG_FILENAME, /* Invalid behavior or content */ SMTP_DECODER_EVENT_DUPLICATE_FIELDS, diff --git a/src/util-decode-mime.c b/src/util-decode-mime.c index 24dee93deb..a176eb84a3 100644 --- a/src/util-decode-mime.c +++ b/src/util-decode-mime.c @@ -1832,6 +1832,7 @@ static int FindMimeHeader(const uint8_t *buf, uint32_t blen, * \param search_end The end of the search (ie. \") * \param tlen The output length of the token (if found) * \param max_len The maximum offset in which to search + * \param toolong Set if the field value was truncated to max_len. * * \return A pointer to the token if found, otherwise NULL if not found */ @@ -1884,7 +1885,7 @@ static uint8_t * FindMimeHeaderTokenRestrict(MimeDecField *field, const char *se static uint8_t * FindMimeHeaderToken(MimeDecField *field, const char *search_start, const char *search_end, uint32_t *tlen) { - return FindMimeHeaderTokenRestrict(field, search_start, search_end, tlen, 0); + return FindMimeHeaderTokenRestrict(field, search_start, search_end, tlen, 0, NULL); } /** @@ -1932,7 +1933,8 @@ static int ProcessMimeHeaders(const uint8_t *buf, uint32_t len, /* Check for file attachment in content disposition */ field = MimeDecFindField(entity, CTNT_DISP_STR); if (field != NULL) { - bptr = FindMimeHeaderTokenRestrict(field, "filename=", TOK_END_STR, &blen, NAME_MAX); + bool truncated_name = false; + bptr = FindMimeHeaderTokenRestrict(field, "filename=", TOK_END_STR, &blen, NAME_MAX, &truncated_name); if (bptr != NULL) { SCLogDebug("File attachment found in disposition"); entity->ctnt_flags |= CTNT_IS_ATTACHMENT; @@ -1945,6 +1947,11 @@ static int ProcessMimeHeaders(const uint8_t *buf, uint32_t len, } memcpy(entity->filename, bptr, blen); entity->filename_len = blen; + + if (truncated_name) { + state->stack->top->data->anomaly_flags |= ANOM_LONG_FILENAME; + state->msg->anomaly_flags |= ANOM_LONG_FILENAME; + } } } @@ -1974,7 +1981,8 @@ static int ProcessMimeHeaders(const uint8_t *buf, uint32_t len, /* Look for file name (if not already found) */ if (!(entity->ctnt_flags & CTNT_IS_ATTACHMENT)) { - bptr = FindMimeHeaderTokenRestrict(field, "name=", TOK_END_STR, &blen, NAME_MAX); + bool truncated_name = false; + bptr = FindMimeHeaderTokenRestrict(field, "name=", TOK_END_STR, &blen, NAME_MAX, &truncated_name); if (bptr != NULL) { SCLogDebug("File attachment found"); entity->ctnt_flags |= CTNT_IS_ATTACHMENT; @@ -1987,6 +1995,11 @@ static int ProcessMimeHeaders(const uint8_t *buf, uint32_t len, } memcpy(entity->filename, bptr, blen); entity->filename_len = blen; + + if (truncated_name) { + state->stack->top->data->anomaly_flags |= ANOM_LONG_FILENAME; + state->msg->anomaly_flags |= ANOM_LONG_FILENAME; + } } } diff --git a/src/util-decode-mime.h b/src/util-decode-mime.h index 1922264bee..5ee347c45c 100644 --- a/src/util-decode-mime.h +++ b/src/util-decode-mime.h @@ -60,6 +60,7 @@ #define ANOM_LONG_ENC_LINE 32 /* Lines that exceed 76 octets */ #define ANOM_MALFORMED_MSG 64 /* Misc msg format errors found */ #define ANOM_LONG_BOUNDARY 128 /* Boundary too long */ +#define ANOM_LONG_FILENAME 256 /* filename truncated */ /* Publicly exposed size constants */ #define DATA_CHUNK_SIZE 3072 /* Should be divisible by 3 */