]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
smtp/mime: look for urls in base64 message
authorPhilippe Antoine <pantoine@oisf.net>
Tue, 4 Jun 2024 12:42:43 +0000 (14:42 +0200)
committerVictor Julien <victor@inliniac.net>
Thu, 6 Jun 2024 20:40:48 +0000 (22:40 +0200)
Ticket: 5185

Previously, it was looked for message in plain text, and base64
encoding was only handled for attachments.

This commit also fixes the buffering got such base64 data streamed
into urls finding, by buffering a beginning non-empty line,
and by ensuring that we run extraction on the last line,
even if it had no EOL.

rust/src/mime/smtp.rs

index 947ea58a74e899fd0826580a4b6c1860141968e2..bca64855c03813c8dca545420969783a3f1a6f50 100644 (file)
@@ -373,7 +373,9 @@ fn mime_smtp_find_url_strings(ctx: &mut MimeStateSMTP, input_new: &[u8]) {
         } else {
             ctx.decoded_line.extend_from_slice(&input_new[x..]);
         }
-    } // else  no end of line, already buffered for next input...
+    } else if ctx.decoded_line.is_empty() {
+        ctx.decoded_line.extend_from_slice(input_new);
+    }
 }
 
 fn mime_base64_map(input: u8) -> io::Result<u8> {
@@ -614,9 +616,30 @@ fn mime_smtp_parse_line(
                     || ctx.content_type == MimeSmtpContentType::Html
                     || ctx.content_type == MimeSmtpContentType::Message
                 {
-                    mime_smtp_find_url_strings(ctx, full);
+                    match ctx.encoding {
+                        MimeSmtpEncoding::Plain => {
+                            mime_smtp_find_url_strings(ctx, full);
+                        }
+                        MimeSmtpEncoding::QuotedPrintable => {
+                            mime_smtp_find_url_strings(ctx, full);
+                        }
+                        MimeSmtpEncoding::Base64 => {
+                            if unsafe { MIME_SMTP_CONFIG_DECODE_BASE64 } {
+                                if let Some(ref mut decoder) = &mut ctx.decoder {
+                                    if i.len() > MAX_ENC_LINE_LEN {
+                                        warnings |= MIME_ANOM_LONG_ENC_LINE;
+                                    }
+                                    if let Ok(dec) = mime_base64_decode(decoder, i) {
+                                        mime_smtp_find_url_strings(ctx, &dec);
+                                    } else {
+                                        warnings |= MIME_ANOM_INVALID_BASE64;
+                                    }
+                                }
+                            }
+                        }
+                    }
                 }
-                return (MimeSmtpParserResult::MimeSmtpNeedsMore, 0);
+                return (MimeSmtpParserResult::MimeSmtpNeedsMore, warnings);
             }
             match ctx.encoding {
                 MimeSmtpEncoding::Plain => {
@@ -735,6 +758,8 @@ fn mime_smtp_complete(ctx: &mut MimeStateSMTP) {
         ctx.md5_state = MimeSmtpMd5State::MimeSmtpMd5Completed;
         ctx.md5_result = ctx.md5.finalize_reset();
     }
+    // look for url in the last unfinished line
+    mime_smtp_find_url_strings(ctx, &[b'\n']);
 }
 
 #[no_mangle]