Applies to master. Hash-mode 17240 arrived after 8.0.0. It reads a ZIP archive itself, where the older PKZIP modes take a hash somebody extracted from one:
$ hashcat -m 17240 -a 0 archive.zip passwords.txt $ hashcat -m 17240 -a 3 archive.zip ?d?d?d?d?d?d
The point of it is size. The native modes 17200 to 17230 hold the encrypted data in fixed device buffers, so a member larger than those buffers cannot be attacked with them at all. 17240 reads from the file as it goes and its memory use does not depend on the member's size.
It covers traditional ZipCrypto with stored members (method 0) and DEFLATE members (method 8), in single-volume ZIP and ZIP64 archives, data descriptors included. AES and the other strong encryption schemes are not supported, and no streaming makes them supportable: those are different ciphers, not a different container.
An archive usually holds several files, and hashcat picks one. By default it takes the smallest supported encrypted member that carries enough data to verify a candidate against, which means at least 4 bytes for a stored member and any content at all for a DEFLATE one.
To choose for yourself, count entries in the central directory from zero and name the index:
$ hashcat -m 17240 --pkzip-member-index 2 -a 0 archive.zip passwords.txt
The count includes directories and members hashcat cannot use, so the index is a position in the archive rather than a position among the attackable files. Naming an empty member, a stored member that is too short, or an unsupported one is an error rather than a silent fall back to another.
--hook-threads is worth setting. The GPU derives the ZipCrypto keys, checks the encryption header and throws out candidates whose DEFLATE header cannot be right. What survives goes to a host hook that decrypts in 32 KiB chunks, inflates where needed, and checks the full length and CRC32. Each worker keeps its own file handles and buffers per device, and on a stored member the GPU filter is weaker, so a run can end up bound by the CPU or by the disk rather than by the card.
ZipCrypto is weak enough that more than one candidate can pass every check. Give --keep-guessing if you want hashcat to carry on after the first match rather than treating it as the answer.
As with the other container modes, the potfile, --show and outfile checking are switched off, and --remove is refused outright because rewriting the hash list would mean rewriting your ZIP file. Use --outfile to keep what you recover.
In that output the hash field is the archive path, so a line can be fed back in as input with the same member selection. An inline hash keeps its inline form.
There is a $pkzip-stream$ line as well, which exists for the self-tests and for small oracle vectors rather than for ordinary use:
$pkzip-stream$*METHOD*0*PACKED*UNPACKED*CRC*CHECK*SAMPLE*-
The numeric fields are hexadecimal, CRC has eight digits and CHECK two. SAMPLE is the whole encrypted member including its 12 byte encryption header, and it is capped at 256 bytes, which is why this form is no substitute for pointing hashcat at the file. The experimental earlier format that referenced an external path is rejected, and the path in it is not opened.