From 498be229975f1b3e526e715ff1187ff6dd40a5f0 Mon Sep 17 00:00:00 2001 From: Andrew Lewis Date: Tue, 30 Aug 2016 15:45:10 +0200 Subject: [PATCH] [Minor] Update rule style: headers.lua --- conf/metrics.conf | 272 --------------------- rules/regexp/headers.lua | 511 ++++++++++++++++++++++++++++++++------- 2 files changed, 427 insertions(+), 356 deletions(-) diff --git a/conf/metrics.conf b/conf/metrics.conf index 0bab8ea51..1294ca2f1 100644 --- a/conf/metrics.conf +++ b/conf/metrics.conf @@ -28,99 +28,23 @@ metric { group "excessqp" { max_score = 2.4; - symbol "FROM_EXCESS_QP" { - weight = 1.2; - description = "From that contains encoded characters while quoted-printable is not needed as all symbols are 7bit"; - } - symbol "TO_EXCESS_QP" { - weight = 1.2; - description = "To that contains encoded characters while quoted-printable is not needed as all symbols are 7bit"; - } - symbol "REPLYTO_EXCESS_QP" { - weight = 1.2; - description = "Reply-To that contains encoded characters while quoted-printable is not needed as all symbols are 7bit"; - } - symbol "CC_EXCESS_QP" { - weight = 1.2; - description = "Cc that contains encoded characters while quoted-printable is not needed as all symbols are 7bit"; - } } group "excessb64" { max_score = 3.0; - symbol "FROM_EXCESS_BASE64" { - weight = 1.5; - description = "From that contains encoded characters while base 64 is not needed as all symbols are 7bit"; - } - symbol "TO_EXCESS_BASE64" { - weight = 1.5; - description = "To that contains encoded characters while base 64 is not needed as all symbols are 7bit"; - } - symbol "REPLYTO_EXCESS_BASE64" { - weight = 1.5; - description = "Reply-To that contains encoded characters while base 64 is not needed as all symbols are 7bit"; - } - symbol "CC_EXCESS_BASE64" { - weight = 1.5; - description = "Cc that contains encoded characters while base 64 is not needed as all symbols are 7bit"; - } } group "header" { - symbol "MISSING_SUBJECT" { - weight = 2.0; - description = "Subject is missing inside message"; - } - symbol "FORGED_OUTLOOK_TAGS" { - weight = 2.100000; - description = "Message pretends to be send from Outlook but has 'strange' tags "; - } symbol "FORGED_SENDER" { weight = 0.30; description = "Sender is forged (different From: header and smtp MAIL FROM: addresses)"; } - symbol "SUSPICIOUS_RECIPS" { - weight = 1.500000; - description = "Recipients seems to be autogenerated (works if recipients count is more than 5)"; - } symbol "MIME_HTML_ONLY" { weight = 0.2; description = "Messages that have only HTML part"; } - symbol "FORGED_MSGID_YAHOO" { - weight = 2.0; - description = "Forged yahoo msgid"; - } - symbol "FORGED_MUA_THEBAT_BOUN" { - weight = 2.0; - description = "Forged The Bat! MUA headers"; - } - symbol "R_MISSING_CHARSET" { - weight = 2.5; - description = "Charset is missing in a message"; - } - symbol "RCVD_DOUBLE_IP_SPAM" { - weight = 2.0; - description = "Two received headers with ip addresses"; - } - symbol "FORGED_OUTLOOK_HTML" { - weight = 5.0; - description = "Forged outlook HTML signature"; - } - symbol "R_UNDISC_RCPT" { - weight = 3.0; - description = "Recipients are absent or undisclosed"; - } symbol "FM_FAKE_HELO_VERIZON" { weight = 2.0; description = "Fake helo for verizon provider"; } - symbol "REPTO_QUOTE_YAHOO" { - weight = 2.0; - description = "Quoted reply-to from yahoo (seems to be forged)"; - } - symbol "MISSING_MIMEOLE" { - weight = 2.0; - description = "Mime-OLE is needed but absent (e.g. fake Outlook or fake Exchange)"; - } symbol "MISSING_TO" { weight = 2.0; description = "To header is missing"; @@ -135,42 +59,6 @@ metric { description = "Mixed characters in a URL inside message"; one_shot = true; } - symbol "SORTED_RECIPS" { - weight = 3.500000; - description = "Recipients list seems to be sorted"; - } - symbol "R_RCVD_SPAMBOTS" { - weight = 3.0; - description = "Spambots signatures in received headers"; - } - symbol "SUBJECT_NEEDS_ENCODING" { - weight = 1.0; - description = "Subject needs encoding"; - } - symbol "TRACKER_ID" { - weight = 3.84; - description = "Spam string at the end of message to make statistics faults 0"; - } - symbol "R_NO_SPACE_IN_FROM" { - weight = 1.0; - description = "No space in from header"; - } - symbol "R_SAJDING" { - weight = 8.0; - description = "Subject seems to be spam"; - } - symbol "R_BAD_CTE_7BIT" { - weight = 3.0; - description = "Detects bad content-transfer-encoding for text parts"; - } - symbol "INVALID_MSGID" { - weight = 1.7; - description = "Message id is incorrect"; - } - symbol "MISSING_MID" { - weight = 2.5; - description = "Message id is missing "; - } symbol "FORGED_RECIPIENTS" { weight = 2.0; description = "Recipients are not the same as RCPT TO: mail command"; @@ -183,14 +71,6 @@ metric { weight = 0.0; description = "Sender is not the same as MAIL FROM: envelope, but a message is from a maillist"; } - symbol "RATWARE_MS_HASH" { - weight = 2.0; - description = "Forged Exchange messages"; - } - symbol "STOX_REPLY_TYPE" { - weight = 1.0; - description = "Reply-type in content-type"; - } symbol "ONCE_RECEIVED" { weight = 0.1; description = "One received header in a message"; @@ -203,99 +83,15 @@ metric { weight = 4.0; description = "One received header with 'bad' patterns inside"; } - symbol "MIME_HEADER_CTYPE_ONLY" { - weight = 2.0; - description = "Only Content-Type header without other MIME headers"; - } symbol "MAILLIST" { weight = -0.2; description = "Message seems to be from maillist"; } - symbol "HEADER_FROM_DELIMITER_TAB" { - weight = 1.0; - description = "Header From begins with tab"; - } - symbol "HEADER_TO_DELIMITER_TAB" { - weight = 1.0; - description = "Header To begins with tab"; - } - symbol "HEADER_CC_DELIMITER_TAB" { - weight = 1.0; - description = "Header Cc begins with tab"; - } - symbol "HEADER_REPLYTO_DELIMITER_TAB" { - weight = 1.0; - description = "Header Reply-To begins with tab"; - } - symbol "HEADER_DATE_DELIMITER_TAB" { - weight = 1.0; - description = "Header Date begins with tab"; - } - symbol "HEADER_FROM_EMPTY_DELIMITER" { - weight = 1.0; - description = "Header From has no delimiter between header name and header value"; - } - symbol "HEADER_TO_EMPTY_DELIMITER" { - weight = 1.0; - description = "Header To has no delimiter between header name and header value"; - } - symbol "HEADER_CC_EMPTY_DELIMITER" { - weight = 1.0; - description = "Header Cc has no delimiter between header name and header value"; - } - symbol "HEADER_REPLYTO_EMPTY_DELIMITER" { - weight = 1.0; - description = "Header Reply-To has no delimiter between header name and header value"; - } - symbol "HEADER_DATE_EMPTY_DELIMITER" { - weight = 1.0; - description = "Header Date has no delimiter between header name and header value"; - } - symbol "RCVD_ILLEGAL_CHARS" { - weight = 4.0; - description = "Header Received has raw illegal character"; - } - symbol "FAKE_RECEIVED_mail_ru" { - weight = 4.0; - description = "Fake helo mail.ru in header Received from non mail.ru sender address"; - } - symbol "FAKE_RECEIVED_smtp_yandex_ru" { - weight = 4.0; - description = "Fake smtp.yandex.ru Received"; - } - symbol "FORGED_GENERIC_RECEIVED" { - weight = 3.6; - description = "Forged generic Received"; - } - symbol "FORGED_GENERIC_RECEIVED2" { - weight = 3.6; - description = "Forged generic Received"; - } - symbol "FORGED_GENERIC_RECEIVED3" { - weight = 3.6; - description = "Forged generic Received"; - } - symbol "FORGED_GENERIC_RECEIVED4" { - weight = 3.6; - description = "Forged generic Received"; - } - symbol "FORGED_GENERIC_RECEIVED5" { - weight = 4.6; - description = "Forged generic Received"; - } - symbol "INVALID_POSTFIX_RECEIVED" { - weight = 3.0; - description = "Invalid Postfix Received"; - } } group "subject" { max_score = 6.0; - symbol "FAKE_REPLY_C" { - weight = 6.0; - description = "Fake reply (has RE in subject, but has not References header)"; - } symbol "LONG_SUBJ" { weight = 6.0; description = "Subject is too long"; @@ -307,58 +103,6 @@ metric { } group "mua" { - symbol "FORGED_MUA_THEBAT_MSGID" { - weight = 4.0; - description = "Message pretends to be send from The Bat! but has forged Message-ID"; - } - symbol "FORGED_MUA_THEBAT_MSGID_UNKNOWN" { - weight = 3.0; - description = "Message pretends to be send from The Bat! but has forged Message-ID"; - } - symbol "FORGED_MUA_KMAIL_MSGID" { - weight = 3.0; - description = "Message pretends to be send from KMail but has forged Message-ID"; - } - symbol "FORGED_MUA_KMAIL_MSGID_UNKNOWN" { - weight = 2.5; - description = "Message pretends to be send from KMail but has forged Message-ID"; - } - symbol "FORGED_MUA_OPERA_MSGID" { - weight = 4.0; - description = "Message pretends to be send from Opera Mail but has forged Message-ID"; - } - symbol "SUSPICIOUS_OPERA_10W_MSGID" { - weight = 4.0; - description = "Message pretends to be send from suspicious Opera Mail/10.x (Windows) but has forged Message-ID, apparently from KMail"; - } - symbol "FORGED_MUA_MOZILLA_MAIL_MSGID" { - weight = 4.0; - description = "Message pretends to be send from Mozilla Mail but has forged Message-ID"; - } - symbol "FORGED_MUA_MOZILLA_MAIL_MSGID_UNKNOWN" { - weight = 2.5; - description = "Message pretends to be send from Mozilla Mail but has forged Message-ID"; - } - symbol "FORGED_MUA_THUNDERBIRD_MSGID" { - weight = 4.0; - description = "Forged mail pretending to be from Mozilla Thunderbird but has forged Message-ID"; - } - symbol "FORGED_MUA_THUNDERBIRD_MSGID_UNKNOWN" { - weight = 2.5; - description = "Forged mail pretending to be from Mozilla Thunderbird but has forged Message-ID"; - } - symbol "FORGED_MUA_SEAMONKEY_MSGID" { - weight = 4.0; - description = "Forged mail pretending to be from Mozilla Seamonkey but has forged Message-ID"; - } - symbol "FORGED_MUA_SEAMONKEY_MSGID_UNKNOWN" { - weight = 2.5; - description = "Forged mail pretending to be from Mozilla Seamonkey but has forged Message-ID"; - } - symbol "FORGED_MUA_OUTLOOK" { - weight = 3.0; - description = "Forged outlook MUA"; - } symbol "FORGED_MUA_MAILLIST" { weight = 0.0; description = "Avoid false positives for FORGED_MUA_* in maillist"; @@ -382,22 +126,6 @@ metric { weight = 0.5; description = "Short html part with a link to an image"; } - symbol "SUSPICIOUS_BOUNDARY" { - weight = 5.0; - description = "Suspicious boundary in header Content-Type"; - } - symbol "SUSPICIOUS_BOUNDARY2" { - weight = 4.0; - description = "Suspicious boundary in header Content-Type"; - } - symbol "SUSPICIOUS_BOUNDARY3" { - weight = 3.0; - description = "Suspicious boundary in header Content-Type"; - } - symbol "SUSPICIOUS_BOUNDARY4" { - weight = 4.0; - description = "Suspicious boundary in header Content-Type"; - } symbol "R_PARTS_DIFFER" { weight = 1.0; description = "Text and HTML parts differ"; diff --git a/rules/regexp/headers.lua b/rules/regexp/headers.lua index 6ec37181f..e645ff007 100644 --- a/rules/regexp/headers.lua +++ b/rules/regexp/headers.lua @@ -27,21 +27,35 @@ local subject_encoded_qp = 'Subject=/=\\?\\S+\\?Q\\?/iX' -- Define whether subject must be encoded (contains non-7bit characters) local subject_needs_mime = 'Subject=/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f-\\xff]/X' -- Final rule -reconf['SUBJECT_NEEDS_ENCODING'] = string.format('!(%s) & !(%s) & (%s)', subject_encoded_b64, subject_encoded_qp, subject_needs_mime) +reconf['SUBJECT_NEEDS_ENCODING'] = { + re = string.format('!(%s) & !(%s) & (%s)', subject_encoded_b64, subject_encoded_qp, subject_needs_mime), + score = 1.0, + description = 'Subject needs encoding', + group = 'header' +} -- Detects that there is no space in From header (e.g. Some Name) -reconf['R_NO_SPACE_IN_FROM'] = 'From=/\\S<[-\\w\\.]+\\@[-\\w\\.]+>/X' +reconf['R_NO_SPACE_IN_FROM'] = { + re = 'From=/\\S<[-\\w\\.]+\\@[-\\w\\.]+>/X', + score = 1.0, + description = 'No space in from header', + group = 'header' +} +rspamd_config.MISSING_SUBJECT = { + score = 2.0, + description = 'Subject is missing inside message', + group = 'header', + callback = function(task) + local hdr = task:get_header('Subject') -rspamd_config.MISSING_SUBJECT = function(task) - local hdr = task:get_header('Subject') + if not hdr or #hdr == 0 then + return true + end - if not hdr or #hdr == 0 then - return true + return false end - - return false -end +} -- Detects bad content-transfer-encoding for text parts -- For text parts (text/plain and text/html mainly) @@ -50,27 +64,62 @@ local r_ctype_text = 'content_type_is_type(text)' local r_cte_7bit = 'compare_transfer_encoding(7bit)' -- And body contains 8bit characters local r_body_8bit = '/[^\\x01-\\x7f]/Pr' -reconf['R_BAD_CTE_7BIT'] = string.format('(%s) & (%s) & (%s)', r_ctype_text, r_cte_7bit, r_body_8bit) +reconf['R_BAD_CTE_7BIT'] = { + re = string.format('(%s) & (%s) & (%s)', r_ctype_text, r_cte_7bit, r_body_8bit), + score = 3.0, + description = 'Detects bad content-transfer-encoding for text parts', + group = 'header' +} -- Detects missing To header -reconf['MISSING_TO']= '!raw_header_exists(To)'; +reconf['MISSING_TO'] = { + re = '!raw_header_exists(To)', + score = 2.0, + description = 'To header is missing', + group = 'header' +} -- Detects undisclosed recipients local undisc_rcpt = 'To=/^?$/mH' -- Correct The Bat! Message-ID template local thebat_msgid = 'Message-ID=/^?/mH' -- Summary rule for forged The Bat! Message-ID header -reconf['FORGED_MUA_THEBAT_MSGID'] = string.format('(%s) & !(%s) & (%s) & !(%s)', thebat_mua_any, thebat_msgid, thebat_msgid_common, unusable_msgid) +reconf['FORGED_MUA_THEBAT_MSGID'] = { + re = string.format('(%s) & !(%s) & (%s) & !(%s)', thebat_mua_any, thebat_msgid, thebat_msgid_common, unusable_msgid), + score = 4.0, + description = 'Message pretends to be send from The Bat! but has forged Message-ID', + group = 'mua' +} -- Summary rule for forged The Bat! Message-ID header with unknown template -reconf['FORGED_MUA_THEBAT_MSGID_UNKNOWN'] = string.format('(%s) & !(%s) & !(%s) & !(%s)', thebat_mua_any, thebat_msgid, thebat_msgid_common, unusable_msgid) - +reconf['FORGED_MUA_THEBAT_MSGID_UNKNOWN'] = { + re = string.format('(%s) & !(%s) & !(%s) & !(%s)', thebat_mua_any, thebat_msgid, thebat_msgid_common, unusable_msgid), + score = 3.0, + description = 'Message pretends to be send from The Bat! but has forged Message-ID', + group = 'mua' +} -- Detect forged KMail headers -- KMail User-Agent header @@ -235,9 +383,19 @@ function kmail_msgid (task) return false end -- Summary rule for forged KMail Message-ID header -reconf['FORGED_MUA_KMAIL_MSGID'] = string.format('(%s) & (%s) & !(%s) & !(%s)', kmail_mua, kmail_msgid_common, 'kmail_msgid', unusable_msgid) +reconf['FORGED_MUA_KMAIL_MSGID'] = { + re = string.format('(%s) & (%s) & !(%s) & !(%s)', kmail_mua, kmail_msgid_common, 'kmail_msgid', unusable_msgid), + score = 3.0, + description = 'Message pretends to be send from KMail but has forged Message-ID', + group = 'mua' +} -- Summary rule for forged KMail Message-ID header with unknown template -reconf['FORGED_MUA_KMAIL_MSGID_UNKNOWN'] = string.format('(%s) & !(%s) & !(%s)', kmail_mua, kmail_msgid_common, unusable_msgid) +reconf['FORGED_MUA_KMAIL_MSGID_UNKNOWN'] = { + re = string.format('(%s) & !(%s) & !(%s)', kmail_mua, kmail_msgid_common, unusable_msgid), + score = 2.5, + description = 'Message pretends to be send from KMail but has forged Message-ID', + group = 'mua' +} -- Detect forged Opera Mail headers -- Opera Mail User-Agent header @@ -249,10 +407,19 @@ local suspicious_opera10w_mua = 'User-Agent=/^\\s*Opera Mail\\/10\\.\\d+ \\(Wind -- Suspicious Opera Mail Message-ID, apparently from KMail local suspicious_opera10w_msgid = 'Message-Id=/^$/H' -- Summary rule for forged Opera Mail User-Agent header and Message-ID header from KMail -reconf['SUSPICIOUS_OPERA_10W_MSGID'] = string.format('(%s) & (%s)', suspicious_opera10w_mua, suspicious_opera10w_msgid) +reconf['SUSPICIOUS_OPERA_10W_MSGID'] = { + re = string.format('(%s) & (%s)', suspicious_opera10w_mua, suspicious_opera10w_msgid), + score = 4.0, + description = 'Message pretends to be send from suspicious Opera Mail/10.x (Windows) but has forged Message-ID, apparently from KMail', + group = 'mua' +} -- Summary rule for forged Opera Mail Message-ID header -reconf['FORGED_MUA_OPERA_MSGID'] = string.format('(%s) & !(%s) & !(%s) & !(%s)', opera1x_mua, opera1x_msgid, reconf['SUSPICIOUS_OPERA_10W_MSGID'], unusable_msgid) - +reconf['FORGED_MUA_OPERA_MSGID'] = { + re = string.format('(%s) & !(%s) & !(%s) & !(%s)', opera1x_mua, opera1x_msgid, reconf['SUSPICIOUS_OPERA_10W_MSGID'], unusable_msgid), + score = 4.0, + description = 'Message pretends to be send from Opera Mail but has forged Message-ID', + group = 'mua' +} -- Detect forged Mozilla Mail/Thunderbird/Seamonkey headers -- Mozilla based X-Mailer @@ -265,20 +432,56 @@ local mozilla_msgid_common = 'Message-ID=/^\\s*<[\\dA-F]{8}\\.\\d{1,7}\\@([^>\\. local mozilla_msgid_common_sec = 'Message-ID=/^\\s*<[\\da-f]{8}-([\\da-f]{4}-){3}[\\da-f]{12}\\@([^>\\.]+\\.)+[^>\\.]+>$/H' local mozilla_msgid = 'Message-ID=/^\\s*<(3[3-9A-F]|4[\\dA-F]|5[\\dA-F])[\\dA-F]{6}\\.(\\d0){1,4}\\d\\@([^>\\.]+\\.)+[^>\\.]+>$/H' -- Summary rule for forged Mozilla Mail Message-ID header -reconf['FORGED_MUA_MOZILLA_MAIL_MSGID'] = string.format('(%s) & (%s) & !(%s) & !(%s)', user_agent_mozilla, mozilla_msgid_common, mozilla_msgid, unusable_msgid) -reconf['FORGED_MUA_MOZILLA_MAIL_MSGID_UNKNOWN'] = string.format('(%s) & !(%s) & !(%s) & !(%s)', user_agent_mozilla, mozilla_msgid_common, mozilla_msgid, unusable_msgid) +reconf['FORGED_MUA_MOZILLA_MAIL_MSGID'] = { + re = string.format('(%s) & (%s) & !(%s) & !(%s)', user_agent_mozilla, mozilla_msgid_common, mozilla_msgid, unusable_msgid), + score = 4.0, + description = 'Message pretends to be send from Mozilla Mail but has forged Message-ID', + group = 'mua' +} +reconf['FORGED_MUA_MOZILLA_MAIL_MSGID_UNKNOWN'] = { + re = string.format('(%s) & !(%s) & !(%s) & !(%s)', user_agent_mozilla, mozilla_msgid_common, mozilla_msgid, unusable_msgid), + score = 2.5, + description = 'Message pretends to be send from Mozilla Mail but has forged Message-ID', + group = 'mua' +} + -- Summary rule for forged Thunderbird Message-ID header -reconf['FORGED_MUA_THUNDERBIRD_MSGID'] = string.format('(%s) & (%s) & !(%s) & !(%s)', user_agent_thunderbird, mozilla_msgid_common, mozilla_msgid, unusable_msgid) -reconf['FORGED_MUA_THUNDERBIRD_MSGID_UNKNOWN'] = string.format('(%s) & !((%s) | (%s)) & !(%s) & !(%s)', user_agent_thunderbird, mozilla_msgid_common, mozilla_msgid_common_sec, mozilla_msgid, unusable_msgid) +reconf['FORGED_MUA_THUNDERBIRD_MSGID'] = { + re = string.format('(%s) & (%s) & !(%s) & !(%s)', user_agent_thunderbird, mozilla_msgid_common, mozilla_msgid, unusable_msgid), + score = 4.0, + description = 'Forged mail pretending to be from Mozilla Thunderbird but has forged Message-ID', + group = 'mua' +} +reconf['FORGED_MUA_THUNDERBIRD_MSGID_UNKNOWN'] = { + re = string.format('(%s) & !((%s) | (%s)) & !(%s) & !(%s)', user_agent_thunderbird, mozilla_msgid_common, mozilla_msgid_common_sec, mozilla_msgid, unusable_msgid), + score = 2.5, + description = 'Forged mail pretending to be from Mozilla Thunderbird but has forged Message-ID', + group = 'mua' +} -- Summary rule for forged Seamonkey Message-ID header -reconf['FORGED_MUA_SEAMONKEY_MSGID'] = string.format('(%s) & (%s) & !(%s) & !(%s)', user_agent_seamonkey, mozilla_msgid_common, mozilla_msgid, unusable_msgid) -reconf['FORGED_MUA_SEAMONKEY_MSGID_UNKNOWN'] = string.format('(%s) & !(%s) & !(%s) & !(%s)', user_agent_seamonkey, mozilla_msgid_common, mozilla_msgid, unusable_msgid) +reconf['FORGED_MUA_SEAMONKEY_MSGID'] = { + re = string.format('(%s) & (%s) & !(%s) & !(%s)', user_agent_seamonkey, mozilla_msgid_common, mozilla_msgid, unusable_msgid), + score = 4.0, + description = 'Forged mail pretending to be from Mozilla Seamonkey but has forged Message-ID', + group = 'mua' +} +reconf['FORGED_MUA_SEAMONKEY_MSGID_UNKNOWN'] = { + re = string.format('(%s) & !(%s) & !(%s) & !(%s)', user_agent_seamonkey, mozilla_msgid_common, mozilla_msgid, unusable_msgid), + score = 2.5, + description = 'Forged mail pretending to be from Mozilla Seamonkey but has forged Message-ID', + group = 'mua' +} -- Message id validity local sane_msgid = 'Message-Id=/^\\\\ \\t\\n\\r\\x0b\\x80-\\xff]+\\@[^<>\\\\ \\t\\n\\r\\x0b\\x80-\\xff]+>?\\s*$/H' local msgid_comment = 'Message-Id=/\\(.*\\)/H' -reconf['INVALID_MSGID'] = string.format('(%s) & !((%s) | (%s))', has_mid, sane_msgid, msgid_comment) +reconf['INVALID_MSGID'] = { + re = string.format('(%s) & !((%s) | (%s))', has_mid, sane_msgid, msgid_comment), + score = 1.7, + description = 'Message id is incorrect', + group = 'header' +} -- Only Content-Type header without other MIME headers @@ -287,17 +490,32 @@ local cte = 'header_exists(Content-Transfer-Encoding)' local ct = 'header_exists(Content-Type)' local mime_version = 'raw_header_exists(MIME-Version)' local ct_text_plain = 'content_type_is_type(text) & content_type_is_subtype(plain)' -reconf['MIME_HEADER_CTYPE_ONLY'] = string.format('!(%s) & !(%s) & (%s) & !(%s) & !(%s)', cd, cte, ct, mime_version, ct_text_plain) +reconf['MIME_HEADER_CTYPE_ONLY'] = { + re = string.format('!(%s) & !(%s) & (%s) & !(%s) & !(%s)', cd, cte, ct, mime_version, ct_text_plain), + score = 2.0, + description = 'Only Content-Type header without other MIME headers', + group = 'header' +} -- Forged Exchange messages local msgid_dollars_ok = 'Message-Id=/[0-9a-f]{4,}\\$[0-9a-f]{4,}\\$[0-9a-f]{4,}\\@\\S+/H' local mimeole_ms = 'X-MimeOLE=/^Produced By Microsoft MimeOLE/H' local rcvd_with_exchange = 'Received=/with Microsoft Exchange Server/H' -reconf['RATWARE_MS_HASH'] = string.format('(%s) & !(%s) & !(%s)', msgid_dollars_ok, mimeole_ms, rcvd_with_exchange) +reconf['RATWARE_MS_HASH'] = { + re = string.format('(%s) & !(%s) & !(%s)', msgid_dollars_ok, mimeole_ms, rcvd_with_exchange), + score = 2.0, + description = 'Forged Exchange messages', + group = 'header' +} -- Reply-type in content-type -reconf['STOX_REPLY_TYPE'] = 'Content-Type=/text\\/plain; .* reply-type=original/H' +reconf['STOX_REPLY_TYPE'] = { + re = 'Content-Type=/text\\/plain; .* reply-type=original/H', + score = 1.0, + description = 'Reply-type in content-type', + group = 'header' +} -- Fake Verizon headers local fhelo_verizon = 'X-Spam-Relays-Untrusted=/^[^\\]]+ helo=[^ ]+verizon\\.net /iH' @@ -308,7 +526,12 @@ reconf['FM_FAKE_HELO_VERIZON'] = string.format('(%s) & !(%s)', fhelo_verizon, fh local at_yahoo_msgid = 'Message-Id=/\\@yahoo\\.com\\b/iH' local at_yahoogroups_msgid = 'Message-Id=/\\@yahoogroups\\.com\\b/iH' local from_yahoo_com = 'From=/\\@yahoo\\.com\\b/iH' -reconf['FORGED_MSGID_YAHOO'] = string.format('(%s) & !(%s)', at_yahoo_msgid, from_yahoo_com) +reconf['FORGED_MSGID_YAHOO'] = { + re = string.format('(%s) & !(%s)', at_yahoo_msgid, from_yahoo_com), + score = 2.0, + description = 'Forged yahoo msgid', + group = 'header' +} local r_from_yahoo_groups = 'From=/rambler.ru\\@returns\\.groups\\.yahoo\\.com\\b/iH' local r_from_yahoo_groups_ro = 'From=/ro.ru\\@returns\\.groups\\.yahoo\\.com\\b/iH' @@ -317,18 +540,33 @@ local thebat_mua_v1 = 'X-Mailer=/^The Bat! \\(v1\\./H' local ctype_has_boundary = 'Content-Type=/boundary/iH' local bat_boundary = 'Content-Type=/boundary=\\"?-{10}/H' local mailman_21 = 'X-Mailman-Version=/\\d/H' -reconf['FORGED_MUA_THEBAT_BOUN'] = string.format('(%s) & (%s) & !(%s) & !(%s)', thebat_mua_v1, ctype_has_boundary, bat_boundary, mailman_21) +reconf['FORGED_MUA_THEBAT_BOUN'] = { + re = string.format('(%s) & (%s) & !(%s) & !(%s)', thebat_mua_v1, ctype_has_boundary, bat_boundary, mailman_21), + score = 2.0, + description = 'Forged The Bat! MUA headers', + group = 'header' +} -- Two received headers with ip addresses local double_ip_spam_1 = 'Received=/from \\[\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\] by \\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3} with/H' local double_ip_spam_2 = 'Received=/from\\s+\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\s+by\\s+\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3};/H' -reconf['RCVD_DOUBLE_IP_SPAM'] = string.format('(%s) | (%s)', double_ip_spam_1, double_ip_spam_2) +reconf['RCVD_DOUBLE_IP_SPAM'] = { + re = string.format('(%s) | (%s)', double_ip_spam_1, double_ip_spam_2), + score = 2.0, + description = 'Two received headers with ip addresses', + group = 'header' +} -- Quoted reply-to from yahoo (seems to be forged) local repto_quote = 'Reply-To=/\\".*\\"\\s*\\