Skip to content

Instantly share code, notes, and snippets.

@jult

jult/jbt-rules.cf

Last active Oct 13, 2020
Embed
What would you like to do?
SpamAssassin rules
# Put this file under /etc/spamassassin/ and run an sa-update or reload amavis etc.
#
# I used https://github.com/ercpe/ercpe-sa-rules/blob/master/ercpe-rules.cf as an example;
#--------------------------------------------------
# top level domain matching
#--------------------------------------------------
header SPAMMY_TLD_IN_RCVD Received =~ /(\.net\.ae|\.net\.id|\.ro|\.ru|\.co\.jp|\.co\.ke|\.AC\.ZA|\.co\.in|\.com\.vn|\.vn|\.cc|\.cu\.ua|\.com\.br|\.gr|\.hr|\.dk|\.win|\.bid|\.tw|\.br|\.pk|\.top|\.club|\.date|\.stream|\.xyz)\s/i
score SPAMMY_TLD_IN_RCVD 0.5
describe SPAMMY_TLD_IN_RCVD Spammy TLD used in Received line
header SPAMMY_TLD_IN_FROM From =~ /(\.net\.ae|\.net\.id|\.ro|\.ru|\.co\.jp|\.co\.ke|\.AC\.ZA|\.co\.in|\.com\.vn|\.vn|\.cc|\.cu\.ua|\.com\.br|\.gr|\.hr|\.dk|\.win|\.bid|\.tw|\.br|\.pk|\.top|\.club|\.date|\.stream|\.xyz)>$/i
score SPAMMY_TLD_IN_FROM 0.3
describe SPAMMY_TLD_IN_FROM Spammy TLD used in From line
header __HIGH_SPAMMY_TLD_RCVD Received =~ /\.(win|bid|top|club|date|stream|xyz)\/.*/i
header __HIGH_SPAMMY_TLD_FROM From =~ /\.(win|bid|top|club|date|stream|xyz)\/.*/i
uri __HIGH_SPAMMY_TLD_URI /\.(win|bid|top|club|date|stream|xyz)\/.+/i
meta HIGH_SPAMMY_TLD (__HIGH_SPAMMY_TLD_RCVD && __HIGH_SPAMMY_TLD_FROM && __HIGH_SPAMMY_TLD_URI)
score HIGH_SPAMMY_TLD 1.25
describe HIGH_SPAMMY_TLD HIGH spammy tld used in Received, From and link
#--------------------------------------------------
# Software matching
#--------------------------------------------------
header EVALED_PHP X-PHP-Originating-Script =~ /eval\(\)\'d code/i
score EVALED_PHP 0.75
describe EVALED_PHP Mail send from evaled PHP code
# outdated php version
header OUTDATED_PHP X-Mailer =~ /PHP v?5\.[1234].*/i
score OUTDATED_PHP 0.1
describe OUTDATED_PHP Mail send from an outdated PHP version
header X_MAILER_SENDEMAIL X-Mailer =~ /sendEmail/i
score X_MAILER_SENDEMAIL 0.2
header VULN_PHPMAILER X-Mailer =~ /PHPMailer 5\.2\.[0-9] /i
score VULN_PHPMAILER 0.75
describe VULN_PHPMAILER Mail was sent from a vulnerable version of PHPMailer
# Various meta rules to match wordpress
header __WP_X_PHP_ORIG_SCRIPT X-PHP-Originating-Script =~ /(post|gallery|user)\.php/i
header __WP_X_PHP_SCRIPT X-PHP-Script =~ /(post|gallery|user)\.php/i
header __WP_X_SOURCE X-Source =~ /php-cgi/i
header __WP_X_SOURCE_ARGS X-Source-Args =~ /(post|gallery|user)\.php/i
header __WP_PATH_X_SOURCE_ARGS X-Source-Args =~ /\/wp\-(content|includes)\//i
# Various meta rules to match joomla
# e.g. X-Source-Args: /usr/bin/php /home/joventa/public_html/OLD/components/com_contact/helpers/files.php
header __JO_COMP_X_SOURCE_ARGS X-Source-Args =~ /components\/com_/i
header __JO_X_SOURCE_ARGS X-Source-Args =~ /\/joomla\//i
meta CMS_MAIL ( __WP_X_PHP_ORIG_SCRIPT || __WP_X_PHP_SCRIPT || __WP_X_SOURCE || __WP_X_SOURCE_ARGS || __WP_PATH_X_SOURCE_ARGS || __JO_COMP_X_SOURCE_ARGS || __JO_X_SOURCE_ARGS )
score CMS_MAIL 1.25
describe CMS_MAIL Mail sent from a probably hacked CMS (like Wordpress or Joomla)
#--------------------------------------------------
# Header matching
#--------------------------------------------------
header X_ORG_REAL_CAPITAL X-Organization =~ /RealCapitalMarkets\.com/i
score X_ORG_REAL_CAPITAL 3.5
#--------------------------------------------------
# Subject matching
#--------------------------------------------------
header __SUBJECT_NEIGHBOR Subject =~ /Neighbou?r/i
header __SUBJECT_NEXT_DOOR Subject =~ /next door/i
meta SUBJECT_NEIGHBOUR (__SUBJECT_NEIGHBOR || __SUBJECT_NEXT_DOOR)
score SUBJECT_NEIGHBOUR 0.5
header __SUBJECT_VIAGRA Subject =~ /viagra/i
header __SUBJECT_PILLS Subject =~ /pills/i
header __SUBJECT_HEALTH_SECRET Subject =~ /health secret/i
meta SUBJECT_HEALTH (__SUBJECT_VIAGRA || __SUBJECT_PILLS || __SUBJECT_HEALTH_SECRET)
score SUBJECT_HEALTH 0.2
describe SUBJECT_HEALTH health-related subject
header SUBJECT_DARLEHEN Subject =~ /Darlehen Angebot jetzt bewerben/i
score SUBJECT_DARLEHEN 1.0
header __FROM_DAVIS_WRIGHT From =~ /Davis Wright/i
header __SUBJECT_LEG_DARLEHEN Subject =~ /Legitimes Darlehen Angebot/i
meta DAVIS_WRIGHT_DARLEHEN (__FROM_DAVIS_WRIGHT && __SUBJECT_LEG_DARLEHEN)
score DAVIS_WRIGHT_DARLEHEN 1.5
header __FROM_KEVIN_PAGE From =~ /Kevin Page/i
meta KEVIN_PAGE_DARLEHEN (__FROM_KEVIN_PAGE && SUBJECT_DARLEHEN)
score KEVIN_PAGE_DARLEHEN 1.2
# "Domain Expiration SEO" spam
header __SUBJECT_EXP_SEO Subject =~ /Expiration SEO/i
header __FROM_EXP_SEO From =~ /(Domain Expiration SEO|Final Reminder)/i
meta EXPIRATION_SEO (__SUBJECT_EXP_SEO && __FROM_EXP_SEO)
score EXPIRATION_SEO 0.6
describe EXPIRATION_SEO Variation of Domain SEO spam
# "SEO issue" spam
header __SUBJECT_SEO_ISSUE Subject =~ /SEO Issue/i
body __BODY_SEO_ISSUE /\s+(Search Specialist|Hello Team)/i
meta SEO_ISSUE (__SUBJECT_SEO_ISSUE && __BODY_SEO_ISSUE)
score SEO_ISSUE 1.0
describe SEO_ISSUE Variation of Domain SEO spam
# Domain Alert
header __SUBJECT_DOMAIN_ALERT Subject =~ /This is your Final (Reminder|Notice)/i
header __FROM_DOMAIN_ALERT From =~ /(Internet Services|Domain Notice)/i
body __BODY_DOMAIN_ALERT /\s+search engine registration/i
meta DOMAIN_ALERT (__SUBJECT_DOMAIN_ALERT && __FROM_DOMAIN_ALERT && __BODY_DOMAIN_ALERT)
score DOMAIN_ALERT 0.9
describe DOMAIN_ALERT Variations of search engine registration spam
header __FROM_BITCOIN_CODE From =~ /bestofmesh.com/i
uri __BITCOIN_CODE_LINK /track.bestofmesh.com.*/i
meta BITCOIN_CODE (__FROM_BITCOIN_CODE && __FROM_BITCOIN_CODE)
score BITCOIN_CODE 0.6
#--------------------------------------------------
# uri matching
#--------------------------------------------------
# Something like .... /plugin.php?t=147&SeBJYnc8AzD8YLd4kvf4uNR=Fqz&12i=Cwb&4f=cL4g
# the common parts are:
# - the first parameter name is one char long
# - at least two more parameter follow
uri SPAM_LINK_1 /\/[a-z]+\.php\?\w=[a-zA-Z0-9]+(&[\w\d]+=[a-zA-Z0-9]+){2,}/i
score SPAM_LINK_1 0.4
describe SPAM_LINK_1 Spam link
# same as above but focused on the link title
rawbody SPAM_LINK_2 /\>.*(profile is here|new photos|photos are here).*\<\/a\>/i
score SPAM_LINK_2 0.4
describe SPAM_LINK_2 Spam link title
# Something like ..../l/lt2K2240EH14R/1014LP2140G4657WU60A33287012SM1334722588
# Common parts:
# - first part is always one character
# - three parts in total
uri SPAM_LINK_3 /\/\w\/\w{10,}\/\w{10,}/i
score SPAM_LINK_3 0.4
describe SPAM_LINK_3 Spam link
# /pass.php?utm_source=6900l3njtv&utm_medium=nc6600mc98&utm_campaign=a1q4sxq0wo&utm_term=tvec4xo652&utm_content=403g22e07g
# Common parts
# - always a .php file in the root of the domain
# - only GA tracking parameters
# - values for utm_source, utm_medium and utm_campaign are always the same (at least between 2017-07 and 2017-10),
# utm_term varies slightly and utm_content is random
# - all tracking parameters have 10 chars
uri SPAM_LINK_4 /\/[a-z]+\.php\?utm_source=[a-zA-Z0-9]{10}&utm_medium=[a-zA-Z0-9]{10}&utm_campaign=[a-zA-Z0-9]{10}&utm_term=[a-zA-Z0-9]{10}&utm_content=[a-zA-Z0-9]{10}/i
score SPAM_LINK_4 0.4
describe SPAM_LINK_4 Spam link
uri SPAM_LINK_4_EXTRA /\/[a-z]+\.php\?utm_source=6900l3njtv&utm_medium=nc6600mc98&utm_campaign=a1q4sxq0wo&utm_term=[a-zA-Z0-9]{10}&utm_content=[a-zA-Z0-9]{10}/i
score SPAM_LINK_4_EXTRA 0.4
describe SPAM_LINK_4_EXTRA Spam link (extra score)
#--------------------------------------------------
# Mime matching
#--------------------------------------------------
mimeheader DOC_ATTACHED Content-Disposition =~ /filename\=.*\.docx?/i
score DOC_ATTACHED 1.0
describe DOC_ATTACHED Contains .doc or .docx attachment
mimeheader XLS_ATTACHED Content-Disposition =~ /filename\=.*\.xlsx?/i
score XLS_ATTACHED 1.0
describe XLS_ATTACHED Contains .xls or .xlsx attachment
mimeheader __ZIP_ATTACHED Content-Disposition =~ /filename\=.*\.zip/i
describe __ZIP_ATTACHED Contains .zip attachment
#--------------------------------------------------
# Text matching (lowered impact to avoid false pos)
#--------------------------------------------------
header __SUBJECT_FUCK Subject =~ /f[ua5\&\%]ck/i
body __BODY_FUCK /\s+(fuck|sex|masturbate|anal|fist)\s+/i
meta FUCKED_MAIL (__SUBJECT_FUCK || __BODY_FUCK )
score FUCKED_MAIL 0.3
describe FUCKED_MAIL Contains variations of 'fuck' in the subject and/or body
header __SUBJECT_FAX_RECEIVED Subject =~ /You have 1 new fax, document/i
header __SUBJECT_FAX_RECEIVED2 Subject =~ /You have received a new fax, document /i
meta FAX_RECEIVED ((__SUBJECT_FAX_RECEIVED || __SUBJECT_FAX_RECEIVED2) && __ZIP_ATTACHED)
score FAX_RECEIVED 1.1
body __BODY_VIAGRA /viagra/i
body __BODY_PILLS /pills/i
body __BODY_HEALTH_SECRET /health secret/i
meta BODY_HEALTH (__BODY_VIAGRA || __BODY_PILLS || __BODY_HEALTH_SECRET)
score BODY_HEALTH 0.2
describe BODY_HEALTH health-related body text
#--------------------------------------------------
# RBL using softened mailspike scores
#--------------------------------------------------
# Obvious spam sources
header __RCVD_IN_MSPIKE eval:check_rbl('mspike-lastexternal','bl.mailspike.net')
tflags __RCVD_IN_MSPIKE net noautolearn
# Bad senders
header __RCVD_IN_MSPIKE_Z eval:check_rbl_sub('mspike-lastexternal', '^127\.0\.0\.2$')
describe __RCVD_IN_MSPIKE_Z Spam wave participant
tflags __RCVD_IN_MSPIKE_Z net noautolearn
header RCVD_IN_MSPIKE_L5 eval:check_rbl_sub('mspike-lastexternal', '^127\.0\.0\.10$')
describe RCVD_IN_MSPIKE_L5 Very bad reputation (-5)
tflags RCVD_IN_MSPIKE_L5 net
header RCVD_IN_MSPIKE_L4 eval:check_rbl_sub('mspike-lastexternal', '^127\.0\.0\.11$')
describe RCVD_IN_MSPIKE_L4 Bad reputation (-4)
tflags RCVD_IN_MSPIKE_L4 net
header RCVD_IN_MSPIKE_L3 eval:check_rbl_sub('mspike-lastexternal', '^127\.0\.0\.12$')
describe RCVD_IN_MSPIKE_L3 Low reputation (-3)
tflags RCVD_IN_MSPIKE_L3 net noautolearn
header RCVD_IN_MSPIKE_L2 eval:check_rbl_sub('mspike-lastexternal', '^127\.0\.0\.13$')
describe RCVD_IN_MSPIKE_L2 Suspicious reputation (-2)
tflags RCVD_IN_MSPIKE_L2 net noautolearn
# Good senders
header RCVD_IN_MSPIKE_H5 eval:check_rbl_sub('mspikeg-firsttrusted', '^127\.0\.0\.20$')
describe RCVD_IN_MSPIKE_H5 Excellent reputation (+5)
tflags RCVD_IN_MSPIKE_H5 nice net
header RCVD_IN_MSPIKE_H4 eval:check_rbl_sub('mspikeg-firsttrusted', '^127\.0\.0\.19$')
describe RCVD_IN_MSPIKE_H4 Very Good reputation (+4)
tflags RCVD_IN_MSPIKE_H4 nice net
header RCVD_IN_MSPIKE_H3 eval:check_rbl_sub('mspikeg-firsttrusted', '^127\.0\.0\.18$')
describe RCVD_IN_MSPIKE_H3 Good reputation (+3)
tflags RCVD_IN_MSPIKE_H3 nice net
header RCVD_IN_MSPIKE_H2 eval:check_rbl_sub('mspikeg-firsttrusted', '^127\.0\.0\.17$')
describe RCVD_IN_MSPIKE_H2 Average reputation (+2)
tflags RCVD_IN_MSPIKE_H2 nice net noautolearn
# *_L and *_Z may overlap, so account for that
meta __RCVD_IN_MSPIKE_LOW RCVD_IN_MSPIKE_L5 || RCVD_IN_MSPIKE_L4 || RCVD_IN_MSPIKE_L3 || RCVD_IN_MSPIKE_L2
meta RCVD_IN_MSPIKE_ZBI __RCVD_IN_MSPIKE_Z && !__RCVD_IN_MSPIKE_LOW
# Scores (lowered impact to avoid false positives)
score RCVD_IN_MSPIKE_ZBI 4.1
score RCVD_IN_MSPIKE_L5 4.8
score RCVD_IN_MSPIKE_L4 3.9
score RCVD_IN_MSPIKE_L3 3.6
score RCVD_IN_MSPIKE_L2 0.6
score RCVD_IN_MSPIKE_H2 -0.3
score RCVD_IN_MSPIKE_H3 -1.3
score RCVD_IN_MSPIKE_H4 -2.3
score RCVD_IN_MSPIKE_H5 -3.3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.