Skip to main content
PwnBroker — Complete User Guide
PwnBroker User Guide

PwnBroker — Complete User Guide

Install, configure and run PwnBroker — scanning, proven-exploitable vulnerability management, threat intelligence and GRC on your own infrastructure.

Version 1.0.0 · Updated 2026-11-11

PwnBroker is a self-hosted security operations platform that combines network scanning, vulnerability management, dependency auditing, threat intelligence, GRC compliance, and endpoint monitoring into a single web UI. All data stays on your infrastructure.

1. Installation#

Requirements#

  • Ubuntu 22.04 LTS or 24.04 LTS (Debian-based distros also work)
  • 2 GB RAM minimum, 4 GB recommended
  • 10 GB disk space
  • Root / sudo access
  • Outbound internet access (for threat intel API calls and NVD CVE lookups)

PWNBroker ships as one file, pwnbroker-<version>-install.run, that contains the signed release and everything that installs it. Download it with your license key and install in one go:

curl -fsS --data-binary @license.key https://pwnbroker.space:7585/updates/v1/installer -o pwnbroker-install.run
sudo bash pwnbroker-install.run --license license.key

Before installing it verifies its own checksum (a truncated or corrupted download is refused) and the PWNBroker release signature (a modified file is refused). Options:

Option Default
--license FILE — Install this license (otherwise upload it under user menu → License)
--port N 443 HTTPS port
--dir PATH /opt/PWNBroker Install directory
--update-url URL https://pwnbroker.space:7585/updates Update server
--check Only verify the file
--extract DIR Only verify and unpack the release

It needs Ubuntu 22.04+/Debian 12+ with systemd, x86_64 or arm64, 3 GB free disk, and internet access for OS and Python packages. Progress is shown and logged to /var/log/pwnbroker-install.log. Running a newer installer on an existing server upgrades it in place and keeps all data; running the same one again repairs the install.

Quick Install (from source)#

setup.sh manages its own git checkout — grab just the script and run it, no separate clone needed:

curl -fsSL https://raw.githubusercontent.com/ChimneyFish/PWNBroker/main/setup.sh -o setup.sh
sudo bash setup.sh

The script will:

  1. Install system packages: python3, nmap, openssl, ufw, and build tools
  2. Create a pwnbroker system user (no shell, no home directory)
  3. Clone (or, on re-runs, fetch + reset) the application into /opt/PWNBroker
  4. Build a Python virtual environment and install all dependencies
  5. Grant nmap raw-socket capabilities (cap_net_raw) so OS fingerprinting works without root
  6. Generate a self-signed TLS certificate (4096-bit RSA, 10-year validity)
  7. Create /opt/PWNBroker/.env with a randomly generated SECRET_KEY
  8. Install and enable a systemd service (pwnbroker.service) that starts automatically on boot
  9. Configure logrotate for daily log rotation with 14-day retention
  10. Open the HTTPS port in ufw if the firewall is active

After the script completes you will see:

  Access URL:       https://<server-ip>
  Default login:    admin / admin

Custom Port or Install Directory#

sudo PORT=8443 INSTALL_DIR=/srv/pwnbroker bash setup.sh

Service Management#

sudo systemctl start   pwnbroker     # start
sudo systemctl stop    pwnbroker     # stop
sudo systemctl restart pwnbroker     # full restart
sudo systemctl reload  pwnbroker     # graceful zero-downtime worker reload
sudo systemctl status  pwnbroker     # health check

journalctl -u pwnbroker -f           # live log stream
journalctl -u pwnbroker -n 100       # last 100 log lines

Application logs are also written to /opt/PWNBroker/logs/.

TLS Certificate#

The installer generates a self-signed certificate. Your browser will show a security warning — click Advanced → Proceed to continue.

For production, upload a CA-signed certificate through Settings → HTTPS / TLS. Both the certificate (PEM) and private key (PEM) files are required. The service must be restarted after uploading.

2. First Login & Initial Setup#

  1. Navigate to https://<your-server-ip>
  2. Log in with admin / admin
  3. Go to Profile (bottom of the sidebar) and change your password immediately
  4. Go to Settings → Time & NTP and set your timezone — all timestamps across the platform will display in this zone
  5. Add your API keys under Settings → Threat Intelligence APIs to unlock IOC lookups, OTX feeds, and SOC triage
