]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
smtp: fix mime boundary parsing issue
authorVictor Julien <victor@inliniac.net>
Thu, 16 Apr 2015 15:05:52 +0000 (17:05 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 6 May 2015 18:30:56 +0000 (20:30 +0200)
If a boundary was longer than 254 bytes a stack overflow would result
in mime decoding.

Ticket #1449

Reported-by: Kostya Kortchinsky of the Google Security Team
rules/smtp-events.rules
src/app-layer-smtp.c
src/app-layer-smtp.h
src/util-decode-mime.c
src/util-decode-mime.h

index 52b4647f9618cd57b3b637635816e23930b8f856..c1ade81ad3df3f4ffa9184690d157cea4a0ef559 100644 (file)
@@ -25,3 +25,6 @@ alert smtp any any -> any any (msg:"SURICATA SMTP data command rejected"; flow:e
 #alert smtp any any -> any any (msg:"SURICATA SMTP Mime quoted-printable-decoding failed"; flow:established; app-layer-event:smtp.mime_invalid_qp; flowint:smtp.anomaly.count,+,1; classtype:protocol-command-decode; sid:2220014; rev:1;)
 #alert smtp any any -> any any (msg:"SURICATA SMTP Mime line len exceeded"; flow:established; app-layer-event:smtp.mime_long_line; flowint:smtp.anomaly.count,+,1; classtype:protocol-command-decode; sid:2220015; rev:1;)
 #alert smtp any any -> any any (msg:"SURICATA SMTP Mime encoded line len exceeded"; flow:established; app-layer-event:smtp.mime_long_enc_line; flowint:smtp.anomaly.count,+,1; classtype:protocol-command-decode; sid:2220016; rev:1;)
+alert smtp any any -> any any (msg:"SURICATA SMTP Mime boundary length exceeded"; flow:established,to_server; app-layer-event:smtp.mime_long_boundary; flowint:smtp.anomaly.count,+,1; classtype:protocol-command-decode; sid:2220017; rev:1;)
+
+# next sid 2220018
index bc6459ab83309072c2712182edc7ba1c99deb66d..1a0894f0f98cc93e2226b1bb9263047491300976 100644 (file)
@@ -133,6 +133,8 @@ SCEnumCharMap smtp_decoder_event_table[ ] = {
       SMTP_DECODER_EVENT_MIME_LONG_HEADER_NAME },
     { "MIME_LONG_HEADER_VALUE",
       SMTP_DECODER_EVENT_MIME_LONG_HEADER_VALUE },
+    { "MIME_LONG_BOUNDARY",
+      SMTP_DECODER_EVENT_MIME_BOUNDARY_TOO_LONG },
 
     { NULL,                      -1 },
 };
@@ -753,6 +755,9 @@ static int SMTPProcessCommandDATA(SMTPState *state, Flow *f,
             if (msg->anomaly_flags & ANOM_MALFORMED_MSG) {
                 SMTPSetEvent(state, SMTP_DECODER_EVENT_MIME_MALFORMED_MSG);
             }
+            if (msg->anomaly_flags & ANOM_LONG_BOUNDARY) {
+                SMTPSetEvent(state, SMTP_DECODER_EVENT_MIME_BOUNDARY_TOO_LONG);
+            }
         }
         state->curr_tx->done = 1;
         SCLogDebug("marked tx as done");
index 8bb4a9323902cf11bef3bb39e7ce68805067bb66..eca2003180fafe24f41e9f3dabca7122d484e681 100644 (file)
@@ -48,6 +48,7 @@ enum {
     SMTP_DECODER_EVENT_MIME_LONG_ENC_LINE,
     SMTP_DECODER_EVENT_MIME_LONG_HEADER_NAME,
     SMTP_DECODER_EVENT_MIME_LONG_HEADER_VALUE,
+    SMTP_DECODER_EVENT_MIME_BOUNDARY_TOO_LONG,
 };
 
 typedef struct SMTPTransaction_ {
index 187740ea874baa138809ec6029b9935dc94a0d6c..3f4affcccf6c9ead356601b6f971128e65b4ef21 100644 (file)
@@ -1889,6 +1889,11 @@ static int ProcessMimeHeaders(const uint8_t *buf, uint32_t len,
                 state->found_child = 1;
                 entity->ctnt_flags |= CTNT_IS_MULTIPART;
 
+                if (blen > (BOUNDARY_BUF - 2)) {
+                    state->stack->top->data->anomaly_flags |= ANOM_LONG_BOUNDARY;
+                    return MIME_DEC_ERR_PARSE;
+                }
+
                 /* Store boundary in parent node */
                 state->stack->top->bdef = SCMalloc(blen);
                 if (unlikely(state->stack->top->bdef == NULL)) {
@@ -2207,6 +2212,12 @@ static int ProcessMimeBody(const uint8_t *buf, uint32_t len,
         if (len > 1 && buf[0] == '-' && buf[1] == '-') {
 
             tlen = node->bdef_len + 2;
+            if (tlen > BOUNDARY_BUF) {
+                if (state->stack->top->data)
+                    state->stack->top->data->anomaly_flags |= ANOM_LONG_BOUNDARY;
+                return MIME_DEC_ERR_PARSE;
+            }
+
             memcpy(temp, "--", 2);
             memcpy(temp + 2, node->bdef, node->bdef_len);
 
index 0b3b2d22b1156790c978bd3e485869a2a0600c13..792fbcc199c737b87b63926344dabbedb13e3836 100644 (file)
@@ -62,6 +62,7 @@
 #define ANOM_LONG_LINE          16  /* Lines that exceed 998 octets */
 #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 */
 
 /* Pubicly exposed size constants */
 #define DATA_CHUNK_SIZE  3072  /* Should be divisible by 3 */