
Un outil de rapport de test d'intrusion écrit en Python. Libérez-vous de Microsoft Word.
WriteHat est un outil de génération de rapports qui élimine Microsoft Word (et de nombreuses heures de souffrance) du processus de création de rapports. Markdown --> HTML --> PDF. Créé par des testeurs d'intrusion, pour les testeurs d'intrusion - mais peut être utilisé pour générer tout type de rapport. Écrit en Django (Python 3).

docker et docker-compose
apt, pacman, dnf, etc.$ sudo apt install docker.io docker-compose
WriteHat peut être déployé en une seule commande :
$ git clone https://github.com/blacklanternsecurity/writehat && cd writehat && docker-compose up
Connectez-vous à https://127.0.0.1 (par défaut : admin / PLEASECHANGETHISFORHEAVENSSAKE)
Installez Docker et Docker Compose
Clonez le dépôt WriteHat dans /opt
$ cd /opt
$ git clone https://github.com/blacklanternsecurity/writehat
$ cd writehat
Créez des mots de passe sécurisés dans writehat/config/writehat.conf pour :
docker-compose.yml)docker-compose.yml)writehat/config/writehat.conf et docker-compose.yml : (chown root:root; chmod 600)Ajoutez votre nom d'hôte souhaité à allowed_hosts dans writehat/config/writehat.conf
Voici des explications de base pour certains termes WriteHat qui peuvent ne pas être évidents.
Engagement
├─ Customer
├─ Finding Group 1
│ ├─ Finding
│ └─ Finding
├─ Finding Group 2
│ ├─ Finding
│ └─ Finding
├─ Report 1
└─ Report 2
└─ Page Template
Un Engagement est l'endroit où le contenu est créé pour le client. C'est là que le travail se fait - créer des rapports et saisir des constatations.
Un Rapport est un agencement modulaire et hiérarchique de Composants qui peut être facilement mis à jour via une interface glisser-déposer, puis rendu en HTML ou PDF. Un engagement peut avoir plusieurs Rapports. Un Modèle de Page peut être utilisé pour personnaliser l'arrière-plan et le pied de page. Un Rapport peut également être converti en Modèle de Rapport.
Un Composant de rapport est une section ou un module du rapport qui peut être glissé/déposé à sa place dans le créateur de rapport. Les exemples incluent "Page de titre", "Markdown", "Constatations", etc. Il existe de nombreux composants intégrés, mais vous pouvez aussi créer les vôtres. (Ce ne sont que du HTML/CSS + Python, c'est donc assez simple. Voir le guide ci-dessous).
Un Modèle de Rapport peut être utilisé comme point de départ pour un Rapport (dans un Engagement). Les Rapports peuvent également être convertis en Modèles de Rapport.
Un Groupe de Constatations est une collection de constatations qui sont notées de la même manière (par exemple CVSS ou DREAD). Vous pouvez créer plusieurs groupes de constatations par engagement (par exemple "Constatations Techniques" et "Constatations du Trésor"). Lors de l'insertion des constatations dans le Rapport (via le Composant "Constatations", par exemple), vous devez sélectionner quel Groupe de Constatations vous souhaitez remplir ce Composant.
Un Modèle de Page vous permet de personnaliser les images d'arrière-plan et les pieds de page du rapport. Vous pouvez définir un Modèle de Page par défaut, et il sera appliqué globalement sauf s'il est remplacé au niveau de l'Engagement ou du Rapport.
Chaque composant de rapport est constitué des éléments suivants :
writehat/components/writehat/templates/componentTemplates/writehat/static/css/component/ (optionnel)Nous recommandons de consulter les fichiers existants dans ces répertoires ; ils constituent de bons points de départ / exemples.
Un composant personnalisé simple ressemblerait à ceci :
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
Note that fields must share the same name in both the component class and its form. All components must either inherit from BaseComponent or another component. Additionally, each component has built-in fields for name, pageBreakBefore (whether to start on a new page), and showTitle (whether or not to display the name field as a header). So it's not necessary to add those.
componentTemplates/CustomComponent.html :Fields from the Python module are automatically added to the template context. In this example, we want to render the summary field as markdown, so we add the markdown tag in front of it. Note that you can also access engagement and report-level variables, such as 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 (optionnel) :The filename must match that of the Python file (but with a .css extension instead of .py). It is loaded automatically when the report is rendered.
div.custom-component-summary {
font-weight: bold;
}
Once the above files are created, simply restart the web app and it the new component will populate automatically.
$ docker-compose restart writehat
Si une mise à jour est publiée et modifie le schéma de la base de données, les migrations de base de données Django sont exécutées automatiquement lors du redémarrage du conteneur. Cependant, une interaction de l'utilisateur peut parfois être nécessaire. Pour appliquer les migrations Django manuellement :
systemctl stop writehat)/opt/writehat)$ docker-compose run writehat bash
$ ./manage.py makemigrations
$ ./manage.py migrate
$ exit
$ docker-compose down
$ systemctl start writehat
Notez qu'il existe déjà une fonctionnalité intégrée pour cela dans la page /admin de l'application web. Vous pouvez utiliser cette méthode si vous souhaitez effectuer une sauvegarde au niveau des fichiers via cron, etc.
systemctl stop writehat)systemctl stop writehat)mysql, mongo et writehat/migrations et copiez l'archive sur le système de destination (même emplacement) :# MUST RUN AS ROOT
$ sudo tar --same-owner -cvzpf db_backup.tar.gz mongo mysql writehat/migrations
migrations$ mv writehat/migrations writehat/migrations.bak
$ sudo tar --same-owner -xvpzf db_backup.tar.gz
$ systemctl start writehat
(Optionnel) Remplacez les certificats SSL auto-signés dans nginx/ :
writehat.crtwritehat.keyTestez que tout fonctionne :
$ docker-compose up --build
Remarque : Si vous utilisez un VPN, vous devez vous déconnecter du VPN la première fois que vous démarrez les services avec docker-compose. Ceci permet à Docker de créer avec succès le réseau virtuel.
Installez et activez le service Systemd :
Cela démarrera WriteHat automatiquement au démarrage
$ sudo cp writehat/config/writehat.service /etc/systemd/system/
$ sudo systemctl enable writehat --now
Suivez les logs du service :
$ sudo journalctl -xefu writehat.service
Créez des utilisateurs
Accédez à https://127.0.0.1/admin après vous être connecté avec l'utilisateur admin spécifié dans writehat/config/writehat.conf
Remarque : Certaines actions ne peuvent être effectuées que par un administrateur (par exemple, les sauvegardes de base de données). Un utilisateur admin est automatiquement créé à partir du nom d'utilisateur et du mot de passe dans writehat/config/writehat.conf, mais vous pouvez également promouvoir un utilisateur LDAP en administrateur :
# Enter the app container
$ docker-compose exec writehat bash
# Promote the user and exit
$ ./manage.py ldap_promote <ldap_username>
$ exit