hickok
A reverse-shell handler and post-exploitation console. Catch shells on multiple listeners, run commands, upgrade to a full PTY, generate reverse-shell one-liners, and walk a SQL injection end-to-end — from one dependency-free CLI.
It's the other half of a hand: wraith holds the aces — it does the recon and proves the way in; hickok brings the eights — it acts on what wraith caught. Aces and eights, the dead man's hand.
Install
pipx install hickok
Or from a clone: pip install -e . — or run it with no install at all:
PYTHONPATH=src python3 -m hickok.
Usage
The listener is the default command, so a bare hickok starts catching shells:
hickok # listen on :9001, drop into the console
hickok -l 9001,9002 --lhost 10.10.14.7 # multiple listeners, fixed LHOST
hickok payloads 10.10.14.7 9001 # print reverse-shell one-liners
hickok call # act on wraith's latest run (found on its own)
hickok call path/to/findings.json # ...or a specific one
hickok sql -u 'http://host/p?id=1' -p id # walk a SQL-injectable parameter
hickok hand # lay down the dead man's hand (the reveal)
hickok showdown # toggle "showdown mode" — a landed shell plays out
Inside the console:
hickok>
sessions list connected shells
payloads reverse-shell one-liners for your LHOST
cmd 1 id run a command on session 1
upgrade [1] full PTY, sized to your terminal (id optional if only one)
interact [1] attach (detach with Ctrl-])
kill [1] drop a session
A dropped shell announces itself (no silently-lost footholds), and every session
is logged to a transcript under ~/.local/share/hickok/sessions/ for your
report. upgrade spawns a PTY and matches its TERM and window size to your
terminal, so clear, vi and friends behave once you interact.
SQL injection — hickok sql
Walk a database through SQL injection — find the way in and read it out. hickok calibrates the injection, fingerprints the DBMS (SQLite / MySQL / MSSQL / PostgreSQL) and picks the fastest technique automatically:
- union — when the page reflects query output, it reads whole values (and
whole tables, via
group_concat) in one request. A full walk that takes ~1000 blind requests is a handful here. - boolean-blind — otherwise, it binary-searches each character through a TRUE/FALSE oracle (error-forcing when a false page barely changes).
- time-based — when nothing leaks (same page, no reflection), it asks through a conditional sleep and times the response. Slow, but universal.
Force one with --technique union|blind|time (default auto, fastest first).
hickok sql -u 'http://host/db?id=1' -p id # or just `hickok sql` to read it
# from wraith's latest SQLi finding
On entry it prints the DBMS and the database(s) it can see, so you have somewhere to start digging:
hickok(sql)>
banner DBMS version user / db current user / database
databases list databases tables list tables
columns <table> a table's columns dump <table> dump its rows
query "<SELECT>" extract one value help / exit this / quit
hickok(sql)> dump users
id | username | password
---+----------+-----------
1 | admin | s3cr3t!
2 | alice | wonderland
[+] 2 row(s) saved → ~/.local/share/hickok/sql/dumps/host_id_users.csv
Every dump is written to a CSV (and the path printed) so it outlives the
session. Pass -o DIR / --output DIR to drop it straight into your engagement
folder instead of the default data dir.
Filtered / WAF'd targets. String literals go in quote-free — a hex
literal on MySQL, char() / chr() elsewhere — so a target that strips single
quotes still reflects and dumps where a quoted payload would come back empty.
And when the catalog (information_schema) is blocked, hickok guesses names
instead: common table/column names plus <db>_<name> and CMS prefixes (wp_,
phpbb_, …), probed by name with no catalog in the payload.
Boolean-blind is slow by nature (each character is binary-searched over many requests) — it turns a live heartbeat with the running count as it goes, and Ctrl-C keeps what it pulled and drops back to the console.
Every value is cached per target as it's extracted, so you never pay for it
twice: re-run and anything pulled before comes back instantly (zero requests),
and a walk you interrupted resumes exactly where it stopped. --fresh ignores
the cache and re-extracts.
Evasion / OPSEC:
hickok sql -u '...' -p id \
--random-agent \ # a random real browser User-Agent
--tor \ # route via Tor, verified (see below)
--cookie 'sid=…' -H 'X-Api: …' \ # authenticated injection
--delay 0.3 -v 2 \ # throttle; print every payload
--dump users -o ./loot # non-interactive: dump to ./loot/users.csv and exit
--tor is zero-dependency, leak-aware and fail-closed: hickok speaks SOCKS5
itself (stdlib), auto-detects the Tor port (9050 / 9150), resolves the target
hostname through Tor (no DNS leak), and verifies the exit is a Tor node
before sending any attack traffic — if it can't confirm, it aborts rather than
deanonymising you. You only need Tor running (sudo systemctl start tor). Check
your setup first with hickok sql --check-tor --tor. --proxy http://host:port
and --proxy socks5://host:port work too.
The bridge — hickok call
hickok call picks up wraith's latest run on its own — wraith writes to a fixed
per-user dir (~/.local/share/wraith/runs/, or wherever WRAITH_RUNS points)
that both tools agree on, so it works from any directory. It reads the table,
lists what wraith found, and flags every finding that means code execution
(command injection, SSTI, …) — those are the doors to a shell.
hickok call # wraith's latest run, wherever you are
hickok call path/to/findings.json # ...or a specific one
[Critical] Command Injection in 'host' http://target/ping ⮕ shell
[High] SSTI in 'name' http://target/render ⮕ shell
[High] Reflected XSS in 'q' http://target/search
hickok hand lays down the dead man's hand — in the terminal the gunslinger
rises first, then the cards:
╭───────╮ ╭───────╮ ╭───────╮ ╭───────╮ ╭───────╮
│ A │ │ A │ │ 8 │ │ 8 │ │╱╲╱╲╱╲╱│
│ ♠ │ │ ♣ │ │ ♠ │ │ ♣ │ │╱╲╱╲╱╲╱│
│ A │ │ A │ │ 8 │ │ 8 │ │╱╲╱╲╱╲╱│
╰───────╯ ╰───────╯ ╰───────╯ ╰───────╯ ╰───────╯
aces and eights — the dead man's hand.
wraith deals the aces; hickok brings the eights. The hand is complete.
Showdown mode — hickok showdown
hickok showdown toggles a mode that sticks between runs. While it's on, the
moment a reverse shell lands the listener plays the catch out: the gunslinger
rises, lays down the dead man's hand, and calls it — the house folds. The reward
is for actually getting in; plain runs and a plain listener stay quiet. Run
hickok showdown again to turn it off.
Tests
pip install -e ".[dev]" && pytest
Disclaimer
Built for authorized security testing and research — point it where you're meant to. What anyone does with it from there is theirs alone; the author takes no responsibility for misuse.
License
MIT.
in memory of J.B. Hickok — shot holding aces and eights, Deadwood, 1876.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hickok-0.7.17.tar.gz.
File metadata
- Download URL: hickok-0.7.17.tar.gz
- Upload date:
- Size: 54.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
30478669d01b3686920527997d68757e3ed7217d72186adb2f9e6b31b84763e3
|
|
| MD5 |
be561ebc104d72bbbc0c967a69bc2d5f
|
|
| BLAKE2b-256 |
e6bd91cb2f05baf0f6a4f55bf4ddf22297f8343cd8f9b31f6a624905fa0ea087
|
Provenance
The following attestation bundles were made for hickok-0.7.17.tar.gz:
Publisher:
release.yml on gusta-ve/hickok
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hickok-0.7.17.tar.gz -
Subject digest:
30478669d01b3686920527997d68757e3ed7217d72186adb2f9e6b31b84763e3 - Sigstore transparency entry: 1819013306
- Sigstore integration time:
-
Permalink:
gusta-ve/hickok@80f17387030c3fe0eaac80fa893d923bcfe152e7 -
Branch / Tag:
refs/tags/v0.7.17 - Owner: https://github.com/gusta-ve
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@80f17387030c3fe0eaac80fa893d923bcfe152e7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file hickok-0.7.17-py3-none-any.whl.
File metadata
- Download URL: hickok-0.7.17-py3-none-any.whl
- Upload date:
- Size: 42.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eda2b48d0859210db318459c010cc8e5df4ee18a1cfcc36b5130ddfaa26b1995
|
|
| MD5 |
85396a7589c40f4be69da732ee67819b
|
|
| BLAKE2b-256 |
a46ae0d3bda221b1202b073fc5117f5d83d3297fbf415dbff7e988b1b88815de
|
Provenance
The following attestation bundles were made for hickok-0.7.17-py3-none-any.whl:
Publisher:
release.yml on gusta-ve/hickok
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hickok-0.7.17-py3-none-any.whl -
Subject digest:
eda2b48d0859210db318459c010cc8e5df4ee18a1cfcc36b5130ddfaa26b1995 - Sigstore transparency entry: 1819013363
- Sigstore integration time:
-
Permalink:
gusta-ve/hickok@80f17387030c3fe0eaac80fa893d923bcfe152e7 -
Branch / Tag:
refs/tags/v0.7.17 - Owner: https://github.com/gusta-ve
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@80f17387030c3fe0eaac80fa893d923bcfe152e7 -
Trigger Event:
push
-
Statement type: