Skip to content

shiva0126/nightfall-tsukuyomi

Repository files navigation

Nightfall Tsukuyomi

Unified Offensive Security Platform — Active/Passive Reconnaissance, DAST, Threat Intelligence, and Breach & Attack Simulation in a single pane of glass.

Built for security teams who need speed. Every scan result, MITRE ATT&CK mapping, CVE correlation, and network asset lands in one dashboard — no external integrations required.


Architecture

Service Role Port Technology
nightfall-backend REST API, scan orchestration, all business logic 8088 (host) Go 1.24, Gin, GORM
nightfall-frontend React SPA 3000 (host) React 18, TypeScript, Vite, TailwindCSS
nightfall-postgres Primary datastore internal only PostgreSQL 16
nightfall-redis Response cache internal only Redis 7 (allkeys-lru, 256 MB)
nightfall-zap DAST sidecar 8090 (host) OWASP ZAP stable

Total: 5 containers. No Elasticsearch, no RabbitMQ, no MinIO, no OpenCTI, no OpenBAS.


Quick Start

Prerequisites

  • Docker & Docker Compose v2
  • 4 GB+ RAM free
  • Ports 3000, 8088, 8090 available on the host

1. Clone

git clone https://github.com/shiva0126/nightfall-tsukuyomi.git
cd nightfall-tsukuyomi

2. Configure environment

cp .env.example .env   # edit values as needed

Required .env variables:

POSTGRES_USER=nightfall
POSTGRES_PASSWORD=changeme
POSTGRES_DB=nightfall
DB_USER=nightfall
DB_PASSWORD=changeme
DB_NAME=nightfall
JWT_SECRET=a-very-long-random-secret-at-least-32-chars
ZAP_API_KEY=nightfall-zap-key

3. Start

docker compose up -d

First boot takes ~30 seconds (Postgres init + Go binary startup).

4. Verify

curl http://localhost:8088/health
# → {"message":"Nightfall Tsukuyomi API","status":"ok"}

docker compose exec nightfall-redis redis-cli ping
# → PONG

5. Open the platform

Navigate to http://localhost:3000 and log in.

Default demo account (created on first register):

Field Value
Email admin@nightfall.local
Password (set on first /auth/register)

Platform Pages

Route Page Description
/ Dashboard Risk score, finding trends, scan history, BAS simulation widget
/scan Unified Scan Launch active/passive scans with auth options; live progress
/findings Findings All findings with severity, MITRE, OWASP, Kill Chain filters
/tools Tool Workbench Run individual security tools; ZAP DAST control panel; embedded terminal
/passive-intel Passive Intel OSINT modules — subdomains, DNS, certs, WHOIS, cloud assets
/threat-intel Threat Intel MITRE ATT&CK, OWASP Top 10, Kill Chain, CVE Intel tabs
/breach Breach Simulation OpenBAS-style scenario builder and simulation runner
/reports Reports Executive, Technical, and Compliance report generation
/target-dashboard Target Dashboard Per-target deep dive — network map, assets, finding timeline
/settings Settings API keys, integrations, platform health

Scanning Capabilities

Active Scan Modes

Mode Tools Use Case
safe httpx, whatweb, nuclei (safe), sslscan Light fingerprinting, no intrusive tests
standard + nmap, nikto, wapiti, fierce Standard pentest coverage
aggressive + sqlmap, dalfox, ffuf, gobuster, amass Full offensive coverage

DAST (ZAP)

ZAP runs as a sidecar container. Two scan modules are available from the Tool Workbench:

Module Description
zap_baseline Spider + passive scan — safe for production
zap_active Spider + AJAX spider + passive + active attack

Auth support: form-based, cookie injection, token/header injection.

Passive Reconnaissance

110+ OSINT modules including:

  • Subfinder, Amass, crt.sh certificate transparency
  • DNS brute-force (dnsx, alterx)
  • GAU (GetAllURLs), Wayback Machine
  • Shodan/Censys/Fofa (via uncover)
  • Cloud asset discovery

Authenticated Scanning

