]> source.dussan.org Git - rspamd.git/commitdiff
Add compromised_host rules
authorSteve Freegard <steve@stevefreegard.com>
Wed, 9 Nov 2016 23:04:18 +0000 (23:04 +0000)
committerSteve Freegard <steve@stevefreegard.com>
Wed, 9 Nov 2016 23:04:18 +0000 (23:04 +0000)
rules/regexp/compromised_hosts.lua [new file with mode: 0644]
rules/rspamd.lua

diff --git a/rules/regexp/compromised_hosts.lua b/rules/regexp/compromised_hosts.lua
new file mode 100644 (file)
index 0000000..e5b4836
--- /dev/null
@@ -0,0 +1,190 @@
+local reconf = config['regexp']
+local rspamd_regexp = require 'rspamd_regexp'
+
+reconf['HAS_PHPMAILER_SIG'] = {
+  re = "X-Mailer=/^PHPMailer/Hi || Content-Type=/boundary=\"b[123]_/Hi",
+  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 = 2.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"
+}
+
+-- 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"
+}
+
+-- 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['PHP_EVALD_CODE'] = {
+  re = "X-PHP-Script=/eval\\(\\)\\'d/Hi || X-PHP-Originating-Script=/eval\\(\\)\\'d/Hi",
+  description = "Message sent using eval'd PHP",
+  score = 5.0,
+  group = "compromised_hosts"
+}
+
+reconf['HAS_WP_URI'] = {
+  re = '/\\/wp-[^\\/]+\\//Ui',
+  description = "Contains WordPress URIs",
+  group = "compromised_hosts"
+}
+
+reconf['WP_COMPROMISED'] = {
+  re = '/\\/wp-(?!content|includes)[^\\/]+\\//Ui',
+  description = "URL that is pointing to a compromised WordPress installation",
+  score = 5.0,
+  group = "compromised_hosts"
+}
+
+reconf['PHP_XPS_PATTERN'] = {
+  re = 'X-PHP-Script=/^[^\\. ]+\.[^\\.\\/ ]+\\/sendmail\\.php\\b/Hi',
+  description = "Message contains X-PHP-Script pattern",
+  score = 5.0,
+  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"
+}
+
+reconf['URI_HIDDEN_PATH'] = {
+  re = "/\\/\\..+/U",
+  description = "URL contains a UNIX hidden file/directory",
+  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)
+      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)
+      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"
+}
+
index a3cdc919be8b23417f46dd414dd99e4b5b6ea41e..086f814971876c438d27f633f3f0e03abf2318d0 100644 (file)
@@ -29,6 +29,7 @@ dofile(local_rules .. '/regexp/lotto.lua')
 dofile(local_rules .. '/regexp/fraud.lua')
 dofile(local_rules .. '/regexp/drugs.lua')
 dofile(local_rules .. '/regexp/upstream_spam_filters.lua')
+dofile(local_rules .. '/regexp/compromised_hosts.lua')
 dofile(local_rules .. '/html.lua')
 dofile(local_rules .. '/misc.lua')
 dofile(local_rules .. '/http_headers.lua')