Skip to main content

Fiddlesticks!

"Aaaagh! I forgot my 7zip password" - James (more times than he cares to remember).

Tests passing Code qual

Version 0.6.1

Description

Password recovery tool, for password-encrypted files, using simple off-line brute force attacks. Password candidates are generated, using common variations of a guessed password (e.g. typos and substitutions). SSH keys, Veracrypt volumes, /etc/shadow lines(*), and Aegis archives, plus .7z, .kdbx, .xlsx and .docx files and are directly supported as optional dependencies. But Fiddlesticks can also call any shell command, that accepts a candidate password, e.g. for Veracrypt volumes (and can pipe candidates to stdout).

(*) If root or sudo is available to read /etc/shadow in the first place, note: if the goal is only to access another user's account, their password can simply be changed, also with sudo.

Raison d'etre

  • Password-protected file owners recovering their own password themselves, as long as they can still recall a rough guess for their password, might only need to test every candidate password that's similar enough to their best guess.
  • This may be a much faster and cheaper computation than the one an adversary must do, without such a guess.

Warning

Strictly speaking, Fiddlesticks is a password-protected file recovery tool. Use it to get your files back. But once you've found a password that protected those files via Fiddlesticks (or any third party tool) it should not be used again. Anywhere else it is also used, the password should be reset (or the files re-encrypted with a different one). By default, Fiddlesticks does not print the password it finds (or any candidates) unless -P is set (or if using --pipe with no pipe).

"Back of envelope" sketch 'calculation'

  • Attackers targetting a truly random password[^0], must try up to 2**N candidate passwords (for each bit length N being considered).
  • Specifically, password owners may only need to consider every candidate within some maximum Weighted-Levenshtein distance from their best guess of the forgotten password, lets say a total of M.
  • Fiddlesticks is intended to assist recovering passwords from "close enough" guesses, when M is much smaller than 2**N.
  • If Fiddlesticks can crack an archive's password with a starting guess of an empty string, (if 2**N is also small enough to be feasible, with no guess) then anyone with the archive can also do so - the password wasn't strong enough.
  • If Fiddlesticks fails to crack an archive's password given some starting guess, a lower bound on how similar the actual password is to the starting guess can still be deduced (e.g. this could indicate that the starting guess was wrong).

Design and security notes

"FAQ: Why the heck would anyone in their right mind trust Fiddlesticks with their password?!"

  • Any similar 3rd party password cracking service based on 'best guess' passwords, requires the user to share the guesses for their passwords with the service. Even if the password was not used for anything else, sharing even guesses for secret credentials with 3rd parties, is a critical security issue.
  • Fiddlesticks is designed to minimise the need for this. It is designed to i) be as easy to install as possible, and in particular ii) require as few dependencies as possible.
    Firstly, the intention of i) is to assist users to run Fiddlesticks in their own secure environment, locked down as much as they want (e.g. offline and disconnected from all external network access), without requiring them to take their password guesses outside of that. For example, for recovery of password encrypted .7z archives, only a normal installation of 7zip is required on Linux (plus a close enough guess of the password!). Fiddlesticks can even generate a file of candidate passwords, for external programs, and other possible applications. Secondly, ii) helps users decide for themselves whether or not to trust Fiddlesticks in the first place. In particular whether or not it will take their password guesses outside of its running environment. When the project was concieved, the intention was also to iii) require as little code as possible. But the code base has since become somewhat more complex, mainly to have a nice CLI. Simplicity and brevity should both be much more highly prized features of software in general. But you be the judge of whether or not c) is still the case. The application code is all in a single file.

General security audit

If considering using any password recovery program at all, perhaps consider the following:

  • does it contain code contained in string literals or obfuscated code?
  • does it utilise arbitrary code execution functions (e.g. eval, exec and compile)?
  • is all the source code visible?
  • does it contain thousands of lines of code?
  • does it require hundreds of third-party dependencies?
  • does it contain compiled binary executables, that are not easily readable?
  • is the code statically typed (so run-time features of dynamic languages are minimised)?
  • is all the code tested?
  • is it tested with high coverage (so all the code really is run, somewhere in the tests)?
  • does it import or install any libraries that allow communication across a network, that could be used for exfiltration purposes?
  • does it require root privileges to run?
  • can it be run on any operating system, and in any Docker container?

Full disclaimer: Fiddlesticks does actually contain 8 lines of Bash in a string literal (to avoid the overhead of subprocess.run for every single candidate to be tested, and to demonstrate how any command line program could read password candidates from stdin). Otherwise we hope the answers to all the other questions with regards to Fiddlesticks, are reassuring.

Usage

uvx fiddlesticks

For 7z archives, it is possible to simply to automate attempts to open the file via a stock 7zip installed in the system, e.g. from:

sudo apt update && sudo apt-get install 7zip

Fiddlesticks can also decrypt KeepassXC vaults and Aegis vault files (for TOTP authenticators) if pykeepass and py-avdu respectively, are also installed.

There are a couple of alternative modes too,

  • firstly: automating any partial external Bash command that a candidate password can be appended to (that exits with return code 0 for the correct password, otherwise some non-zero exit code). Specify --shell or by default if the partial command is specified after --.

Secondly with --pipe candidate passwords can be sent to stdout, from where they can be piped to stdin of a user's own external program or code (all the normal output from fiddlesticks goes to stderr).

Thirdly, if py7zr is also installed, with --py7zr fiddlesticks can use it to test passwords for 7z archives, entirely within Python.

Main options

Password guesses

If no password is specified, and if a password guess is requires for the selected command, the user will be prompted to enter their password guesses securely (via Python's getpass.getpass).
For convenience passwords may also be supplied on separate lines of a text file specified in --input-file, or directly on the command line, each after --password-guess or -p. If using the latter in Bash and similar shells, please be aware the full command entered may be saved in the Bash history. After using Fiddlesticks you should run history -a and asome history -d $(history 1 | awk '{print $1}') command to clear this.

Number of substitutions

For candidate password generation strategies that use character substitutions (the only ones supported so far) the number of substitutions required for each candidate can be capped by setting --max-subs

Output control & verbosity

If a file is specified in --output-file or -o Fiddlesticks will write a successfully found password to it. Unless -P or --print-passwords is set, Fiddlesticks does not print any candidate passwords by default (on successfully finding a password, the candidate index is printed; candidate generation is deterministic). The number of output messages (printed to stderr) can be increased by raising the verbosity, by setting -v or --verbosity, once or twice (e.g. -vv). "Two" is the maximum verbosity available.

Custom alternative character maps

Any custom JSON file supplied to --char-map containing a mapping of characters to alternatives can be used (instead of the default L33t substitutions and capitalisations ascii-based map). To assist creating this, the default map (or the relevant sub-mapping applicable for a specified password guess) can be printed to stderr with --print-char-map (and >>ed to a local file, where its JSON can be customised in any text editor). This provides a simple method for limiting the substitutions to specific characters in a password guess.

Other Notes

  • Successful attempts to extract a password-protected archive, result in the archive being unencrypted (naturally) by some methods. Currently all such plaintext unencrypted archives are not deleted from the file system afterwards. If the options --extract-to or -x are given, archives are extracted there.
  • Fiddlesticks cannot recover passwords for online accounts. Online password entry attempts should be rate limited. Cracking is only possible locally if the website owner shares the password hash with the user, in which case they can probably provide the rest of their account data too.
  • If Fiddlesticks fails to 'crack' or find a known password, this should not be taken as proof of the password's strength. It won't ever be possible to think everything, and we certainly don't wish users to draw a false sense of security from Fiddlesticks.

Alternatives

[^0] Truly random passwords are difficult for humans to remember (without writing them down or saving them). At the very least, real world adversaries (posessing a stolen file or password hash) are likely to first attempt a dictionary attack

Benchmarks

Num subs Num pwds .docx/s per pwd/cpu ms .kdbx/s per pwd/cpu ms .json/s per pwd/cpu ms .7z /s per pwd/cpu ms .key /s per pwd/cpu ms .hc /s per pwd/cpu ms
0 1 10 40339.412689208984 20 80084.81884002686 10 40073.225021362305 20 80056.3097000122 20 80056.48422241211 10 40072.23320007324
1 42 20 1908.452306474958 20 1908.4490140279133 20 1908.4565525963194 20 1908.7251481555757 20 1907.8663417271205 20 1908.5558709644135
2 842 20 96.46233583572642 10 48.93052153236226 20 96.45510852478462 20 96.49051226799392 20 96.44632951097647 20 96.43983048101502
3 10724 23 8.813216943253513 23 8.81822400020157 23 8.808564268266563 13 5.058712231850544 13 5.071774742043939 23 8.794312955549696
4 97431 52 2.1614515430617898 52 2.1749609552847717 43 1.7742308170991132 53 2.1980988163370605 53 2.21338118517836 53 2.2093424457554316
5 672118 242 1.4430960060459646 257 1.5301919328892881 263 1.567255141390218 244 1.4564930530505062 269 1.6068344686839404 256 1.5272892323243892
6 3658692 1361 1.4885278247339404 931 1.0179169681424118 1342 1.468057746344242 930 1.0174063220909733 1359 1.4865520419278282 1351 1.4778001960510592

more in ./dev/Benchmarks.md

Metadata

Release files for fiddlesticks 0.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fiddlesticks 0.7.0
File Size Uploaded Provenance Actions
fiddlesticks-0.7.0.tar.gz 65.1 kB Without provenance Details for fiddlesticks-0.7.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for fiddlesticks 0.7.0
File Interpreter ABI Platform Actions
fiddlesticks-0.7.0-py3-none-any.whl Python 3 none any Details for fiddlesticks-0.7.0-py3-none-any.whl

Total release size: 85.5 kB

Release files / fiddlesticks-0.7.0.tar.gz

Download URL fiddlesticks-0.7.0.tar.gz
Size 65.1 kB
Tags Source
SHA-256 checksum
How to use checksums
233d31ff697602072a9e95c5350f1c2cdb68fcfab963d734c4f4af0492b91671
BLAKE2b-256 checksum
How to use checksums
c29800af44e7d73b1e2110de1098495cfa3e206b8b545f0c7e7d68bbbfc377e1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / fiddlesticks-0.7.0-py3-none-any.whl

Download URL fiddlesticks-0.7.0-py3-none-any.whl
Size 20.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
26ce7a985a61995e8c236e7e6c05d56a7c9d6bce316547a5a8532aa80c0bfe30
BLAKE2b-256 checksum
How to use checksums
3627f8850915e35d635e2f19a653a7f7759e78b95323f5f70428fe74e09407c3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for fiddlesticks 0.7.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page