Step Where
Change admin password Sidebar → Profile
Set timezone Settings → Time & NTP
Add threat intel API keys Settings → Threat Intelligence APIs
Add your first target Targets → New Target
Run your first scan Scans → New Scan

3. Dashboard#

The dashboard is fully customizable. All widgets pull live data from the API and refresh every 30 seconds.

Customizing the Layout#

Click Customize in the top-right corner to open the widget picker panel. From there you can:

  • Add any widget by clicking the + button next to it
  • Remove any widget by clicking the − button (or hover over a widget and click the × in the top-right corner)
  • Reorder widgets by dragging them to a new position (grab the ⠿ handle that appears on hover)
  • Reset to the default layout with the "Reset defaults" button

Your layout is saved in the browser's localStorage and persists across page refreshes.

Available Widgets#

Stat cards (small, shows a single number with a link):

Widget Shows Links to
Total Scans All scans ever run Scans
Running Now Active scans Scans
Targets Configured scan targets Targets
Critical Vulns Unresolved critical findings Vuln Management
High Vulns High severity findings Vuln Management
Online Agents Endpoint agents with recent heartbeat Threat Intel → Agents
Assets Total discovered assets Assets
Open SOC Cases Pending SOC triage cases Threat Intel → SOC Triage

Charts (medium width):

Widget Chart type Shows
Severity Breakdown Doughnut Distribution of all findings by severity
Scan Trend (14d) Line Number of scans launched per day
Vulns by Target Horizontal bar Top 5 targets ranked by vulnerability count
Agent Health Status list Online / Offline / Unknown agent counts

Tables & Tools (full or half width):

Widget Shows
Recent Scans Last 8 scans with status, vuln count, and date
Recent Findings Last 10 vulnerabilities with severity, CVSS, and CVE
Quick Actions One-click shortcuts to New Scan, SOC Triage, Add Target, IOC Lookup

4. Targets#

Targets are the hosts, IP addresses, IP ranges, or domains that PwnBroker scans and monitors.

Target Types#

Type Example Notes
Host 192.168.1.100 Single IP or hostname
IP Range 192.168.1.0/24 CIDR range, scanned as one job
Domain example.com Enables DNS/subdomain enumeration

Adding a Target#

  1. Go to Targets → New Target
  2. Enter a name, the host/IP/domain, and an optional description
  3. Click Create Target

Target Detail Page#

Clicking a target shows:

  • Scan history for that target
  • Domain records (for domain targets) — A, AAAA, CNAME, MX, NS records discovered via crt.sh and DNSDumpster
  • DNS enumeration — click Re-Enumerate to refresh DNS records
  • Subdomain changes are tracked: new records show as new, changed values as changed, removed entries as removed

SSH Credentials (credentialed checks)#

Add an SSH login to a host or subnet target when you create it, or any time later with the key icon on the Targets page (filled key = a login is saved). Supported auth types:

  • Password — username + password
  • Key — paste an OpenSSH or PEM private key (Ed25519, ECDSA or RSA), with its passphrase if it's encrypted

Use Test login before saving: it logs in and shows the OS, the package manager it found, and whether passwordless sudo is available. Secrets are stored encrypted and never shown again; leave a secret blank when editing to keep the saved one. Remove saved credentials deletes the login.

The login is used for credentialed CVE checks (see Credentialed checks in section 7), precise end-of-life checks on full scans, and remote dependency scans. Use a dedicated low-privilege account; everything run on the host is read-only. On a subnet target the login is tried on every host found; a target saved for an individual IP takes precedence for that IP.

Deleting a Target#

Deleting a target also deletes all associated scans, results, assets, and reports. This action cannot be undone.

5. Assets#

Assets are individual network devices discovered during scans. They are tracked automatically — every completed scan populates the asset inventory.

Asset Inventory (/assets)#

The inventory table shows every known device with its:

  • IP address and hostname (editable inline)
  • Operating system
  • Last seen timestamp
  • Status (Active / Inactive)
  • Tags
  • Open vulnerability count
  • Parent target

