Home

Awesome

Build Status

Mail Security Testing Framework

A testing framework for mail security and filtering solutions.

IMPORTANT: Don't do anything evil with this! Tests of cloud or otherwise hosted solutions should always be approved by the tested provider. Only use your own test accounts and don't annoy anyone with a load of test mails.

Installation

The mail security testing framework works with with Python >=3.5. Just pull this repository and go ahead. No further dependencies are required.

Usage

The script mail-tester.py runs the tests. Read the help message with ./mail-tester.py --help and check the list of test and evasion modules with ./mail-tester.py -l to get an overview about the capabilities and the usage of the script. Some hints:

Development and Extension

Tests

Own tests can be implemented with a class in one of the iexisting or newly created Python files in the tests/ directory. The class must be a subclass of MailTestBase located in the module tests.base of this project. Newly implemented tests are discovered automatically when the class variable active is set to True. Further (if you plan to contribute tests back to the main repository), the class variables identifier, name and description should be set appropriately.

The following base classes exist with methods or class variables intended for overriding:

Setting the subjects of generated messages is highly recommended to be able to recongize the tests in the receiving inbox.

Evasions

Evasion classes implement techniques for evading recognition of particular mail properties by mail security solutions. Currently, a evasion technique that tries to hide attachments from such solutions by intentionally broken Content-Disposition headers is implemented.

Implement new Evasions

Evasions are implemented by a factory class pattern. The DeliveryBase class instantiaties a factory class derived from the BaseEvasionFactory class. The factory constructor receives a flag that indicates if the evasion is activated. The evasion factory instance is then passed to the test class and stored in its evasions attribute that contains a dict with the evasion identifiers as keys. Inside the test, a evasion class (based on EvasionBase) is instantiated with getEvasionGenerator(). The constructor parameter are defined individually per evasion technique.

The following base classes are used to implement evasions:

Generally, the evasion class should yield all evasion variants and pass the default as dedicated test case, while the default evasion classes only pass the given object or create the required data structures, like headers.

Using Evasion Techniques in Test Cases

Evasion techniques are used in test cases where they are applicable. E.g. if an evasion technique manipulates the header of a mail or attachment, the following steps have to be implemented:

  1. Generate the base object (mail or attachment) without consideration of the evasion.
  2. Instantiate the appropriate evasion class by utilization of the evasion factory instance from self.evasions, e.g.: evasion_items = self.evasions["evasion_identifier"].getEvasionGenerator(message)
  3. Iterate over the generator and yield the test cases:
for evasion_item in evasion_items:
    yield evasion_item

Usage of the Content Disposition Evasion Technique

The content disposition evasion technique is already implemented in the framework and should be used for all test cases that target on the recognition of malicious attachments. The constructor receives an attachment and the intended file name. The evasion class then yields (evasion name, attachment with applied evasion technique) tuples that can directly be yielded by the tests generateAttachments() method.