trustedsec / trustedsec/hate_crack
A password consisting only of line breaks derives to an empty baseword, writing a blank line into basewords.txt
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.9k
- Forks
- 284
- Avg merge
- 21m
- Merged PRs (30d)
- 14
Description
What happens
A cracked password that is only line-break bytes — which arrives hex-wrapped, e.g. $HEX[0a] — derives to an empty baseword. generate() then writes "" + "\n" into basewords.txt, i.e. a blank line.
Reproduction with a two-line corpus:
$HEX[0a]
quibbleflange1
basewords.txt comes out as b'\nquibbleflange\n' — the first line is empty. derive("\n") returns ("", "i0\\x0a"), which is a correct pair in isolation: the rule really does rebuild the password from an empty word, and the reconstruction self-check passes honestly. unwritable_basewords stays 0, because the baseword holds no break — it holds nothing at all.
Why it is worth fixing
This is the same shape as #295 — a line-based output file gaining a line that does not mean what the writer intended — one case further along. It is milder: a blank wordlist line is an empty candidate rather than a corrupted rule, so it does not silently destroy a neighbouring record the way c$1$2$ did. But:
- The suite already treats a blank line in these files as a defect. Several tests assert
b"" not in raw.split(b"\n")[:-1]againstbasewords.txtandrules.full.rule(e.g.tests/test_rulegen.py, the embedded-line-break and tail-break classes). A corpus containing$HEX[0a]would trip that guard — the invariant is asserted but not enforced. - Whether the password is actually covered depends on hashcat's handling of an empty wordlist line, which is unverified here. If hashcat skips it, the password is silently uncovered while the coverage figures count it as derived.
Not introduced by the recent work
Present on main and unchanged by #295's fix or by PR #303 — _literal_with_line_breaks behaves identically in all three. Found while reviewing #303 and deliberately left out of scope there, since it is a distinct defect (an empty baseword, not an unwritable one) and would have widened that change.
Suggested direction
Either skip-and-count such a password alongside the existing unwritable_basewords statistic, or give it a non-empty baseword and let the rule build the password from it. Whichever way, the first step is asking hashcat what it does with a blank wordlist line, so the choice rests on measured behaviour rather than assumption — tests/test_rule_oracle.py is the existing harness for that kind of question.
Environment
- hashcat
v7.1.2-484-g64e1bff93 - macOS (Darwin 25.6.0), hash mode
1000 - hate_crack
nightly-devatf8fbecd
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with tests/test_rule_oracle.py and ask hashcat how it handles a blank wordlist line for the reproduced $HEX[0a] case. Then trace _literal_with_line_breaks and the generation path that writes basewords.txt, using tests/test_rulegen.py and its embedded-line-break and tail-break cases as regression references. Done means the chosen behavior is measured, tracked consistently, and no unintended blank baseword remains.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cli, security, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100