Comment puis-je rejeter les e-mails de spam encodés en base64?

11

Je viens de recevoir quelques mails avec un contenu similaire qui ont été encodés en base64. Maintenant, je veux rejeter ou supprimer ce type d'e-mails à l'aide de la vérification corporelle.

Avant j'avais dans mon corps_checks quelque chose comme ça:

/Quanzhoucooway/ DISCARD

Mais puisque le message est encodé, ce mot-clé ne sera pas détecté.

Voici un message encodé en base64:

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

Quelle est donc la meilleure pratique pour bloquer ce type d'e-mails?

user134969
la source
3
Un filtrage anti-spam approprié qui agit sur le contenu décodé réel du message?
ceejayoz
Pourriez-vous être plus précis, quel type de mécanisme utiliser? J'utilise déjà spamassassin et il fait un excellent travail en matière de lutte contre le spam.
user134969
Je les rejeterais par MTA avec un message d'erreur "Ne pas coder en base64 les corps de message".
joshudson

Réponses:

19

Ne faites pas cela avec Postfix body_checkmais écrivez plutôt une règle Spamassassin pour cela. Spamassain décode le corps du message avant d'appliquer ses règles. Quelque chose comme:

body     LOCAL_QUANZHOUCOOWAY  /Quanzhoucooway/
score    LOCAL_QUANZHOUCOOWAY  7.0
describe LOCAL_QUANZHOUCOOWAY  Block word Quanzhoucooway

Ces règles appartiennent à /etc/mail/spamassassin/local.cf(ou ~/.spamassassin/user_prefs).

Esa Jokinen
la source
1
Est-ce que cela fonctionnera même si ce mot-clé est encodé en base64, comme ce contenu là-haut?
user134969
2
Oui. Quelqu'un a déjà modifié ma réponse pour clarifier cela. Merci à cette personne anonyme! :)
Esa Jokinen
9

Techniquement, vous pouvez filtrer directement les données encodées en base64 pour les mots clés. Je ne dis pas que c'est une pratique ou une chose raisonnable à faire, étant donné l'existence de meilleures et des solutions plus simples (comme décrit par exemple dans la réponse ci - dessus Esa), mais il est possible.

L'astuce consiste à réaliser que le codage base64 est un mappage déterministe de blocs de 3 octets de données brutes non codées en blocs de 4 caractères de caractères base64. Ainsi, chaque fois qu'une certaine séquence de blocs de 3 octets apparaît dans les données non codées, la même séquence de blocs de 4 caractères apparaîtra dans la version codée.

Par exemple, si vous entrez la chaîne Quanzhoucoowaydans un encodeur base64 , vous obtiendrez la sortie UXVhbnpob3Vjb293YXk=. Étant donné que la longueur de l'entrée n'est pas un multiple de 3 octets, la sortie contient un remplissage à la fin, mais si nous supprimons les =signes finaux et le dernier caractère base64 réel k(car il code également certains bits de remplissage), nous obtenons la chaîne UXVhbnpob3Vjb293YXqui est garanti pour apparaître dans les données codées en base64 chaque fois que les triplets d'octets Qua, nzh, ouc, oowet le triplet partielle ayapparaissent dans l'entrée dans cet ordre.

Mais, bien sûr, la chaîne Quanzhoucoowaypeut ne pas démarrer exactement à la limite du triplet. Par exemple, si nous encodons la chaîne à la XQuanzhoucoowayplace, nous obtenons la sortie WFF1YW56aG91Y29vd2F5, qui semble complètement différente. Cette fois, la longueur d'entrée est divisible par trois, il n'y a donc pas de caractères de remplissage à éliminer à la fin, mais nous devons éliminer les deux premiers caractères ( WF) qui codent chacun certains des bits de l' Xoctet ajouté , nous laissant avec F1YW56aG91Y29vd2F5.

Enfin, le codage base64 XXQuanzhoucoowaydonne la sortie WFhRdWFuemhvdWNvb3dheQ==, qui a un rembourrage aux deux extrémités. En supprimant les trois premiers caractères WFh(qui codent le XXpréfixe) et les trois derniers caractères Q==(qui codent le remplissage zéro bit à la fin), nous nous retrouvons avec la chaîne RdWFuemhvdWNvb3dhe. Ainsi, nous obtenons les trois chaînes codées en base64 suivantes:

UXVhbnpob3Vjb293YX
F1YW56aG91Y29vd2F5
RdWFuemhvdWNvb3dhe

dont (au moins) un doit apparaître sous la forme codée en base64 de toute chaîne d'entrée contenant le mot Quanzhoucooway.

Bien sûr, si vous n'avez pas de chance, l'encodeur base64 peut insérer un saut de ligne au milieu d'entre eux, entre deux triplets encodés. (Votre exemple de message, par exemple, en a un entre F1YW56et aG91Y29vd2F5.) Ainsi, pour faire correspondre de manière fiable ces chaînes avec des expressions rationnelles, vous aurez besoin de quelque chose comme ce qui suit (en utilisant la syntaxe 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

Générer ces modèles à la main est un peu fastidieux, mais il ne serait pas difficile d'écrire un script simple pour le faire dans votre langage de programmation préféré, au moins tant qu'il fournit un encodeur base64.

Si vous le vouliez vraiment, vous pourriez même implémenter une correspondance insensible à la casse en codant en base64 les versions minuscule et majuscule du mot-clé et en les combinant dans une expression rationnelle qui correspond à n'importe quelle combinaison d'entre eux. Par exemple, le codage base64 de quanzhoucoowayest cXVhbnpob3Vjb293YXk=alors que celui de QUANZHOUCOOWAYest UVVBTlpIT1VDT09XQVk=, donc la règle:

/[cU][XV]V[hB]\s*[bT][nl]p[oI]\s*[bT][31]V[jD]\s*[bT][20]9[3X]\s*[YQ][XV]/ DISCARD

correspondra au mot encodé en base64 "Quanzhoucooway" dans tous les cas, à condition qu'il commence sur une limite de triplet. La génération des deux autres expressions rationnelles correspondantes pour les versions décalées est laissée en exercice. ;)

Hélas, faire quelque chose de plus compliqué que la simple correspondance de sous-chaînes comme celle-ci devient rapidement impossible. Mais au moins, c'est un bon truc. En principe, cela pourrait même être utile si, pour une raison quelconque, vous ne pouviez pas utiliser SpamAssassin ou tout autre filtre capable de décoder l'encodage base64 avant le filtrage. Mais si vous pouvez le faire, au lieu d'utiliser des hacks comme celui-ci, vous devriez certainement le faire.

Ilmari Karonen
la source
1
Oui, c'est possible ; pas si pratique, et pas quelque chose que vous aimeriez refaire pour chaque mot. +1 pour l'explication: bien que cela ne soit peut-être pas très utile, c'est certainement instructif!
Esa Jokinen du