]> source.dussan.org Git - rspamd.git/commitdiff
[Rules] Add dedicated bitcoin addresses filter rule
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 18 Jun 2019 11:46:34 +0000 (12:46 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 18 Jun 2019 11:46:34 +0000 (12:46 +0100)
rules/bitcoin.lua [new file with mode: 0644]
rules/misc.lua
rules/rspamd.lua
src/lua/lua_mimepart.c

diff --git a/rules/bitcoin.lua b/rules/bitcoin.lua
new file mode 100644 (file)
index 0000000..df6fed2
--- /dev/null
@@ -0,0 +1,86 @@
+--[[
+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.
+]]--
+
+-- Bitcoin filter rules
+
+local fun = require "fun"
+local off = 0
+local base58_dec = fun.tomap(fun.map(
+    function(c)
+      off = off + 1
+      return c,(off - 1)
+    end,
+    "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"))
+
+rspamd_config:register_symbol{
+  name = 'BITCOIN_ADDR',
+  callback = function(task)
+    local rspamd_re = require "rspamd_regexp"
+    local hash = require "rspamd_cryptobox_hash"
+
+    local wallet_re = rspamd_re.create_cached('^[13][1-9A-Za-z]{25,34}$')
+    local words_matched = {}
+    local valid_wallets = {}
+
+    for _,part in ipairs(task:get_text_parts() or {}) do
+      local pw = part:filter_words(wallet_re, 'raw', 3)
+
+      if pw and #pw > 0 then
+        for _,w in ipairs(pw) do
+          words_matched[#words_matched + 1] = w
+        end
+      end
+    end
+
+    for _,word in ipairs(words_matched) do
+      local bytes = {}
+      for i=1,25 do bytes[i] = 0 end
+      -- Base58 decode loop
+      fun.each(function(ch)
+        local acc = base58_dec[ch] or 0
+        for i=25,1,-1 do
+          acc = acc + (58 * bytes[i]);
+          bytes[i] = acc % 256
+          acc = math.floor(acc / 256);
+        end
+      end, word)
+      -- Now create a validation tag
+      local sha256 = hash.create_specific('sha256')
+      for i=1,21 do
+        sha256:update(string.char(bytes[i]))
+      end
+      sha256 = hash.create_specific('sha256', sha256:bin()):bin()
+
+      -- Compare tags
+      local valid = true
+      for i=1,4 do
+        if string.sub(sha256, i, i) ~= string.char(bytes[21 + i]) then
+          valid = false
+        end
+      end
+
+      if valid then
+        valid_wallets[#valid_wallets + 1] = word
+      end
+    end
+
+    if #valid_wallets > 0 then
+      return true,1.0,valid_wallets
+    end
+  end,
+  score = 0.0,
+  group = 'scams'
+}
\ No newline at end of file
index a01b8ecd1947e083a4634826ac1a43ece01b3ed1..7d36822715d5beae847e32b3aca2c7166133670a 100644 (file)
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 ]]--
 
--- This is main lua config file for rspamd
+-- Misc rules
 
 local E = {}
 local fun = require "fun"
index 646dc5afd44412b9e6a54790e9578142f3d60410..50b1aadf1d1ae760034767d57c59d8aad2e4f2fe 100644 (file)
@@ -36,6 +36,7 @@ dofile(local_rules .. '/misc.lua')
 dofile(local_rules .. '/http_headers.lua')
 dofile(local_rules .. '/forwarding.lua')
 dofile(local_rules .. '/mid.lua')
+dofile(local_rules .. '/bitcoin.lua')
 
 if rspamd_util.file_exists(local_conf .. '/rspamd.local.lua') then
   dofile(local_conf .. '/rspamd.local.lua')
@@ -46,6 +47,10 @@ else
   end
 end
 
+if rspamd_util.file_exists(local_conf .. '/local.d/rspamd.lua') then
+  dofile(local_conf .. '/local.d/rspamd.lua')
+end
+
 if rspamd_util.file_exists(local_rules .. '/rspamd.classifiers.lua') then
   dofile(local_rules .. '/rspamd.classifiers.lua')
 end
index 2981939a079b888ff3efc002f37a49c7b03d69dc..5401ed031a8e9e31ce04adee17269b6182f44367 100644 (file)
@@ -930,7 +930,7 @@ lua_textpart_filter_words (lua_State *L)
        }
        else {
                if (lua_type (L, 3) == LUA_TSTRING) {
-                       const gchar *how_str = lua_tostring (L, 2);
+                       const gchar *how_str = lua_tostring (L, 3);
 
                        how = word_extract_type_from_string (how_str);