Tools That Don’t Fit One Category
Some tools in a security toolchain don’t map cleanly to a single vulnerability class. Screenshots organize visual reconnaissance. Subdomain takeover detection spans recon and exploitation. Diff analysis shows what changed between engagement sessions. These tools make the workflow sharper without belonging to any single testing phase.
Eleven tools fall into this category.
mg-screenshot: Visual Inventory
mg-screenshot target-bounty
mg-screenshot reads HTTP and HTTPS hosts from recon/summary.json and visits each
one with a headless Chromium instance via chromiumoxide 0.7. Chromium must be on
PATH or specified with --chromium.
Each host produces a PNG saved to screenshots/<hostname>.png. After all hosts are
captured, the tool writes screenshots/index.html: an HTML page with each hostname,
the screenshot as an embedded image, and the HTTP status code from the visit.
The practical use: after running the full recon pipeline against a large program with many subdomains, reviewing screenshots manually takes minutes instead of visiting each host individually. Parked domains, default server pages, and interesting-looking applications are immediately visible. Interesting ones get flagged for crawling and deeper testing.
mg-takeover: Subdomain Takeover Detection
mg-takeover target-bounty
Subdomain takeover happens when a DNS record points to a third-party service that no longer has the target’s account registered. An attacker registers an account on that service and claims the subdomain.
The tool reads recon/subdomain-enum.json and the CNAME chain data produced by
mg-cname-chain. For each subdomain with an
external CNAME, it matches the terminal CNAME against a catalog of known-vulnerable
service fingerprints: GitHub Pages (github.io), Heroku (herokudns.com), Fastly,
Netlify, Surge, Cargo, and others.
Two confidence levels: if the CNAME matches a known-vulnerable fingerprint AND the
HTTP response body contains the service’s “unclaimed” page text (e.g., “There isn’t
a GitHub Pages site here”), the finding is CONFIRMED HIGH. If the CNAME matches
but the HTTP check fails or returns ambiguously, the finding is potential — worth
manual review.
mg-vhost: Virtual Host Discovery
mg-vhost target-bounty
Multiple virtual hosts may run on the same IP. The Host header controls which
application the server routes to. VHost discovery sends requests with different Host
values and compares responses to the baseline.
The baseline is a request to the bare IP address. Each wordlist entry is tried as a
Host header value. Responses that differ in status code or body length from the
baseline are flagged. A wordlist of common subdomain prefixes is built in; --wordlist
specifies a custom list.
The tool also tests host header injection: sending attacker.example.com as the
Host value and checking whether the server reflects it in a redirect Location,
a <base> tag, or a password reset link. Host header injection in password reset
flows is a consistently paid bug class.
mg-diff: Recon Change Detection
mg-diff target-bounty
Running mg-recon at the start of an engagement and again a week later produces two
summary.json files. mg-diff compares them.
Without arguments, it auto-selects the two most recent recon/summary.json files
in the engagement directory. With arguments, any two summary files can be compared:
mg-diff target-bounty --a recon/summary-2026-05-01.json --b recon/summary-2026-05-15.json
Output covers four change categories: new hosts (appeared in the second scan but not the first), removed hosts, port changes (new ports open or previously-open ports now closed), and tech stack changes (fingerprint changed between scans).
New hosts during an engagement are high-priority targets. Infrastructure changes during active testing sometimes expose services that were behind a firewall when the engagement started.
mg-notify: Real-Time Finding Alerts
MG_SLACK_WEBHOOK=<url> mg-notify target-bounty
mg-notify watches the findings/ directory for new files and pushes notifications
to configured channels. Supported destinations: Slack webhook, Discord webhook, and
ntfy.sh topic.
State is persisted to notify/state.json so the watcher can restart without re-sending
previously seen findings. The tool handles SIGINT and writes final state before exiting.
# Keep running while testing, get Slack alerts for each new finding
mg-notify target-bounty &
# Run injection tests in another terminal
mg-sqli target-bounty
mg-xss target-bounty
High and critical findings produce an alert with the title, severity, affected URL,
and a note that the full finding is in findings/. Informational findings are
suppressed by default; --all-severities includes them.
mg-timeline: Engagement Chronology
mg-timeline target-bounty
After an engagement, understanding what happened and when matters for both reporting
and debugging. mg-timeline walks the entire engagement workspace and builds a
sorted chronological view.
Two time sources are used: filesystem mtime for tool output files, and the
"timestamp" JSON field in finding files and tool output JSON. The JSON timestamp
is preferred when available.
The output is a sorted list of events: [2026-05-15T14:32:11] mg-recon completed: 47 hosts discovered, [2026-05-15T16:44:02] FINDING HIGH: CORS misconfiguration on api.target.example.com. This reconstructs the sequence of tool runs and findings
for after-action review or report writing.
mg-nuclei-bridge: Nuclei Template Integration
mg-nuclei-bridge target-bounty --templates /path/to/nuclei-templates/
Nuclei is an external scanner with an extensive template library. mg-nuclei-bridge
runs the nuclei binary against in-scope hosts, streams its JSONL stdout, and
normalizes each finding into the engagement’s findings/ directory using the standard
GeistScope finding format.
Each nuclei finding gets a deduplicated engagement finding ID based on the template ID, host, and matched URL. Running the bridge a second time with the same templates doesn’t produce duplicate findings for already-seen results.
The bridge adds Nuclei’s coverage to the engagement without coupling the toolchain to
Nuclei’s output format. All downstream tools (mg-timeline, mg-notify, ai-prioritize)
see Nuclei findings the same way they see findings from any other GeistScope tool.
mg-privesc-linux: Local Privilege Escalation Checks
mg-privesc-linux
This tool runs locally on a target Linux system after gaining access. It has no engagement dependency and makes no network requests.
Checks cover the most common local escalation paths: SUID and SGID binaries (find / -perm -4000), directories in PATH that are writable by the current user, sudo -l
output parsed for NOPASSWD entries, cron jobs owned or writable by non-root users,
world-writable files in sensitive directories, and the kernel version for reference
against known local privilege escalation CVEs.
Output is printed to stdout. There’s no engagement integration because this tool runs on the compromised host, not the operator’s machine.
mg-privesc-windows: Windows Privilege Escalation
mg-privesc-windows
The Windows equivalent, gated with cfg(target_os = "windows") so it only compiles
for Windows targets. Checks: unquoted service executable paths (a path with spaces
and no quotes that traverses a writable directory), writable service binary paths,
AlwaysInstallElevated registry key (allows MSI packages to install with SYSTEM
privileges), scheduled tasks running as higher-privileged users, and enabled token
privileges (SeImpersonatePrivilege, SeAssignPrimaryTokenPrivilege) that enable
potato-family exploits.
mg-loot: Credential Harvesting
mg-loot
Post-access credential collection. mg-loot scans common locations on the current
system for credentials and secrets: ~/.ssh/ for private keys and known_hosts,
~/.aws/credentials and ~/.aws/config, ~/.config/ for application configs that
embed tokens, .env files in common web application paths (/var/www/, /srv/),
shell history files (.bash_history, .zsh_history), and common application config
paths for databases and services.
All secret values are masked to the first 8 characters in output. The full paths and key names are reported so the operator knows where to look.
mg-dns-rebind: DNS Rebinding Payload Generation
mg-dns-rebind target-bounty target.example.com
DNS rebinding bypasses same-origin policy by having a domain resolve to the attacker’s IP first (for the initial page load) and then resolve to the victim’s internal IP (for subsequent requests). The victim’s browser, believing it’s talking to the original domain, allows the cross-origin request.
The tool resolves the target’s current TTL, checks whether the target IP is in private RFC 1918 space (a rebinding attack targeting an internal service), and writes a ready-to-use HTML payload that uses a cooperating DNS rebinding service to perform the resolution switch. No active probing beyond the DNS resolution itself.
The Engagement as a Unit
These tools reinforce a design principle that runs through GeistScope: the engagement
directory is the single source of truth. mg-diff compares two snapshots of it.
mg-notify watches it. mg-timeline walks it. mg-nuclei-bridge writes into it.
Every tool that reads from or writes to engagements/<name>/ is interoperable with
every other tool that does the same. Adding Nuclei coverage doesn’t require changing
any other tool. Enabling Slack notifications doesn’t require modifying the scanner.
The directory structure is the integration layer.