/emlrender

EML file rendering tool

Primary LanguagePythonGNU General Public License v3.0GPL-3.0

EMLRender

Introduction

Sometimes, while investigating incident implying emails, you can get a copy of the original message in EML format. Reading an EML file is not easy with all the SMTP headers and the mulitple MIME parts it may contain. But it may also contain suspicious code that is dangerous to be executed from sensitive environments. EMLRender is a Python script that provides a REST API to render submitted EML files into PNG images. This way, it's easy to have a clear overview of the mail content.

Here is a sample of generated image: alt text

Compoments

EMLRender is based on the wkhtmltoimage tool to render HTML code. It consists of a single Python script that provides an HTTP interface or REST API. The best way to use it is to run it in a Docker container. This way, it can be easily deployed.

Installation

Building the container

Use the provide Dockerfile to build your image:

$ git clone https://github.com/xme/emlrender
$ cd emlrender
$ docker build -t emlrender:latest .

An image is ready to use on hub.docker.com: https://hub.docker.com/r/rootshell/emlrender/

Starting the container

EMLRender is a stand-alone container that does not have any dependency.

$ docker run emlrender:latest

Once started, it will listing to port 443. Note: a self-signed certificate is generated when the container is created.

Setup & Configuration

User database creation

EMLRender requires user authentication to render EML files. The first action is to generate the users database and an admin account:

$ curl -k -X POST -d '{"password":"strongpw"}' https://127.0.0.1/init
[{"message": "Users database successfully initialized"}, {"password": "strongpw"}]

If you don't specify a password, a random one will be generated:

$ curl -k -X POST -d '{}' https://127.0.0.1/init
[{"message": "Users database successfully initialized"}, {"password": "1o03uqjm6w"}]

User accounts management

Creation

New users can be added with the following request:

$ curl -k -u admin:secretpw -X POST -d '{"username":"john", "password":"strongpw"}' https://127.0.0.1/users/add
[{"message": "Account successfully created", "username": "john", "password": "strongpw"}]

Note: If no password is provided, a random one will be generated.

Password change

Account passwords can be changed with the following request:

$ curl -k -u admin:secretpw -X POST -d '{"username":"john", "newpassword":"verystrongpw"}' https://127.0.0.1/users/resetpw
[{"message": "Password successfully updated", "username": "john", newpassword": "verystrongpw"}]

Note: Regular users can change their own password.

Deletion

Users can be deleted with the following request:

$ curl -k -u admin:secretpw -X POST -d '{"username":"john"}' https://127.0.0.1/users/delete
[{ "message" : "Account successfully deleted" }]

Users listing

A list of users can be fetched with the following request:

$ curl -k -u admin:secretpw https://127.0.0.1/users/list
[{"message": "Success"}, {"username": "admin"}, {"username": "john"}]

Usage

Help page

A simple help page is available when you point your browser to the following URL: https://127.0.0.1/help

EML Rendering

REST API

To submit an EML file, use the following request:

$ curl -k -u john:strongpw -F file=@"spam.eml" -o spam.png https://127.0.0.1/upload

The generated picture will be saved into spam.png. It is possible to submit a ZIP archive containing the EML file (encrypted archives are supported):

$ curl -k -u john:strongpw -F file=@"malicious.zip" -F password=infected -o malicious.png https://127.0.0.1/upload

Web browser

Point your browser to https://127.0.0.1/upload to submit your EML file via a normal HTML form.

Logging

HTTP log

A classic HTTP log is available via the Docker interface:

$ docker logs -f emlrender
 * Running on https://0.0.0.0:443/ (Press CTRL+C to quit)
172.17.0.1 - - [18/May/2018 11:59:43] "POST /init HTTP/1.1" 200 -
172.17.0.1 - - [18/May/2018 12:06:36] "POST /users/add HTTP/1.1" 200 -
172.17.0.1 - - [18/May/2018 12:12:08] "GET /users/list HTTP/1.1" 200 -

The application log is available via the api.log file in the container:

$ docker exec -it emlrender tail -f api.log
[2018-May-18 11:59] 172.17.0.1 POST /init? [INFO] Init page requested
[2018-May-18 11:59] 172.17.0.1 POST /init? [INFO] Users database successfully initialized
[2018-May-18 12:06] 172.17.0.1 POST /users/add? [INFO] AddUser page requested
[2018-May-18 12:06] 172.17.0.1 POST /users/add? [INFO] Admin authentication successful
[2018-May-18 12:06] 172.17.0.1 POST /users/add? [INFO] Account john successfully created
[2018-May-18 12:12] 172.17.0.1 GET /users/list? [INFO] ListUsers page requested
[2018-May-18 12:12] 172.17.0.1 GET /users/list? [INFO] Accounts list successfully returned
[2018-May-18 12:24] 172.17.0.1 POST /upload? [INFO] User john successfully authenticated
[2018-May-18 12:24] 172.17.0.1 POST /upload? [INFO] Date: Fri, 18 May 2018 10:38:26 +0200
[2018-May-18 12:24] 172.17.0.1 POST /upload? [INFO] From: <redacted>
[2018-May-18 12:24] 172.17.0.1 POST /upload? [INFO] To: <redacted>
[2018-May-18 12:24] 172.17.0.1 POST /upload? [INFO] Subject: <redacted>
[2018-May-18 12:24] 172.17.0.1 POST /upload? [INFO] Message-Id: <redacted>
[2018-May-18 12:24] 172.17.0.1 POST /upload? [INFO] Created headers 6346209b0e191fe5e9a740db4e7a2db6.png
[2018-May-18 12:24] 172.17.0.1 POST /upload? [INFO] Multipart found, continue
[2018-May-18 12:24] 172.17.0.1 POST /upload? [INFO] Found MIME part: text/plain
[2018-May-18 12:24] 172.17.0.1 POST /upload? [INFO] Decoded 693d8cdec2a72278157ac4bb107b44b0.png
[2018-May-18 12:24] 172.17.0.1 POST /upload? [INFO] Found MIME part: text/html
[2018-May-18 12:24] 172.17.0.1 POST /upload? [INFO] Decoded 461c46fefa1b887857398ba17446b822.png