
An modular asset discovery framework written in python to automate the repeating manual work
Cygor is a modular asset discovery framework that brings scanning, parsing, and service enumeration together in one workflow. It replaces the patchwork of separate tools with an automated process that handles discovery, enrichment, and targeted enumeration seamlessly — reducing manual overhead and letting you focus on results instead of tool management.
Cygor’s Web UI takes the chaos of raw scan data and organizes it into a single, visual command center. Instead of combing through endless XML, JSON, or flat text, results are automatically parsed, enriched, and displayed in one space that’s built for fast triage and decision-making.
Powered by FastAPI and Bootstrap 5, the dashboard makes it easy to:
The Web UI isn’t just for presentation — it’s about efficiency and clarity. By bringing all collected data into a single, interactive workspace, it cuts down the time spent parsing files or reconciling outputs and lets testers focus on what matters: understanding the environment and acting on it.
A lot of tools, techniques, and tradecrafts that I create are inspired from the Spawn Universe. If you have never read a Spawn comic, it's okay as I will share some information as to why I selected the character to be the name of this tool.
The name Cygor draws from Cy-Gor, a tragic anti-hero in the Spawn universe. Once Michael Konieczny — a government operative and close friend of Al Simmons — he tried to expose corruption after Simmons’s murder. However, he was captured and forced into Project Sim, the Simian experiments of Dr. Frederick Willheim, where a gorilla’s body was merged with Konieczny’s mind through invasive cybernetics. The result was the beast known as Cy-Gor — short for Cybernetic Gorilla.
After escaping captivity, Cy-Gor went on violent rampages, even tearing through government data centers in fits of confusion and rage. Though hunted and recaptured multiple times, he eventually fought back against the systems that sought to control him — removing tracking implants and breaking free to forge his own path, torn between machine, beast, and man.
webenum module (only the installed tools run).There are a few methods that are supported to install Cygor: pip, pipx, uv, and docker.
Some dependencies (e.g. gssapi for Kerberos/WinRM) build C extensions, so install the build toolchain and Kerberos headers first:
# Debian/Ubuntu/Kali:
sudo apt install -y build-essential python3-dev libkrb5-dev
# Stable version:
pipx install cygor
# Install from source:
git clone https://github.com/tjnull/cygor
cd cygor
pipx install .
Cygor's Docker setup includes both the application and a PostgreSQL database service. The system automatically falls back to SQLite if PostgreSQL is unavailable.
Production (recommended):
# Option 1: Use the wrapper script (automatically handles port conflicts)
./docker-compose-up.sh up --build
# Option 2: Direct docker compose (uses default ports)
docker compose up --build
Development (with source code mounted):
# Option 1: Use the wrapper script (automatically handles port conflicts)
./docker-compose-up.sh dev up --build
# Option 2: Direct docker compose (uses default ports)
docker compose -f docker-compose-dev.yaml up --build
The Docker Compose setup includes:
results/: Scan outputs, credrecon results, and database filescygor-config/: Local config volume (created automatically)By default:
5432 (if available)5434 (if available)5432 internally (Docker network)If ports are in use, you can:
Use the wrapper script (recommended - auto-detects available ports):
./docker-compose-up.sh up --build
Set port manually:
export POSTGRES_HOST_PORT=5435
docker compose up --build
Remove port mapping (if you don't need external PostgreSQL access):
Comment out the ports: section in docker-compose.yaml
To build the Docker image manually:
docker build -t cygor .
Run a single container (without PostgreSQL service):
docker run --rm -v ./results:/opt/cygor/results \
-e CYGOR_RESULTS_DIR=/opt/cygor/results \
cygor web --host 0.0.0.0 --port 8080 --load-dir /opt/cygor/results
CYGOR_DB_URL is set)Key environment variables for Docker:
Data & Workspace:
CYGOR_RESULTS_DIR: Results directory (default: /opt/cygor/results)CYGOR_WORKSPACE: Workspace directory (default: /opt/cygor/results)CYGOR_RESULTS_PATH: Host path for results volume (default: ./results)CYGOR_CONFIG_PATH: Host path for authentication config volume (default: ./cygor-config)Database:
CYGOR_DB_URL: Database connection string (auto-set by docker-compose)CYGOR_DB_USER: PostgreSQL database user (default: cygor)CYGOR_DB_PASSWORD: PostgreSQL database passwordPOSTGRES_HOST_PORT: PostgreSQL host port mapping (for port conflict resolution)Debug & Verbosity:
CYGOR_DEBUG: Enable debug mode (set to 1 to enable)CYGOR_VERBOSE: Verbosity level (0=normal, 1=verbose, 2=debug)Detailed guides live in cygor/wiki/ — installation, the 11 built-in enumeration modules, plugin development, workspace management, and more. GitHub renders the directory as a navigable docs site (start at cygor/wiki/README.md). The same pages are also served by the web UI at /docs once you run cygor web start.
Use the top-level Cygor command to access the available tools. Each subcommand has its own help screen (Cygor --help) that documents flags and actions.
tjnull@kali:~$ cygor
Usage:
cygor <command> [args]
Commands:
banner Cygor tool banner (Warning it is large!)
scan Automated scanner to discover hosts and services. (Will require root/sudo privileges for scanning).
parse Analyze a NMAP scan file (nmap, gnmap, xml) and extract categorized hostlists by common service.
enum Loads enumeration modules that are located in the cygor modules directory.
workspace Manage workspaces (init/set-default/show).
web Control/launch the Cygor Web UI (start/stop/status) or run directly.
Environment:
CYGOR_WORKSPACE Override default workspace just for this run.
CYGOR_RESULTS_DIR Used by web and modules if set. (Auto-set from default workspace.)
You will need sudo (root) privileges to run the scanner in cygor:
Run host discovery with Masscan only:
cygor scan -i eth0 -f scope.txt --discover masscan
Run host discovery with both Masscan and Naabu, then Nmap on merged results:
cygor scan -i eth0 -f scope.txt --discover masscan naabu --nmap-source merge
Discovery only (no Nmap), save results in results/discovery/:
cygor scan -i eth0 -f scope.txt --discover masscan naabu --discover-only
Reuse saved discovery results for Nmap top ports scan:
cygor scan --use-discovery results/discovery/merged-discovered.txt --scan-type top-ports
Run Nmap with custom ports on discovered hosts:
cygor scan --use-discovery results/discovery/masscan-discovered.txt --ports 80,443,8443
Run Nmap with 10 parallel processes on full scope (Max is 100):
\cygor scan -i eth0 -f scope.txt --discover naabu --processes 10 --scan-type fullscan:
Run Cygor to discover hosts and scan them with Nmap with a provided lists of IP Addresses or CDRs:
cygor scan -i eth0 --ips 10.10.10.1 10.10.10.5 10.10.20.0/24 --discover naabu --processes 10 --scan-type fullscan
Exclude specific subnets or hosts from scan:
cygor scan -i eth0 -f scope.txt --exclusions exclusions.txt --discover masscan
Parse a directory of Nmap results and print hostlists:
cygor parse results/nmap
Parse a single XML and write hostlists to results/parsed-hostlists:
cygor parse results/nmap/scan1.xml -o results
Recursively parse .xml/.nmap/.gnmap files and write outputs:
cygor parse /path/to/scans --out-dir results
Cygor ships a growing set of protocol-specific enumeration modules. Each one wraps proven tooling, parses the output into typed rows ("parse-don't-dump"), and lands the results in the inventory (DB + Web UI) where they're searchable and correlatable by host. High-signal observations are also fed automatically into the next-steps engine, which surfaces prioritized findings and ready-to-run follow-up commands in the Web UI.
List all available modules:
cygor enum --list
Run lockon against an http hostlist:
cygor enum lockon web -f results/parsed-hostlists/http/http-hostlist.txt -o results/enum/lockon
Run web content discovery (multi-tool, with screenshots):
cygor enum webenum -f results/parsed-hostlists/http-https/http-https-hostlist.txt --screenshot
Run nfsexplorer against NFS targets (exports only):
cygor enum nfsexplorer -i results/parsed-hostlists/nfs/nfs-hostlist.txt --info
Run smbexplorer and list files:
cygor enum smbexplorer -i results/parsed-hostlists/smb/smb-hostlist.txt --list-files
Enumerate MSRPC (null session) with password policy + RID cycling:
cygor enum rpcexplorer -i results/parsed-hostlists/smb/smb-hostlist.txt --rid-cycle
Probe databases for unauthenticated access (point at any DB service hostlist):
cygor enum dbprobe -i results/parsed-hostlists/mysql/mysql-hostlist.txt
Run cygor enum <module> --help for the full per-module option reference.
Cygor is extensible — drop a Python file into ~/.cygor/plugins/ and it shows up under cygor enum --list (and in the Web UI) like any built-in module. Wrap your own tools, ship internal scanners across your team, or extend Cygor for a specific engagement without forking it.
Scaffold a new plugin (writes ~/.cygor/plugins/my_scanner.py):
cygor plugin create "My Scanner"
Install a plugin from a local file or a git URL:
cygor plugin install ./my_scanner.py
cygor plugin install https://github.com/example/cygor-myscanner
Validate, list, update, remove:
cygor plugin validate ./my_scanner.py
cygor plugin list
cygor plugin update --all
cygor plugin remove my_scanner
Run an installed plugin (same as a built-in module):
cygor enum my_scanner -t 10.10.10.5
Three reference plugins live under docs/examples/modules/: a minimal example, an external-tool wrapper, and a full annotated template. See the Plugin Development Guide for the full plugin format, options/columns/views, dependency handling, version compatibility, and the optional plugin allowlist.
After collecting data, you can load it into Cygor's Web UI to transform scan results into a clear visualization of hosts, services, and other key findings. Cygor will create a file called cygor.db that will contain the necessary data to model into Cygor's Web UI
# Basic usage - start on default host/port (127.0.0.1:8000)
cygor web start
# Start on all interfaces, port 8080
cygor web start -H 0.0.0.0 -p 8080
# Start with custom results directory
cygor web start --load-dir /path/to/results
# Start with verbose output
cygor web start -vv
# Start with all options
cygor web start -H 0.0.0.0 -p 8080 --load-dir ~/scan-results -vv
Run cygor web start --help for the full list of options.
# Check if the web server is running
cygor web status
# Stop a running web server
cygor web stop
Cygor automatically detects and uses PostgreSQL if available, otherwise falls back to SQLite:
PostgreSQL (recommended for production):
psql is availablepostgresql+psycopg_async://user:pass@host/dbSQLite (default fallback):
cygor.db in the results directoryCygor is a security research and educational framework. It is intended to be used only in environments where you have explicit, written authorization — such as penetration testing engagements, red team operations, classroom labs, or personal test ranges.
This software must not be used for unauthorized access, intrusion, or disruption of systems you do not own or control. Doing so may violate laws and regulations in your jurisdiction, and could result in criminal prosecution or civil penalties.
By downloading, running, or modifying Cygor, you agree that:
The authors and contributors of Cygor accept no liability for misuse, damage, or consequences arising from the use of this software.
If you are uncertain whether you are authorized to use Cygor in a given environment, do not run it.
| Module | Service | What it does |
|---|
lockon | HTTP/S, RDP, VNC, X11 | Captures screenshots across protocols for fast visual triage. |
webenum | HTTP/S | Parallel multi-tool content discovery (ffuf, feroxbuster, gobuster, dirsearch) with cross-tool dedup/correlation and optional screenshots. |
smbexplorer | SMB (445) | Enumerates shares, permissions, and accessible files; NTLM/Kerberos/pass-the-hash. |
nfsexplorer | NFS (2049) | Enumerates exports, versions, and files; UID/GID spoofing and no_root_squash checks. |
rpcexplorer | MSRPC (445) | Null/auth session: server info, domain SID, users, groups, full password policy, and RID cycling. |
ldapexplorer | LDAP/AD (389/636) | rootDSE, anonymous bind/search, and authenticated domain dump. |
snmpexplorer | SNMP (161) | v1/v2c community brute, device system info, and a MIB sweep (users/processes/software/ports/interfaces). |
dnsexplorer | DNS (53) | Version, open-resolver detection, and AXFR zone transfer. |
ftpexplorer | FTP (21) | Banner, anonymous login, directory listing, FEAT, anonymous write test. |
smtpexplorer | SMTP (25/587) | Banner, STARTTLS, AUTH mechanisms, VRFY user-enum, open-relay test. |
dbprobe | Databases | Probes Redis/MySQL/PostgreSQL/MongoDB/Elasticsearch/CouchDB for unauth access and version. |