mirror of
https://github.com/rspamd/rspamd.git
synced 2024-09-13 15:45:47 +02:00
0248bd6615
Remove /i flag from regexp string "eval()'d code" is always in lower case. While here use long string format for readability.
215 lines
6.9 KiB
Lua
215 lines
6.9 KiB
Lua
local reconf = config['regexp']
|
|
local rspamd_regexp = require 'rspamd_regexp'
|
|
local util = require 'rspamd_util'
|
|
|
|
reconf['HAS_PHPMAILER_SIG'] = {
|
|
-- PHPMailer 6.0.0 and older used hex hash in boundary:
|
|
-- boundary="b1_2a45d5e29f78d3408e318878b049f474"
|
|
-- Since 6.0.1 it uses base64 (without =+/):
|
|
-- boundary="b1_uBN0UPD3n6RU04VPxI54tENiDgaCGoh15l9s73oFnlM"
|
|
-- boundary="b1_Ez5tmpb4bSqknyUZ1B1hIvLAfR1MlspDEKGioCOXc"
|
|
-- https://github.com/PHPMailer/PHPMailer/blob/v6.4.0/src/PHPMailer.php#L2660
|
|
re = [[X-Mailer=/^PHPMailer /H || Content-Type=/boundary="b1_[0-9a-zA-Z]+"/H]],
|
|
description = "PHPMailer signature",
|
|
group = "compromised_hosts"
|
|
}
|
|
|
|
reconf['PHP_SCRIPT_ROOT'] = {
|
|
re = "X-PHP-Originating-Script=/^0:/Hi",
|
|
description = "PHP Script executed by root UID",
|
|
score = 1.0,
|
|
group = "compromised_hosts"
|
|
}
|
|
|
|
reconf['HAS_X_POS'] = {
|
|
re = "header_exists('X-PHP-Originating-Script')",
|
|
description = "Has X-PHP-Originating-Script header",
|
|
group = "compromised_hosts"
|
|
}
|
|
|
|
reconf['HAS_X_PHP_SCRIPT'] = {
|
|
re = "header_exists('X-PHP-Script')",
|
|
description = "Has X-PHP-Script header",
|
|
group = "compromised_hosts"
|
|
}
|
|
|
|
-- X-Source:
|
|
-- X-Source-Args: /usr/sbin/proxyexec -q -d -s /var/run/proxyexec/cagefs.sock/socket /bin/cagefs.server
|
|
-- X-Source-Dir: silvianimberg.com:/public_html/wp-content/themes/ultimatum
|
|
reconf['HAS_X_SOURCE'] = {
|
|
re = "header_exists('X-Source') || header_exists('X-Source-Args') || header_exists('X-Source-Dir')",
|
|
description = "Has X-Source headers",
|
|
group = "compromised_hosts"
|
|
}
|
|
|
|
-- X-Authenticated-Sender: accord.host-care.com: sales@cortaflex.si
|
|
rspamd_config.HAS_X_AS = {
|
|
callback = function (task)
|
|
local xas = task:get_header('X-Authenticated-Sender')
|
|
if not xas then return false end
|
|
local _,_,auth = xas:find('[^:]+:%s(.+)$')
|
|
if auth then
|
|
-- TODO: see if we can parse an e-mail address from auth
|
|
-- and see if it matches the from address or not
|
|
return true, auth
|
|
else
|
|
return true
|
|
end
|
|
end,
|
|
description = 'Has X-Authenticated-Sender header',
|
|
group = "compromised_hosts",
|
|
score = 0.0
|
|
}
|
|
|
|
-- X-Get-Message-Sender-Via: accord.host-care.com: authenticated_id: sales@cortaflex.si
|
|
rspamd_config.HAS_X_GMSV = {
|
|
callback = function (task)
|
|
local xgmsv = task:get_header('X-Get-Message-Sender-Via')
|
|
if not xgmsv then return false end
|
|
local _,_,auth = xgmsv:find('authenticated_id: (.+)$')
|
|
if auth then
|
|
-- TODO: see if we can parse an e-mail address from auth
|
|
-- and see if it matches the from address or not.
|
|
return true, auth
|
|
else
|
|
return true
|
|
end
|
|
end,
|
|
description = 'Has X-Get-Message-Sender-Via: header',
|
|
group = "compromised_hosts",
|
|
score = 0.0,
|
|
}
|
|
|
|
-- X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
|
|
-- X-AntiAbuse: Primary Hostname - accord.host-care.com
|
|
-- X-AntiAbuse: Original Domain - swaney.com
|
|
-- X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
|
|
-- X-AntiAbuse: Sender Address Domain - dropbox.com
|
|
reconf['HAS_X_ANTIABUSE'] = {
|
|
re = "header_exists('X-AntiAbuse')",
|
|
description = "Has X-AntiAbuse headers",
|
|
group = "compromised_hosts"
|
|
}
|
|
|
|
reconf['X_PHP_EVAL'] = {
|
|
re = [[X-PHP-Script=/eval\(\)'d code/H || X-PHP-Originating-Script=/eval\(\)'d code/H]],
|
|
description = "Message sent using eval'd PHP",
|
|
score = 4.0,
|
|
group = "compromised_hosts"
|
|
}
|
|
|
|
reconf['HAS_WP_URI'] = {
|
|
re = '/\\/wp-[^\\/]+\\//Ui',
|
|
description = "Contains WordPress URIs",
|
|
one_shot = true,
|
|
group = "compromised_hosts"
|
|
}
|
|
|
|
reconf['WP_COMPROMISED'] = {
|
|
re = '/\\/wp-(?:content|includes)[^\\/]+\\//Ui',
|
|
description = "URL that is pointing to a compromised WordPress installation",
|
|
one_shot = true,
|
|
group = "compromised_hosts"
|
|
}
|
|
|
|
reconf['PHP_XPS_PATTERN'] = {
|
|
re = 'X-PHP-Script=/^[^\\. ]+\\.[^\\.\\/ ]+\\/sendmail\\.php\\b/Hi',
|
|
description = "Message contains X-PHP-Script pattern",
|
|
group = "compromised_hosts"
|
|
}
|
|
|
|
reconf['HAS_XAW'] = {
|
|
re = "header_exists('X-Authentication-Warning')",
|
|
description = "Has X-Authentication-Warning header",
|
|
group = "compromised_hosts"
|
|
}
|
|
|
|
-- X-Authentication-Warning: localhost.localdomain: www-data set sender to info@globalstock.lv using -f
|
|
reconf['XAW_SERVICE_ACCT'] = {
|
|
re = "X-Authentication-Warning=/\\b(?:www-data|anonymous|ftp|apache|nobody|guest|nginx|web|www) set sender to\\b/Hi",
|
|
description = "Message originally from a service account",
|
|
score = 1.0,
|
|
group = "compromised_hosts"
|
|
}
|
|
|
|
reconf['ENVFROM_SERVICE_ACCT'] = {
|
|
re = "check_smtp_data('from',/^(?:www-data|anonymous|ftp|apache|nobody|guest|nginx|web|www)@/i)",
|
|
description = "Envelope from is a service account",
|
|
score = 1.0,
|
|
group = "compromised_hosts"
|
|
}
|
|
|
|
reconf['HIDDEN_SOURCE_OBJ'] = {
|
|
re = "X-PHP-Script=/\\/\\..+/Hi || X-PHP-Originating-Script=/(?:^\\d+:|\\/)\\..+/Hi || X-Source-Args=/\\/\\..+/Hi",
|
|
description = "UNIX hidden file/directory in path",
|
|
score = 2.0,
|
|
group = "compromised_hosts"
|
|
}
|
|
|
|
local hidden_uri_re = rspamd_regexp.create_cached('/(?!\\/\\.well[-_]known\\/)(?:^\\.[A-Za-z0-9]|\\/'..
|
|
'\\.[A-Za-z0-9]|\\/\\.\\.\\/)/i')
|
|
rspamd_config.URI_HIDDEN_PATH = {
|
|
callback = function (task)
|
|
local urls = task:get_urls(false)
|
|
if (urls) then
|
|
for _, url in ipairs(urls) do
|
|
if (not (url:is_subject() and url:is_html_displayed())) then
|
|
local path = url:get_path()
|
|
if (hidden_uri_re:match(path)) then
|
|
-- TODO: need url:is_schemeless() to improve this
|
|
return true, 1.0, url:get_text()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
description = 'Message contains URI with a hidden path',
|
|
score = 1.0,
|
|
group = 'compromised_hosts',
|
|
}
|
|
|
|
reconf['MID_RHS_WWW'] = {
|
|
re = "Message-Id=/@www\\./Hi",
|
|
description = "Message-ID from www host",
|
|
score = 0.5,
|
|
group = "compromised_hosts"
|
|
}
|
|
|
|
rspamd_config.FROM_SERVICE_ACCT = {
|
|
callback = function (task)
|
|
local re = rspamd_regexp.create_cached('/^(?:www-data|anonymous|ftp|apache|nobody|guest|nginx|web|www)@/i');
|
|
-- From
|
|
local from = task:get_from(2)
|
|
if (from and from[1]) then
|
|
if (re:match(from[1].addr)) then return true end
|
|
end
|
|
-- Sender
|
|
local sender = task:get_header('Sender')
|
|
if sender then
|
|
local s = util.parse_mail_address(sender, task:get_mempool())
|
|
if (s and s[1]) then
|
|
if (re:match(s[1].addr)) then return true end
|
|
end
|
|
end
|
|
-- Reply-To
|
|
local replyto = task:get_header('Reply-To')
|
|
if replyto then
|
|
local rt = util.parse_mail_address(replyto, task:get_mempool())
|
|
if (rt and rt[1]) then
|
|
if (re:match(rt[1].addr)) then return true end
|
|
end
|
|
end
|
|
end,
|
|
description = "Sender/From/Reply-To is a service account",
|
|
score = 1.0,
|
|
group = "compromised_hosts"
|
|
}
|
|
|
|
reconf['WWW_DOT_DOMAIN'] = {
|
|
re = "From=/@www\\./Hi || Sender=/@www\\./Hi || Reply-To=/@www\\./Hi || check_smtp_data('from',/@www\\./i)",
|
|
description = "From/Sender/Reply-To or Envelope is @www.domain.com",
|
|
score = 0.5,
|
|
group = "compromised_hosts"
|
|
}
|
|
|