Pass credentials at scan creation; the scanner handles login flows, cookie extraction, and token injection automatically across all active modules.


Framework Intelligence

On startup (and on demand via POST /api/v1/frameworks/sync), Nightfall pulls the full MITRE ATT&CK Enterprise STIX bundle and seeds OWASP Top 10 + Kill Chain phases. Every finding is automatically enriched with:

  • mitre_attack_id / mitre_tactic / mitre_technique
  • owasp_category / owasp_name
  • kill_chain_phase
  • correlation_id (cross-tool deduplication)

Redis Caching

All heavy read endpoints are cached in Redis with graceful degradation — the app runs fully without Redis if it's unavailable.

Endpoint Cache Key TTL
GET /frameworks/mitre nightfall:mitre:ttps 2h
GET /frameworks/owasp nightfall:owasp:categories 2h
GET /frameworks/kill-chain nightfall:killchain:phases 2h
GET /findings/stats nightfall:findings:stats 10m
GET /findings/techstack nightfall:techstack:* 15m
GET /findings/by-tool nightfall:findings:by-tool 20m
GET /findings/mitre-matrix nightfall:findings:mitre-matrix 20m
GET /findings/correlations nightfall:findings:correlations 30m
GET /mitre/matrix nightfall:mitre:full-matrix 2h
GET /tools/status nightfall:tools:status 5m
GET /network-assets nightfall:network-assets:* 10m

Cache is automatically invalidated when a scan completes or a framework sync runs.

# Inspect live cache keys
docker compose exec nightfall-redis redis-cli keys "nightfall:*"

# Flush all cache (admin endpoint)
curl -X POST http://localhost:8088/api/v1/cache/flush \
  -H "Authorization: Bearer <jwt>"

# Cache stats
curl http://localhost:8088/api/v1/cache/status \
  -H "Authorization: Bearer <jwt>"

API Reference

All endpoints (except auth) require Authorization: Bearer <jwt>.

Auth

Method Endpoint Description
POST /api/v1/auth/register Create account
POST /api/v1/auth/login Login → JWT
POST /api/v1/auth/refresh Refresh JWT
GET /api/v1/auth/me Current user

Targets & Scans

Method Endpoint Description
POST /api/v1/targets Create target
GET /api/v1/targets List targets
GET /api/v1/targets/:id Get target
GET /api/v1/targets/:id/inventory Target asset inventory
DELETE /api/v1/targets/:id Delete target
POST /api/v1/scans Start scan
GET /api/v1/scans List scans
GET /api/v1/scans/:id Get scan
GET /api/v1/scans/:id/modules Live module progress
POST /api/v1/scans/:id/cancel Cancel scan

Findings

Method Endpoint Description
GET /api/v1/findings List (filter by scan_id, severity, status, tool_source, target_id)
GET /api/v1/findings/stats Severity counts
GET /api/v1/findings/techstack Detected tech stack
GET /api/v1/findings/by-tool Grouped by tool
GET /api/v1/findings/mitre-matrix MITRE heatmap data
GET /api/v1/findings/correlations Cross-tool correlated findings
PUT /api/v1/findings/:id Update finding (status, assignee)

Tool Workbench

Method Endpoint Description
GET /api/v1/tools/status Tool availability + versions
POST /api/v1/tools/execute Run a single tool/module
POST /api/v1/tools/scan-all Run all tools against a target
POST /api/v1/tools/scan-custom Run selected modules
GET /api/v1/tools/executions List executions
GET /api/v1/tools/executions/:id Execution detail + output
POST /api/v1/tools/executions/:id/stop Stop execution
POST /api/v1/tools/terminal Raw terminal command

ZAP DAST

Method Endpoint Description
GET /api/v1/zap/status ZAP sidecar health
POST /api/v1/zap/scan Start ZAP scan
GET /api/v1/zap/scan/:id/status Scan progress
POST /api/v1/zap/scan/:id/stop Stop scan
GET /api/v1/zap/scan/:id/alerts Get alerts
GET /api/v1/zap/scan/:id/report Download HTML report
GET /api/v1/zap/scans List ZAP scans
POST /api/v1/zap/clear-session Reset ZAP session

