smtp: fix mime boundary parsing issue

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
pull/1147/head
Victor Julien 10 years ago
parent a4a1c396e1
commit 6d170cadd7

@ -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

@ -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");

@ -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_ {

@ -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);

@ -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 */

Loading…
Cancel
Save