Tags#

Tags let you group and filter assets. Examples: production, dmz, windows, critical.

  • Create a tag with a name and hex color
  • Assign tags to assets from the inventory or asset row
  • Filter the inventory by tag using the tag buttons at the top

Asset Groups#

Groups are collections of assets that can be scanned together as a single job. Three group types:

Type How assets are collected
Manual You add assets individually
By Tag All assets with a chosen tag
By Network All assets belonging to a target

Creating a group: Assets → Asset Groups → New Group

Scanning a group: On the group detail page, click Scan Group to launch a full scan against all member assets simultaneously.

Quick Scan#

From the asset inventory, click Quick Scan on any row to immediately launch a full scan of that single asset without going through the scan wizard.

6. Scans#

Scans run nmap against targets or asset groups and enrich results with CVE data from NVD.

Scan Types#

Type What it does
Full Port scan + service detection + OS fingerprinting + CVE lookup
Port Port scan and service detection only
Web HTTP/HTTPS service checks
CVE CVE lookup against already-discovered services (no new port scan)
OSV Dependency vulnerability scan via SSH (see Dependency Scanner)

Running a Scan#

  1. Go to Scans → New Scan
  2. Select a target or asset group
  3. Choose scan type and port range (default: 1–1024)
  4. Give it a name and click Launch Scan

The scan runs in the background. The scan detail page polls every 2.5 seconds and updates automatically when complete.

Scan Results#

Each scan result falls into one of these categories:

  • Port — open port with service, version, and protocol
  • Vulnerability — CVE-matched finding with severity, CVSS score, and remediation
  • Web Check — HTTP header findings (missing security headers, etc.)
  • Info — general host/OS information

Findings are color-coded by severity: Critical (red) · High (orange) · Medium (yellow) · Low (blue) · Info (gray)

Marking Findings as Remediated#

On the scan detail page, click Remediate next to any finding to mark it resolved. Remediated findings are excluded from future vulnerability ticket counts.

Scheduled Scans#

Set up recurring scans using cron expressions:

  1. Go to Scans → Schedule New
  2. Pick a target or asset group, scan type, and port range
  3. Choose how credentialed checks log in (same options as a one-off scan)
  4. Enter a cron expression (e.g., 0 2 * * * for 2 AM daily)
  5. Click Create Schedule

Active schedules can be paused/resumed with the toggle on the Scans index page. Scheduled scans appear in the activity log when they run.

7. Vulnerability Management#

The Vuln Management module tracks findings as tickets through their remediation lifecycle.

Only proven vulnerabilities are counted#

A CVE matched from a service's version banner only says the product can be vulnerable; whether this host is depends on configuration. (Apache 2.4.49 is only exploitable through CVE-2021-41773 if a non-default setting allows it.) So every version-matched CVE is re-tested against the live service with a check written for that CVE, and gets one of three verdicts:

Verdict What happened Counted?
Exploitable The check reproduced the issue. The proof (request + response) is on the finding. Yes — open ticket with SLA
Not exploitable The check ran cleanly and the vulnerable behaviour wasn't there (feature disabled, fix backported, not that product). No — kept under "Not Exploitable"
Unverified No safe check exists for this CVE, or the check couldn't complete. Each one says why. No — kept under "Unverified"
  • Checks come from the nuclei template library (~4,500 CVEs), installed by setup.sh and refreshed weekly. nmap's own vuln-script verdicts count too (VULNERABLE proves, NOT VULNERABLE rules out; LIKELY VULNERABLE is not proof).
  • Only safe checks run: never ones tagged DoS/intrusive/fuzzing, never ones needing credentials, and never ones that call out to an external server — no scan data leaves your network.
  • A later scan that proves an unverified finding reopens it automatically; a rescan that shows an open one is no longer exploitable (fixed, or the feature turned off) closes it as Not Exploitable.
  • Verify now on the Vulnerabilities page re-tests every unverified finding without a full rescan (useful after the check library updates).
  • Dashboard, reports, exports and Jira/Confluence only include proven vulnerabilities. Dependency (OSV), EOL, secrets and other non-version findings are unchanged.
  • Set VULN_VERIFY=0 in .env to turn checking off (findings then stay unverified).

