WriteHat es una herramienta de elaboración de informes que elimina Microsoft Word (y muchas horas de sufrimiento) del proceso de elaboración de informes.
Markdown –> HTML –> PDF. Creado por probadores de penetración, para probadores de penetración – pero puede ser utilizado para generar cualquier tipo de informe. Escrito en Django (Python 3).
- Características
- Despliegue de WriteHat (La manera rápida y fácil, para las pruebas)
- Despliegue de WriteHat (La manera correcta)
- Terminología
- Escribir Componentes de Informes Personalizados
- Actualización/Migración Manual de la Base de Datos
- Copia de seguridad/restauración Manual de la Base de Datos
- Hoja de ruta / Posibles desarrollos futuros
- Errores conocidos / Limitaciones
Características
- Genera sin esfuerzo hermosos informes de pentest
- Constructor de informes de arrastrar y soltar sobre la marcha
- Soporte de Markdown – incluyendo bloques de código, tablas, etc.
- Recorte, anotaciones, subtítulos y carga de imágenes
- Fondo / pie de página del informe personalizable
- Asignación de operadores y estados de seguimiento para las secciones individuales del informe
- Posibilidad de clonar y crear plantillas de informes
- Base de datos de hallazgos
- Soporta múltiples tipos de puntuación (CVSS 3.1, DREAD)
- Puede generar fácilmente varios informes a partir del mismo conjunto de hallazgos
- El diseño extensible permite a los usuarios avanzados crear secciones de informes altamente personalizadas
- Integración de LDAP
Instalar docker
y docker-compose
- Normalmente se pueden instalar con
apt
,pacman
,dnf
, etc.
$ sudo apt install docker.io docker-compose
Despliegue de WriteHat (La manera rápida y fácil, para las pruebas)
WriteHat puede desplegarse con un solo comando:
$ git clone https://github.com/blacklanternsecurity/writehat && cd writehat && docker-compose up
Inicia sesión en https://127.0.0.1 (por defecto: admin
/ PLEASECHANGETHISFORHEAVENSSAKE
)
Despliegue de WriteHat (La manera correcta)
- Instalar Docker y Docker Compose
- Clona el Repo de WriteHat en
/opt
$ cd /opt
$ git clone https://github.com/blacklanternsecurity/writehat
$ cd writehat
- Crear contraseñas seguras en
writehat/config/writehat.conf
para:- MongoDB (también introducir en
docker-compose.yml
) - MySQL (también introducir en
docker-compose.yml
) - Django (usado para encriptar cookies, etc.)
- Admin user Nota: Nota: No es necesario modificar nada más, aparte de las contraseñas, si utiliza la configuración por defect Nota: No olvides bloquear los permisos en
writehat/config/writehat.conf
ydocker-compose.yml
: (chown root:root; chmod 600
)
- MongoDB (también introducir en
- Añade tu nombre de host deseado a
allowed_hosts
inwritehat/config/writehat.conf
- (Opcional) Reemplaza los certificados SSL autofirmados en
nginx/
:writehat.crt
writehat.key
- Pruebe que todo funciona:
$ docker-compose up --build
Nota: Si se utiliza una VPN, es necesario desconectarse de la VPN la primera vez que se ejecutan los servicios con docker-compose
. Esto es para que docker pueda crear con éxito la red virtual.
- Instalar y activar el servicio Systemd:
Esto iniciará WriteHat automáticamente al arrancar
$ sudo cp writehat/config/writehat.service /etc/systemd/system/
$ sudo systemctl enable writehat --now
- Cola de los registros de servicio:
$ sudo journalctl -xefu writehat.service
- Crear usuarios
Navega a https://127.0.0.1/admin después de iniciar sesión con el usuario admin especificado en writehat/config/writehat.conf
Nota: Hay algunas acciones que sólo puede realizar un admin (por ejemplo, las copias de seguridad de la base de datos) Un usuario admin se crea automáticamente a partir del nombre de usuario y la contraseña en writehat/config/writehat.conf
, pero también puedes promover un usuario LDAP a admin:
# Enter the app container
$ docker-compose exec writehat bash
# Promote the user and exit
$ ./manage.py ldap_promote <ldap_username>
$ exit
Terminología
Aquí hay explicaciones básicas para algunos términos de WriteHat que pueden no ser obvios.
Engagement
├─ Customer
├─ Finding Group 1
│ ├─ Finding
│ └─ Finding
├─ Finding Group 2
│ ├─ Finding
│ └─ Finding
├─ Report 1
└─ Report 2
└─ Page Template
Engagement
Un Engagement es donde se crea el contenido para el cliente. Aquí es donde tiene lugar el trabajo: la creación de informes y la introducción de resultados.
Report
Un Report es una disposición modular y jerárquica de componentes que pueden actualizarse fácilmente mediante una interfaz de arrastrar y soltar, y luego convertirse en HTML o PDF. Un Engagement puede tener múltiples Reports. Se puede utilizar una plantilla de página para personalizar el fondo y el pie de página. Un Reports también puede convertirse en una plantilla de informe.
Report Component
Un Component del informe es una sección o módulo del informe que puede ser arrastrado/soltado en su lugar dentro del creador del informe. Los ejemplos incluyen “Página de título“, “Markdown“, “Hallazgos“, etc. Hay muchos componentes incorporados, pero también puedes crear los tuyos propios. (Son sólo HTML/CSS + Python, así que es bastante fácil. Ver la guía más abajo)
Report Template
Un Report Template puede utilizarse como punto de partida para un informe (en un Engagement). Los informes también se pueden convertir en plantillas de informes.
Finding Group
Un Finding Group es una colección de hallazgos que se puntúan de la misma manera (por ejemplo, CVSS o DREAD). Se pueden crear varios grupos de hallazgos por Engagement (por ejemplo, “Hallazgos técnicos” y “Hallazgos de tesorería“). Al insertar los hallazgos en el informe (a través del componente “Findings“, por ejemplo), hay que seleccionar qué grupo de hallazgos quiere rellenar ese componente.
Page Template
Una Page Template te permite personalizar las imágenes de fondo y los pies de página de los informes. Puedes establecer una Plantilla de Página como la predeterminada, y se aplicará globalmente a menos que se anule en el nivel de Engagement o de Report.
Escribir Componentes de Informes Personalizados
Cada componente del informe se compone de lo siguiente:
- Un archivo Python en
writehat/components/
- Una plantilla HTML en
writehat/templates/componentTemplates/
- Un archivo CSS en
writehat/static/css/component/
(opcional)
Recomendamos hacer referencia a los archivos existentes en estos directorios; funcionan bien como puntos de partida / ejemplos.
Un simple componente personalizado tendría este aspecto:
components/CustomComponent.py:
from .base import *
class CustomComponentForm(ComponentForm):
summary = forms.CharField(label='Component Text', widget=forms.Textarea, max_length=50000, required=False)
field_order = ['name', 'summary', 'pageBreakBefore', 'showTitle']
class Component(BaseComponent):
default_name = 'Custom Report Component'
formClass = CustomComponentForm
# the "templatable" attribute decides whether or not that field
# gets saved if the report is ever converted into a template
fieldList = {
'summary': StringField(markdown=True, templatable=True),
}
# make sure to specify the HTML template
htmlTemplate = 'componentTemplates/CustomComponent.html'
# Font Awesome icon type + color (HTML/CSS)
# This is just eye candy in the web app
iconType = 'fas fa-stream'
iconColor = 'var(--blue)'
# the "preprocess" function is executed when the report is rendered
# use this to perform any last-minute operations on its data
def preprocess(self, context):
# for example, to uppercase the entire "summary" field:
# context['summary'] = context['summary'].upper()
return context
Ten en cuenta que los campos deben compartir el mismo nombre tanto en la clase del componente como en su formulario. Todos los componentes deben heredar de BaseComponent
o de otro componente. Además, cada componente tiene campos incorporados paraname
, pageBreakBefore
(si se inicia en una nueva página), y showTitle
(si se muestra o no el campo name
como cabecera/header). Así que no es necesario añadirlos.
componentTemplates/CustomComponent.html:
Los campos del módulo Python se añaden automáticamente al contexto de la plantilla. En este ejemplo, queremos renderizar el campo summary
como markdown, así que añadimos la etiqueta markdown
delante de él. Ten en cuenta que también puedes acceder a las variables de nivel de engagement y de report, como report.name
, report.findings
, engagement.customer.name
, etc.
{% load custom_tags %}
<section class="l{{ level }} component{% if pageBreakBefore %} page-break{% endif %}" id="container_{{ id }}">
{% include 'componentTemplates/Heading.html' %}
<div class='markdown-align-justify custom-component-summary'>
<p>
{% markdown summary %}
</p>
</div>
</section>
componentTemplates/CustomComponent.css (opcional):
El nombre del archivo debe coincidir con el del archivo Python (pero con una extensión .css
en lugar de .py
). Se cargará automáticamente cuando el informe se renderice.
div.custom-component-summary {
font-weight: bold;
}
Una vez creados los archivos anteriores, basta con reiniciar la aplicación web para que el nuevo componente se rellene automáticamente.
$ docker-compose restart writehat
Actualización/Migración Manual de la Base de Datos
Si se envía una actualización que cambia el esquema de la base de datos, las migraciones de la base de datos de Django se ejecutan automáticamente cuando se reinicia el contenedor. Sin embargo, a veces puede ser necesaria la interacción del usuario. Para aplicar las migraciones de Django manualmente:
- Detener WriteHat (
systemctl stop writehat
) - cd para entrar en el directorio de WriteHat (
/opt/writehat
) - Inicia el contenedor docker
$ docker-compose run writehat bash
- Una vez en el contenedor, aplica las migraciones como de costumbre:
$ ./manage.py makemigrations
$ ./manage.py migrate
$ exit
- Desactivar los contenedores Docker y reiniciar el servicio
$ docker-compose down
$ systemctl start writehat
Copia de seguridad/restauración Manual de la Base de Datos
Ten en cuenta que ya existe una funcionalidad in-app para esto en la página /admin
de la aplicación web. Puedes utilizar este método si quieres hacer un trabajo de copia de seguridad a nivel de archivo a través de cron
, etc.
- En el sistema de destino:
- Sigue los pasos normales de instalación
- Detener WriteHat (
systemctl stop writehat
)
- En el sistema de origen:
- Detener WriteHat (
systemctl stop writehat
)
- Detener WriteHat (
- THaz un TAR de los directorios
mysql
,mongo
, ywritehat/migrations
y copia el archivo en el sistema de destino (en la misma ubicación):
# MUST RUN AS ROOT
$ sudo tar --same-owner -cvzpf db_backup.tar.gz mongo mysql writehat/migrations
- En el sistema de destino, haz una copia de seguridad del directorio
migrations
$ mv writehat/migrations writehat/migrations.bak
- Extraer el archivo TAR en el destino
$ sudo tar --same-owner -xvpzf db_backup.tar.gz
- Iniciar WriteHat en el nuevo sistema
$ systemctl start writehat
Hoja de ruta / Posibles desarrollos futuros
- Seguimiento de cambios y revisiones
- Funcionalidad de revisión/retroalimentación más profunda
- Edición colaborativa multiusuario similar a la de Google Docs
- Función de exportación JSON
- Generación de diapositivas para presentaciones
- Creador de tablas más avanzado con función de carga de CSV
- Permisos más granulares / ACLs (más allá de los roles de usuario + administrador)
Errores conocidos / Limitaciones
- Chrome o Chromium es el navegador recomendado. Otros no han sido probados y pueden presentar errores.
- El campo “Assignee” en los componentes de los informes sólo funciona con usuarios LDAP, no locales.
- Las anotaciones en las imágenes a veces saltan ligeramente cuando se aplican. Es un error conocido que estamos rastreando con la biblioteca JS: issues-40 – https://github.com/ailon/markerjs/issues/40
- Los errores visuales aparecen ocasionalmente en los saltos de página. Se pueden solucionar insertando manualmente un salto de página en el markdown afectado (hay un botón para ello en el editor).
https://github.com/blacklanternsecurity/writehat