Skip to content

pdf2john: fix missing /Length for V4 PDFs using crypt filters - #6043

Open
kholia wants to merge 2 commits into
openwall:bleeding-jumbofrom
kholia:fix-pdf2john-v4-length
Open

kholia wants to merge 2 commits into
openwall:bleeding-jumbofrom
kholia:fix-pdf2john-v4-length

Conversation

@kholia

@kholia kholia commented Sep 30, 2026

Copy link
Copy Markdown
Member

PDF 1.4+ (V4) allows the encryption dictionary to omit the top-level /Length entry when the key length is specified only inside the applicable crypt filter (CF → StmF filter → /Length). The PDF spec (§3.5) states that the top-level /Length is optional for V2 and V3; in practice some generators (e.g. PDFsharp 6.2.0 / Aspose) also omit it for V4 and rely only on the CF /Length.

Both extractors incorrectly defaulted to 40 bits in that case, causing JtR to treat the document as 40-bit RC4 and fail to crack even when the true algorithm is AES-128.

Fix: when /Length is absent at the top level and V==4, read the key length from the crypt filter identified by /StmF (defaulting to /StdCF). The CF /Length is in bytes; multiply by 8 to get bits.

pdf2john.py: derived via encrypt_dict → /CF → /StmF filter → /Length*8. PDF.pm (pdf2john.pl): fill in $$encrypt{Length} at the point where the CF is already validated, so all downstream uses (hash printf and RC4 key derivation) automatically pick up the correct value.

Fixes #6033

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Crypt-filter selection remains incorrect for omitted or non-StdCF stream filters.

Review effort: Balanced
Findings: 2 Medium severity

Open (2)
What changed in this PR

Adds crypt-filter key-length fallback for V4 PDFs missing top-level /Length.

Changes:

  • Derives bit length from crypt-filter /Length.
  • Applies fallback in Python and Perl extractors.
File Description
run/​pdf2john.py Adds crypt-filter length resolution.
run/​lib/​PDF.pm Propagates StdCF length into hash generation.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread run/lib/PDF.pm Outdated
Comment thread run/pdf2john.py Outdated
kholia pushed a commit to kholia/john that referenced this pull request Sep 30, 2026
Address Copilot review comments on PR openwall#6043:

- The PDF spec says /StmF and /StrF default to /Identity (no encryption),
  not /StdCF.  The previous code assumed /StdCF when /StmF was absent,
  which could read an unrelated filter entry and emit a wrong key length.

- The Perl path hard-coded 'StdCF' instead of resolving the actual filter
  name from $$encrypt{StmF}, making the two extractors inconsistent.

Both pdf2john.py and PDF.pm now iterate over StmF then StrF, skip any
/Identity entry, and use the first filter that carries a /Length value.
The CF /Length (bytes) → bits multiplication is unchanged.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@kholia
kholia force-pushed the fix-pdf2john-v4-length branch from b6eafef to e97a3f7 Compare September 30, 2026 06:56

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The Perl extractor still emits 40-bit hashes when an AES crypt filter omits its optional length.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
Resolved since last review (2)

Comment thread run/lib/PDF.pm Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pdf2john.py incorrectly defaults to 40-bit key length in V4/R4 PDF

2 participants