Credentialed checks (SSH)#

Most version-matched CVEs have no safe remote check, so on their own they stay Unverified. With an SSH login, scans also look inside the host and rule out the ones that don't apply:

Rule-out How it's checked
Vendor backport Finds the package that owns the listening service, its exact installed version, and the vendor changelog. If the changelog lists the CVE, the fix is installed even though the banner shows the old upstream version. Ubuntu trims the on-disk changelog, so the full one for that exact version is fetched from changelogs.ubuntu.com (only the package name and version are sent).
Module not loaded For Apache httpd (apachectl -M) and nginx (nginx -V): a CVE in a module the server doesn't load is ruled out.
Different OS A CVE that only affects the product on Windows, on a host running Linux/Unix.

Credentialed checks only ever rule findings out. They never make a finding count as a vulnerability on their own; that still needs a live check that reproduces it. Findings they can't rule out stay Unverified with a note saying what was found (e.g. "apache2-bin 2.4.52-1ubuntu4.26 has no vendor fix listed for CVE-…").

On New Scan / Schedule Scan, Credentialed Checks (SSH) chooses the login:

  • Use the target's saved SSH login (default): uses the login saved on the target.
  • Use these credentials for this scan: enter a login just for this scan (stored encrypted with the scan). For a subnet or asset group it's tried on every host.
  • Off: don't log in to hosts.

Each scan shows which login it used, and adds one info row per host with how many CVEs were ruled out, or why the login failed. Verify now reuses each finding's scan login (or its target's). In a real test against stock Ubuntu 22.04 Apache, credentialed checks ruled out 88 of 95 version-matched CVEs.

Vuln Tickets (/vulns/tickets)#

A ticket is automatically created for each unique vulnerability the first time it is found on a host. If the same CVE reappears on the same host in a later scan, the existing ticket is updated rather than duplicated.

Ticket statuses:

Status Meaning
Open Newly found, not yet being worked
In Progress Someone is actively remediating
Patched Fix confirmed
Accepted Risk Risk accepted by the team
False Positive Finding is wrong (marked by hand)
Unverified Version match only, not proven on this host (no SLA)
Not Exploitable The CVE's check ran and the issue wasn't present (no SLA)

SLA tracking: Each severity level has a default SLA (Critical: 1 day, High: 7 days, Medium: 30 days, Low: 90 days). Overdue tickets are highlighted in red.

Device View (/vulns/device/<target>)#

Shows all open tickets grouped by target with a risk heat-map. Use this view to get a per-host risk summary.

Updating a Ticket#

Click any ticket to open the detail panel and:

  • Change status
  • Assign to a user
  • Add notes
  • Record the patch date

8. Dependency Scanner#

The dependency scanner connects to a target over SSH, reads the installed package manifest, and cross-references it against the OSV (Open Source Vulnerabilities) database.

Supported Ecosystems#

Python (pip), Node.js (npm), Go modules, Rust (Cargo), Ruby (Bundler), Java (Maven/Gradle), PHP (Composer), and others supported by OSV.

Prerequisites#

  • The target must have SSH enabled and credentials configured on the Target detail page
  • Test the connection with Test SSH before running a scan

Running a Dependency Scan#

  1. Go to Dependency Scanner → New Scan
  2. Select a target that has SSH credentials configured
  3. Optionally specify a path on the remote host to scan (defaults to home directory)
  4. Click Launch

Results#

Results list each vulnerable package with:

  • Package name and installed version
  • First fixed version
  • CVE ID and CVSS score
  • Severity badge

Click Remediate on any row to mark it resolved.

9. Reports#

Reports generate PDF or HTML summaries of scan results.

Generating a Report#

  1. Go to Reports
  2. Find a completed scan in the table
  3. Click Generate and choose PDF or HTML format

The report includes: executive summary, severity breakdown chart, full findings table with CVSS scores and remediation advice, and scan metadata.

Downloading Reports#

Generated reports appear in the Saved Reports table. Click Download to save the file locally.

