A small toolkit of shell scripts that wraps hashcat and makes it pleasant to run β locally or on a remote host over SSH, inside a Docker container or directly on the host.
- Why
- Features
- Scripts
- Requirements
- Installation
- Configuration
- Usage
- Task Queue
- Directory Checks
- Process Control
- Directory Layout
- Logs and State
- Exit Codes
- Troubleshooting
- FAQ
- Security Notes
- Contributing
- License
Hashcat is fantastic. The command line around it β less so:
- Long
-m β¦ -a β¦ -o β¦ --username β¦lines that you keep retyping. - No built-in way to fire off a batch of attacks and walk away.
- Running it on a beefy remote GPU box means either a mess of
sshcommands or copying everything around.
hashcat-toolkit fixes all three with one small, readable Bash script per
scenario, plus a shared queue, logging, and consistent CLI. Nothing to
compile. No Python. Just git clone && chmod +x.
- π Task queue β add, list, remove, clear, run.
- π
--checkβ quickly inspect hash / wordlist / rules / output dirs. - ποΈ Process control β
--status,--kill,--benchmark,--restart. - π¨ Colored output with properly aligned boxes. Colors auto-disable when output is piped to a file.
- π Logging of every run (command + exit code) to
~/.local/share/. - π‘οΈ Safe Ctrl-C handling β the Docker mode restarts the remote container on interrupt, so you never leave a zombie behind.
- π Configs in
~/.config/*.confβ no secrets ever land in the repo. - π§© Consistent interface β the local and Docker scripts share the same flags, so muscle memory carries over.
| Script | Runs where | Requires |
|---|---|---|
hashcat-local.sh |
On this machine | hashcat in PATH |
remote-hashcat.sh |
Inside a Docker container on a remote host over SSH | ssh + docker on the remote |
Both scripts expose the same subcommands (--queue, --check, --status, β¦),
so you can switch between them without relearning anything.
- bash β₯ 4.0 (any modern Linux distro has it β Kali, Ubuntu, Debian, Archβ¦)
- ssh client (for the remote script)
- docker on the remote host (for the remote script)
- hashcat in
PATH(for the local script) β or setHASHCAT_BINin the config to an absolute path.
Optional but recommended:
shellcheckβ for linting the scripts.- A modern terminal with UTF-8 support (for aligned boxes).
git clone https://github.com/lexapypsik10/hashcat-toolkit.git
cd hashcat-toolkitchmod +x *.shsudo ln -s "$PWD/hashcat-local.sh" /usr/local/bin/hcl
sudo ln -s "$PWD/remote-hashcat.sh" /usr/local/bin/rhcNow you can call hcl β¦ and rhc β¦ from anywhere.
hcl --help
rhc --helpYou should see a blood-red box with usage instructions. π©Έ
The scripts read configuration from ~/.config/*.conf if the file exists.
If it doesn't, sane defaults are used.
Never commit your real config to Git. They live in
~/.config/, not in the repo. The bundled.gitignorealready excludes*.conf.
# Path to the hashcat binary (name in PATH or absolute path)
HASHCAT_BIN="hashcat"
# Working root for local hashes/wordlists/rules/output
LOCAL_ROOT="$HOME/hashcat"
# Optional overrides
# QUEUE_FILE="$HOME/.local/share/hashcat-local/queue.txt"
# LOG_FILE="$HOME/.local/share/hashcat-local/hashcat-local.log"# SSH target β hostname or ~/.ssh/config alias
HOST="user@my-server.com"
# Name of the running hashcat container
CONTAINER="hashcat"
# Paths **inside the container**
REMOTE_ROOT="/road/road"
REMOTE_OUTPUT="/road/road/output"
# Optional overrides
# QUEUE_FILE="$HOME/.local/share/remote-hashcat/queue.txt"
# LOG_FILE="$HOME/.local/share/remote-hashcat/remote-hashcat.log"Tighten permissions:
chmod 600 ~/.config/hashcat-local.conf ~/.config/remote-hashcat.confFor remote-hashcat.sh to work, on the remote host:
-
SSH key access is set up (no password prompt):
ssh-copy-id user@my-server.com ssh user@my-server.com "echo ok" -
A container with hashcat is running:
ssh user@my-server.com "docker ps" # CONTAINER ID IMAGE ... NAMES # abc123... hashcat/hashcat ... hashcat
-
Inside the container the working tree exists:
ssh user@my-server.com "docker exec -i hashcat mkdir -p /road/road/{hashes,wordlists,rules,output}"
Golden rule: every hashcat argument is passed as one quoted string. The scripts pass that string straight through to hashcat, preserving order.
./hashcat-local.sh --help
./hashcat-local.sh --check
./hashcat-local.sh --check wordlists
./hashcat-local.sh "-m 0 -a 0 \
$HOME/hashcat/hashes/md5.txt \
$HOME/hashcat/wordlists/rockyou.txt \
-O -w 3 \
-o $HOME/hashcat/output/md5.cracked"./remote-hashcat.sh --help
./remote-hashcat.sh --check
./remote-hashcat.sh --check output
./remote-hashcat.sh "-m 1000 -a 0 \
/road/road/hashes/ntlm.txt \
/road/road/wordlists/rockyou.txt \
-O -w 3 \
-o /road/road/output/ntlm.cracked \
--username"Note the paths inside the Docker mode are container paths (
/road/road/...), not host paths.
Works identically in both scripts. Example with hashcat-local.sh
β swap the binary name for remote-hashcat.sh in the Docker case.
# Add a task
./hashcat-local.sh --queue add "-m 0 -a 0 ~/hashcat/hashes/md5.txt ~/hashcat/wordlists/rockyou.txt -O -w 3"
# Add another one
./hashcat-local.sh --queue add "-m 1000 -a 0 ~/hashcat/hashes/ntlm.txt ~/hashcat/wordlists/rockyou.txt -O -w 3"
# Inspect
./hashcat-local.sh --queue list
# ========== QUEUE ==========
# 1. -m 0 -a 0 ...
# 2. -m 1000 -a 0 ...
# Remove the 2nd task
./hashcat-local.sh --queue rm 2
# Run everything one after another
./hashcat-local.sh --queue run
# Clear
./hashcat-local.sh --queue clearThe queue is stored as plain text (one command per line) in:
- Local mode β
~/.local/share/hashcat-local/queue.txt - Docker mode β
~/.local/share/remote-hashcat/queue.txt
You can edit it by hand if you want.
Quickly list the contents of the working tree, without remembering paths:
./hashcat-local.sh --check # the whole root
./hashcat-local.sh --check hashes
./hashcat-local.sh --check wordlists
./hashcat-local.sh --check rules
./hashcat-local.sh --check outputFor remote mode, the same flags run ls inside the container:
./remote-hashcat.sh --check
./remote-hashcat.sh --check wordlists./hashcat-local.sh --status # hashcat --status
./hashcat-local.sh --kill # pkill hashcat
./hashcat-local.sh --benchmark # hashcat -b./remote-hashcat.sh --status # hashcat --status inside the container
./remote-hashcat.sh --kill # pkill hashcat inside the container
./remote-hashcat.sh --restart # docker restart the containerBoth modes expect (and, in the local case, create) this layout:
<root>/
βββ hashes/ # your hash files
βββ wordlists/ # wordlists (rockyou.txt, etc.)
βββ rules/ # hashcat rule files
βββ output/ # cracked results (-o ...)
Where <root> is:
- local β
$LOCAL_ROOT(default~/hashcat) - remote β
$REMOTE_ROOT(default/road/road, inside the container)
| What | Path |
|---|---|
| Local log | ~/.local/share/hashcat-local/hashcat-local.log |
| Local queue | ~/.local/share/hashcat-local/queue.txt |
| Remote log | ~/.local/share/remote-hashcat/remote-hashcat.log |
| Remote queue | ~/.local/share/remote-hashcat/queue.txt |
Each log line is timestamped:
[2025-01-15 21:04:12] RUN: -m 0 -a 0 ...
[2025-01-15 21:07:55] EXIT: 0 β -m 0 -a 0 ...
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Bad arguments, missing config, unreachable host |
130 |
Interrupted by user (Ctrl-C) β cleanup already ran |
| other | Passed through from hashcat |
βCannot reach user@host over SSHβ
- Check the
HOSTvalue in~/.config/remote-hashcat.conf. - Run
ssh user@host "echo ok"manually. - Make sure your SSH key is loaded (
ssh-add -l) and copied withssh-copy-id.
βcontainer 'hashcat' is not runningβ
ssh user@host "docker ps -a | grep hashcat"
ssh user@host "docker start hashcat"Or change CONTAINER in the config to the actual container name.
Boxes look misaligned
Your locale is not UTF-8. Fix:
sudo locale-gen en_US.UTF-8
sudo update-locale LANG=en_US.UTF-8
# re-login, or:
export LANG=en_US.UTF-8Also make sure your terminal font is monospace.
Colors show up as `\033[0;36m`
You are using an old version of the script that used cat <<EOF.
Update to the latest version from this repo β it uses printf with $'\033β¦'.
hashcat not found
which hashcat
# if empty, install it:
sudo apt install hashcat # Debian/Kali/UbuntuOr set an absolute path:
HASHCAT_BIN="/opt/hashcat/hashcat" # in ~/.config/hashcat-local.confCan I run several hashcat jobs at once?
Yes β put them in the queue and run --queue run in the background with &
plus nohup, or use tmux/screen on the machine where the script runs.
Does this work on macOS?
The hashcat-local.sh script should work if you have bash β₯ 4.0
(brew install bash) and hashcat in PATH. The remote script works over SSH
regardless of your OS.
Why do I need to wrap arguments in quotes?
Because hashcat options contain spaces and characters that the shell would otherwise split. Passing one quoted string preserves the exact order and lets the script forward them unchanged.
Can I use a different container name?
Yes β set CONTAINER="whatever" in ~/.config/remote-hashcat.conf.
- Never commit your
~/.config/*.conffiles. They may contain hostnames, usernames, and internal paths. The bundled.gitignorealready excludes*.conf. - Use SSH keys, not passwords.
- If you publish screenshots or logs, redact
HOST=and internal paths. - This tool runs hashcat with your privileges. It doesn't add or bypass any authorization β only use hashcat on data you are legally allowed to test.
Pull requests are welcome.
- Fork the repo.
- Create a branch:
git checkout -b feature/my-change. - Run
shellcheck *.shbefore committing. - Keep the coding style: 4-space indentation,
set -uo pipefail, ANSI colors via$'\033[β¦', helpers namedbox_line/box_rule/die. - Open a PR with a clear description.
MIT β see LICENSE.
π©Έ Stay in the red. Crack responsibly. π©Έ
