{"id":48115286,"url":"https://github.com/thijsvos/crackswarm","last_synced_at":"2026-04-04T16:14:57.467Z","repository":{"id":347856393,"uuid":"1177299065","full_name":"thijsvos/crackswarm","owner":"thijsvos","description":"Crackswarm — distributed hashcat orchestration with Noise-encrypted transport, live TUI dashboards, and multi-phase campaign support","archived":false,"fork":false,"pushed_at":"2026-03-29T20:42:13.000Z","size":419,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-29T20:50:04.292Z","etag":null,"topics":["distributed-computing","hashcat","noise-protocol","password-cracking","rust","tui"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thijsvos.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-09T22:31:45.000Z","updated_at":"2026-03-29T20:42:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/thijsvos/crackswarm","commit_stats":null,"previous_names":["thijsvos/crackswarm"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/thijsvos/crackswarm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thijsvos%2Fcrackswarm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thijsvos%2Fcrackswarm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thijsvos%2Fcrackswarm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thijsvos%2Fcrackswarm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thijsvos","download_url":"https://codeload.github.com/thijsvos/crackswarm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thijsvos%2Fcrackswarm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31405699,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["distributed-computing","hashcat","noise-protocol","password-cracking","rust","tui"],"created_at":"2026-04-04T16:14:56.829Z","updated_at":"2026-04-04T16:14:57.456Z","avatar_url":"https://github.com/thijsvos.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# crackswarm\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![CI](https://github.com/thijsvos/crackswarm/actions/workflows/ci.yml/badge.svg)](https://github.com/thijsvos/crackswarm/actions/workflows/ci.yml)\n[![Release](https://img.shields.io/github/v/release/thijsvos/crackswarm)](https://github.com/thijsvos/crackswarm/releases)\n\nDistributed hashcat orchestration tool. Splits cracking work across GPU workers with encrypted transport, live TUI dashboards, and multi-phase campaign support.\n\n![Crackswarm TUI Demo](docs/demo.gif)\n\n## Table of Contents\n\n- [Features](#features)\n- [Architecture](#architecture)\n- [Quick Start](#quick-start)\n- [TUI Dashboard](#tui-dashboard)\n- [Campaigns](#campaigns)\n- [Commands](#commands)\n- [Security](#security)\n- [How It Works](#how-it-works)\n- [Changelog](CHANGELOG.md)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Features\n\n- **Distributed cracking** -- coordinate hashcat across multiple GPU workers from a single dashboard\n- **Multiple attack modes** -- brute-force/mask, dictionary, and dictionary+rules attacks\n- **Bundled rules** -- includes [OneRuleToRuleThemStill](https://github.com/stealthsploit/OneRuleToRuleThemStill) (48K rules by [Will Hunt](https://github.com/stealthsploit), MIT license)\n- **Noise IK encryption** -- all worker traffic is end-to-end encrypted (WireGuard-grade, via `snow`)\n- **Live TUI dashboards** -- real-time progress on both coordinator and agents with vim keybindings\n- **Multi-phase campaigns** -- chain attack phases together; uncracked hashes roll forward automatically\n- **Pattern analyzer** -- examines cracked passwords to generate targeted masks for subsequent phases\n- **Adaptive chunking** -- chunk sizes tuned to worker GPU speed (~10 min target per chunk)\n- **Token-based enrollment** -- onboard new workers with a single command, no manual key exchange\n- **Automatic failover** -- heartbeat monitoring with chunk reassignment on worker disconnect\n\n## Architecture\n\n```\n                 crackctl (CLI)\n                      |\n              REST API (127.0.0.1)\n                      |\n  ┌───────────────────┴───────────────────┐\n  │            crack-coord                │\n  │                                       │\n  │  ┌───────────┐ ┌────────┐ ┌─────────┐ │\n  │  │ Scheduler │ │ SQLite │ │   TUI   │ │\n  │  └───────────┘ └────────┘ └─────────┘ │\n  │                                       │\n  │        Noise IK encrypted TCP         │\n  └──────────┬───────────────┬────────────┘\n             │               │\n     ┌───────┴───────┐ ┌─────┴─────────┐\n     │  crack-agent  │ │  crack-agent  │  ...\n     │    hashcat    │ │    hashcat    │\n     │    GPU(s)     │ │    GPU(s)     │\n     └───────────────┘ └───────────────┘\n```\n\n| Binary | Role |\n|--------|------|\n| `crack-coord` | Coordinator server with TUI dashboard |\n| `crack-agent` | Worker agent -- runs hashcat, reports results |\n| `crackctl` | Operator CLI for task/worker/campaign management |\n\n## Quick Start\n\n### Prerequisites\n\n- **Rust toolchain** -- install via [rustup](https://rustup.rs/)\n- **hashcat** -- installed and in PATH ([hashcat.net](https://hashcat.net/hashcat/))\n- GPU drivers appropriate for your hardware (NVIDIA, AMD, etc.)\n\n### Build\n\n```bash\ncargo build --release\n```\n\nBinaries are in `target/release/`: `crack-coord`, `crack-agent`, `crackctl`.\n\nPre-built binaries for Linux, macOS, and Windows are available on the [releases page](https://github.com/thijsvos/crackswarm/releases).\n\n### Single-Machine Setup\n\nThe fastest way to get started -- coordinator and agent on the same box:\n\n```bash\n# Start coordinator with a built-in local agent\ncrack-coord run --with-agent\n\n# Upload a hash file\ncrackctl file upload hashes.txt\n\n# Create a brute-force task\ncrackctl task create \\\n  --name \"NTLM brute\" \\\n  --hash-mode 1000 \\\n  --hash-file \u003cfile-id\u003e \\\n  --mask '?a?a?a?a?a?a'\n```\n\nThe coordinator TUI shows live progress across five tabs: Tasks, Workers, Results, Audit Log, and Campaigns.\n\n### Multi-Machine Setup\n\n**On the coordinator:**\n\n```bash\n# Start the coordinator\ncrack-coord run --bind 0.0.0.0:8443\n\n# Generate an enrollment token for a new worker\ncrackctl worker enroll --name \"gpu-server-1\"\n```\n\n**On each worker:**\n\n```bash\n# Enroll using the token (server address is embedded in it)\ncrack-agent enroll --token '\u003ctoken\u003e'\n\n# On subsequent runs, the agent reconnects automatically\ncrack-agent run --server \u003ccoord-ip\u003e:8443\n```\n\nWorkers reconnect automatically with exponential backoff (1s to 60s) if the connection drops.\n\n### Dictionary Attacks\n\nUpload a wordlist and create a dictionary task:\n\n```bash\n# Upload a wordlist\ncrackctl file upload rockyou.txt --type wordlist\n\n# Dictionary attack (hashcat -a 0)\ncrackctl task create --name \"Dict attack\" --hash-mode 1000 \\\n  --hash-file \u003chash-id\u003e --wordlist \u003cwordlist-id\u003e\n```\n\n### Dictionary with Rules\n\nThe `rules/` directory includes [OneRuleToRuleThemStill](https://github.com/stealthsploit/OneRuleToRuleThemStill) -- an optimized rule set of 48,439 rules by [Will Hunt (@stealthsploit)](https://github.com/stealthsploit), MIT licensed. Upload it and combine with a wordlist:\n\n```bash\n# Upload rules file\ncrackctl file upload rules/OneRuleToRuleThemStill.rule --type rules\n\n# Dictionary + rules attack\ncrackctl task create --name \"Dict+OTRTS\" --hash-mode 1000 \\\n  --hash-file \u003chash-id\u003e --wordlist \u003cwordlist-id\u003e --rules-file \u003crules-id\u003e\n```\n\nWordlist and rules files are transferred to workers over the encrypted Noise channel and cached locally. Files are sent in ~40KB chunks and only transferred once per worker.\n\n## TUI Dashboard\n\n### Coordinator\n\nThe coordinator TUI has five tabs with vim-style navigation:\n\n| Tab | Content |\n|-----|---------|\n| **Tasks** | Task list with progress gauges, speed, ETA, chunk breakdown |\n| **Workers** | Worker status, GPU devices, hashcat version, last seen |\n| **Results** | Cracked hashes with plaintext, worker attribution, timestamps |\n| **Audit Log** | System events: connections, completions, errors |\n| **Campaigns** | Campaign progress with per-phase status |\n\n**Keybindings:**\n\n| Key | Action |\n|-----|--------|\n| `1`-`5` | Jump to tab |\n| `j`/`k` | Navigate up/down |\n| `g`/`G` | Jump to top/bottom |\n| `Ctrl+d`/`Ctrl+u` | Page down/up |\n| `Tab` | Cycle panel focus |\n| `/` | Search/filter current list |\n| `:` | Command mode (`:cancel`, `:start`, `:delete`, `:quit`) |\n| `?` | Toggle help overlay |\n| `q` | Quit |\n\nToast notifications appear for worker connects/disconnects, completed tasks, and cracked hashes. Use `--headless` for log-only output (no TUI).\n\n### Agent\n\nThe agent displays a single-screen dashboard with connection status, current chunk progress with speed/ETA, recent cracks (last 10), and session stats. Use `--headless` for log-only output.\n\n## Campaigns\n\nCampaigns chain multiple attack phases together. Uncracked hashes automatically carry forward between phases.\n\n```bash\n# Create a campaign from a built-in template (mask-only)\ncrackctl campaign create \\\n  --name \"Full NTLM audit\" \\\n  --hash-mode 1000 \\\n  --hash-file-path ntds_hashes.txt \\\n  --template ntlm-standard \\\n  --auto-start\n\n# Create a campaign with dictionary + rules phases included\ncrackctl campaign create \\\n  --name \"Full NTLM audit\" \\\n  --hash-mode 1000 \\\n  --hash-file-path ntds_hashes.txt \\\n  --template ntlm-standard \\\n  --wordlist \u003cwordlist-id\u003e \\\n  --rules-file \u003crules-id\u003e \\\n  --auto-start\n\n# List available templates\ncrackctl campaign templates\n\n# Monitor progress\ncrackctl campaign show \u003cid\u003e\n```\n\nIf `--wordlist` is provided, templates include a dictionary (+rules) phase early in the pipeline. Without it, dictionary phases are automatically skipped.\n\n### Built-in Templates\n\n| Template | Hash Mode | Phases | Description |\n|----------|-----------|--------|-------------|\n| `ntlm-standard` | 1000 (NTLM) | 7 | PIN sweep, dictionary+rules, common masks, pattern analysis, brute-force up to 8 chars |\n| `wpa-quick` | 22000 (WPA) | 4 | 8-digit PINs, dictionary+rules, common 8-char masks, pattern analysis |\n| `generic-quick` | Any | 6 | PIN sweep, dictionary+rules, common masks, pattern analysis, brute-force up to 7 chars |\n\n### Phase Types\n\n- **StaticMask** -- single mask attack\n- **MultiMask** -- sequential list of masks, auto-advances through each\n- **ExpandingBrute** -- brute-force with incrementing length (e.g., `?a` length 1 through 8)\n- **Dictionary** -- wordlist attack with optional rules file (skipped if no wordlist provided)\n- **AutoGenerated** -- the pattern analyzer examines already-cracked passwords and generates targeted masks for the next round\n\n### Pattern Analyzer\n\nThe `AutoGenerated` phase type is the most distinctive feature. It examines passwords cracked in earlier phases to infer structural patterns:\n\n1. Converts each cracked password to a skeleton (e.g., `Password1!` becomes `Ullllllld s`)\n2. Ranks skeletons by frequency across the cracked set\n3. Generates masks from the top patterns, including custom charset narrowing and suffix-anchored variants\n4. Filters out masks already tried in previous phases\n\nThis creates a feedback loop: each round of cracking informs the next, targeting the most likely remaining password structures.\n\n## Commands\n\n### crackctl\n\n```\ncrackctl [--api-url \u003curl\u003e]       Override API URL (default: http://127.0.0.1:9443)\n                                 env: CRACKCTL_API_URL\n\nTasks:\n  task create                    Create a cracking task\n    --name \u003cname\u003e                  Task name (required)\n    --hash-mode \u003cmode\u003e             Hashcat hash mode (required)\n    --hash-file \u003cid\u003e               Hash file ID (required)\n    --mask \u003cmask\u003e                  Attack mask for brute-force (mutually exclusive with --wordlist)\n    --wordlist \u003cid\u003e                Wordlist file ID for dictionary attacks\n    --rules-file \u003cid\u003e              Rules file ID (requires --wordlist)\n    --charset1..4 \u003cchars\u003e          Custom charsets for ?1..?4\n    --priority \u003c1-10\u003e              Task priority (default: 5)\n    --extra-args \u003cargs\u003e            Additional hashcat arguments\n  task list                      List all tasks\n  task show \u003cid\u003e                 Show task details with chunks\n  task results \u003cid\u003e              Show cracked hashes for a task\n  task cancel \u003cid\u003e               Cancel a running task\n  task delete \u003cid\u003e               Delete a task\n\nFiles:\n  file upload \u003cpath\u003e             Upload a hash file\n    --type \u003ctype\u003e                  File type (default: hash)\n  file list                      List uploaded files\n\nWorkers:\n  worker list                    List all workers\n  worker authorize               Pre-authorize a worker by public key\n    --pubkey \u003ckey\u003e                 Worker's base64 public key (required)\n    --name \u003cname\u003e                  Worker name (required)\n  worker enroll                  Generate an enrollment token\n    --name \u003cname\u003e                  Worker name (required)\n    --expires-minutes \u003cmin\u003e        Token TTL (default: 60)\n\nCampaigns:\n  campaign create                Create a multi-phase campaign\n    --name \u003cname\u003e                  Campaign name (required)\n    --hash-mode \u003cmode\u003e             Hashcat hash mode (required)\n    --hash-file-path \u003cpath\u003e        Hash file path (auto-uploads)\n    --template \u003cname\u003e              Use a built-in template\n    --wordlist \u003cid\u003e                Wordlist file ID for dictionary phases in templates\n    --rules-file \u003cid\u003e              Rules file ID for dictionary+rules phases in templates\n    --auto-start                   Start immediately after creation\n    --priority \u003c1-10\u003e              Task priority (default: 5)\n  campaign list                  List all campaigns\n  campaign show \u003cid\u003e             Show campaign with phases\n  campaign start \u003cid\u003e            Start a draft campaign\n  campaign results \u003cid\u003e          Show all cracked hashes\n  campaign cancel \u003cid\u003e           Cancel a running campaign\n  campaign delete \u003cid\u003e           Delete a campaign\n  campaign templates             List built-in templates\n\nPotfile:\n  potfile stats                  Show potfile statistics\n  potfile export                 Export cracked plaintexts\n    --output \u003cpath\u003e                Write to file instead of stdout\n\nSystem:\n  status                         System overview\n```\n\n### crack-coord\n\n```\ncrack-coord init                 Initialize coordinator (generate keys)\n  --data-dir \u003cpath\u003e                Data directory (default: platform data dir)\n\ncrack-coord run                  Start the coordinator\n  --bind \u003caddr\u003e                    Worker transport address (default: 0.0.0.0:8443)\n  --api-bind \u003caddr\u003e                REST API address (default: 127.0.0.1:9443)\n  --data-dir \u003cpath\u003e                Data directory\n  --with-agent                     Run a local worker agent in the same process\n  --headless                       No TUI, log output only\n  --hashcat-path \u003cpath\u003e            Path to hashcat binary (default: hashcat)\n```\n\nEnvironment variables: `CRACK_COORD_DATA_DIR`, `CRACK_COORD_BIND`, `CRACK_COORD_API_BIND`\n\n### crack-agent\n\n```\ncrack-agent init                 Initialize agent (generate keys)\n  --coord-key \u003ckey\u003e                Coordinator's base64 public key (required)\n  --data-dir \u003cpath\u003e                Data directory (default: platform data dir)\n\ncrack-agent enroll               Enroll via token from coordinator\n  --token \u003ctoken\u003e                  Enrollment token (required)\n  --server \u003caddr\u003e                  Override server address from token\n  --data-dir \u003cpath\u003e                Data directory\n  --hashcat-path \u003cpath\u003e            Path to hashcat binary\n\ncrack-agent run                  Connect and process work\n  --server \u003caddr\u003e                  Coordinator address (required)\n  --name \u003cname\u003e                    Worker name (default: hostname)\n  --data-dir \u003cpath\u003e                Data directory\n  --headless                       No TUI, log output only\n  --hashcat-path \u003cpath\u003e            Path to hashcat binary (default: hashcat)\n```\n\nEnvironment variables: `CRACK_AGENT_DATA_DIR`, `CRACK_AGENT_SERVER`\n\n## Security\n\n- **Noise IK protocol** (via `snow`) for all worker-coordinator traffic -- mutual authentication with Curve25519 static keys, ChaCha20-Poly1305 encryption, forward secrecy, no plaintext fallback\n- **REST API binds to 127.0.0.1 by default** -- same-machine access only, no authentication. If you override `--api-bind` to a non-loopback address, the API will be exposed without authentication\n- **Token-based enrollment** -- time-limited tokens (default 60 min) with embedded coordinator public key and server address\n- **Private key protection** -- keys stored with 0600 permissions (Unix), zeroed from memory on drop\n- **SQLite with WAL mode** -- embedded, no network-exposed database\n- **Heartbeat monitoring** -- 15-second interval, 60-second timeout; disconnected workers have their chunks automatically reassigned\n\n## How It Works\n\n1. **Hash file upload** -- operator uploads hashes via `crackctl`, stored on coordinator disk and transferred to agents over the encrypted channel\n2. **Task/campaign creation** -- defines hash mode, attack mask, priority, and optional custom charsets\n3. **Keyspace computation** -- coordinator runs `hashcat --keyspace` to determine total work units\n4. **Adaptive chunking** -- chunk sizes tuned per-worker based on benchmark speed (~10 min target), with fair-share capping so no single worker monopolizes the keyspace\n5. **Chunk dispatch** -- coordinator assigns chunks to idle workers over the Noise-encrypted channel\n6. **Hashcat execution** -- agent runs hashcat with `--status-json`, streams progress and speed back to the coordinator in real-time\n7. **Result collection** -- each chunk uses an isolated per-chunk potfile and outfile to prevent interference between workers. Cracked hashes are sent to the coordinator in real-time over the Noise channel as they're found (not batched at the end). The coordinator stores all results in SQLite, which acts as the centralized potfile. Temporary potfiles and outfiles are cleaned up after each chunk completes\n8. **Campaign advancement** -- when a phase exhausts its keyspace, uncracked hashes roll into the next phase. `AutoGenerated` phases analyze cracked passwords to generate new targeted masks\n\n## Contributing\n\nContributions are welcome. Please open an issue to discuss proposed changes before submitting a pull request.\n\nFor security vulnerabilities, see [SECURITY.md](SECURITY.md).\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthijsvos%2Fcrackswarm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthijsvos%2Fcrackswarm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthijsvos%2Fcrackswarm/lists"}