Pushing Reports to a Cloud API#

If you have configured a Cloud API endpoint under Settings → Cloud API Integration, click Push next to any saved report to POST it to the endpoint. The payload includes scan metadata and optionally a base64-encoded copy of the report file.

Scheduled Reports#

Schedule automatic report delivery by email:

  1. Go to Reports → Schedule New
  2. Select a target, cron schedule, recipients, and format
  3. Click Create Schedule

Recipients will receive an email with the report attached each time the schedule fires. SMTP must be configured under Settings → Email / SMTP.

Atlassian Integration#

If Confluence and/or Jira are configured under Settings → Atlassian:

  • Publish to Confluence: From the scan detail page, click Publish to Confluence to create a formatted wiki page in your configured space
  • Create Jira Tickets: From the scan detail page, click Create Jira Tickets to open issues for findings at or above your configured severity threshold

10. Threat Intelligence#

The Threat Intelligence module provides IOC lookups, threat feed monitoring, SOC triage workflows, subdomain enumeration, and domain-change tracking.

Required API Keys#

Configure all keys under Settings → Threat Intelligence APIs.

Service Used for
OTX (AlienVault) IOC reputation, threat feed pulses
AbuseIPDB IP abuse reports and confidence scores
GreyNoise Internet noise classification (RIOT / mass-scanner detection)
DNSDumpster Subdomain enumeration
NVD CVE lookup and CVSS enrichment

Click Test All Keys on the Settings page to validate each key without leaving the page.

IOC Lookup (/threat/lookup)#

Enter any of the following and get a multi-source reputation report:

  • IPv4 / IPv6 address
  • Domain name
  • File hash (MD5, SHA-1, SHA-256)
  • URL

Results are cached for 24 hours to avoid burning API quota.

OTX Feed (/threat/feed)#

Displays the latest threat pulses from your AlienVault OTX subscriptions. Each pulse shows indicator counts, tags, and adversary attribution. Requires an OTX API key.

SOC Triage (/threat/triage)#

The triage queue collects IOCs that need analyst review. IOCs reach the queue either:

  • Manually submitted via the Lookup page when the threat score exceeds the threshold
  • Automatically when an endpoint agent reports a network connection to a known-malicious IP and GreyNoise or VT confirm it

Triage actions:

Action Meaning
Alert Flag as confirmed threat, add analyst notes
Dismiss Mark as benign / false positive

Alerted cases can be exported. Dismissed cases are removed from the active queue but retained in history.

Subdomain Enumeration (/threat/subdomains)#

Enter a domain to enumerate subdomains using crt.sh certificate transparency logs and DNSDumpster. Results show IP addresses, record types, and first/last seen dates.

11. Endpoint Agents#

Endpoint agents are lightweight Python scripts that run on monitored hosts. They send heartbeats and report suspicious network connections back to PwnBroker.

How Agents Work#

  1. The agent runs as a background process (service/daemon) on the endpoint
  2. Every 60 seconds it sends a heartbeat with the host's IP, OS, and hostname
  3. It monitors active network connections and cross-checks destination IPs against your IOC database
  4. If a connection to a known-malicious IP is detected, an alert is created in PwnBroker
  5. Agents that have not sent a heartbeat in 5 minutes are marked Offline

Deploying an Agent#

Step 1 — Download the agent script#

Go to Threat Intel → Agents → Download Agent. The download page shows three options:

Platform File Method
Linux install_linux.sh Bash one-liner
macOS install_mac.sh Bash one-liner
Windows install_windows.ps1 PowerShell script

Each installer downloads the Python agent, sets the server URL and registration token automatically, and installs it as a system service.

Step 2 — Note the registration token#

The registration token is auto-generated. Find it on the Threat Intel → Agents → Download Agent page (/threat/download). All agents must present this token when registering for the first time. You do not need to set it manually — it is created automatically on first use.

Step 3 — Install on the endpoint#

Linux / macOS:

curl -k https://<pwnbroker-server>/threat/download/script/linux | sudo bash

Windows (PowerShell as Administrator):

iwr https://<pwnbroker-server>/threat/download/script/windows -UseBasicParsing | iex

Step 4 — Verify registration#

