Gophish – instalación con Docker

Gophish es una es una plataforma para el envío de campañas de concienciación muy completa e intuitiva. Con ella podremos realizar envío de campañas de phising para la obtención de credenciales, permitiendo identificar a los usuarios susceptibles de ser realmente engañados. Es una herramienta realmente útil para las corporaciones, tanto grandes como pequeñas, que destinan esfuerzos en la educación de sus empleados/colaboradores con el fin de evitar fugas de información.

La herramienta permite realizar campañas de emailing usando ingeniería social con el fin de obtener información de las víctimas a las que van dirigidas. Para ello se crea un mensaje en donde se solicita al usuario que ingrese en un enlace para facilitar cierta información (credenciales u otro tipo de datos). En este enlace se puede configurar una web estática con un formulario en donde se puede simular la apariencia de un webmail cuya identidad queramos suplantar, incluso nos permite la importación de una URL para obtener los elementos HTML/CSS y facilitarnos un poco la labor, aunque ya adelanto que aún así tendremos que tocar algo el código. Una vez la víctima envíe los datos del formulario podemos configurar una redirección a otro portal, por ejemplo el legítimo o una web en donde se muestre que ha sido engañada. Posteriormente podremos identificar el estado de los buzones en cada campaña, si han recibido el email, si lo han abierto, si han picado en el enlace o no, los datos que han enviado en el formulario (ojo que las contraseñas se almacenan y muestran en texto plano), … una herramienta realmente completa y en continuo desarrollo.

En la actualidad se encuentra en la versión 0.6.0. Para su actualización basta con copiar el archivo de configuración config.json, copiar el directorio de instalación, descargar el nuevo y recuperar el archivo de configuración anterior (recuerda hacer una nueva copia del descargado).Tienes toda la información en la web oficial.

En mi caso he optado por la instalación de esta plataforma en un contenedor de Docker, evitando errores de compatibilidad con versiones o dependencias, sistemas operativos, … Por ejemplo, si tienes un Centos 6 vas a tener problemas con la versión del compilador gcc, ya que requiere una versión que solo se puede usar en un Centos 7 si no quieres generar problemas al sistema. Con Docker no tendrás obstáculo alguno en este sentido.

También he optado por utilizar la base de datos fuera del contenedor, bien en otro contenedor o en el host anfitrión, ya que toda la información se guarda en esta y un reinicio del host sin un backup previo del contenedor borrará toda la información volviendo al estado inicial tras su arranque. También he cambiado el motor de base de datos que usa por defecto SQLite por MySQL/Mariadb y apuntando al motor instalado en el host que contiene los contenedores.

Los requisitos mínimos necesarios para usar este programa en nuestro escenario son:

  • Docker instalado.
  • MySQL/Mariadb instalado.
  • Puertos 3333 de administración accesible pero no público (se puede cambiar).
  • Puerto 8080 de acceso al phising accesible público (se puede cambiar).
  • Conocimientos básico de HTML/CSS.
  • Servidor de correo o cuenta en servidor externo que no bloquee tus envíos.

Los puertos se pueden cambiar tanto en el host anfitrión como en el contenedor a partir de un contenedor inicial arrancado, como veremos más adelante.

Damos por supuesto que tanto Docker como MySQL/Mariadb están instalados en el sistema. Hay mucha documentación al respecto en Internet sobre como hacerlo, pero este no es el objetivo de esta entrada.

Al lío!!!!!

 


Descarga

Lo primero que tenemos que hacer es acceder a la sección de Gophish en GitHub, pinchando aquí, en donde nos remite al enlace del hub de Docker, pinchando aquí. La versión que contiene es la 0.6.0, las más reciente en este momento, creado en un Debian Jessie.

Nos descargamos la imagen con el siguiente comando:

docker pull matteoggl/gophish

Siendo el resultado:

Using default tag: latest
Trying to pull repository docker.io/matteoggl/gophish ...
latest: Pulling from docker.io/matteoggl/gophish
3d77ce4481b1: Pull complete
24071f356e70: Pull complete
6ff8c180320c: Pull complete
7403558d9197: Pull complete
a850c9f0aa43: Pull complete
Digest: sha256:d29c352e7d305b85f2c084070d5eda2fa821586cda51866ef88da5490686fdc2
Status: Downloaded newer image for docker.io/matteoggl/gophish:latest

Comprobamos que la imagen se descargó correctamente:

# docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
docker.io/matteoggl/gophish   latest              43a7c6101591        3 months ago        248 MB


Arranque del contenedor

A continuación podemos arrancar el contenedor en modo pruebas:

docker run -ti --name gophish -p 3333:3333 -p 8083:80 matteoggl/gophish

O en modo demonio:

docker run -d --name gophish -p 3333:3333 -p 8083:80 matteoggl/gophish

Te recomiendo probar con el primero y cuando hayas comprobado que no devuelve ningún error durante las pruebas dejarlo en producción como demonio.

En ambos comandos se redirigen los puertos del host anfitrión al contenedor, del 3333 origen al 3333 destino y del 8083 al 80. Esto quiere decir que en el FW se deben de abrir los puertos origen, aunque no te recomiendo hacerlo para el de gestión y acceder a través de un acceso privado o local.


Acceso

Una vez arrancado en modo pruebas veremos la siguiente información:

time="2018-08-22T12:11:19Z" level=info msg="Background Worker Started Successfully - Waiting for Campaigns"
goose: migrating db environment 'production', current version: 0, target: 20180223101813
OK 20160118194630_init.sql
OK 20160131153104_0.1.2_add_event_details.sql
OK 20160211211220_0.1.2_add_ignore_cert_errors.sql
OK 20160217211342_0.1.2_create_from_col_results.sql
OK 20160225173824_0.1.2_capture_credentials.sql
OK 20160227180335_0.1.2_store-smtp-settings.sql
OK 20160317214457_0.2_redirect_url.sql
OK 20160605210903_0.2_campaign_scheduling.sql
OK 20170104220731_0.2_result_statuses.sql
OK 20170219122503_0.2.1_email_headers.sql
OK 20170827141312_0.4_utc_dates.sql
OK 20171027213457_0.4.1_maillogs.sql
OK 20171208201932_0.4.1_next_send_date.sql
OK 20180223101813_0.5.1_user_reporting.sql
time="2018-08-22T12:11:19Z" level=info msg="Starting phishing server at http://0.0.0.0:80\n"
time="2018-08-22T12:11:19Z" level=info msg="Creating new self-signed certificates for administration interface"
time="2018-08-22T12:11:19Z" level=info msg="TLS Certificate Generation complete"
time="2018-08-22T12:11:19Z" level=info msg="Starting admin server at https://0.0.0.0:3333\n"

En donde se crean dentro del contenedor las bases de datos SQLite, se levanta el puerto 80 para publicar la/s página/s de phising, se genera el certificado autofirmado genérico para el acceso al portal de gestión y se levanta el puerto para este en el 3333. Recuerda que los puertos a abrir son los origen indicandos en el apartado anterior.

Probamos el acceso al portal de administración:

 

Y a la interfaz de publicación del phising:

En ambos casos el acceso es correcto, y la ventana del contenedor muestra los logs con ambos accesos. Esto nos indica que todo está funcionando correctamente.

Paramos el contenedor con las teclas Ctrl + C y observamos que el contenedor está parado.

# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                          PORTS               NAMES
0967258c3849        matteoggl/gophish   "./gophish"         29 minutes ago      Exited (2) About a minute ago                       gophish

Podemos proceder al borrado del contenedor que hemos utilizado para las pruebas.

# docker rm 0967

# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

Ahora podemos arrancar el contenedor como demonio para utilizarlo en producción.


Cambio de puertos

Puertos origen

Si queremos cambiar los puertos origen del host anfitrión bastaría con indicar en el comando docker run los puertos origen deseados, por ejemplo levantamos los puertos origen 3331 y 8081:

docker run -d --name gophish -p 3331:3333 -p 8081:80 matteoggl/gophish

El contenedor muestra la redirección de puertos configurada:

# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                                          NAMES
fab32aa8313c        matteoggl/gophish   "./gophish"         3 seconds ago       Up 3 seconds        0.0.0.0:8081->80/tcp, 0.0.0.0:3331->3333/tcp   gophish

Y en el equipo vemos los puertos levantados:

# netstat -an | grep -E "3331|8081"
tcp6       0      0 :::8081                 :::*                    LISTEN
tcp6       0      0 :::3331                 :::*                    LISTEN

Todo funcionaría correctamente.

Puertos destino

Sin embargo, si lo que queremos es cambiar los puertos destinos del contenedor debemos de acceder a este y modificar el archivo de configuración de Gophish,  salir de este y hacer una copia de la imagen con el estado actual que será la que usaremos para arrancar el contenedor.

Para ello arrancamos el contenedor descargado en modo demonio y accedemos a su la consola:

# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                                          NAMES
bd83393f40cd        matteoggl/gophish   "./gophish"         3 seconds ago       Up 2 seconds        0.0.0.0:3333->3333/tcp, 0.0.0.0:8083->80/tcp   gophish

# docker exec -ti bd83393f40cd bash
root@bd83393f40cd:/opt/gophish-v0.6.0-linux-64bit#

Una vez dentro hacemos una copia del archivo de configuración config.json de Gophish:

root@bd83393f40cd:/opt/gophish-v0.6.0-linux-64bit# ls
LICENSE  README.md  VERSION  config.json  db  gophish  gophish.db  gophish_admin.crt  gophish_admin.key  static  templates

root@bd83393f40cd:/opt/gophish-v0.6.0-linux-64bit# cp -pr config.json config.json.bkp

root@bd83393f40cd:/opt/gophish-v0.6.0-linux-64bit# ls
LICENSE  README.md  VERSION  config.json  config.json.bkp  db  gophish  gophish.db  gophish_admin.crt  gophish_admin.key  static  templates

Lo editamos y modificamos con los datos que queremos.

Contenido original:

# cat config.json
{
        "admin_server" : {
                "listen_url" : "0.0.0.0:3333",
                "use_tls" : true,
                "cert_path" : "gophish_admin.crt",
                "key_path" : "gophish_admin.key"
        },
        "phish_server" : {
                "listen_url" : "0.0.0.0:80",
                "use_tls" : false,
                "cert_path" : "example.crt",
                "key_path": "example.key"
        },
        "db_name" : "sqlite3",
        "db_path" : "gophish.db",
        "migrations_prefix" : "db/db_"
}

Cambiamos los puertos, por ejemplo del 80 al 81:

root@bd83393f40cd:/opt/gophish-v0.6.0-linux-64bit# sed -i "s|:80|:81|g" config.json

Contenido nuevo:

root@bd83393f40cd:/opt/gophish-v0.6.0-linux-64bit# cat config.json
{
        "admin_server" : {
                "listen_url" : "0.0.0.0:3333",
                "use_tls" : true,
                "cert_path" : "gophish_admin.crt",
                "key_path" : "gophish_admin.key"
        },
        "phish_server" : {
                "listen_url" : "0.0.0.0:81",
                "use_tls" : false,
                "cert_path" : "example.crt",
                "key_path": "example.key"
        },
        "db_name" : "sqlite3",
        "db_path" : "gophish.db",
        "migrations_prefix" : "db/db_"
}

Salimos del contenedor con el comando exit y creamos una imagen de este con el nombre que queramos. Observamos que se crea una imagen nueva pero no se levanta ningún contenedor:

# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                                          NAMES
bd83393f40cd        matteoggl/gophish   "./gophish"         9 minutes ago       Up 9 minutes        0.0.0.0:3333->3333/tcp, 0.0.0.0:8083->80/tcp   gophish

# docker commit bd83393f40cd matteogg/gophish-81
sha256:4202ce9c9bcac2f84819c47812ccbc734b9d36fbd157d1d7db6fe1016614a349

# docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
matteogg/gophish-81           latest              4202ce9c9bca        2 seconds ago       248 MB
docker.io/matteoggl/gophish   latest              43a7c6101591        3 months ago        248 MB

# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                                          NAMES
bd83393f40cd        matteoggl/gophish   "./gophish"         10 minutes ago      Up 10 minutes       0.0.0.0:3333->3333/tcp, 0.0.0.0:8083->80/tcp   gophish

Ahora paramos el contenedor actual y borramos, si no lo vamos a utilizar más, para liberar los puertos ocupados, y procedemos a levantar el nuevo contenedor:

# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                                          NAMES
bd83393f40cd        matteoggl/gophish   "./gophish"         12 minutes ago      Up 12 minutes       0.0.0.0:3333->3333/tcp, 0.0.0.0:8083->80/tcp   gophish

# docker stop bd83393f40cd
bd83393f40cd

# docker rm bd83393f40cd
bd83393f40cd
# docker run -d --name gophish-81 -p 3333:3333 -p 8083:81 matteogg/gophish-81
33715710ae8aea013555df74066f7a4aa03bd2265afecd3196c4c7b7ae9e7011

# docker ps
CONTAINER ID        IMAGE                 COMMAND             CREATED             STATUS              PORTS                                                  NAMES
33715710ae8a        matteogg/gophish-81   "./gophish"         31 seconds ago      Up 29 seconds       80/tcp, 0.0.0.0:3333->3333/tcp, 0.0.0.0:8083->81/tcp   gophish-81


Cambiar el motor de DB

Por defecto el contenedor viene con el motor de DB SQLite, pero si queremos cambiarlo a MySQL/Mariadb tendremos que realizar los siguientes pasos. Te recomiendo alojarlo bien en el host anfitrión, en otro contenedor o en un host externo.

Crear la DB en el host destino, cambiando los valores de DBNAME, USER y PWD:

MariaDB [(none)]> create database DBNAME;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> create user 'USER'@'%' identified by 'PWD';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> grant all privileges on DBNAME.* to 'USER'@'%';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)

Ahora tendremos que seguir exactamente el mismo procedimiento que el indicado en el apartado anterior, pero en lugar de cambiar los puertos en el contenedor vamos a especificar el nuevo acceso a la DB en el archivo de configuración.

Nos conectamos al contenedor (docker exec -ti ID bash), hacemos un backup del archivo de configuración (cp -pr config.json config.json.bkp) y agregamos el nuevo contenido en donde XX.XX.XX.XX es la IP del host que contiene la DB, USER y PWD el usuario y pasword , DBNAME el nombre de la base de datos indicados en su creación previa (echo ‘….’ > config.json):

{
        "admin_server" : {
                "listen_url" : "0.0.0.0:3333",
                "use_tls" : true,
                "cert_path" : "gophish_admin.crt",
                "key_path" : "gophish_admin.key"
        },
        "phish_server" : {
                "listen_url" : "0.0.0.0:80",
                "use_tls" : false,
                "cert_path" : "example.crt",
                "key_path": "example.key"
        },
        "db_name" : "mysql",
        "db_path" : "USER:PWD@(XX.XX.XX.XX:3306)/DBNAME?charset=utf8&parseTime=True&loc=Local",
        "migrations_prefix" : "db/db_"
}

Salimos del contenedor (exit), creamos una imagen del contenedor actual (dicker commit ID nuevo), paramos el contenedor actual para liberar los puertos (docker ps; docker stop ID; y si no queremos usarlo más lo borramos con docker rm ID), y levantamos el nuevo contenedor como demonio.

OJO CUIDADO!!! Si has parado los servicios de seguridad en tu servidor local o en el remoto (selinux, firewalld, ufw, …) puede que obtengas un error a la hora de levantar el contenedor, como el siguiente:

# docker run -d --name gophish -p 3333:3333 -p 8083:80 gophis-image
2024c1dcc8343e321a00d44b1af38a13885bb4ff906a5a0cdd43127b99fcf419
/usr/bin/docker-current: Error response from daemon: driver failed programming external connectivity on endpoint gophish-image (f7dead4f911baaf18fc5de7be87a5763c70349fe5fcff02c570befffc080938c):  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 8083 -j DNAT --to-destination 172.17.0.2:80 ! -i docker0: iptables: No chain/target/match by that name.
 (exit status 1)).

Esto es debido a que tras parar los elementos de seguridad es necesario reiniciar el demonio de Docker:

# service docker restart

Con esto ya se podría levantar el contenedor sin problema alguno. Recuerda antes borrar el contenedor creado.

# docker ps -a
CONTAINER ID        IMAGE                         COMMAND             CREATED             STATUS              PORTS                                          NAMES
fb24e58546d0        docker.io/matteoggl/gophish   "./gophish"         7 seconds ago       Up 6 seconds        0.0.0.0:3333->3333/tcp, 0.0.0.0:8083->80/tcp   gophish-mariadb

# docker stop fb24e58546d0; docker rm fb24e58546d0
fb24e58546d0
fb24e58546d0

# docker run -d --name gophish -p 3333:3333 -p 8083:80 gophish-image
fed51a48ed742e66c2aa6939e382753f611ac5c0f7f68e4862188dcdfc45f917

Para confirmar que todo funciona correctamente podemos observar los logs tras levantar el contenedor y ver que tanto la creación de las bases de datos como los puertos en las interfaces se levantaron correctamente:

# docker logs 11c2085053ae
time="2018-08-23T11:25:27Z" level=info msg="Background Worker Started Successfully - Waiting for Campaigns"
goose: migrating db environment 'production', current version: 0, target: 20180223101813
OK    20160118194630_init.sql
OK    20160131153104_0.1.2_add_event_details.sql
OK    20160211211220_0.1.2_add_ignore_cert_errors.sql
OK    20160217211342_0.1.2_create_from_col_results.sql
OK    20160225173824_0.1.2_capture_credentials.sql
OK    20160227180335_0.1.2_store-smtp-settings.sql
OK    20160317214457_0.2_redirect_url.sql
OK    20160605210903_0.2_campaign_scheduling.sql
OK    20161202153627_AttachmentFix.sql
OK    20170104231222_0.2_result_statuses.sql
OK    20170219122503_0.2.1_email_headers.sql
OK    20170828220440_0.4_utc_dates.sql
OK    20171027213457_0.4.1_maillogs.sql
OK    20171208201932_0.4.1_next_send_date.sql
OK    20180223101813_0.5.1_user_reporting.sql
time="2018-08-23T11:25:27Z" level=info msg="Starting phishing server at http://0.0.0.0:80\n"
time="2018-08-23T11:25:27Z" level=info msg="Starting admin server at https://0.0.0.0:3333\n"

 


Recomendaciones de seguridad

Para mejorar la seguridad del servicio es recomendable realizar las siguientes tareas previas a levantar el contenedor en producción, es decir realizar estas durante el proceso de creación y copia del contenedor original:

  • Levantar la interfaz de gestión en una IP sin acceso público.
  • Restringir el acceso a la interfaz de gestión identificando los orígenes permitidos.
  • Instalar un certificado correcto en lugar de usar los de por defecto.
  • Tras el cambio de Google sobre las páginas no seguras HTTP, levantar la página de phising en un puerto seguro (cambiar la línea del archivo de configuración «use_tls» : false por «use_tls» : true).
  • Hacer un backup diario o tras cada cambio en el contenedor para evitar problemas de pérdida de datos tras un reinicio del host.

 


Con estos pasos tendríamos nuestro entorno listo para comenzar a preparar las campañas de envío, cuyos pasos mostraremos en próximas entradas.

Aaaadios!!!!

 


Enlaces relacionados:

Gophish sitio oficial pincha aquí.

Docker contenedor oficial pincha aquí.

Docker sitio oficial pincha aquí.

Docker lista de comandos en Castellano pincha aquí.