我刚刚收到一些与base64编码类似内容的邮件。 现在我想用身体检查来拒绝或放弃这类电子邮件。
在我进入body_checks之前,有如下所示:
/Quanzhoucooway/ DISCARD
但是由于邮件编码的关键字不会被检测到。
这是一个base64编码的消息:
DQpIaSBGcmllbmRzLA0KDQpHb29kIGRheSENCg0KVGhpcyBpcyBWaWN0b3JpYSBmcm9tIFF1YW56 aG91Y29vd2F5IHNob2VzIHRyYWRpbmcgY28uLGx0ZCwgYSBwcm9mZXNzaW9uYWxtYW51ZmFjdHVy ZXIgYW5kIGV4cG9ydGVyIG9mIGFsbCBraW5kcyBvZiBzaG9lcywgbWFpbmx5IGluIGNhc3VhbCBz aG9lcyBhbmQgc3BvcnRzIHNob2VzICwgd2hpY2ggaGFzIGJlZW4gc3VwcGxpZWQgdG8gdGhlIGZh bW91cyBmYXNoaW9uIGJyYW5kIHN0b3JlcyBmcm9tIDIwMTAuDQoNCk5vdGljaW5ndGhhdCB5b3Ug YXJlIGxvb2tpbmcgZm9yIGhpZ2ggcXVhbGl0eSBmYXNoaW9uIHNob2VzLCBzbyBJIGhvcGUgd2Ug Y2FuIHdvcmsgdG9nZXRoZXIgaW4gdGhlIGZ1dHVyZS4gSWYgeW91IGFyZSBpbnRlcmVzdGVkLCBJ IHdpbGwgc2VuZCB5b3Ugb3VyIGl0ZW1zIGFjY29yZGluZ2x5Lg0KDQpGWUksIHdlIGNhbiBtYWtl IGN1c3RvbWl6ZWQgc2FtcGxlcyBmb3IgeW91IGFjY29yZGluZ2x5Lg0KDQpMb29raW5nIGZvciB5 b3VyIHNvb25lc3QgcmVzcG9uc2UuDQoNCkJSIQ0KDQpWaWN0b3JpYSANCg==
那么阻止这类电子邮件的最佳做法是什么?
不要用Postfix的body_check
做这个,而是写一个 body_check
规则 。 Spamassain在应用其规则之前对邮件正文进行解码。 就像是:
body LOCAL_QUANZHOUCOOWAY /Quanzhoucooway/ score LOCAL_QUANZHOUCOOWAY 7.0 describe LOCAL_QUANZHOUCOOWAY Block word Quanzhoucooway
这些规则属于/etc/mail/spamassassin/local.cf
(或~/.spamassassin/user_prefs
)。
从技术上讲,你可以直接过滤关键字的base64编码数据。 我并不是说这是一个实际的或合理的事情,因为存在更好更简单的select(如上面Esa的回答中所述),但这是可能的。
诀窍是要认识到, base64编码是一个确定性的3个字节的原始未编码数据块映射到4个字符的base64字符块。 因此,任何时候在未编码数据中出现某个3字节块的序列时,在编码版本中将出现相同的4个字符块的序列。
例如,如果将stringQuanzhoucooway
input到base64编码器中 ,则会得到输出UXVhbnpob3Vjb293YXk=
。 由于input的长度不是3个字节的倍数,所以输出结尾包含一些填充 ,但是如果我们放弃最后的=
符号和最后一个实际的base64字符k
(因为它也编码了一些填充位),我们得到stringUXVhbnpob3Vjb293YX
保证出现在base64编码的数据中,只要字节三元组Qua
, nzh
, ouc
, oow
和部分三元组ay
以该顺序出现在input中。
但是,当然,弦乐Quanzhoucooway
可能不会在三重界线上开始。 例如,如果我们将stringXQuanzhoucooway
编码,我们得到输出WFF1YW56aG91Y29vd2F5
,看起来完全不同。 这次input长度可以被3整除,所以最后没有填充字符可以丢弃,但是我们需要丢弃前两个字符( WF
),每个字符对前面的X
字节中的一些位进行编码,我们用F1YW56aG91Y29vd2F5
。
最后,base64编码XXQuanzhoucooway
给出了输出WFhRdWFuemhvdWNvb3dheQ==
,两端都有填充。 删除前三个字符WFh
(编码XX
前缀)和最后三个字符Q==
(编码末尾的零位填充),我们留下stringRdWFuemhvdWNvb3dhe
。 因此,我们获得以下三个base64编码的string:
UXVhbnpob3Vjb293YX F1YW56aG91Y29vd2F5 RdWFuemhvdWNvb3dhe
其中(至less)一个必须以包含单词Quanzhoucooway
的任何inputstring的base64编码forms出现。
当然,如果你运气不好,base64编码器可能会在任何两个编码三元组之间的中间插入一个换行符。 (例如,您的示例消息在F1YW56
和aG91Y29vd2F5
之间有一个。)因此,要可靠地将这些string与正则aG91Y29vd2F5
匹配,您需要类似以下内容(使用PCRE语法):
/UXVh\s*bnpo\s*b3Vj\s*b293\s*YX/ DISCARD /F1\s*YW56\s*aG91\s*Y29v\s*d2F5/ DISCARD /R\s*dWFu\s*emhv\s*dWNv\s*b3dh\s*e/ DISCARD
手工生成这些模式有点乏味,但用您最喜欢的编程语言编写一个简单的脚本并不难,至less只要它提供一个base64编码器即可。
如果你真的想要的话,甚至可以通过base64编码来实现不区分大小写的匹配,这个base64编码关键字的小写和大写版本,并把它们组合成匹配任意组合的正则expression式。 例如, quanzhoucooway
的base64编码是cXVhbnpob3Vjb293YXk=
QUANZHOUCOOWAY
编码是UVVBTlpIT1VDT09XQVk=
,所以规则:
/[cU][XV]V[hB]\s*[bT][nl]p[oI]\s*[bT][31]V[jD]\s*[bT][20]9[3X]\s*[YQ][XV]/ DISCARD
在任何情况下都将与base64编码的词“Quanzhoucooway”相匹配,前提条件是它开始于三元组边界。 生成移位版本的另外两个相应的正则expression式将作为练习。 ;)
唉,像这样做比简单的子string匹配更复杂的事情很快变得不切实际。 但至less这是一个巧妙的把戏。 原则上,它甚至可能是有用的,如果你出于某种原因不能使用SpamAssassin或任何其他filter,可以在过滤之前解码base64编码。 但是,如果你能这样做,而不是像这样的黑客,你当然应该。