aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Lewis <nerf@judo.za.org>2024-05-27 12:05:53 +0200
committerAndrew Lewis <nerf@judo.za.org>2024-05-27 12:05:53 +0200
commit93b8af4f62ef8361864049e042dcf257371ec859 (patch)
tree543da4e08f3c21e0d83bced402735a5fd0ce16cb
parent08990def9860c586d9d9ec5a4e9865e3a9747aa4 (diff)
downloadrspamd-93b8af4f62ef8361864049e042dcf257371ec859.tar.gz
rspamd-93b8af4f62ef8361864049e042dcf257371ec859.zip
[Rules] Added rules for detecting likely malware
-rw-r--r--conf/maps.d/exe_clickbait.inc15
-rw-r--r--rules/archives.lua156
-rw-r--r--rules/rspamd.lua1
3 files changed, 172 insertions, 0 deletions
diff --git a/conf/maps.d/exe_clickbait.inc b/conf/maps.d/exe_clickbait.inc
new file mode 100644
index 000000000..b980ad79f
--- /dev/null
+++ b/conf/maps.d/exe_clickbait.inc
@@ -0,0 +1,15 @@
+/\badvice\b/i
+/\badvisory\b/i
+/\baviso\b/i
+/\bdocuments?\b/i
+/\bcontract\b/i
+/\bjustificante pago\b/i
+/\bnotice\b/
+/\borden de litigio\b/i
+/\border\b/i
+/\bpago\b/i
+/\bpayments?\b/i
+/\bRFQ\b/
+/\bshipment\b/
+/\bshipping\b/
+/\bquotation\b/i
diff --git a/rules/archives.lua b/rules/archives.lua
new file mode 100644
index 000000000..83ac27df8
--- /dev/null
+++ b/rules/archives.lua
@@ -0,0 +1,156 @@
+local rspamd_regexp = require "rspamd_regexp"
+local lua_maps = require "lua_maps"
+
+local clickbait_map = lua_maps.map_add_from_ucl(
+ {
+ string.format('%s/maps.d/%s', rspamd_paths.CONFDIR, 'exe_clickbait.inc'),
+ string.format('%s/local.d/maps.d/%s', rspamd_paths.LOCAL_CONFDIR, 'exe_clickbait.inc')
+ },
+ 'regexp',
+ 'Inappropriate descriptions for executables'
+)
+
+local exe_re = rspamd_regexp.create_cached([[/\.exe$|\.com$/i]])
+local img_re = rspamd_regexp.create_cached([[/\.img$/i]])
+local rar_re = rspamd_regexp.create_cached([[/\.rar$|\.r[0-9]{2}$/i]])
+
+local id = rspamd_config:register_symbol{
+ callback = function(task)
+ local num_checked = 0
+ local have_subject_clickbait = false
+
+ if clickbait_map:get_key(task:get_subject()) then
+ have_subject_clickbait = true
+ end
+
+ for _, p in ipairs(task:get_parts()) do
+ local clickbait, exe, misidentified_rar = false, false, false
+
+ if p:is_archive() then
+ num_checked = num_checked + 1
+ local arc = p:get_archive()
+ local fn = p:get_filename()
+
+ if clickbait_map:get_key(fn) ~= false then
+ clickbait = true
+ end
+
+ if arc:get_type() == 'rar' then
+ if fn then
+ if not rar_re:match(fn) then
+ task:insert_result('MISIDENTIFIED_RAR', 1.0)
+ misidentified_rar = true
+ end
+ end
+ end
+
+ local files = arc:get_files_full()
+ local max_check = math.min(#files, 10)
+
+ for i = 1, max_check do
+ local info = files[i]
+ local name = info.name
+
+ if img_re:match(name) then
+ local ratio = info.uncompressed_size/info.compressed_size
+ if ratio >= 500 then
+ task:insert_result('UDF_COMPRESSION_500PLUS', 1.0)
+ end
+ elseif exe_re:match(name) then
+ exe = true
+ task:insert_result('EXE_IN_ARCHIVE', 1.0)
+ if misidentified_rar then
+ task:insert_result('EXE_IN_MISIDENTIFIED_RAR', 1.0)
+ end
+ if clickbait then
+ task:insert_result('EXE_ARCHIVE_CLICKBAIT_FILENAME', 1.0)
+ elseif have_subject_clickbait then
+ task:insert_result('EXE_ARCHIVE_CLICKBAIT_SUBJECT', 1.0)
+ end
+ end
+ end
+
+ if exe then
+ if #files == 1 then
+ task:insert_result('SINGLE_FILE_ARCHIVE_WITH_EXE', 1.0)
+ end
+ end
+
+ if num_checked >= 10 then
+ return
+ end
+ end
+ end
+ end,
+ name = 'CHECK_ARCHIVES',
+ type = 'callback',
+}
+
+rspamd_config:register_symbol{
+ description = 'exe file in archive with clickbait filename',
+ group = 'malware',
+ name = 'EXE_ARCHIVE_CLICKBAIT_FILENAME',
+ one_shot = true,
+ parent = id,
+ score = 9.0,
+ type = 'virtual',
+}
+
+rspamd_config:register_symbol{
+ description = 'exe file in archive with clickbait subject',
+ group = 'malware',
+ name = 'EXE_ARCHIVE_CLICKBAIT_SUBJECT',
+ one_shot = true,
+ parent = id,
+ score = 9.0,
+ type = 'virtual',
+}
+
+rspamd_config:register_symbol{
+ description = 'exe file in archive',
+ group = 'malware',
+ name = 'EXE_IN_ARCHIVE',
+ one_shot = true,
+ parent = id,
+ score = 0.5,
+ type = 'virtual',
+}
+
+rspamd_config:register_symbol{
+ description = 'rar with wrong extension containing exe file',
+ group = 'malware',
+ name = 'EXE_IN_MISIDENTIFIED_RAR',
+ one_shot = true,
+ parent = id,
+ score = 2.0,
+ type = 'virtual',
+}
+
+rspamd_config:register_symbol{
+ description = 'rar with wrong extension',
+ group = 'malware',
+ name = 'MISIDENTIFIED_RAR',
+ one_shot = true,
+ parent = id,
+ score = 2.0,
+ type = 'virtual',
+}
+
+rspamd_config:register_symbol{
+ description = 'single file container bearing executable',
+ group = 'malware',
+ name = 'SINGLE_FILE_ARCHIVE_WITH_EXE',
+ one_shot = true,
+ parent = id,
+ score = 1.0,
+ type = 'virtual',
+}
+
+rspamd_config:register_symbol{
+ description = 'very well compressed img file in archive',
+ name = 'UDF_COMPRESSION_500PLUS',
+ one_shot = true,
+ parent = id,
+ score = 9.0,
+ type = 'virtual',
+}
diff --git a/rules/rspamd.lua b/rules/rspamd.lua
index 6b2c1a51c..dcc872d15 100644
--- a/rules/rspamd.lua
+++ b/rules/rspamd.lua
@@ -25,6 +25,7 @@ local local_conf = rspamd_paths['LOCAL_CONFDIR']
local local_rules = rspamd_paths['RULESDIR']
local rspamd_util = require "rspamd_util"
+dofile(local_rules .. '/archives.lua')
dofile(local_rules .. '/regexp/headers.lua')
dofile(local_rules .. '/regexp/misc.lua')
dofile(local_rules .. '/regexp/upstream_spam_filters.lua')