Назад | Перейти на главную страницу

Как я могу отклонить спам в кодировке base64?

Я только что получил пару писем с похожим содержанием, которые были закодированы с помощью base64. Теперь я хочу отклонить или отклонить такие электронные письма с помощью проверки тела.

Раньше у меня в body_checks было что-то вроде этого:

/Quanzhoucooway/ DISCARD

Но поскольку сообщение закодировано, это ключевое слово не будет обнаружено.

Вот сообщение в кодировке base64:

DQpIaSBGcmllbmRzLA0KDQpHb29kIGRheSENCg0KVGhpcyBpcyBWaWN0b3JpYSBmcm9tIFF1YW56
aG91Y29vd2F5IHNob2VzIHRyYWRpbmcgY28uLGx0ZCwgYSBwcm9mZXNzaW9uYWxtYW51ZmFjdHVy
ZXIgYW5kIGV4cG9ydGVyIG9mIGFsbCBraW5kcyBvZiBzaG9lcywgbWFpbmx5IGluIGNhc3VhbCBz
aG9lcyBhbmQgc3BvcnRzIHNob2VzICwgd2hpY2ggaGFzIGJlZW4gc3VwcGxpZWQgdG8gdGhlIGZh
bW91cyBmYXNoaW9uIGJyYW5kIHN0b3JlcyBmcm9tIDIwMTAuDQoNCk5vdGljaW5ndGhhdCB5b3Ug
YXJlIGxvb2tpbmcgZm9yIGhpZ2ggcXVhbGl0eSBmYXNoaW9uIHNob2VzLCBzbyBJIGhvcGUgd2Ug
Y2FuIHdvcmsgdG9nZXRoZXIgaW4gdGhlIGZ1dHVyZS4gSWYgeW91IGFyZSBpbnRlcmVzdGVkLCBJ
IHdpbGwgc2VuZCB5b3Ugb3VyIGl0ZW1zIGFjY29yZGluZ2x5Lg0KDQpGWUksIHdlIGNhbiBtYWtl
IGN1c3RvbWl6ZWQgc2FtcGxlcyBmb3IgeW91IGFjY29yZGluZ2x5Lg0KDQpMb29raW5nIGZvciB5
b3VyIHNvb25lc3QgcmVzcG9uc2UuDQoNCkJSIQ0KDQpWaWN0b3JpYSANCg==

Итак, как лучше всего блокировать такие электронные письма?

Не делайте этого с Postfix body_check но написать правило Spamassassin вместо этого. 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 по ключевым словам. Я не говорю, что это практично или разумно, учитывая существование лучших и более простых альтернатив (как описано, например, в ответе Esa выше), но это является возможно.

Уловка состоит в том, чтобы понять, что кодировка base64 представляет собой детерминированное отображение 3-байтовых блоков необработанных некодированных данных в 4-символьные блоки символов base64. Таким образом, каждый раз, когда определенная последовательность 3-байтовых блоков появляется в незашифрованных данных, такая же последовательность 4-значных блоков появляется в закодированной версии.

Например, если вы введете строку Quanzhoucooway в кодировщик base64, вы получите результат UXVhbnpob3Vjb293YXk=. Поскольку длина ввода не кратна 3 байтам, вывод содержит некоторые набивка в конце, но если отбросить финал = знаки и последний фактический символ base64 k (поскольку он также кодирует некоторые биты заполнения), мы получаем строку UXVhbnpob3Vjb293YX который гарантированно появляется в данных в кодировке base64 всякий раз, когда байты тройки Qua, nzh, ouc, oow и частичная тройка ay появляются во входных данных в таком порядке.

Но, конечно, струна Quanzhoucooway может не начинаться точно на границе триплета. Например, если мы кодируем строку XQuanzhoucooway вместо этого мы получаем вывод WFF1YW56aG91Y29vd2F5, который выглядит совершенно иначе. На этот раз длина ввода делится на три, поэтому в конце нет дополнительных символов, которые нужно отбрасывать, но нам нужно отбросить первые два символа (WF), каждый из которых кодирует некоторые биты из добавленных X байт, оставив нас с F1YW56aG91Y29vd2F5.

Наконец, кодировка base64 XXQuanzhoucooway дает результат WFhRdWFuemhvdWNvb3dheQ==, который имеет отступы на обоих концах. Удаление первых трех символов WFh (которые кодируют XX префикс) и последние три символа Q== (который кодирует заполнение нулевым битом в конце), у нас остается строка RdWFuemhvdWNvb3dhe. Таким образом, мы получаем следующие три строки в кодировке base64:

UXVhbnpob3Vjb293YX
F1YW56aG91Y29vd2F5
RdWFuemhvdWNvb3dhe

из которых (по крайней мере) одно должно появиться в кодированной base64 форме любой входной строки, содержащей слово Quanzhoucooway.

Конечно, если вам не повезло, кодировщик base64 может вставить разрыв строки посередине между любыми двумя закодированными триплетами. (В вашем примере сообщения, например, есть одно между F1YW56 и 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

Создание этих шаблонов вручную довольно утомительно, но было бы несложно написать простой скрипт для этого на вашем любимом языке программирования, по крайней мере, если он предоставляет кодировщик base64.

Если вы действительно хотите, вы могли бы даже реализовать сопоставление без учета регистра, кодируя base64 как строчную, так и верхнюю версию ключевого слова и объединяя их в регулярное выражение, которое соответствует любой их комбинации. Например, кодировка base64 quanzhoucooway является 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

в любом случае будет соответствовать слову «Quanzhoucooway» в кодировке base64, при условии, что оно начинается на границе триплета. Генерация двух других соответствующих регулярных выражений для сдвинутых версий оставлена ​​в качестве упражнения. ;)

Увы, делать что-либо более сложное, чем простое сопоставление подстрок, подобное быстро становится непрактичным. Но, по крайней мере, это хитрый трюк. В принципе, это может быть даже полезно, если вы по какой-то причине не можете использовать SpamAssassin или любой другой фильтр, который может декодировать кодировку base64 перед фильтрацией. Но если вы можете это сделать, то вам, безусловно, следует, вместо того, чтобы использовать подобные хаки.