SCOPTIX is a passive reconnaissance and attack surface exploration tool that helps analysts identify exposed content, potentially sensitive information, and application endpoints that may warrant further investigation. It aggregates subdomains, URLs, IP addresses, and archived web assets from external data sources to support security analysis and exposure discovery.
Data is currently sourced from VirusTotal and the Internet Archive's Wayback Machine.
- Asset Discovery: Discover subdomains, URLs, IP addresses, and archived web assets from multiple external data sources. IP resolutions come from VirusTotal passive DNS (hostname ↔ IP history for the apex and discovered subdomains). Each scan keeps an observed IP list for that run; the target view aggregates the same addresses across all scans with hostname timelines and historical resolution detail.
- Exposure Discovery: Identify potentially exposed credentials, API keys, tokens, cloud secrets, and configuration artifacts across discovered assets using customizable detection rules.
- Asset Categorization: Automatically group discovered URLs into extension categories you define in Settings—create categories and map pathname suffixes (e.g.
.pdf,.js,.zip) so assets are organized for review. - Deep Scan: Optionally download JavaScript files when starting a scan and analyze their contents against your detection rules, in addition to the URL-string checks applied to every URL.
- Endpoint Discovery: Explore parameters, application endpoints, authentication-related resources, and other security-relevant application assets.
- Scan Comparison: Track changes across scans and quickly identify newly discovered subdomains, URLs, IP addresses, archived assets, and exposure findings.
SCOPTIX was built around methodologies demonstrated by Urwah Atiyat (OrwaGodFather) in the following presentations:
- Art of VirusTotal Hacking – https://www.youtube.com/watch?v=Xosa-1o-01M
- Essence of Recon in Bug Bounty and Pentesting – https://www.youtube.com/watch?v=CJnXjWXXB1Y
Real-world examples discussed in these presentations include:
- Identifying exposed origin infrastructure behind WAF.
- Discovering publicly accessible sensitive documents, including identity records, passports, and other personal information.
- Finding forgotten backup archives (such as
backup.7z) exposing source code, credentials, configuration files, or other sensitive internal information. - Identifying password reset URLs that remain valid beyond their intended lifetime, potentially leading to account compromise.
- Discover subdomains, URLs, and IP resolution history from external data sources.
- Review identified assets (including per-IP hostname history on the target) and archived content.
- Analyze URLs and content for exposed credentials, secrets, and sensitive files.
- Investigate application endpoints and other security-relevant findings.
- Compare results across scans to identify newly discovered exposures.
- Not for production: This tool focuses on functionality over hardened security. Use it exclusively in isolated, trusted environments.
- No built-in authentication: Anyone with network access can view findings and trigger scans. Do NOT expose SCOPTIX to the public internet without your own access controls (e.g., VPN, reverse proxy).
- Third-party APIs and data: VirusTotal and the Internet Archive impose their own terms, rate limits, and acceptable-use policies. This repository orchestrates queries and stores results locally; it is not a redistribution of upstream datasets.
- Node.js (LTS recommended) and npm
- Git (to clone the repository)
- Either Docker (recommended for Postgres + Redis) or your own PostgreSQL and Redis instances
- One or more VirusTotal API keys (required for VT-powered discovery)
Tested platform: Ubuntu 26.04 (Docker and local dev workflows above). Other Linux distributions and macOS may work but are not routinely verified.
Optional: SOCKS proxy (if outbound API or deep-fetch traffic must route through a proxy)
Note on VirusTotal API Keys:
Community (Free) VirusTotal API keys are fully supported, although throughput is limited by VirusTotal's public API quotas (≈4 requests/minute, ≈500 requests/day, and ≈15,500 requests/month per key). If faster scans are needed, additional API keys can be configured, and SCOPTIX will automatically distribute requests across them. For example:
- 1 API key ≈ 4 requests/minute
- 4 API keys ≈ 16 requests/minute
Choose one of two workflows:
| Workflow | Best for | Command |
|---|---|---|
| Local dev (hot reload) | Changing UI/worker code | npm run dev:local |
| Full Docker | Try production-like stack without Node on host | bash docker-start.sh |
Both use the same .env file with localhost URLs for Postgres and Redis when developing on your machine. Docker Compose maps containers to localhost:5432 and localhost:6379.
git clone <your-clone-url>
cd scoptix
npm installcp .env.example .envThe helper scripts can create .env automatically on first run (scripts/ensure-env.sh).
Edit .env and set at minimum:
| Variable | Required | Purpose |
|---|---|---|
DATABASE_URL |
Yes | PostgreSQL connection string (postgresql://recon:recon@localhost:5432/recon?schema=public with Docker infra) |
REDIS_URL |
Yes | Redis connection string (redis://127.0.0.1:6379 with Docker infra) |
APP_ENCRYPTION_KEY |
Recommended | 32-byte key (base64 or hex) for encrypting stored API keys |
VT_SEED_API_KEY |
Optional | Seed a VirusTotal key during npm run db:seed (dev convenience) |
Generate an encryption key (Linux/macOS):
openssl rand -base64 32If APP_ENCRYPTION_KEY is omitted, the app can auto-provision a key in the database on first use—but setting it explicitly is recommended so keys remain decryptable across deployments.
One command starts Postgres + Redis in Docker, runs migrations on first use, then the Next.js dev server and scan worker with hot reload:
npm run dev:localOr step by step:
npm run docker:infra # Postgres + Redis only
npm run docker:wait # wait until both are healthy
npm run setup # first time: migrate + seed
npm run dev:all # dev server + workerEquivalent shell wrapper: bash docker-start-infra.sh then npm run dev:all.
Builds and runs the app, worker, database setup, Postgres, and Redis in containers (no hot reload):
bash docker-start.shOpen http://localhost:3000.
- Check status:
./docker-status.sh - Logs:
npm run docker:logs - Stop:
bash docker-stop.shornpm run docker:down
If you already run Postgres and Redis (not via this repo’s Compose file), point DATABASE_URL and REDIS_URL in .env at your instances, then:
npm run setup
npm run dev:all- Open Settings → API & network and add at least one VirusTotal API key (unless seeded).
- Confirm VirusTotal (and optionally Wayback Machine) are enabled under scan engines.
- Go to Scans, enter a domain, optionally enable deep scan, and start.
Development and Docker helper scripts in this repo were validated on Ubuntu 26.04.
- Postgres data is stored in a named Docker volume (
scoptix_pg), not a host bind mount—so you avoid UID/GID permission issues on./datafolders. - Linux: add your user to the
dockergroup so you do not needsudofor Compose:sudo usermod -aG docker $USER, then log out and back in. - Ports: defaults are
5432(Postgres) and6379(Redis). Override withPOSTGRES_PORT/REDIS_PORTin.envif those ports are already in use.
| Script | Purpose |
|---|---|
npm run dev:local |
Docker infra + migrate (if needed) + dev:all (one-shot local dev) |
npm run docker:infra |
Start only Postgres + Redis |
npm run docker:infra:setup |
Infra + wait + setup |
npm run docker:up / docker:down |
Full stack in Docker |
npm run dev |
Next.js dev server |
npm run worker |
BullMQ scan worker (required for scans to run) |
npm run dev:all |
Dev server + worker via concurrently |
npm run build / npm run start |
Production build and server |
npm run lint |
ESLint |
npm run db:migrate |
Apply Prisma migrations |
npm run db:push |
Push schema without migration files (dev shortcut) |
npm run db:seed |
Seed extension rules and default settings |
npm run setup |
db:migrate + db:seed |
The schema ships as a single Prisma migration: prisma/migrations/0001_init. Fresh installs (npm run setup, bash docker-start.sh) apply that file automatically.
When both engines are enabled for a root-domain scan, the worker roughly follows:
- VirusTotal — apex: domain report, URL harvest, and passive DNS resolutions for the root domain.
- VirusTotal — subdomains: BFS expansion up to
maxSubdomains(URLs and passive DNS per hostname). - VirusTotal — IP resolutions: persist observed IPs for the scan and merge hostname↔IP sightings into the target’s global IP directory.
- Wayback — apex: CDX URL list for the root domain.
- Wayback — subdomains: CDX per discovered subdomain (rate-limited).
- Consolidate: dedupe URLs, assign extension categories, update target caches.
- Analysis: regex scan on URL strings; optional deep fetch + body scan for selected categories.
Subdomain-only scans skip full apex expansion but still run enabled engines against the input hostname.
Improvements, bug reports, and security feedback are welcome as issues or pull requests. Please respect VirusTotal and Internet Archive terms of use when testing against live APIs.