
Ein Test-Framework für E-Mail-Sicherheits- und Filterlösungen.
Ein Test-Framework für Mail-Sicherheits- und Filterlösungen.
WICHTIG: Tun Sie damit nichts Böses! Tests von Cloud- oder anderweitig gehosteten Lösungen sollten immer vom getesteten Anbieter genehmigt werden. Verwenden Sie nur Ihre eigenen Testkonten und belästigen Sie niemanden mit einer Flut von Test-Mails.
Das Mail-Sicherheits-Test-Framework funktioniert mit Python >=3.5. Ziehen Sie einfach dieses Repository und legen Sie los. Es werden keine weiteren Abhängigkeiten benötigt.
Das Skript mail-tester.py führt die Tests aus. Lesen Sie die Hilfemeldung mit ./mail-tester.py --help und prüfen Sie die Liste der Test- und Evasion-Module mit ./mail-tester.py -l, um einen Überblick über die Fähigkeiten und die Verwendung des Skripts zu erhalten. Einige Hinweise:
--smtp-server und --to angegeben werden.-- gespeichert werden. Diese Konfigurationsdateien können durch Aufruf von ./mail-tester.py @tester.conf verwendet werden (Konfiguration in tester.conf).--to konfiguriert werden, um verschiedene Filterkonfigurationen zu testen.--auto-delay zur automatischen Drosselung der Mails. Dies kann mit --delay-step, --delay-max und --delay fein abgestimmt werden.--spam-folder und --malware-folder. Die Beispiele sind nicht in diesem Repository enthalten (und werden es auch nicht). Gute Quellen für Malware sind theZoo, Das Malwerk oder andere Sammlungen. Spam kann direkt aus Ihrem Spam-Ordner exportiert werden, muss aber im EML-Format vorliegen.--blacklist bereitgestellt werden und werden als Absenderadressen verwendet.--evasion content-disposition aktiviert werden. Diese wurden in der Vergangenheit verwendet, um AV/Sandboxing-Lösungen zu verwirren und bösartige Mails durchzulassen.--log zu protokollieren. Mail-Filteranbieter lehnen Mails oft im SMTP-Dialog ab, was im erstellten Protokoll vermerkt wird.--output als einfache Dateien in einem Verzeichnis, im MBox-Format (--mbox) oder im MailDir-Format (--maildir) ausgegeben werden. Dies ist nützlich, um Mail-Benutzeragenten zu testen, ohne Mails zu versenden, oder um generierte Testfälle zu dokumentieren oder zu überprüfen.Eigene Tests können mit einer Klasse in einer der vorhandenen oder neu erstellten Python-Dateien im Verzeichnis tests/ implementiert werden. Die Klasse muss eine Unterklasse von MailTestBase sein, die sich im Modul tests.base dieses Projekts befindet. Neu implementierte Tests werden automatisch erkannt, wenn die Klassenvariable active auf True gesetzt ist. Außerdem sollten (falls Sie planen, Tests wieder an das Haupt-Repository zurückzugeben) die Klassenvariablen identifier, name und description entsprechend gesetzt werden.
Die folgenden Basisklassen existieren mit Methoden oder Klassenvariablen, die zum Überschreiben vorgesehen sind:
MailTestBase: Testklasse für generische Tests.
generateTestCases(): Liefert Testnachrichten. Diese sollten mit den MIME*-Klassen aus den Python-Paketen email.mime.* oder mit der Klasse Message aus email.message erzeugt werden, um gültige Mail-Nachrichten zu gewährleisten.active: Boolescher Wert, der angibt, ob der Test aktiv sein soll.identifier: Kurzer Bezeichner des Tests. Dieser wird verwendet, um Tests in Parametern zu aktivieren oder zu deaktivieren.name: Kurzer Testtitel.description: Längere Testbeschreibung, sollte innerhalb von etwa 100 Zeichen passen.delivery_sender und delivery_recipient: Boolesche Werte, standardmäßig False. Normalerweise werden der Absender und die Empfänger in der Nachricht gesetzt, und das Python-SMTP-Modul übernimmt sie von dort. Manchmal ist es wünschenswert, sie explizit in der SMTP-Bibliothek zu setzen, was durch Setzen dieser Werte auf konfiguriert werden kann.Es wird dringend empfohlen, die Betreffe der generierten Nachrichten zu setzen, um die Tests im empfangenden Posteingang erkennen zu können.
Evasion-Klassen implementieren Techniken zur Umgehung der Erkennung bestimmter Mail-Eigenschaften durch Mail-Sicherheitslösungen. Derzeit ist eine Evasion-Technik implementiert, die versucht, Anhänge vor solchen Lösungen zu verstecken, indem sie absichtlich fehlerhafte Content-Disposition-Header verwendet.
Evasions werden über ein Factory-Klassenmuster implementiert. Die Klasse DeliveryBase instanziiert eine Factory-Klasse, die von der Klasse BaseEvasionFactory abgeleitet ist. Der Factory-Konstruktor erhält ein Flag, das anzeigt, ob die Evasion aktiviert ist. Die Evasion-Factory-Instanz wird dann an die Testklasse übergeben und in deren Attribut evasions gespeichert, das ein Dictionary mit den Evasion-Bezeichnern als Schlüssel enthält. Innerhalb des Tests wird eine Evasion-Klasse (basierend auf EvasionBase) mit getEvasionGenerator() instanziiert. Die Konstruktorparameter werden pro Evasion-Technik individuell definiert.
Die folgenden Basisklassen werden zur Implementierung von Evasions verwendet:
BaseEvasionFactory: Evasion-Factories müssen auf dieser Klasse basieren. Normalerweise sollten nur die folgenden Klassenvariablen gesetzt werden:
active: Auf True setzen, wenn die Evasion aktiv sein soll.identifier: Kurzer Bezeichner des Evasion-Moduls, der zur Aktivierung in der Testkonfiguration verwendet wird.name: Kurzer Titel der Evasion-Technik.description: Längere Beschreibung der Evasion-Technik. Sollte in etwa 100 Zeichen passen.generator_evasion: Evasion-Klasse, die instanziiert wird, wenn die Evasion aktiviert ist.generator_default: Evasion-Klasse, die instanziiert wird, wenn die Evasion deaktiviert ist.BaseEvasion: Die Implementierung von Evasions muss eine Unterklasse dieser Basisklasse sein. Die folgende Methode muss überschrieben werden:
__init__(): Soll die Klasse mit der Basisnachricht oder dem Basisanhang instanziieren, der mit Evasion-Techniken manipuliert werden soll.generate(): Wendet die Evasion-Technik auf das an den Konstruktor übergebene Objekt an und liefert es als (Beschreibung, Objekt mit angewandter Evasion)-Tupel an den Aufrufer zurück.Im Allgemeinen sollte die Evasion-Klasse alle Evasion-Varianten liefern und den Standard als dedizierten Testfall weitergeben, während die Standard-Evasion-Klassen nur das gegebene Objekt weitergeben oder die erforderlichen Datenstrukturen wie Header erstellen.
Evasion-Techniken werden in Testfällen verwendet, wo sie anwendbar sind. Z.B. wenn eine Evasion-Technik den Header einer Mail oder eines Anhangs manipuliert, müssen die folgenden Schritte implementiert werden:
self.evasions, z.B.:
evasion_items = self.evasions["evasion_identifier"].getEvasionGenerator(message)for evasion_item in evasion_items:
yield evasion_item
Die Content-Disposition-Evasion-Technik ist bereits im Framework implementiert und sollte für alle Testfälle verwendet werden, die auf die Erkennung bösartiger Anhänge abzielen. Der Konstruktor erhält einen Anhang und den beabsichtigten Dateinamen. Die Evasion-Klasse liefert dann (Evasion-Name, Anhang mit angewandter Evasion-Technik)-Tupel, die direkt von der Methode generateAttachments() des Tests zurückgegeben werden können.
finalizeMessage(msg): Standardmäßig setzt die Basis-Testklasse die Kopfzeilen From und To entsprechend. Dieses Verhalten kann überschrieben werden, falls es für den Testfall erforderlich ist.MailAttachmentTestBase: Testklasse für Anhangstestfälle. Diese erzeugt eine vollständige gültige Mail mit einem Betreff und einem Textteil und fügt den Testfall daran an. Abgeleitet von MailTestBase, daher können die Methoden/Variablen von dort ebenfalls überschrieben werden.
generateAttachments(): Liefert Testfälle als (Beschreibung, Anhang)-Tupel.subject: Setzt den Betreff. Der Platzhalter {} wird durch die von generateAttachments() gelieferte Beschreibung ersetzt.generateTestCases(): Ist bereits mit einer Implementierung der oben beschriebenen Nachrichtenerzeugung überschrieben, kann aber bei Bedarf weiter angepasst werden.