From: Vsevolod Stakhov Date: Tue, 18 Jun 2019 11:46:34 +0000 (+0100) Subject: [Rules] Add dedicated bitcoin addresses filter rule X-Git-Tag: 2.0~763 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=db44cc510d4991859d2682d4b8a18dc9a88be5cd;p=rspamd.git [Rules] Add dedicated bitcoin addresses filter rule --- diff --git a/rules/bitcoin.lua b/rules/bitcoin.lua new file mode 100644 index 000000000..df6fed2f6 --- /dev/null +++ b/rules/bitcoin.lua @@ -0,0 +1,86 @@ +--[[ +Copyright (c) 2019, Vsevolod Stakhov + +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 diff --git a/rules/misc.lua b/rules/misc.lua index a01b8ecd1..7d3682271 100644 --- a/rules/misc.lua +++ b/rules/misc.lua @@ -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" diff --git a/rules/rspamd.lua b/rules/rspamd.lua index 646dc5afd..50b1aadf1 100644 --- a/rules/rspamd.lua +++ b/rules/rspamd.lua @@ -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 diff --git a/src/lua/lua_mimepart.c b/src/lua/lua_mimepart.c index 2981939a0..5401ed031 100644 --- a/src/lua/lua_mimepart.c +++ b/src/lua/lua_mimepart.c @@ -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);