Skip to main content

Terminal client for selected Hack The Box Labs API workflows.

Project description

htb-terminal

CI Python 3.10+ License: MIT

Python terminal client for selected HTB Labs v4 API workflows: machines, VPN, OVPN files, and raw API calls. Zero external dependencies.

See the command reference for every command, option, default, and the API endpoint each command calls.

Sources

Note: HTB officially documents the Enterprise API. The Labs v4 endpoints used here come from the Postman collection and community references; they may change without notice.

Screenshots

Compact active-machine output keeps the session details and profile-only status text readable without dumping the full HTB profile.

Active machine output

Tables use compact columns, terminal colors, and truncation by default. Use --wide when you need full values.

VPN server table output

Installation

Requires Python 3.10+. This project has no external dependencies.

Install as a global command with pipx (recommended) so htb is available from any directory:

pipx install htbx
htb --help

Or with pip:

pip install htbx
htb --help

The package is published on PyPI as htbx; it installs the htb command (an htbx alias is installed too). To run the latest from source without installing, use a clone:

chmod +x ./htb
./htb --help

Authentication

Generate an App Token from your HTB profile settings, then save it once with init:

htb init
# Paste your HTB App Token (input hidden): ...

htb init --check   # also verify the token and print who you are

init stores the token in your user config directory (~/.config/htb-terminal/token, or $XDG_CONFIG_HOME/htb-terminal/token) with owner-only permissions, so a pipx-installed htb finds it from anywhere. You can also pass it non-interactively:

htb init --token "$MY_TOKEN"
echo "$MY_TOKEN" | htb init

The token is resolved in this order, first match wins:

  1. HTB_API_TOKEN environment variable.
  2. --token-file PATH, when given.
  3. ./api.token in the current directory (handy as a per-project override).
  4. The user config file written by htb init.

api.token is gitignored; never commit your token.

Examples

Full details for each command are in the command reference.

./htb machine active
./htb machine profile "BoardLight"
./htb machine list
./htb machine list --retired --page 1
./htb machine list --sp-tier 1
./htb machine search board
./htb machine search kerberos --all --limit 10
./htb machine search "breach creds" --all --profiles

./htb machine start "BoardLight" --mode auto
./htb machine start 444 --mode play
./htb machine start 478 --mode spawn
./htb machine stop
./htb machine reset
./htb machine extend
./htb machine submit 444 HTB{flag} --difficulty 50
./htb machine active --oneline

./htb user info

./htb vpn servers
./htb vpn switch us-free-1
./htb vpn download us-free-1 -o lab-vpn.ovpn
./htb vpn connect us-free-1 -o lab-vpn.ovpn

# Speedrun a seasonal release: connect VPN, set MTU 1300, spawn, wait for IP.
sudo htb speedrun Seasonal us-free-1

./htb raw GET /machine/active
./htb raw POST /vm/spawn --data '{"machine_id":478}'

Output

By default, commands print human-readable output with terminal-width wrapping and automatic color when stdout is an interactive terminal.

Use raw JSON for scripts:

./htb --json machine active

Color can be controlled globally:

./htb --color never machine active
./htb --color always machine list

Tables are compact by default and truncate long cells to fit common terminal widths. Use --wide to keep full table values:

./htb --wide machine list
./htb --wide machine search active-directory --all

machine active enriches the active session response with the matching machine profile when a machine is active, but prints a compact summary by default. The summary includes useful profile-only text such as info_status and description when HTB returns it. Use --details for synopsis and Academy module names, or --json before the command for the full enriched response:

./htb machine active --details
./htb --json machine active

Machine search

machine search intentionally uses the documented/listed Labs v4 machine list endpoints and filters the results locally. It does not depend on an undocumented search endpoint.

By default it scans playable machines:

./htb machine search linux

Useful options:

  • --retired: search retired machines only.
  • --all: search playable and retired machines.
  • --profiles: also fetch each scanned machine profile and search profile-only fields such as descriptions.
  • --limit N: stop after printing up to N matches.
  • --max-pages N: cap the number of API pages scanned per list.

Without --profiles, the query matches machine id, name, OS, difficulty, tags, maker names, and common list fields. Use --profiles for terms that may only exist in the detailed machine profile, for example description text mentioning breached credentials.

Speedrun a season release

