]> source.dussan.org Git - rspamd.git/commitdiff
[Rules] Add PDF related rules
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 27 Nov 2019 14:53:27 +0000 (14:53 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 27 Nov 2019 14:53:27 +0000 (14:53 +0000)
conf/groups.conf
conf/scores.d/content_group.conf [new file with mode: 0644]
rules/content.lua [new file with mode: 0644]
rules/rspamd.lua

index bf783cc2f2d8a63d97b16cb4ec8f2183bc905194..dcea1bcd00e4fa8d41ec28298e7b3a03653a17a8 100644 (file)
@@ -116,5 +116,11 @@ group "external_services" {
     .include(try=true; priority=10) "$LOCAL_CONFDIR/override.d/external_services_group.conf"
 }
 
+group "content" {
+    .include "$CONFDIR/scores.d/content_group.conf"
+    .include(try=true; priority=1; duplicate=merge) "$LOCAL_CONFDIR/local.d/content_group.conf"
+    .include(try=true; priority=10) "$LOCAL_CONFDIR/override.d/content_group.conf"
+}
+
 .include(try=true; priority=1; duplicate=merge) "$LOCAL_CONFDIR/local.d/groups.conf"
 .include(try=true; priority=10) "$LOCAL_CONFDIR/override.d/groups.conf"
diff --git a/conf/scores.d/content_group.conf b/conf/scores.d/content_group.conf
new file mode 100644 (file)
index 0000000..b53ec31
--- /dev/null
@@ -0,0 +1,37 @@
+# Content matching rules
+#
+# Please don't modify this file as your changes might be overwritten with
+# the next update.
+#
+# You can modify '$LOCAL_CONFDIR/rspamd.conf.local.override' to redefine
+# parameters defined on the top level
+#
+# You can modify '$LOCAL_CONFDIR/rspamd.conf.local' to add
+# parameters defined on the top level
+#
+# For specific modules or configuration you can also modify
+# '$LOCAL_CONFDIR/local.d/file.conf' - to add your options or rewrite defaults
+# '$LOCAL_CONFDIR/override.d/file.conf' - to override the defaults
+#
+# See https://rspamd.com/doc/tutorials/writing_rules.html for details
+
+description = "Content rules";
+
+symbols = {
+    "PDF_ENCRYPTED" {
+        weight = 0.3;
+        description = "There is an encrypted PDF in the message";
+        one_shot = true;
+    }
+    "PDF_JAVASCRIPT" {
+        weight = 0.1;
+        description = "There is an PDF with JavaScript in the message";
+        one_shot = true;
+    }
+    "PDF_SUSPICIOUS" {
+        weight = 4.5;
+        description = "There is an PDF with suspicious properties in the message";
+        one_shot = true;
+    }
+}
+
diff --git a/rules/content.lua b/rules/content.lua
new file mode 100644 (file)
index 0000000..718fd22
--- /dev/null
@@ -0,0 +1,88 @@
+--[[
+Copyright (c) 2019, Vsevolod Stakhov <vsevolod@highsecure.ru>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+]]--
+
+local function process_pdf_specific(task, part, specific)
+  local suspicious_factor = 0
+  if specific.encrypted then
+    task:insert_result('PDF_ENCRYPTED', 1.0, part:get_filename())
+    suspicious_factor = suspicious_factor + 0.1
+    if specific.openaction then
+      suspicious_factor = suspicious_factor + 0.5
+    end
+  end
+
+  if specific.javascript then
+    task:insert_result('PDF_JAVASCRIPT', 1.0, part:get_filename())
+    suspicious_factor = suspicious_factor + 0.1
+    if specific.openaction then
+      suspicious_factor = suspicious_factor + 0.5
+    end
+  end
+
+  if specific.suspicious then
+    suspicious_factor = suspicious_factor + 0.7
+  end
+
+  if suspicious_factor > 0.5 then
+    if suspicious_factor > 1.0 then suspicious_factor = 1.0 end
+    task:insert_result('PDF_SUSPICIOUS', suspicious_factor, part:get_filename())
+  end
+end
+
+local tags_processors = {
+  pdf = process_pdf_specific
+}
+
+local function process_specific_cb(task)
+  local parts = task:get_parts() or {}
+
+  for _,p in ipairs(parts) do
+    if p:is_specific() then
+      local data = p:get_specific()
+
+      if data and type(data) == 'table' and data.tag then
+        if tags_processors[data.tag] then
+          tags_processors[data.tag](task, p, data)
+        end
+      end
+    end
+  end
+end
+
+local id = rspamd_config:register_symbol{
+  type = 'callback',
+  name = 'SPECIFIC_CONTENT_CHECK',
+  callback = process_specific_cb
+}
+
+rspamd_config:register_symbol{
+  type = 'virtual',
+  name = 'PDF_ENCRYPTED',
+  parent = id,
+  groups = {"content", "pdf"},
+}
+rspamd_config:register_symbol{
+  type = 'virtual',
+  name = 'PDF_JAVASCRIPT',
+  parent = id,
+  groups = {"content", "pdf"},
+}
+rspamd_config:register_symbol{
+  type = 'virtual',
+  name = 'PDF_SUSPICIOUS',
+  parent = id,
+  groups = {"content", "pdf"},
+}
index e82eee4fa899e25462ab2f3a5d651b6fed8a4cc5..8ce90b0d0d134e31efd3cd5987979fc6fbfd2a70 100644 (file)
@@ -37,6 +37,7 @@ dofile(local_rules .. '/http_headers.lua')
 dofile(local_rules .. '/forwarding.lua')
 dofile(local_rules .. '/mid.lua')
 dofile(local_rules .. '/bitcoin.lua')
+dofile(local_rules .. '/content.lua')
 
 if rspamd_util.file_exists(local_conf .. '/rspamd.local.lua') then
   dofile(local_conf .. '/rspamd.local.lua')