Network Assets

Method Endpoint Description
GET /api/v1/network-assets List assets (filter: tenant_id, scan_id)
GET /api/v1/network-assets/:id Asset detail + open ports

Framework Intelligence

Method Endpoint Description
GET /api/v1/frameworks/status Sync status + counts
POST /api/v1/frameworks/sync Re-sync MITRE/OWASP/Kill Chain
POST /api/v1/frameworks/remap Re-enrich existing findings
GET /api/v1/frameworks/mitre All MITRE ATT&CK TTPs
GET /api/v1/frameworks/owasp OWASP Top 10
GET /api/v1/frameworks/kill-chain Kill Chain phases
GET /api/v1/mitre/matrix Full MITRE matrix (static)

CVE Intel

Method Endpoint Description
GET /api/v1/cve/mapped CVE→finding mappings
GET /api/v1/cve/status Last sync run
POST /api/v1/cve/remap Trigger CVE re-mapping

Passive Intel

Method Endpoint Description
POST /api/v1/intel/passive Start passive recon
GET /api/v1/intel/passive List passive scans
GET /api/v1/intel/passive/:domain Results for domain

Admin

Method Endpoint Role Description
GET /api/v1/cache/status any Redis info + key count
POST /api/v1/cache/flush admin Flush all cache keys

Environment Variables

Backend

Variable Default Description
DB_HOST postgres PostgreSQL host
DB_PORT 5432 PostgreSQL port
DB_USER Database user
DB_PASSWORD Database password
DB_NAME Database name
JWT_SECRET required JWT signing secret (min 32 chars)
REDIS_HOST nightfall-redis Redis host
REDIS_PORT 6379 Redis port
ZAP_API_KEY nightfall-zap-key ZAP REST API key
FRAMEWORK_AUTO_SYNC 1 Sync MITRE/OWASP on startup (0 to disable)
FRAMEWORK_REMAP_INTERVAL_SECONDS 30 How often to re-enrich unmapped findings
CVE_INTEL_ENABLE 1 Enable periodic CVE mapping (0 to disable)
CVE_INTEL_INTERVAL_HOURS 24 CVE sync interval
SCAN_STALE_MINUTES 45 Timeout before orphaned "running" scans are marked failed

Local Development

Backend

cd backend
go run cmd/api/main.go
# API on :8080 — connect to local Postgres + Redis

Frontend

cd frontend
npm install
npm run dev
# Dev server on :5173 — proxies /api to :8088

CLI Utilities

# Force re-sync MITRE/OWASP/Kill Chain from upstream
cd backend
go run ./cmd/framework-sync

# Push completed scans to OpenCTI (legacy, optional)
go run ./cmd/export-opencti -limit 20
go run ./cmd/export-opencti -list-connectors

Tech Stack

Layer Technology
Backend Go 1.24, Gin, GORM, PostgreSQL 16
Frontend React 18, TypeScript, Vite, TailwindCSS, Recharts, Lucide
Cache Redis 7 (go-redis/v9)
DAST OWASP ZAP stable (sidecar)
Infrastructure Docker Compose

Troubleshooting

Backend won't start: FATAL: JWT_SECRET environment variable is not set Add JWT_SECRET to your .env file (minimum 32 characters).

ZAP scans time out or return no alerts ZAP takes 60+ seconds to fully initialize. Check: docker compose logs nightfall-zap

Redis shows as unavailable in /cache/status The backend degrades gracefully — all endpoints still work, just without caching. Check: docker compose ps nightfall-redis

Stale scans stuck as "running" after restart They are automatically marked failed on backend startup after SCAN_STALE_MINUTES (default 45). Set to a lower value if needed.

DB constraint error on target creation (targets_domain_key) Expected — GORM AutoMigrate sees the existing unique index by its Postgres name. The app handles this correctly.


Legal Notice

Authorized Use Only. This platform is for security research, authorized penetration testing, CTF competitions, and educational purposes only. Do not use against systems you do not own or have explicit written permission to test.


Built with Nightfall

About

Advanced Security Intelligence Platform

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors