Skip to content
avitwilPublic

About

Fluent, immutable Python builder around the hashcat CLI

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

13 Commits

Folders and files

Repository files navigation

Phashcat

License: MIT Python 3.9+

Phashcat is a small Python helper for the hashcat command line. You chain readable methods, and it hands you a checked argument list you can pass to subprocess. It does not ship a hashcat binary and it does not recover passwords by itself.

Contents

Authorized use only

Use hashcat only on hashes and systems you are allowed to test. Unauthorized password recovery is illegal. Follow local law, your organization's policy, and responsible disclosure.

The walkthrough below uses one public test vector on files you create yourself: the MD5 of the word password, which is 5f4dcc3b5aa765d61d8327deb882cf99. It does not use a real credential, a real host, or a downloaded wordlist.

Features

  • Fluent commands such as .hash_type(0).attack_mode(0).outfile("cracked.txt").
  • Immutable builders. Each call returns a new builder, so presets stay unchanged.
  • Composable presets. .mappend(other) merges two builders. Later values win.
  • Light checks. Values are checked against flags.VALUE_KIND before you run anything.
  • Safe to execute. .value() is a list for subprocess, not a shell string.
  • One import. from Phashcat import hashcat, flags.

How it works

hashcat(...) finds the hashcat binary and returns a HashcatBuilder.

  1. An explicit binary= argument is used if you pass one.
  2. Otherwise HASHCAT_BINARY is used when it points at a real program.
  3. Otherwise a hashcat binary placed next to the package is used, if you put one there. None is shipped.
  4. Otherwise the first hashcat on PATH is used.

Each method (.hash_type, .attack_mode, .outfile, and the rest) copies the builder and sets one flag. .value() sorts those flags and appends your hash file and wordlist or mask. .run() sends that list to subprocess.run. .cmdline() is the same list, quoted for display.

Hash mode 0 is MD5. Attack mode 0 is a straight wordlist. Those two numbers are hashcat's own -m and -a values.

Install

Clone the repository and install it locally:

git clone https://github.com/avitwil/Phashcat.git
cd Phashcat
pip install .

Optional tests:

pip install -e ".[test]"
pytest

Install hashcat itself from hashcat.net or your OS packages, then put hashcat on PATH, set HASHCAT_BINARY, or pass binary=.

The old GitHub release v0.1.1 is a wheel that vendored hashcat. Do not install it.

Usage

Create two local files. The hash file holds the well-known MD5 test vector. The wordlist holds the matching test word.

printf '%s\n' '5f4dcc3b5aa765d61d8327deb882cf99' > md5.hash
printf '%s\n' 'password' > wordlist.txt

Build a command

from Phashcat import hashcat, flags

print("Attack modes:")
for mode, name in sorted(flags.ATTACK_MODES.items()):
    print(f"  {mode}: {name}")

cmd = (
    hashcat("md5.hash", "wordlist.txt")
    .hash_type(0)     # -m 0 MD5
    .attack_mode(0)   # -a 0 straight wordlist
    .outfile("cracked.txt")
    .potfile_path("lab.pot")
    .value()
)
print()
print("argv passed to subprocess:")
print(cmd)

Expected shape (the first item is whatever hashcat resolved to on that machine):

Attack modes:
  0: Straight
  1: Combination
  3: Brute-force
  6: Hybrid Wordlist + Mask
  7: Hybrid Mask + Wordlist
  9: Association

argv passed to subprocess:
['/usr/bin/hashcat', '--attack-mode', '0', '--hash-type', '0', '--outfile', 'cracked.txt', '--potfile-path', 'lab.pot', 'md5.hash', 'wordlist.txt']

Building an MD5 wordlist command and printing attack modes

Run it

from Phashcat import hashcat

cmd = (
    hashcat("md5.hash", "wordlist.txt")
    .hash_type(0)
    .attack_mode(0)
    .outfile("cracked.txt")
    .potfile_path("lab.pot")
)
print(cmd.cmdline())
cmd.run(check=False)

Hashcat prints a device banner, then a status block. On this local file the run ends as cracked, and the only candidate is the test word:

Status...........: Cracked
Hash.Mode........: 0 (MD5)
Hash.Target......: 5f4dcc3b5aa765d61d8327deb882cf99
Recovered........: 1/1 (100.00%) Digests
Candidates.#1....: password -> password

Hashcat status after Phashcat ran the local MD5 test

Startup time and speed depend on the machine. A one-word list is only there so the demo finishes immediately.

Read the recovered line

hashcat -m 0 md5.hash --show --potfile-path lab.pot
cat cracked.txt

Both print the same line:

5f4dcc3b5aa765d61d8327deb882cf99:password

Showing the recovered test word from the potfile and outfile

You can build that --show command the same way:

from Phashcat import hashcat

print(hashcat("md5.hash").hash_type(0).potfile_path("lab.pot").show(True).cmdline())

More command shapes

These only build argument lists. They are not extra cracks. Swap in the same local md5.hash when you want to run one.

Wordlist plus a rules file:

from Phashcat import hashcat

cmd = (
    hashcat("md5.hash", "wordlist.txt")
    .hash_type(0).attack_mode(0)
    .rules_file("rules/best64.rule")
    .outfile("out_rules.txt")
    .value()
)

Mask attack (-a 3) with a custom charset. ?1 is defined by .cs1("?l?d"):

cmd = (
    hashcat("md5.hash", "?1?1?1?1")
    .hash_type(0).attack_mode(3)
    .cs1("?l?d")
    .increment(True).increment_min(4).increment_max(4)
    .outfile("out_mask.txt")
    .value()
)

Hybrid wordlist plus a two-digit mask (-a 6):

cmd = (
    hashcat("md5.hash", "wordlist.txt", "?d?d")
    .hash_type(0).attack_mode(6)
    .outfile("out_hybrid.txt")
    .value()
)

Reusable presets, merged with .mappend(...). The right-hand builder wins when both set the same flag:

preset_md5 = hashcat().hash_type(0)
preset_wordlist = hashcat().attack_mode(0).workload_profile(2)

cmd = (
    preset_md5
    .mappend(preset_wordlist)
    .outfile("cracked.txt")
    .potfile_path("lab.pot")
    .arg("md5.hash", "wordlist.txt")
    .value()
)

Flag tables live on flags (ATTACK_MODES, WORKLOAD_PROFILES, OUTFILE_FORMATS, VALUE_KIND). Longer notes are in MANUAL.md.

License

Phashcat is MIT licensed. See LICENSE.

Hashcat is not included in this repository. Install and license it separately: hashcat.net.

About

Fluent, immutable Python builder around the hashcat CLI

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages