• Stars
    star
    1,260
  • Rank 37,337 (Top 0.8 %)
  • Language
    Python
  • License
    GNU General Publi...
  • Created almost 4 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A pentest reporting tool written in Python. Free yourself from Microsoft Word.

WriteHat WriteHat is a reporting tool which removes Microsoft Word (and many hours of suffering) from the reporting process. Markdown --> HTML --> PDF. Created by penetration testers, for penetration testers - but can be used to generate any kind of report. Written in Django (Python 3).

Features:

  • Effortlessly generate beautiful pentest reports
  • On-the-fly drag-and-drop report builder
  • Markdown support - including code blocks, tables, etc.
  • Crop, annotate, caption, and upload images
  • Customizable report background / footer
  • Assign operators and track statuses for individual report sections
  • Ability to clone and template reports
  • Findings database
  • Supports multiple scoring types (CVSS 3.1, DREAD)
  • Can easily generate multiple reports from the same set of findings
  • Extensible design enables power users to craft highly-customized report sections
  • LDAP integration

writehat_report

Installation Prerequisites:

  • Install docker and docker-compose
    • These can usually be installed using apt, pacman, dnf, etc.
    $ sudo apt install docker.io docker-compose
    

Deploying WriteHat (The quick and easy way, for testing):

WriteHat can be deployed in a single command:

$ git clone https://github.com/blacklanternsecurity/writehat && cd writehat && docker-compose up

Log in at https://127.0.0.1 (default: admin / PLEASECHANGETHISFORHEAVENSSAKE)

Deploying WriteHat (The right way):

  1. Install Docker and Docker Compose

  2. Clone the WriteHat Repo into /opt

    $ cd /opt
    $ git clone https://github.com/blacklanternsecurity/writehat
    $ cd writehat
    
  3. Create Secure Passwords in writehat/config/writehat.conf for:

    • MongoDB (also enter in docker-compose.yml)
    • MySQL (also enter in docker-compose.yml)
    • Django (used for encrypting cookies, etc.)
    • Admin user Note: Nothing else aside from the passwords need to be modified if you are using the default configuration Note: Don't forget to lock down the permissions on writehat/config/writehat.conf and docker-compose.yml: (chown root:root; chmod 600)
  4. Add Your Desired Hostname to allowed_hosts in writehat/config/writehat.conf

  5. (Optional) Replace the self-signed SSL certificates in nginx/:

    • writehat.crt
    • writehat.key
  6. Test That Everything's Working:

    $ docker-compose up --build
    

    Note: If using a VPN, you need to be disconnected from the VPN the first time you run bring up the services with docker-compose. This is so docker can successfully create the virtual network.

  7. Install and Activate the Systemd Service:

    This will start WriteHat automatically upon boot

    $ sudo cp writehat/config/writehat.service /etc/systemd/system/
    $ sudo systemctl enable writehat --now
    
  8. Tail the Service Logs:

    $ sudo journalctl -xefu writehat.service
    
  9. Create Users

    Browse to https://127.0.0.1/admin after logging in with the admin user specified in writehat/config/writehat.conf Note: There are some actions which only an admin can perform (e.g. database backups) An admin user is automatically created from the username and password in writehat/config/writehat.conf, but you can also promote an LDAP user to admin:

    # Enter the app container
    $ docker-compose exec writehat bash
    
    # Promote the user and exit
    $ ./manage.py ldap_promote <ldap_username>
    $ exit
    

Terminology

Here are basic explanations for some WriteHat terms which may not be obvious.

Engagement
 ├─ Customer
 ├─ Finding Group 1
 │   ├─ Finding
 │   └─ Finding
 ├─ Finding Group 2
 │   ├─ Finding
 │   └─ Finding
 ├─ Report 1
 └─ Report 2
     └─ Page Template

Engagement

An Engagement is where content is created for the customer. This is where the work happens - creating reports and entering findings.

Report

A Report is a modular, hierarchical arrangement of Components which can be easily updated via a drag-and-drop interface, then rendered into HTML or PDF. An engagement can have multiple Reports. A Page Template can be used to customize the background and footer. A Report can also be converted into a Report Template.

