在工作中,我们最近开始收到电子邮件正文中包含看似恶意代码的电子邮件。我正在尝试创建一个 procmail 配方,它将使用正则表达式仅匹配长字符串中列出的非单词字符,如下所示:
/]\/[%}(-:{{[%+\!(?|}[[+{>-|*;\]}>?]}?(>:-\-/[\[%-=\//>[??+]}}(:)/|{/#Afe0:/]\/[%}(-:{{[%+\!(?|}[[+{>-|*;\]}>?]}?(>:-\-/[\[%-=\//>[??+]}}(:)/|{/#Jenny:/]\/[%}(-:{{[%+\!(?|}[[+{>-|*;\]}>?]}?(>:-\-/[\[%-=\//>[??+]}}(:)/|{/#preston:/]\/[%}(-:{{[%+\!(?|}[[+{>-|*;\]}>?]}?(>:-\-/[\[%-=\//>[??+]}}(:)/|{/#Afectarac:/]\/[%}(-:{{[%+\!(?|}[[+{>-|*;\]}>?]}?(>:-\-/[\[%-=\//>[??+]}}(:)/|{/#FORTHCO:/]\/[%}(-:{{[%+\!(?|}[[+{>-|*;\]}>?]}?(>:-\-/[\[%-=\//>[??+]}}(:)/|{/#backgrounds:/]\/[%}(-:{{[%+\!(?|}[[+{>-|*;\]}>?]}?(>:-\-/[\[%-=\//>[??+]}}(:)/|{/#legumes
请注意,没有空格。这是一个小例子,有些电子邮件的行长度超过 20,000 个字符。这扰乱了我们的垃圾邮件过滤,我希望有一种方法可以匹配长行的非单词字符,没有空格分隔符。到目前为止,我已经尝试使用下面的几种变体/片段/组合,但只取得了部分成功 - 我很难找到一种方法来完成这项工作,同时又不会捕获很多误报:
:0
* B ?? ^.*(!@#$%^&*()[]{})+ && ! </([a-z|A-Z])/>
$DEFAULT/MalSpam/
我在想,如果我可以制作一个匹配的正则表达式,那么我可以将其与另一个规则结合起来,如果每行的总字符数超过一定数量(例如 500),则将电子邮件发送到单独的目录。还没有弄清楚这一部分还没有...我过去使用过的其他正则表达式有 \W 标志,仅匹配非单词字符,procmail 是否有等效的?我怎样才能做到这一点?
答案1
关于你最后一个问题\W
,你不需要它。你可以做 的逆操作\w
。例如,如果您认为这是单词字符[a-zA-Z0-9_]
(例如,Vim 的定义\w
),则使用[^a-zA-Z0-9_]
。
答案2
你的尝试的表面修复是
:0
* B ?? [][!@#$%^&*(){}]+
* ! B ?? </[a-zA-Z]+/>
$DEFAULT/MalSpam/
</
如果我猜对了,您正在尝试匹配两个或多个标点字符的序列,以及作为否定条件的介于和之间的字母字符序列/>
(意味着如果存在匹配,则会阻止配方匹配)。
然而,任何两个标点字符(例如!!
)将匹配第一个正则表达式;我不明白你为什么像你那样阐明第二个条件。
一个挑战是许多标点字符是正则表达式元字符。要匹配文字[
或(
或,*
您需要反斜杠转义它们,或将它们放入字符类中。 (包含[
is的字符类[[]
需要一段时间才能理解。这是[
字符类括号内的文字[
...。并且包含并且需要按此顺序包含它们的]
字符类,所以。)我制作了第一个正则表达式简单地通过放置]
[
[][]
一切在一个字符类中,但事实上,它可能太宽泛了。我可能会要求有一个序列,例如四个或五个依次排列。 (不幸的是,Procmail 的正则表达式变体不支持 的egrep
数字[class]{5,}
量词;它在这里会很方便。)
:0B
* [][!@#$%^&*(){}][][!@#$%^&*(){}][][!@#$%^&*(){}][][!@#$%^&*(){}][][!@#$%^&*(){}]
* ! </[a-zA-Z]+/>
$DEFAULT/MalSpam/
如果你仔细观察,你会发现第一个[][!@#$%^&*(){}]
重复了五次。如果您想让它更长(例如,500 次相邻出现),只需根据需要重复多次即可。如果整个表达式长于LINEBUF
,您还需要注意这一点 - 如果您想为七个字符的正则表达式腾出空间 500 次,即 10,200 字节,因此您需要确保LINEBUF
至少是big 在包含这个长表达式的菜谱之前。
B
还要注意配方上的标志如何消除B ??
在每个单独的配方行上放置的要求。
如果您想比较消息的长度,只需使用>
和 您想要的数字。与:0B
标志,* > 512
将匹配身体其长度超过 512 字节。
对于您的最后一个问题,\W
基本上相当于字符类[^A-Za-z0-9_]
(不在范围A-Z
或范围a-z
或范围0-9
或字符中的单个字符_
)。