fiddlesticks 0.2.0__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. fiddlesticks-0.4.0/.gitattributes +5 -0
  2. fiddlesticks-0.4.0/.github/workflows/lint.yml +25 -0
  3. fiddlesticks-0.4.0/.github/workflows/tests.yml +44 -0
  4. {fiddlesticks-0.2.0 → fiddlesticks-0.4.0}/.gitignore +4 -0
  5. fiddlesticks-0.4.0/.pre-commit-config.yaml +23 -0
  6. fiddlesticks-0.4.0/PKG-INFO +187 -0
  7. fiddlesticks-0.4.0/README.md +165 -0
  8. {fiddlesticks-0.2.0 → fiddlesticks-0.4.0}/pyproject.toml +47 -9
  9. fiddlesticks-0.4.0/src/fiddlesticks.py +894 -0
  10. fiddlesticks-0.4.0/tests/checker_tests.py +144 -0
  11. fiddlesticks-0.4.0/tests/data_files/Test_vault_Do_Not_Use.kdbx +0 -0
  12. fiddlesticks-0.4.0/tests/data_files/foo.7z +0 -0
  13. fiddlesticks-0.4.0/tests/data_files/test.docx +0 -0
  14. fiddlesticks-0.4.0/tests/data_files/test.xlsx +0 -0
  15. fiddlesticks-0.4.0/tests/end_to_end_tests.py +544 -0
  16. fiddlesticks-0.4.0/tests/helpers.py +271 -0
  17. fiddlesticks-0.4.0/tests/misc_tests.py +121 -0
  18. fiddlesticks-0.4.0/tests/pw_generator_tests.py +55 -0
  19. fiddlesticks-0.2.0/.gitattributes +0 -3
  20. fiddlesticks-0.2.0/.github/workflows/tests.yml +0 -38
  21. fiddlesticks-0.2.0/PKG-INFO +0 -116
  22. fiddlesticks-0.2.0/README.md +0 -96
  23. fiddlesticks-0.2.0/src/fiddlesticks.py +0 -526
  24. fiddlesticks-0.2.0/tests/Test_vault_Do_Not_Use.kdbx +0 -0
  25. fiddlesticks-0.2.0/tests/checker_tests.py +0 -29
  26. fiddlesticks-0.2.0/tests/end_to_end_tests.py +0 -252
  27. fiddlesticks-0.2.0/tests/helpers.py +0 -166
  28. fiddlesticks-0.2.0/tests/pw_generator_tests.py +0 -24
  29. fiddlesticks-0.2.0/tests/smoke_tests.py +0 -6
  30. {fiddlesticks-0.2.0 → fiddlesticks-0.4.0}/CANARY +0 -0
  31. {fiddlesticks-0.2.0 → fiddlesticks-0.4.0}/LICENSE +0 -0
  32. {fiddlesticks-0.2.0 → fiddlesticks-0.4.0}/tests/__init__.py +0 -0
@@ -0,0 +1,5 @@
1
+ * text eol=lf
2
+ *.kdbx binary
3
+ *.7z binary
4
+ *.docx binary
5
+ *.xlsx binary
@@ -0,0 +1,25 @@
1
+ name: Run pre-commit hooks
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+ workflow_dispatch:
7
+
8
+ jobs:
9
+ pre-commit:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v7
13
+
14
+ - name: Install uv and set the python version
15
+ uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
16
+ with:
17
+ version: 0.12.7
18
+ python-version: "3.14"
19
+
20
+ - name: uv Sync project with all dependency groups (for type checker)
21
+ run: uv sync --group dev
22
+
23
+ - name: Run pre-commit
24
+ run: uv run pre-commit run --all-files --show-diff-on-failure --color=always
25
+ shell: bash
@@ -0,0 +1,44 @@
1
+ name: Tests
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - name: Check out repo
14
+ uses: actions/checkout@v7
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v7
18
+ with:
19
+ python-version: "3.14"
20
+
21
+
22
+ - name: Check Git hasn't corrupted test data files
23
+ run: |
24
+ sha256sum tests/data_files/Test_vault_Do_Not_Use.kdbx
25
+
26
+ - name: Install Veracrypt from unit193's apt repo
27
+ run: |
28
+ sudo add-apt-repository ppa:unit193/encryption
29
+ sudo apt update
30
+ sudo apt install veracrypt
31
+
32
+ - name: Create venv
33
+ run: |
34
+ python3 -m venv .venv
35
+
36
+ - name: Install dependencies
37
+ run: |
38
+ . ./.venv/bin/activate
39
+ pip install -e . --group=test
40
+
41
+ - name: Run PyTest (via Coverage)
42
+ run: |
43
+ . ./.venv/bin/activate
44
+ coverage run -m pytest -rA -vv --tb=short tests && coverage combine && coverage report
@@ -11,3 +11,7 @@ wheels/
11
11
 