Report Component

A report Component is a section or module of the report that can be dragged/dropped into place inside the report creator. Examples include "Title Page", "Markdown", "Findings", etc. There are plenty of built-in components, but you can make your own as well. (They're just HTML/CSS + Python, so it's pretty easy. See the guide below)

Report Template

A Report Template can be used as a starting point for a Report (in an Engagement). Reports can also be converted to Report Templates.

Finding Group

A Finding Group is a collection of findings that are scored in the same way (e.g. CVSS or DREAD). You can create multiple finding groups per engagement (e.g. "Technical Findings" and "Treasury Findings"). When inserting the findings into the Report (via the "Findings" Component, for example), you need to select which Finding Group you want to populate that Component.

Page Template

A Page Template lets you customize report background images and footers. You can set one Page Template as the default, and it will be applied globally unless overridden at the Engagement or Report level.

Writing Custom Report Components

report_creation Each report component is made up of the following:

  1. A Python file in writehat/components/
  2. An HTML template in writehat/templates/componentTemplates/
  3. A CSS file in writehat/static/css/component/ (optional)

We recommend referencing the existing files in these directories; they work well as starting points / examples.

A simple custom component would look like this:

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 (optional):

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

Manual DB Update/Migration

If an update is pushed that changes the database schema, Django database migrations are executed automatically when the container is restarted. However, user interaction may sometimes be required. To apply Django migrations manually:

  1. Stop WriteHat (systemctl stop writehat)
  2. cd into the WriteHat directory (/opt/writehat)
  3. Start the docker container
$ docker-compose run writehat bash
  1. Once in the container, apply the migrations as usual:
$ ./manage.py makemigrations
$ ./manage.py migrate
$ exit
  1. Bring down the docker containers and restart the service
$ docker-compose down
$ systemctl start writehat

Manual DB Backup/Restore

Note that there is already in-app functionality for this in the /admin page of the web app. You can use this method if you want to make a file-level backup job via cron, etc.

  1. On the destination system:
    • Follow normal installation steps
    • Stop WriteHat (systemctl stop writehat)
  2. On the source system:
    • Stop WriteHat (systemctl stop writehat)
  3. TAR up the mysql, mongo, and writehat/migrations directories and copy the archive to the destination system (same location):
# MUST RUN AS ROOT
$ sudo tar --same-owner -cvzpf db_backup.tar.gz mongo mysql writehat/migrations
  1. On the destination system, make a backup of the migrations directory
$ mv writehat/migrations writehat/migrations.bak
  1. Extract the TAR archive on the destination
$ sudo tar --same-owner -xvpzf db_backup.tar.gz
  1. Start WriteHat on the new system
$ systemctl start writehat

Roadmap / Potential Future Developments:

  • Change tracking and revisions
  • More in-depth review/feedback functionality
  • Collaborative multi-user editing similar to Google Docs
  • JSON export feature
  • Presentation slide generation
  • More advanced table creator with CSV upload feature
  • More granular permissions / ACLs (beyond just user + admin roles)

Known Bugs / Limitations:

  • Chrome or Chromium is the recommended browser. Others are untested and may experience bugs.
  • "Assignee" field on report components only works with LDAP users, not local ones.
  • Annotations on images sometimes jump slightly when applied. It's a known bug that we're tracking with the JS library: ailon/markerjs#40
  • Visual bugs appear occasionally on page breaks. These can be fixed by manually inserting a page break in the affected markdown (there's a button for it in the editor).

More Repositories

1

bbot

A recursive internet scanner for hackers.
Python
4,389
star
2

TREVORspray

TREVORspray is a modular password sprayer with threading, clever proxying, loot modules, and more!
Python
1,016
star
3

MANSPIDER

Spider entire networks for juicy files sitting on SMB shares. Search filenames or file content - regex supported!
Python
974
star
4

badsecrets

A library for detecting known secrets across many web frameworks
Python
471
star
5

TREVORproxy

A SOCKS proxy written in Python that randomizes your source IP address. Round-robin your evil packets through SSH tunnels or give them billions of unique source addresses!
Python
315
star
6

offensive-azure

Collection of offensive tools targeting Microsoft Azure
Python
164
star
7

kali-setup-script

Bash script which prepares Kali for a pentest by enabling session logging, installing tools, and making common configuration changes
Shell
136
star
8

baddns

Check subdomains for subdomain takeovers and other DNS tomfoolery
Python
94
star
9

spiderfoot-neo4j

Import, visualize, and analyze SpiderFoot scans in Neo4j, a graph database
Python
65
star
10

credshed

credshed - a scalable database for credential leaks. Written in Python, it can easily ingest poorly-formatted files or entire directories into a searchable database. MongoDB is used in the backend.
Python
53
star
11

cloudcheck

Check whether an IP address or hostname belongs to popular cloud providers
Python
45
star
12

dp_cryptomg

Another tool for exploiting CVE-2017-9248, a cryptographic weakness in Telerik UI for ASP.NET AJAX dialog handler.
Python
43
star
13

KCMTicketFormatter

Format SSSD Raw Kerberos Payloads into CCACHE files for use on Windows systems
Python
35
star
14

Convert-Invoke-Kerberoast

Converts the output from Invoke-Kerberoast into hashcat format.
Python
32
star
15

fulcrom

A web shell for pivoting and lateral movement
Python
32
star
16

evilginx-setup-script

A quick-and-easy bash script installing and launching EvilGinx2, a phishing reverse-proxy
Shell
24
star
17

bls-bible

BLS-Bible is a knowledge-base application that houses a collection of guides and write-ups that BLS uses for our various operations.
Python
24
star
18

zmap-asset-inventory

Python script which takes internal asset inventory at scale using zmap. Outputs to CSV.
Python
20
star
19

public-dns-servers

A CI/CD-verified list of the internet's known-good public DNS servers (from public-dns.info) Updated weekly!
Python
20
star
20

enter_the_matrix

ETM enables the creation of detailed attack graphs and figures while calculating the risk associated with your attack narratives. ETM was built keeping NIST recommendations on threat matrices in mind. Features an API to interact on your data to act as a living database of your executed threat models.
C#
20
star
21

bbot-vivagraphjs

Visualize BBOT scans in realtime with VivaGraphJS
HTML
19
star
22

webspray

Fuzz for hidden proxies, vhosts, and URLs
Python
16
star
23

sigma-rules

A collection of Sigma rules organized by MITRE ATT&CK technique
13
star
24

bbot-module-playground

A proving grounds for young and aspiring BBOT modules
Python
13
star
25

nmappalyzer

A lightweight Python 3 Nmap wrapper that doesn't try too hard. Gracefully handles any Nmap command, providing access to all output types (normal, greppable, xml), plus JSON!
Python
12
star
26

mklnk

Create a lnk shortcut file for Windows
Python
8
star
27

parse-crackmapexec

Generates statistics based on output from CrackMapExec. Ideal for enumeration of host-based controls.
Python
8
star
28

credshed-api

REST API for Credshed
Python
6
star
29

credshed-gui

Vue.js frontend for credshed
SCSS
6
star
30

Cisco-7937G-PoCs

Proofs of concept for three vulnerabilities affecting the Cisco 7937G Conference Station
Python
5
star
31

JSDiagrammer

Simple javascript library that will aid in creating simple diagrams with pictures for nodes and arrows for the edges connecting nodes.
JavaScript
5
star
32

blue-resources

A collection of helpful blue team resources
4
star
33

radixtarget

RadixTarget is a performant radix implementation designed for quick lookups of IP addresses/networks and DNS hostnames.
Python
4
star
34

filter-qualys-csv

Cut down on the size of Qualys' scan results by filtering based on severity, keywords, etc. Written in Python.
Python
3
star
35

BLSPyUtils

Repo for small functions used often in Python.
Python
3
star
36

ASM_BBOT_Training

HCL
2
star