When a seasonal machine drops (Saturdays 19:00 UTC), the slow part is the manual dance of connecting the VPN, fixing the tunnel MTU, and spamming spawn until a slot frees up. speedrun does all of it in one command and shows a live, emoji-free status for each step:

sudo htb speedrun Seasonal us-free-1
speedrun: Seasonal via us-free-1
  resolve machine 'Seasonal' ... ok
  switch vpn server us-free-1 ... ok
  download ovpn config ... ok
  start openvpn ... ok
  wait for tun0 ... ok (3s)
  set tun0 mtu 1300 ... ok
  spawn machine ... ok (42s)
  wait for machine ip ... ok (18s)
ready: Seasonal 10.10.11.50

It needs root (for OpenVPN and the MTU change), so run it with sudo. The VPN runs in the foreground; press Ctrl-C to disconnect. Tunables: --mtu, --interface, --retry-for, --interval, --mode, and --variant.

Shell completion

Enable tab-completion for commands, subcommands, and options. The same script works for both the htb and htbx commands.

# bash — add to ~/.bashrc:
eval "$(htb completion bash)"

# zsh — add to ~/.zshrc (before compinit, or save to a file on your $fpath):
eval "$(htb completion zsh)"

Architecture

  • htb_terminal/cli.py: thin entry point — dispatch and error rendering.
  • htb_terminal/parser.py: argparse definitions, one builder per command group.
  • htb_terminal/handlers.py: command handlers (args + client -> result).
  • htb_terminal/config.py: loads/saves the token and API URL.
  • htb_terminal/http.py: authenticated HTTP client.
  • htb_terminal/output.py: human-readable and JSON rendering.
  • htb_terminal/ui.py: StepRunner live step status for workflows.
  • htb_terminal/netcfg.py: host network/process ops (OpenVPN, interface, MTU).
  • htb_terminal/timefmt.py: relative time formatting for display.
  • htb_terminal/completion.py: bash/zsh completion scripts from one command map.
  • htb_terminal/services/machines.py: MachineService — machine API operations.
  • htb_terminal/services/user.py: UserService — current-user profile.
  • htb_terminal/services/speedrun.py: SpeedrunService — season-release flow.
  • htb_terminal/services/payloads.py: pure helpers that reshape machine-list JSON.
  • htb_terminal/services/search.py: local machine search and result ranking.
  • htb_terminal/services/spawn.py: transient spawn-failure detection.
  • htb_terminal/services/vpn.py: VPN and OVPN operations.

Each module keeps a single responsibility to make future changes easier if HTB changes an endpoint. MachineService only talks to the API; payload reshaping, search ranking, and spawn-error detection are stateless modules it composes, so they are testable in isolation and stay small.

Development

Install the dev tools and run the test suite:

pip install -e ".[dev]"
pytest
ruff check .

The tests are also runnable with the standard library alone:

python3 -m unittest discover -s tests -v

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

htbx-0.2.0.tar.gz (38.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

htbx-0.2.0-py3-none-any.whl (32.2 kB view details)

Uploaded Python 3

File details

Details for the file htbx-0.2.0.tar.gz.

File metadata

  • Download URL: htbx-0.2.0.tar.gz
  • Upload date:
  • Size: 38.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for htbx-0.2.0.tar.gz
Algorithm Hash digest
SHA256 58f9b0060424c0ed124029f2fc38528a134304161f4a98c8e1b2d182ea8cfb6d
MD5 e156b5eef5431605b26d8e61b9de5395
BLAKE2b-256 2aeb093f88aad416959ac76dff7cbebb7e6b69e06e4451dd5fdb7e5e2913dcb5

See more details on using hashes here.

Provenance

The following attestation bundles were made for htbx-0.2.0.tar.gz:

Publisher: release.yml on Okymi-X/htb-terminal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file htbx-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: htbx-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 32.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for htbx-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 47811867f8fee546ad2d896fb7d2661c6601cc051c203c42f2591711b4c844f7
MD5 97a1782a4f338e712d47f67d212f9f1f
BLAKE2b-256 2b1da42c5f975afc2427e91020d48d306ae54e212de5bfec378ef23e6d91e82c

See more details on using hashes here.

Provenance

The following attestation bundles were made for htbx-0.2.0-py3-none-any.whl:

Publisher: release.yml on Okymi-X/htb-terminal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page