12
12
  # Virtual environments
13
13
  .venv
14
+
15
+ # Dev environment lock file
16
+ # (to avoid confusion with possible application lock files)
17
+ uv.lock
@@ -0,0 +1,23 @@
1
+ repos:
2
+ - repo: local
3
+ hooks:
4
+ - id: ruff-check
5
+ name: ruff check
6
+ entry: uv run ruff check
7
+ language: system
8
+ pass_filenames: false
9
+ - id: ruff-format
10
+ name: ruff format
11
+ entry: uv run ruff format
12
+ language: system
13
+ pass_filenames: false
14
+ - id: ty
15
+ name: ty
16
+ entry: uv run ty check .
17
+ language: system
18
+ pass_filenames: false
19
+
20
+ - repo: https://github.com/pre-commit/pre-commit-hooks
21
+ rev: v6.0.0
22
+ hooks:
23
+ - id: check-yaml
@@ -0,0 +1,187 @@
1
+ Metadata-Version: 2.5
2
+ Name: fiddlesticks
3
+ Version: 0.4.0
4
+ Summary: Password recovery tool for encrypted files (.7z archives .kdbx files, and Aegis archives).
5
+ Project-URL: GitHub, https://github.com/Hazardous-Area/fiddlesticks
6
+ Author-email: James Parrott <james@jamesparrott.dev>
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Requires-Python: >=3.12
10
+ Provides-Extra: aegis
11
+ Requires-Dist: py-avdu; extra == 'aegis'
12
+ Provides-Extra: keepassxc
13
+ Requires-Dist: pykeepass; extra == 'keepassxc'
14
+ Provides-Extra: msoffice
15
+ Requires-Dist: msoffcrypto-tool; extra == 'msoffice'
16
+ Provides-Extra: py7zr
17
+ Requires-Dist: py7zr; extra == 'py7zr'
18
+ Provides-Extra: ssh
19
+ Requires-Dist: bcrypt; extra == 'ssh'
20
+ Requires-Dist: cryptography>=47; extra == 'ssh'
21
+ Description-Content-Type: text/markdown
22
+
23
+ # Fiddlesticks!
24
+ *"Aaaagh! I forgot my 7zip password"* - James (more times than he cares to remember).
25
+ ![Tests passing](https://github.com/Hazardous-Area/fiddlesticks/actions/workflows/tests.yml/badge.svg)
26
+ ![Code qual](https://github.com/Hazardous-Area/fiddlesticks/actions/workflows/lint.yml/badge.svg)
27
+
28
+ Version 0.4.0
29
+
30
+ ## Description
31
+ Password recovery tool, for password-encrypted files, using simple off-line brute
32
+ force attacks. Password candidates are generated, using common variations
33
+ of a guessed password (e.g. typos and substitutions). SSH keys, Aegis archives,
34
+ and Veracrypt volumes, plus .7z, .kdbx, .xlsx, and .docx files,
35
+ are directly supported as optional dependencies. But
36
+ Fiddlesticks can also call any shell command, that accepts a candidate password,
37
+ e.g. for Veracrypt volumes (and can pipe candidates to stdout).
38
+
39
+ ### Raison d'etre
40
+ - Password-protected file owners recovering their own password themselves, as long as
41
+ they can still recall a rough guess for their password, might only need to test
42
+ every candidate password that's similar enough to the guess.
43
+ - This may be a much faster and cheaper computation
44
+ than the one an adversary must do, without such a guess, but in possession
45
+ of a stolen password protected file[^0].
46
+
47
+ ### Warning
48
+ Strictly speaking, Fiddlesticks is a password-protected file recovery tool. Use it to
49
+ get your files back. But once you've found a password that protected those files via Fiddlesticks
50
+ (or any third party tool) it should not be used again. Anywhere else it is also used, the
51
+ password should be reset (or the files re-encrypted with a different one). By default,
52
+ Fiddlesticks does not print the password it finds (or any candidates) unless `-P` is set
53
+ (or if using `--pipe` with no pipe).
54
+
55
+ ### "Back of envelope" sketch 'calculation'
56
+ - Attackers targetting a truly[^0] random password, must try up to `2**N`
57
+ candidate passwords (for each bit length `N` being considered).
58
+ - Specifically, password owners may only need to consider every candidate within some
59
+ maximum [Weighted-Levenshtein distance](https://en.wikipedia.org/wiki/Edit_distance#Types_of_edit_distance)
60
+ from their best guess of the forgotten password, lets say a total of `M`.
61
+ - Fiddlesticks is intended to assist recovering passwords from "close enough" guesses,
62
+ when `M` is much smaller than `2**N`.
63
+ - If Fiddlesticks can crack an archive's password with a starting guess of an empty string,
64
+ (if `2**N` is also small enough to be feasible, with no guess) then anyone with the
65
+ archive can also do so - the password wasn't strong enough.
66
+ - If Fiddlesticks fails to crack an archive's password given some starting guess, a lower
67
+ bound on how similar the actual password is to the starting guess can still be deduced
68
+ (e.g. this could indicate that the starting guess was wrong).
69
+
70
+ ### Design and security notes
71
+ *"FAQ: Why the heck should anyone in their right mind trust this with their password?"*
72
+ - Any similar 3rd party password cracking service based on 'best guess' passwords, requires
73
+ the user to share the guesses for their passwords with the service. Even if the password
74
+ was not used for anything else, sharing even guesses for secret credentials with 3rd parties,
75
+ is a critical security issue.
76
+ - Fiddlesticks is designed to minimise the need for this. It is designed to i) be as easy
77
+ to install as possible, and in particular ii) require as few dependencies as possible.
78
+ Firstly, the intention of i) is to assist users to run Fiddlesticks in their own secure
79
+ environment, locked down as much as they want (e.g. offline and disconnected from
80
+ all external network access), without requiring them to take their
81
+ password guesses outside of that. For example, for recovery of password encrypted .7z archives,
82
+ only a normal installation of 7zip is required on Linux (plus a close enough guess of the password!).
83
+ Fiddlesticks can even generate a file of candidate passwords, for external programs, and other
84
+ possible applications. Secondly, ii) helps users decide for themselves whether or not to trust Fiddlesticks
85
+ in the first place. In particular whether or not it will take their password guesses outside
86
+ of its running environment. When the project was concieved, the intention was also to
87
+ iii) require as little code as possible. But the code base has since become somewhat more
88
+ complex, mainly to have a nice CLI. Simplicity and brevity should both be much
89
+ more highly prized features of software in general. But you
90
+ be the judge of whether or not c) is still the case. The application code is all in a single file.
91
+
92
+ #### General security audit
93
+ If considering using any password recovery program at all, perhaps consider the following:
94
+ - does it contain code contained in string literals or obfuscated code?
95
+ - does it utilise arbitrary code execution functions (e.g. `eval`, `exec` and `compile`)?
96
+ - is all the source code visible?
97
+ - does it contain thousands of lines of code?
98
+ - does it require hundreds of third-party dependencies?
99
+ - does it contain compiled binary executables, that are not easily readable?
100
+ - is the code statically typed (so run-time features of dynamic languages are minimised)?
101
+ - is all the code tested?
102
+ - is it tested with high coverage (so all the code really is run, somewhere in the tests)?
103
+ - does it import or install any libraries that allow communication across a network, that
104
+ could be used for exfiltration purposes?
105
+ - does it require root privileges to run?
106
+ - can it be run on any operating system, and in any Docker container?
107
+
108
+ Full disclaimer: Fiddlesticks does actually contain 8 lines of Bash in a string
109
+ literal (to avoid the overhead of `subprocess.run` for every single candidate to be
110
+ tested, and to demonstrate how any command line program could read
111
+ password candidates from stdin). Otherwise we hope the answers to all the other questions
112
+ with regards to Fiddlesticks, are all reassuring.
113
+
114
+ ### Usage
115
+ ```
116
+ uvx fiddlesticks
117
+ ```
118
+
119
+ For 7z archives, it is possible to simply to automate attempts to open the file via a stock
120
+ 7zip installed in the system, e.g. from:
121
+ ```
122
+ sudo apt update && sudo apt-get install 7zip
123
+ ```
124
+
125
+ Fiddlesticks can also decrypt KeepassXC vaults and Aegis vault files (for TOTP authenticators) if
126
+ [pykeepass](https://pypi.org/project/pykeepass/) and [py-avdu](https://pypi.org/project/py-avdu/) respectively, are
127
+ also installed.
128
+
129
+ There are a couple of alternative modes too,
130
+
131
+ - firstly: automating any partial external Bash command that a candidate password can be appended to (that exits with return code 0
132
+ for the correct password, otherwise some non-zero exit code). Specify `--shell` or by default if the partial command is specified after `--`.
133
+
134
+ 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).
135
+
136
+ Thirdly, if py7zr is also installed, with `--py7zr` fiddlesticks can use it to test passwords for 7z archives,
137
+ entirely within Python.
138
+
139
+ ### Main options
140
+ #### Password guesses
141
+ If no password is specified, and if a password guess is requires for the selected command,
142
+ the user will be prompted to enter their password guesses securely (via Python's `getpass.getpass`).
143
+ For convenience passwords may also be supplied on separate lines of a text file specified
144
+ in `--input-file`, or directly on the command line, each after `--password-guess` or `-p`. If using
145
+ the latter in Bash and similar shells, please be aware the full command entered may be saved
146
+ in the Bash history. After using Fiddlesticks you should run `history -a` and
147
+ asome `history -d $(history 1 | awk '{print $1}')` command to clear this.
148
+
149
+ #### Number of substitutions
150
+ For candidate password generation strategies that use character substitutions (the only ones supported so far)
151
+ the number of substitutions required for each candidate can be capped by setting `--max-subs`
152
+
153
+ #### Output control & verbosity
154
+ If a file is specified in `--output-file` or `-o` Fiddlesticks will write a successfully found
155
+ password to it. Unless `-P` or `--print-passwords` is set, Fiddlesticks does not print any
156
+ candidate passwords by default (on successfully finding a password, the
157
+ candidate number is printed; candidate generation is deterministic).
158
+ The number of output messages (printed to stderr) can be increased by raising
159
+ the verbosity, by setting `-v` or `--verbosity`, once or twice (e.g. `-vv`).
160
+ "Two" is the maximum verbosity available.
161
+
162
+ ### Custom alternative character maps
163
+
164
+ 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
165
+ sub-mapping applicable for a specified password guess) can be printed to stderr with `--print-char-map` (and `>>`ed
166
+ to a local file, where its JSON can be customised in any text editor). This provides a simple method for
167
+ limiting the substitutions to specific characters in a password guess.
168
+
169
+ ### Other Notes
170
+ - Successful attempts to extract a password-protected archive, result in the archive being
171
+ unencrypted (naturally) by some methods. Currently all such plaintext unencrypted archives
172
+ are not deleted from the file system afterwards. If the options `--extract-to` or `-x`
173
+ are given, archives are extracted there.
174
+ - Fiddlesticks cannot recover passwords for online accounts. Online password entry attempts
175
+ should be rate limited. Cracking is only possible locally if the website owner shares the
176
+ password hash with the user, in which case they can probably provide the rest of their
177
+ account data too.
178
+ - If Fiddlesticks fails to 'crack' or find a known password, this should not be taken as
179
+ proof of the password's strength. It won't ever be possible to think everything, and
180
+ we certainly don't wish users to draw a false sense of security from Fiddlesticks.
181
+
182
+ ## Alternatives
183
+ - https://github.com/philsmd/7z2hashcat
184
+ - https://en.wikipedia.org/wiki/Dictionary_attack#Dictionary_attack_software
185
+
186
+ [^0] Truly random passwords are difficult for humans to remember (without writing them down or saving them).
187
+ At the very least, real world adversaries (posessing a stolen file or password hash) are likely to first attempt a [dictionary attack](https://en.wikipedia.org/wiki/Dictionary_attack#Dictionary_attack_software)
@@ -0,0 +1,165 @@
1
+ # Fiddlesticks!
2
+ *"Aaaagh! I forgot my 7zip password"* - James (more times than he cares to remember).
3
+ ![Tests passing](https://github.com/Hazardous-Area/fiddlesticks/actions/workflows/tests.yml/badge.svg)
4
+ ![Code qual](https://github.com/Hazardous-Area/fiddlesticks/actions/workflows/lint.yml/badge.svg)
5
+
6
+ Version 0.4.0
7
+
8
+ ## Description
9
+ Password recovery tool, for password-encrypted files, using simple off-line brute
10
+ force attacks. Password candidates are generated, using common variations
11
+ of a guessed password (e.g. typos and substitutions). SSH keys, Aegis archives,
12
+ and Veracrypt volumes, plus .7z, .kdbx, .xlsx, and .docx files,
13
+ are directly supported as optional dependencies. But
14
+ Fiddlesticks can also call any shell command, that accepts a candidate password,
15
+ e.g. for Veracrypt volumes (and can pipe candidates to stdout).
16
+
17
+ ### Raison d'etre
18
+ - Password-protected file owners recovering their own password themselves, as long as
19
+ they can still recall a rough guess for their password, might only need to test
20
+ every candidate password that's similar enough to the guess.
21
+ - This may be a much faster and cheaper computation
22
+ than the one an adversary must do, without such a guess, but in possession
23
+ of a stolen password protected file[^0].
24
+
25
+ ### Warning
26
+ Strictly speaking, Fiddlesticks is a password-protected file recovery tool. Use it to
27
+ get your files back. But once you've found a password that protected those files via Fiddlesticks
28
+ (or any third party tool) it should not be used again. Anywhere else it is also used, the
29
+ password should be reset (or the files re-encrypted with a different one). By default,
30
+ Fiddlesticks does not print the password it finds (or any candidates) unless `-P` is set
31
+ (or if using `--pipe` with no pipe).
32
+
33
+ ### "Back of envelope" sketch 'calculation'
34
+ - Attackers targetting a truly[^0] random password, must try up to `2**N`
35
+ candidate passwords (for each bit length `N` being considered).
36
+ - Specifically, password owners may only need to consider every candidate within some
37
+ maximum [Weighted-Levenshtein distance](https://en.wikipedia.org/wiki/Edit_distance#Types_of_edit_distance)
38
+ from their best guess of the forgotten password, lets say a total of `M`.
39
+ - Fiddlesticks is intended to assist recovering passwords from "close enough" guesses,
40
+ when `M` is much smaller than `2**N`.
41
+ - If Fiddlesticks can crack an archive's password with a starting guess of an empty string,
42
+ (if `2**N` is also small enough to be feasible, with no guess) then anyone with the
43
+ archive can also do so - the password wasn't strong enough.
44
+ - If Fiddlesticks fails to crack an archive's password given some starting guess, a lower
45
+ bound on how similar the actual password is to the starting guess can still be deduced
46
+ (e.g. this could indicate that the starting guess was wrong).
47
+
48
+ ### Design and security notes
49
+ *"FAQ: Why the heck should anyone in their right mind trust this with their password?"*
50
+ - Any similar 3rd party password cracking service based on 'best guess' passwords, requires
51
+ the user to share the guesses for their passwords with the service. Even if the password
52
+ was not used for anything else, sharing even guesses for secret credentials with 3rd parties,
53
+ is a critical security issue.
54
+ - Fiddlesticks is designed to minimise the need for this. It is designed to i) be as easy
55
+ to install as possible, and in particular ii) require as few dependencies as possible.
56
+ Firstly, the intention of i) is to assist users to run Fiddlesticks in their own secure
57
+ environment, locked down as much as they want (e.g. offline and disconnected from
58
+ all external network access), without requiring them to take their
59
+ password guesses outside of that. For example, for recovery of password encrypted .7z archives,
60
+ only a normal installation of 7zip is required on Linux (plus a close enough guess of the password!).
61
+ Fiddlesticks can even generate a file of candidate passwords, for external programs, and other
62
+ possible applications. Secondly, ii) helps users decide for themselves whether or not to trust Fiddlesticks
63
+ in the first place. In particular whether or not it will take their password guesses outside
64
+ of its running environment. When the project was concieved, the intention was also to
65
+ iii) require as little code as possible. But the code base has since become somewhat more
66
+ complex, mainly to have a nice CLI. Simplicity and brevity should both be much
67
+ more highly prized features of software in general. But you
68
+ be the judge of whether or not c) is still the case. The application code is all in a single file.
69
+
70
+ #### General security audit
71
+ If considering using any password recovery program at all, perhaps consider the following:
72
+ - does it contain code contained in string literals or obfuscated code?
73
+ - does it utilise arbitrary code execution functions (e.g. `eval`, `exec` and `compile`)?
74
+ - is all the source code visible?
75
+ - does it contain thousands of lines of code?
76
+ - does it require hundreds of third-party dependencies?
77
+ - does it contain compiled binary executables, that are not easily readable?
78
+ - is the code statically typed (so run-time features of dynamic languages are minimised)?
79
+ - is all the code tested?
80
+ - is it tested with high coverage (so all the code really is run, somewhere in the tests)?
81
+ - does it import or install any libraries that allow communication across a network, that
82
+ could be used for exfiltration purposes?
83
+ - does it require root privileges to run?
84
+ - can it be run on any operating system, and in any Docker container?
85
+
86
+ Full disclaimer: Fiddlesticks does actually contain 8 lines of Bash in a string
87
+ literal (to avoid the overhead of `subprocess.run` for every single candidate to be
88
+ tested, and to demonstrate how any command line program could read
89
+ password candidates from stdin). Otherwise we hope the answers to all the other questions
90
+ with regards to Fiddlesticks, are all reassuring.
91
+
92
+ ### Usage
93
+ ```
94
+ uvx fiddlesticks
95
+ ```
96
+
97
+ For 7z archives, it is possible to simply to automate attempts to open the file via a stock
98
+ 7zip installed in the system, e.g. from:
99
+ ```
100
+ sudo apt update && sudo apt-get install 7zip
101
+ ```
102
+
103
+ Fiddlesticks can also decrypt KeepassXC vaults and Aegis vault files (for TOTP authenticators) if
104
+ [pykeepass](https://pypi.org/project/pykeepass/) and [py-avdu](https://pypi.org/project/py-avdu/) respectively, are
105
+ also installed.
106
+
107
+ There are a couple of alternative modes too,
108
+
109
+ - firstly: automating any partial external Bash command that a candidate password can be appended to (that exits with return code 0
110
+ for the correct password, otherwise some non-zero exit code). Specify `--shell` or by default if the partial command is specified after `--`.
111
+
112
+ 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).
113
+
114
+ Thirdly, if py7zr is also installed, with `--py7zr` fiddlesticks can use it to test passwords for 7z archives,
115
+ entirely within Python.
116
+
117
+ ### Main options
118
+ #### Password guesses
119
+ If no password is specified, and if a password guess is requires for the selected command,
120
+ the user will be prompted to enter their password guesses securely (via Python's `getpass.getpass`).
121
+ For convenience passwords may also be supplied on separate lines of a text file specified
122
+ in `--input-file`, or directly on the command line, each after `--password-guess` or `-p`. If using
123
+ the latter in Bash and similar shells, please be aware the full command entered may be saved
124
+ in the Bash history. After using Fiddlesticks you should run `history -a` and
125
+ asome `history -d $(history 1 | awk '{print $1}')` command to clear this.
126
+
127
+ #### Number of substitutions
128
+ For candidate password generation strategies that use character substitutions (the only ones supported so far)
129
+ the number of substitutions required for each candidate can be capped by setting `--max-subs`
130
+
131
+ #### Output control & verbosity
132
+ If a file is specified in `--output-file` or `-o` Fiddlesticks will write a successfully found
133
+ password to it. Unless `-P` or `--print-passwords` is set, Fiddlesticks does not print any
134
+ candidate passwords by default (on successfully finding a password, the
135
+ candidate number is printed; candidate generation is deterministic).
136
+ The number of output messages (printed to stderr) can be increased by raising
137
+ the verbosity, by setting `-v` or `--verbosity`, once or twice (e.g. `-vv`).
138
+ "Two" is the maximum verbosity available.
139
+
140
+ ### Custom alternative character maps
141
+
142
+ 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
143
+ sub-mapping applicable for a specified password guess) can be printed to stderr with `--print-char-map` (and `>>`ed
144
+ to a local file, where its JSON can be customised in any text editor). This provides a simple method for
145
+ limiting the substitutions to specific characters in a password guess.
146
+
147
+ ### Other Notes
148
+ - Successful attempts to extract a password-protected archive, result in the archive being
149
+ unencrypted (naturally) by some methods. Currently all such plaintext unencrypted archives
150
+ are not deleted from the file system afterwards. If the options `--extract-to` or `-x`
151
+ are given, archives are extracted there.
152
+ - Fiddlesticks cannot recover passwords for online accounts. Online password entry attempts
153
+ should be rate limited. Cracking is only possible locally if the website owner shares the
154
+ password hash with the user, in which case they can probably provide the rest of their
155
+ account data too.
156
+ - If Fiddlesticks fails to 'crack' or find a known password, this should not be taken as
157
+ proof of the password's strength. It won't ever be possible to think everything, and
158
+ we certainly don't wish users to draw a false sense of security from Fiddlesticks.
159
+
160
+ ## Alternatives
161
+ - https://github.com/philsmd/7z2hashcat
162
+ - https://en.wikipedia.org/wiki/Dictionary_attack#Dictionary_attack_software
163
+
164
+ [^0] Truly random passwords are difficult for humans to remember (without writing them down or saving them).
165
+ At the very least, real world adversaries (posessing a stolen file or password hash) are likely to first attempt a [dictionary attack](https://en.wikipedia.org/wiki/Dictionary_attack#Dictionary_attack_software)
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "fiddlesticks"
7
- description = "Password recovery tool for encrypted archives (currently only .7z files supported)."
7
+ description = "Password recovery tool for encrypted files (.7z archives .kdbx files, and Aegis archives)."
8
8
  readme = "README.md"
9
9
  license = "MIT"
10
10
  license-files = ["LICENSE"]
@@ -13,14 +13,8 @@ authors = [
13
13
  ]
14
14
  requires-python = ">=3.12"
15
15
  dynamic=["version"]
16
- dependencies = []
17
-
18
- [project.optional-dependencies]
19
- py7zr = ["py7zr"]
20
- aegis = ["py-avdu"]
21
- keepassxc = ["pykeepass"]
22
- tests = ["pytest", "hypothesis"]
23
16
 
17
+ dependencies = []
24
18
 
25
19
  [project.urls]
26
20
  GitHub = "https://github.com/Hazardous-Area/fiddlesticks"
@@ -28,6 +22,44 @@ GitHub = "https://github.com/Hazardous-Area/fiddlesticks"
28
22
  [project.scripts]
29
23
  fiddlesticks = "fiddlesticks:cli"
30
24
 
25
+ [project.optional-dependencies]
26
+ ssh = [
27
+ "cryptography>=47", # For "incorrect PW" error message from Rust code
28
+ "bcrypt",
29
+ ]
30
+ keepassxc = [
31
+ "pykeepass",
32
+ ]
33
+ aegis = [
34
+ "py-avdu",
35
+ ]
36
+ py7zr = [
37
+ "py7zr",
38
+ ]
39
+ msoffice = [
40
+ "msoffcrypto-tool",
41
+ ]
42
+
43
+ [dependency-groups]
44
+ dev = [
45
+ {include-group = "lint"},
46
+ {include-group = "test"},
47
+ ]
48
+ test = [
49
+ "fiddlesticks[ssh,keepassxc,aegis,py7zr,msoffice]",
50
+ "pytest",
51
+ "hypothesis",
52
+ "coverage>=7.13",
53
+ "covdefaults",
54
+ ]
55
+ lint = [
56
+ "ruff",
57
+ "ty",
58
+ "pre-commit",
59
+ ]
60
+
61
+
62
+
31
63
  [tool.hatch.build.targets.wheel]
32
64
  only-include = ["src"]
33
65
  sources = {"src" = ""} # move from "src" directory for wheel
@@ -35,7 +67,6 @@ sources = {"src" = ""} # move from "src" directory for wheel
35
67
  [tool.hatch.version]
36
68
  path = "src/fiddlesticks.py"
37
69
 
38
-
39
70
  [tool.pytest.ini_options]
40
71
  markers = [
41
72
  "slow: marks other tests that cause bottlenecks",
@@ -43,3 +74,10 @@ markers = [
43
74
  ]
44
75
  python_files = "test_*.py *_test.py *_tests.py"
45
76
 
77
+ [tool.coverage.run]
78
+ source = ["src"]
79
+ omit = ["tests/*"]
80
+ patch = ["subprocess"]
81
+ plugins = [
82
+ "covdefaults",
83
+ ]