The agent appears in Threat Intel → Agents within a minute of first startup. Status shows Online when heartbeats are received.

Agent Alerts#

When an agent detects a suspicious connection, the alert appears on:

  • The agent's detail page
  • The Threat Intel overview page
  • The SOC Triage queue (if the threat score exceeds the threshold)

Acknowledge alerts from the agent detail page to clear them from the active list.

Manual Registration (advanced)#

python3 pwnbroker_agent.py --register --no-verify-ssl

This prompts for server URL and registration token, saves the config, then exits. Subsequent runs without --register operate in normal heartbeat mode.

12. GRC — Governance, Risk & Compliance#

The GRC module manages risk registers, compliance frameworks, and security policies.

Risk Register (/grc/risks)#

Track risks across five categories: Technical, Operational, Compliance, Strategic, Financial.

Risk scoring: likelihood (1–5) × impact (1–5) = risk score (1–25)

Score Level
1–5 Low
6–11 Medium
12–19 High
20–25 Critical

Risk statuses: Open · In Treatment · Mitigated · Accepted · Transferred · Closed

Each risk can have a mitigation plan, target date, assigned owner, and optionally be linked to a specific asset. Residual likelihood and impact can be recorded after controls are applied to show risk reduction.

Compliance (/grc/compliance)#

PwnBroker ships with seeded compliance frameworks:

  • NIST CSF 2.0 — Govern, Identify, Protect, Detect, Respond, Recover
  • CIS Controls v8 — 18 control groups
  • ISO 27001:2022 — Annex A controls

Assessing a control: Click any framework to see its controls. Click Assess on any control to record:

  • Status: Compliant · Partial · Non-Compliant · Not Applicable · Not Assessed
  • Evidence notes
  • Next review date

Auto-assessment: Click Run Auto-Assessment to have PwnBroker automatically evaluate controls it can infer from scan data (e.g., patch status, open ports, missing headers).

Evidence files: Upload supporting evidence documents (PDFs, screenshots, configs) directly to a control.

Compliance report: Generate a PDF compliance report for any framework showing pass/fail counts and a gap summary. Useful for auditors.

Policies (/grc/policies)#

Maintain a library of security policies with version tracking.

Policy categories: Access Control · Data Classification · Incident Response · Vulnerability Management · Change Management · Acceptable Use · General

Policy statuses: Draft · Active · Under Review · Retired

Each policy tracks the owner, approver, approval date, and next review date. Overdue review dates are highlighted in red.

13. Settings#

Time & NTP#

Timezone: Select any IANA timezone from the dropdown. All timestamps across the entire platform — scans, findings, activity logs, SOC cases — display in this timezone. The preview updates live as you change the selection.

NTP Server: Enter the hostname of your NTP server (e.g., pool.ntp.org, time.cloudflare.com). PwnBroker writes this to /etc/systemd/timesyncd.conf and restarts the sync service. This requires the process to run as root or have sudo access — if it fails, the timezone is still saved and the error message shows the exact command to run manually.

Email / SMTP#

Configure outbound email for scheduled reports and alerts.

Field Example
SMTP Server smtp.gmail.com
Port 587
Use STARTTLS Checked
Username alerts@company.com
Password App password (not your login password)
From Address pwnbroker@company.com

Use the Send Test Email button to verify the configuration before saving.

Threat Intelligence APIs#

API keys are stored in the database. Entering a key and saving replaces the existing value; leaving a field blank keeps the current key. Click Test All Keys to verify connectivity for each configured service.

Atlassian Integration#

Connect to Confluence and Jira for automated report publishing and ticket creation.

Field Notes
Base URL https://yourorg.atlassian.net
Email Your Atlassian account email
API Token Generate at id.atlassian.com → Security → API tokens
Confluence Space Key e.g., SEC
Parent Page ID Optional — found in the page URL
Jira Project Key e.g., SEC
Issue Type Usually Bug or Security
Minimum Severity Only findings at or above this level create Jira tickets

Cloud API Integration#

Forward scan reports to an external API endpoint (e.g., a SIEM, ticketing system, or custom webhook).

