Skip to content
Web Inventory tool, takes screenshots of webpages using Pyppeteer (headless Chrome/Chromium) and provides some extra bells & whistles to make life easier.
Branch: master
Clone or download
byt3bl33d3r Potential temporary fix for #4
There's a bug in the underlying library that communicates with headless
Chrome/Chromium that causes the WS connection to the browser to close at
seemingly random intervals ? (Seems to happen consistently after 4-5 min
from the connection being established).

I *think* this is caused by the Chrome DevTools Protocol not having
implemented a WS ping/pong frame to maintain a connection open for long
periods of time. Consequently, whenever pyppeteer sends one of these, Chrome freaks
the fuck out and closes the WS connection. You can reproduce this by
forcibly calling in the underlying WS connection.

The only way to get around this currently seems to be opening and
closing Chrome after a 'batch' screenshots have been taken. Sucks but it works.
Latest commit e1b5ec1 Dec 2, 2019



My take on a Web Inventory tool, heavily inspired by Eyewitness. Takes screenshots of webpages using Pyppeteer (headless Chrome/Chromium).

Supports Python >= 3.7, uses Asyncio and has some extra bells & whistles that makes life easier.

Why & what problems does this solve

  • Python >= 3.7
  • No dependency/installation hell, works on a variety of *nix flavors
  • Asyncio provides Mad Max level speeds
  • Headless chrome/chromium is just straight up gangsta


git clone && cd WitnessMe
pip3 install --user pipenv && pipenv install --three
pipenv shell # Enter the virtualenv

Call for Signatures!

If you run into a new webapp write a signature for it! It's beyond simple and they're all in YAML!

Don't believe me? Here's the AirOS signature (you can find them all in the signatures directory):

- password: ubnt
  username: ubnt
name: AirOS
- airos_logo.png
- form enctype="multipart/form-data" id="loginform" method="post"
- align="center" class="loginsubtable"
- function onLangChange()
# AirOS ubnt/ubnt

Yup that's it. Just plop it in the signatures folder and POW! Done.

Usage & Examples is what takes the screenshots, allows you to browse the database created on each scan.

usage: [-h] [-p PORTS [PORTS ...]] [--threads THREADS]
                    [--timeout TIMEOUT]
                    target [target ...]

positional arguments:
  target                The target IP(s), range(s), CIDR(s) or hostname(s)

optional arguments:
  -h, --help            show this help message and exit
  -p PORTS [PORTS ...], --ports PORTS [PORTS ...]
                        Ports to scan if IP Range/CIDR is provided (default:
                        [80, 8080, 443, 8443])
  --threads THREADS     Number of concurrent threads (default: 25)
  --timeout TIMEOUT     Timeout for each connection attempt in seconds
                        (default: 35)

Can accept a mix of .Nessus file(s), Nmap XML file(s), files containing URLs and/or IPs, IP addresses/ranges/CIDRs and URLs. Long story short, should be able to handle anything you throw at it:

python ~/my_nessus_scan.nessus ~/my_nmap_scan.xml ~/myfilewithURLSandIPs

Note: as of writing, WitnessMe detects .Nessus and NMap files by their extension so make sure Nessus files have a .nessus extension and NMap scans have a .xml extension

If an IP address/range/CIDR is specified as a target, WitnessMe will attempt to screenshot HTTP & HTTPS pages on ports 80, 8080, 443, 8443 by default. This is customizable with the --port argument.

Once a scan is completed, a folder with all the screenshots and a database will be in the current directory, point to the database in order to see the results.

python scan_2019_11_05_021237/witnessme.db

Pressing tab will show you the available commands and a help menu:


Searching the Database

The servers and hosts commands in the CLI accept 1 argument. WMDB is smart enough to know what you're trying to do with that argument

Server Command

No arguments will show all discovered servers. Passing it an argument will search the title and server columns for that pattern (it's case insensitive).

For example if you wanted to search for all discovered Apache Tomcat servers:

  • servers tomcat or servers 'apache tomcat'

Similarly if you wanted to find servers with a 'login' in the title:

  • servers login

Hosts Command

No arguments will show all discovered hosts. Passing it an argument will search the IP and Hostname columns for that pattern (it's case insensitive). If the value corresponds to a Host ID it will show you the host information and all of the servers discovered on that host which is extremely useful for reporting purposes and/or when targeting specific hosts.

Signature Scan

You can perform a signature scan on all discovered services using the scan command.

Preview Screenshots Directly in the Terminal (ITerm2 on MacOSX)

If you're using ITerm2 on MacOSX, you can preview screenshots directly in the terminal using the show command:


To Do

  1. Store server info to a database
  2. HTML report generation
  3. Cmdline script to search database
  4. Support NMap & .nessus files as input (Almost there, still some bugs but usable)
  5. Web server categorization & signature support
  6. Accept URLs as targets (cmdline, files)
  7. Add support for previewing screenshots in *nix terminals using w3m
You can’t perform that action at this time.