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!!!!!
Tabla de contenidos
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í.