PwnBroker POSTs a JSON payload containing scan metadata, all findings, and optionally a base64-encoded report file. Authentication options: None, Bearer Token, or API Key header.

HTTPS / TLS#

Upload a CA-signed certificate to replace the self-signed one. Provide both the certificate file (PEM/CRT/CER) and the matching private key file (PEM/KEY). The pair is validated before being written to disk. Restart the service after uploading:

sudo systemctl restart pwnbroker

14. User Management#

Users are managed under Settings → User Management (admin only).

Roles#

Role Permissions
Admin Full access: create/delete targets, run scans, manage users and settings, generate reports
User Read-only: view dashboard, scans, targets, and reports; update own profile

Adding a User#

Fill in username, email, temporary password, and role, then click Add User. The user can change their password under Profile.

Managing Existing Users#

  • Change role: Select from the dropdown in the role column — takes effect immediately
  • Disable/Enable: Prevent login without deleting the account
  • Delete: Permanently removes the account (cannot be undone)

You cannot change your own role or delete your own account.

Profile#

Each user can update their own username, email, and password under Sidebar → Profile. Admins do not need to be involved for password changes.

15. Activity Log#

The Activity Log (/activity) is an immutable audit trail of every significant action taken in PwnBroker. It is only visible to admin users.

Each entry records:

  • Timestamp (in the configured timezone)
  • Actor (username or "System" for automated actions)
  • Action type (e.g., scan.created, user.login, settings.threat_save)
  • Entity name (e.g., the scan name or target)
  • Detail string
  • Source IP address

The log is grouped by date. Hover over a timestamp to see the full date/time with seconds.

Admins can clear the entire log with the Clear Log button. This is irreversible.

16. API Reference#

PwnBroker exposes a small JSON API for programmatic access. All endpoints require an authenticated session (cookie-based).

GET /api/dashboard/stats#

Returns basic dashboard counts.

{
  "total_scans": 42,
  "running_scans": 1,
  "total_targets": 8,
  "total_vulns": 137,
  "critical_vulns": 5
}

GET /api/dashboard/widgets#

Returns all dashboard widget data in one call. Used by the dashboard widget system.

{
  "stats": {
    "total_scans": 42,
    "running_scans": 1,
    "total_targets": 8,
    "total_assets": 64,
    "online_agents": 3,
    "open_soc": 2,
    "critical_vulns": 5,
    "high_vulns": 18,
    "medium_vulns": 61,
    "low_vulns": 48,
    "info_vulns": 5
  },
  "severity_map": { "critical": 5, "high": 18, "medium": 61, "low": 48, "info": 5 },
  "trend": {
    "labels": ["Jun 04", "Jun 05", "..."],
    "data":   [2, 0, 1, 3, "..."]
  },
  "vuln_by_target": {
    "labels": ["web-server", "db-host"],
    "data":   [42, 19]
  },
  "agent_stats": { "online": 3, "offline": 1, "unknown": 0 },
  "recent_scans": [ { "id": 9, "name": "...", "status": "done", "..." } ],
  "recent_vulns": [ { "severity": "critical", "title": "...", "cve_id": "CVE-2024-..." } ]
}

GET /api/scans/<scan_id>/status#

Poll the live status of a running scan. Used by the scan view page.

{
  "id": 9,
  "status": "running",
  "vuln_count": 12,
  "critical_count": 2,
  "duration": null
}

status values: pending · running · done · failed

Endpoint Agent API#

These endpoints are used exclusively by the agent script.

POST /threat/api/register#

Register a new agent. Requires the pre-shared registration token.

// Request
{
  "reg_token": "<registration-token>",
  "hostname": "workstation-01",
  "os": "linux",
  "os_version": "Ubuntu 22.04",
  "ip_address": "10.0.0.45"
}

// Response 200
{
  "agent_id": "abc123...",
  "token": "<agent-session-token>"
}

POST /threat/api/heartbeat#

Send a periodic heartbeat with current network connections. Requires the agent's session token in the X-Agent-Token header.

// Request body (auth via X-Agent-ID and X-Agent-Token headers)
{
  "ip_address": "10.0.0.45",
  "connections": [
    { "remote_ip": "185.220.101.5", "status": "ESTABLISHED", "pid": 1234 }
  ]
}

// Response 200
{ "ok": true }

17. Upgrading#

/opt/PWNBroker is a live git checkout, so upgrading is a normal git pull:

cd /opt/PWNBroker
sudo git pull
sudo systemctl restart pwnbroker

Or re-run sudo bash setup.sh — it's safe and idempotent, fetching and resetting to the latest commit, updating Python dependencies, and restarting the service, without touching data/, logs/, evidence_uploads/, your existing .env, or TLS certificates.

New database columns (added by migrations) are applied automatically on startup by _migrate_columns() in app/__init__.py. No manual schema changes are needed.

18. Troubleshooting#

Service won't start#

# Check the last 50 log lines
journalctl -u pwnbroker -n 50

# Common causes:
# - Port already in use:     ss -tlnp | grep 443
# - Missing .env file:       ls /opt/PWNBroker/.env
# - Bad TLS cert:            openssl x509 -in /opt/PWNBroker/data/ssl/cert.pem -noout -text
# - Python import error:     /opt/PWNBroker/venv/bin/python -c "from app import create_app; create_app()"

Scans stuck in "running" state#

The scan background thread may have died. Restart the service:

sudo systemctl restart pwnbroker

Scans still marked running at that point were killed mid-scan, not still in progress — the app automatically sweeps any running scan to failed on every boot (_recover_orphaned_scans in app/__init__.py), so no manual database edit is needed.

OS detection not working#

nmap needs CAP_NET_RAW for -O (OS fingerprinting). Re-run the capability grant:

sudo setcap cap_net_raw+eip,cap_net_admin+eip $(which nmap)

Verify it worked:

getcap $(which nmap)
# Expected: /usr/bin/nmap cap_net_admin,cap_net_raw+eip

API keys "INVALID" even though they are correct#

  • Ensure there are no leading/trailing spaces in the key fields
  • Some services (NVD) have rate limits — a 429 response is treated as "key accepted"
  • Network issues (DNS, firewall) to the external APIs will show as "Network error"

Timezone not applying to old timestamps#

The localdt Jinja2 filter converts UTC datetimes at render time. All timestamps stored in the database are always UTC — only the display changes. If a page is still showing UTC, hard-refresh the browser (Ctrl+Shift+R) to clear cached template responses.

Agents showing as Offline immediately#

The agent is considered Offline if no heartbeat is received within 5 minutes. Common causes:

  • The agent process is not running — check the service status on the endpoint
  • The server URL in the agent config is wrong or not reachable from the endpoint
  • TLS verification is failing — re-run the agent with --no-verify-ssl if using a self-signed cert

Agent config file location: - Linux/macOS: ~/.pwnbroker_agent.json - Windows: %APPDATA%\pwnbroker_agent.json

"Permission denied" when setting NTP server#

PwnBroker writes to /etc/systemd/timesyncd.conf. If the service runs as the pwnbroker user (not root), this will fail. The timezone setting is always saved regardless. To apply the NTP server change manually:

sudo nano /etc/systemd/timesyncd.conf
# Set: NTP=your.ntp.server

sudo systemctl restart systemd-timesyncd
sudo timedatectl set-ntp true

Database locked errors#

SQLite allows only one writer at a time; the app runs it in WAL mode with a busy-timeout so concurrent reads/writes don't immediately fail, but if you still see "database is locked" errors under heavy load, consider switching to PostgreSQL:

# Install psycopg2
/opt/PWNBroker/venv/bin/pip install psycopg2-binary

# Update DATABASE_URL in /opt/PWNBroker/.env
DATABASE_URL=postgresql://pwnbroker:password@localhost/pwnbroker

# Create the database
sudo -u postgres createuser pwnbroker
sudo -u postgres createdb -O pwnbroker pwnbroker
sudo -u postgres psql -c "ALTER USER pwnbroker WITH PASSWORD 'password';"

# Restart to apply
sudo systemctl restart pwnbroker

PwnBroker — built for security teams that prefer owning their own data.

PwnBroker 1.0.0 · © PwnBroker. All data stays on your infrastructure.