forked from hashcat/hashcat
-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathchanges.txt
More file actions
3127 lines (2758 loc) · 212 KB
/
Copy pathchanges.txt
File metadata and controls
3127 lines (2758 loc) · 212 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
* changes v7.1.2 -> v7.1.x
##
## Backward Incompatible Changes
##
1. Plugins: the core is now a shared library and every plugin links against it
A module, a bridge and a feed no longer carry their own copy of the core, so a third party plugin has
to be rebuilt for this release and needs libhashcat present one directory above it. The library ships
beside the hashcat binary as libhashcat.so.7 on Linux, libhashcat.7.dylib on macOS and hashcat.dll on
Windows. A plugin built against an older interface is refused, and hashcat names both versions.
2. Plugins: what the core offers is now declared rather than inferred
Each function says for itself whether a plugin may call it, instead of the set being taken from what
the plugins in this tree happen to use. A module can therefore call a host side hash or cipher entry
point that no module here calls. See "The Core Library" in docs/hashcat-plugin-development-guide.md.
3. Build: SHARED now defaults to 1
A build that wants the old arrangement, where every plugin holds its own copy of the core, asks for
SHARED=0. A package built the new way has to ship the library alongside the binary.
4. Plugins: module_dictstat_disable was removed from the module interface
A module that still sets it will not compile and reports that module_ctx_t has no such member, so
delete the line. Nothing replaces it. It existed because a hash mode could produce a different number
of candidates than the wordlist had lines, and a wordlist keyspace is now always its line count.
5. Distribution: --skip and --limit now apply to the whole run
Multiple wordlists in -a 0, and --increment or mask files in -a 3/6/7, used to be separate attacks
with their own keyspace numbering, and hashcat refused --skip and --limit for all three. A scheduler
therefore had to split every wordlist, every mask and every increment length into a task of its own
and add the pieces up itself. They now form one virtual keyspace, so --skip 1000 skips the first
thousand units of the whole run rather than the first thousand of every file or mask, and hashcat
seeks to the right wordlist or mask itself. A run over eighteen wordlists is one range to divide up,
and so is "-i ?d?d?d?d".
Two queues are still refused, and both for the same reason: --loopback and --induction-dir write the
wordlist the next round reads, so how long the queue will be is not known when the window would have
to be divided up.
6. Distribution: --keyspace answers for the whole run as well
--keyspace used to be refused for every one of these. The error named --increment and mask files, and
the same check also caught a directory of wordlists and several wordlists on the command line. It now
returns one number covering every wordlist, every mask in a mask file and every length in an increment
range, and that number is the one --skip and --limit address. "-a 3 -i --increment-min 1
--increment-max 4 ?d?d?d?d" answers 1111, which is 1 + 10 + 100 + 1000.
Both options stay in --keyspace units, which are base words and not final candidates, and that part is
unchanged. Amplification still happens afterwards, from rules in -a 0 and from the remaining mask
positions in -a 3. "?l?l?l" is 676 base words and 17576 candidates, so --skip 300 leaves 376 base
words, which expand to 9776 candidates.
7. Status: the progress counters are now relative to --skip
Progress in the status screen, "progress" in --status-json and PROGRESS in --machine-readable now
count the work this run was asked for, and the total beside them is the size of that work. A run given
"--skip 1000000 --limit 20000000" starts at 0 and ends at 20000000 units, where it used to start at
1000000 and end at 21000000. The percentage therefore runs from 0 to 100 over the requested range. It
used to be the position in the whole keyspace, so a chunk taken from the end of a large keyspace
displayed close to 100 percent for the whole of its run.
CURKU in --machine-readable and Restore.Point in the status screen are unchanged. Both remain
positions in the whole keyspace and still include what --skip left out, because they answer where the
run has reached in the wordlist or the mask, not how much of its own work is done. Anything that
parses --machine-readable and corrects PROGRESS for --skip itself has to stop doing so.
8. Brain: --brain-client-features now defaults to 3 instead of 2
The client dedups on the candidate itself again, not only on the keyspace position of an attack, so
two different wordlists holding the same words dedup against each other out of the box. That is what
most people expect the brain to do.
9. Brain: the candidate feature switches itself off where it cannot pay
It costs the server eight bytes per candidate for as long as the session lives, and a mode that
computes inside the kernel with fewer than 1024 salts produces candidates faster than the server can
usefully remember. The attack feature stays on there, so clients still keep out of each other's
keyspace and nothing is aborted. Setting the option by hand overrules the decision either way.
10. Restore: --restore no longer takes a command line out of the restore file
The file holds the command line of the session it belongs to, and hashcat used to parse that line and
run it, so anyone able to write the file could choose the arguments. --restore now prints the command
line it holds and stops.
11. Restore: --restore-position
--restore-position takes only the resume position from the file and uses the command line you actually
ran, so no argv is parsed out of a file at all. It is what the line printed by --restore carries, and
it is the only way to resume.
12. Restore: the printed command line is shell quoted
Where an argument holds a byte outside printable ASCII, no pasteable line is printed and the escaped
argument list is shown instead.
13. Compression: zlib and the LZMA SDK are loaded from the system rather than compiled in
hashcat carried its own copy of both. They are gone, and the library the machine already has is
loaded the first time a compressed file is opened. Nothing links against them, so hashcat starts and
runs normally where none of them is present, and only reading a compressed file needs one. Linux and
the BSDs have all three in almost every case, and on macOS they come from brew. Windows provides none
of them, so the Windows package carries all three beside hashcat.exe, built from pinned upstream
sources. A hashcat built from source on Windows has none of them: liblzma.dll and libzstd.dll are
published by the xz and Zstandard projects, while .gz there works only if a zlib1.dll is already on
the machine, because the zlib project publishes no Windows build at all. Where one is missing,
hashcat names the file names it looked for and what to install.
See docs/hashcat-compression-libraries.md.
14. Compression: zip files are no longer read
A wordlist, hash list or rule file inside a .zip is no longer opened. Reading zip meant carrying
minizip, and minizip meant carrying zlib's source along with it, so the format that cost the most to
support was also the one gzip, xz and zstd already cover.
15. Wordlists: -c and --segment-size were removed
The wordlist segment cache the option sized no longer exists. It went away when the feeds layer
replaced the old wordlist reader, and nothing took the value over, so the option has been parsed and
then ignored ever since. A command line carrying -c or --segment-size now fails with an unknown
option rather than being accepted and having no effect. The letter c is retired rather than reused,
so that an old script does not one day mean something new.
16. Brain: a client and a server from different releases can no longer talk to each other
The brain link version moved from 1 to 2. The candidate identities the brain stores are computed by
a different hash than before, and the authentication handshake now stretches with SHA-256 instead of
a checksum, so a mixed pair could neither agree on what a candidate is nor authenticate. Both ends
must be upgraded together. A mismatch is refused at the handshake with both versions named rather
than failing later as a wrong password.
An existing brain server database is not converted. Its stored candidate hashes were computed by the
old function and mean nothing to the new one. The files are named after a session id that also
changes, so an old database is left alone on disk rather than misread, and a session that pinned
--brain-session starts its deduplication from empty.
17. Seek databases: every cached seek database is rebuilt once
A seek database is named after a hash of the wordlist it describes, and that hash changed, so the
first run against a given wordlist builds a new one. The old files are not found again and can be
deleted. No shipped hashcat wrote one: they arrived after v7.1.2.
18. Encoding: iconv is loaded from the system rather than linked
hashcat linked an iconv library on every platform. It is now opened the first time --encoding-from
and --encoding-to ask for a conversion, the way the compression libraries are, so a run that does
not change encoding needs no iconv at all. Machines using the GNU C library or musl need nothing
installed, because iconv is part of the C library there and hashcat reads it out of the running
process. macOS and the BSDs carry it in a library of their own that they already ship. Windows ships
none, so --encoding-from and --encoding-to there need libiconv-2.dll beside hashcat.exe, and the
Windows binaries no longer carry a copy of it. Where it is missing, hashcat names the file names it
looked for and what to install.
19. Plugins: module_hook_extra_param_init and module_hook_extra_param_term take hashcat_ctx first
Both functions gained a leading hashcat_ctx_t * parameter, so a module can call event_log_warning and
the other logging functions from them. A module that implements either one adds the parameter to its
own definition. Only two modules in this tree implement them, and nothing else in the module
interface changed. The interface version is unchanged, because it already moved from 700 to 720 since
v7.1.2 and every out of tree plugin has to be rebuilt for this release anyway.
20. Bridges: every entry point takes hashcat_ctx first
Each function in bridge_ctx_t gained a leading hashcat_ctx_t parameter, and platform_init takes
nothing else. An out of tree bridge adds the parameter to its own entry points and rebuilds.
21. Folders: $HOME/.hashcat is no longer used
An installed hashcat reads its potfile, sessions and kernel cache from the XDG directories instead. A
machine that already has a $HOME/.hashcat keeps it, and nothing moves the contents, so a session
started before this release is not found by a run after it.
22. --backend-devices-keepfree was removed
Its 2 useful values did unrelated jobs. 0 applied the reserve that keeps a desktop responsive and 100
walked past it, and neither is a fraction of anything. The reserve is now sized from what the runtime
reports free, and -Y covers the case the option was reached for.
##
## New Algorithms
##
- Added hash-mode: GPG (AES-OCB-128 (SHA-1($pass)))
- Added hash-mode: KeePass AESKDF (KDBX v4)
- Added hash-mode: Kerberos 5, etype 23, TGS-REP (NT)
- Added hash-mode: Kerberos 5, etype 23, AS-REP (NT)
- Added hash-mode: Wordpress bcrypt(hmac-sha384($pass))
- Added hash-mode: gost12512crypt [$gost12512hash$] (Unix)
- Added hash-mode: phpass(md5($pass))
- Added hash-mode: Symfony Legacy SHA256
- Added hash-mode: yescrypt
- Added hash-mode: gost-yescrypt
- Added hash-mode: scryptcrypt, scrypt (Unix)
- Added hash-mode: KDE KWallet 4.13+ (PBKDF2-HMAC-SHA512, Blowfish)
- Added hash-mode: KDE KWallet < 4.13 (SHA-1, Blowfish)
##
## New Attack modes and changed Attack modes
##
- Attack-mode 8: Generate candidates from a feed plugin instead of a built-in attack
- Attack-Mode 8: Feeds can be written in C or Rust and are named like a module, not pathed
- Attack-Mode 8: Shipped feeds are: wordlist, stdin, random and rust_random
- Attack-Mode 8: Feeds support implementations which can't report a keyspace
- Attack-Mode 8: A feed that cannot report a keyspace runs without a progress denominator
- Attack-Mode 0: Wordlists are now read through the attack-mode 8 wordlist feed, which can seek
- Attack-Mode 0: Several wordlists now form one keyspace, so --skip and --limit apply to all of them
- Attack-Mode 0: --keyspace, --total-candidates and --lookup now accept more than one wordlist as well
- Attack-Mode 0: Reading candidates from stdin is now a feed and appears as Feed (stdin)
- Attack-Mode 0: --skip, --limit and --restore now work on stdin if the same stream is fed again
- Attack-Mode 1: Both dictionaries are now read through a feed, with --slow-candidates as well
- Attack-Mode 9: Compares wordlist lines against unique salts, refusing files it once accepted
- Attack-Mode 9: A hash file of username, separator and hash is now split by hashcat, with no wordlist
- Attack-Mode 9: The username in front of the first separator becomes the candidate, and rules apply
- Mask attacks: --increment and mask files now form one keyspace, so --skip and --limit apply to all
- Mask attacks: --keyspace now answers for the whole increment or mask file instead of being refused
- Attack-Mode 12: A hybrid attack where the mask says where the word goes, with ?w marking the place
- Attack-Mode 12: ?w?d?d is what -a 6 does and ?d?d?w is what -a 7 does, and mask on both sides is new
- Attack-Mode 12: ?q marks a word from a second wordlist and has to come after ?w, so ?w?q is -a 1
- Attack-Mode 12: Literals work anywhere in the mask, so Pass?w?d?d is a valid mask
- Attack-Mode 9: A username is also split at separators and at case and digit boundaries, so j.smith also tries smith and JEdgarHoover also tries Edgar and Hoover
##
## New Features
- Added rewind and advance keys, on r and a, which move a running attack back or forward through the keyspace it walks. A single press is a small fixed step and holding the key accelerates, up to half a percent of the keyspace per press. The bypass key is unchanged and still moves on to the next wordlist or mask
- Added a key to change a --runtime limit while a run is going. It asks for a number of seconds to add, and a negative number shortens the limit instead
##
- Dictionary cache was removed. Wordlist line counts, and offsets, are now in the new seekdbs
- Seekdbs are portable between machines, so a distributed setup can build one once and hand it out
- New option --seekdb-path: Store seek databases in a given directory, which several hosts can share
- New option --lookup: Report where an attack reaches one given candidate, then quit. A candidate no shell can pass is written as $HEX[...]
- Added --encrypt-with-pubkey, which encrypts recovered plains with an RSA public key
- Encrypted plains mean the cracking host never sees them, see docs/hashcat-encrypted-plains.md
- Wordlists, hash lists and rule files may now be zstd compressed, alongside gzip and xz. A .zst wordlist written in several frames, which is what pzstd writes, is seeked into rather than decoded from the start
- -m 23800 unpacks the archive with hashcat's own RAR3 decoder, which runs all 6 RAR3 filters, so every archive that cracked before cracks now
- Added tools/rar32hashcat.py, which writes -m 23800 hash lines from a password protected RAR3 archive
- -m 23800 now reports at the end of a run how many candidates reached a RAR3 construct it could not decode
- Rules: A character outside ASCII can be written directly in the operand of the five rule operations that emit bytes, $ ^ i v o, instead of one \xHH per byte
- Windows: The binary now carries an application manifest and a version block. The manifest declares the process code page as UTF-8, which is what makes a path or an argument holding any character mean the same thing it means on every other platform, and it also opts into long paths
- Added option --task-time-breakdown, which reports where a run's wall clock went, split into session initialization, attack preparation, the attack itself and cleanup, with each section naming what it could not account for
- Added option --pipeline-stats, which reports where each launch's time goes, split into feeding, copying, init, transfer, the loop itself and comp, per device and with an effective hash rate. Adding --machine-readable prints the same thing as JSON. It replaces the HASHCAT_PIPE environment variable, which still works
- Added a dynamic hash plugin for -m 74000, selected by pointing --bridge-parameter1 at bridges/subs/dynamic_hash, which builds the hash from a description such as md5(sha1($pass).$salt) given in --bridge-parameter2. A combination of the built-in primitives no longer needs a Rust plugin written and compiled for it
- Added tools/gpg-ocb-aes2hashcat.py, which writes -m 17050 hash lines from a GnuPG key file in private-keys-v1.d
- Added --brain-feed, which reads candidates from stdin and stores them in a running brain server, so the session database picked with --brain-session can be extended without stopping the server
- --dynamic-x now loads a hash written in John's $dynamic_N$ format instead of only stripping the tag. The number selects the hash-mode, covering 56 of John's built in formats, and --show, --left and --remove write the line back in John's own spelling
- Potfile: --show and --left with --username or --dynamic-x no longer walk every copy of a hash once per potfile line naming it. A list of 200000 hashes against a potfile of 200000 lines took over a minute and was killed for memory, where it now takes about 0.1 seconds, and the message warning against the combination is gone
##
## Improvements
- CUDA: Devices that a run has already excluded no longer get a context. One was created for every device the driver reported, only to read how much memory that device had free, so a box of 8 cards running one agent per card built 8 contexts in every agent and used 1. Each of the others cost about 36 ms and a reservation of card memory
- Rule application for --stdout is spread across the host cores. It ran on one core while the rest of the machine idled, and a second device did not help because the outfile mutex is held for the whole generation loop. On a 24 thread box, 50,000 words against 30,000 rules falls from 34.0 to 7.6 seconds. Output is unchanged, byte for byte
- The directory named by --outfile-check-dir is read once before the attack is built rather than only while it runs. A hash list another run has already finished no longer pays for bitmaps, kernel building, device buffers and autotune before anything notices there is nothing left to do
##
- An .xz wordlist written in blocks, which is what xz -T0 writes, is seeked into rather than decoded from the start
- Autotune: Set the thread count of -m 23800 from the device, which the lower workload profiles tuned far too low
- Docker: Added hashcat-toolchain
- Docker: Added Ubuntu 26.04 runtime images for CUDA and AMD
- Docker: Added an Ubuntu 18.04 image with separate gcc/mingw and clang builds
- Docker: Updated the bundled Python to 3.14.6 and Rust to 1.97.1
- Docker: Removed the Ubuntu 18.04 build because its mingw-w64 cannot link current Rust
- Build: Disabled LTO by default, and release binaries still enable it
- Build: Disabled setShouldMaximizeConcurrentCompilation in ext_metal.m due to a macOS Tahoe crash
- Build: The frontend and every plugin link one shared core, so the unpacked release drops from about 413 MB to about 91 MB
- Build: The development install ships only the headers the plugin API needs, instead of every header in the tree
- Build: Plugins are no longer compiled for the processor that builds them, taking about a third off a clean build
- Build: The binaries name the hardening flags they are built with, instead of inheriting them from the build machine
- Build: A DEBUG=1 build keeps its debug information instead of having it stripped off at the link
- Build: Two builds of one commit are the same bytes, with SOURCE_DATE_EPOCH and PRODUCTION=1 pinning what would otherwise move
- Build: The build tracks its own dependencies, so editing a shared module body, a feed header or a bundled dependency rebuilds what uses it
- Backend: Removed OpenCL device-type 3, the accelerator card, so -D 3 is now an error naming the removal
- Backend: Accelerator hardware is reached through an assimilation bridge, which the hash-mode selects and -D never does
- Rules: Added the 'convert to lower hex' and 'convert to upper hex' operations
- Rules: Added the 'insert every' operation
- Rules: Added the 'shift case' operation
- Rules: Added the 'add byte value' operation
- Wordlists: Added runtime-selected vectorized line scanning, AVX2 on x86 and NEON on arm64
- Building: Added support for Android and Termux
- Building: Added support for LoongArch, PowerPC and MIPS
- Building: Added OpenBSD, NetBSD and MSYS2 jobs to the GitHub workflow
- Rust Bridge: Bridge parameters are now passed to the plugin
- Rust Bridge: Both bridges now share one hashcat-sys crate for their bindings
- Rust: Added a GitHub action that checks and tests the Rust code
- Plugins: Every helper in the OpenCL hash headers that takes a buffer and a length now reads only the words that length covers, the HMAC key readers included
- Plugins: A kernel no longer has to pad a buffer to the block size and zero the rest before calling those helpers, and one that still does behaves as before
- Documentation: Added docs/hashcat-rust-plugin-quickstart.md
- Documentation: Added a usage and advice notice to every module
- Documentation: Added module numbers and extraction advice to the 2hashcat scripts
- Modules: PBKDF2-based modes now accept iteration counts of up to 8 digits
- Modules: GPG (CAST5 (SHA-1($pass))) now supports nonzero IVs and s2ktype 3
- Modules: Added --hash-copy to keep the original hash line for the potfile and status output
- Startup: Hash parsing errors now explain what is wrong and name the part of the line that failed
- Startup: Module advice notices are now suppressed by --quiet
- Testing Framework: LUKS1 and LUKS2 test containers are now generated on demand
- Status View: Devices of the same kind share one speed line showing the member count
- Status View: Grouped temperatures show the hottest members and count the rest
- Backends: OpenCL clones share contexts and programs, and HASHCAT_CLSHARE=0 turns that off
- Backends: Memory budgets are divided among virtual devices on one physical device
- Backends: A failed clone no longer causes the remaining clones to allocate resources
- Bridges: Added three optional entry points for units made from multiple components
- Attack-Mode 0: Reading candidates from a pipe no longer slows down as devices are added
- Startup: Hash files, potfiles, rule files and mask files are read about three times faster
- Status View: Attacks reading one source per round report their position again in Guess.Queue
- Threads: Updated thread macros and types
- Benchmark: Added a workaround for a CUDA benchmark memory leak caused by register spilling
- secp256k1: inv_mod uses a fixed-iteration safegcd inverse, and -D USE_LEGACY_BINARY_GCD_INV_MOD restores the binary GCD
- secp256k1: Factored the repeated Jacobian to affine conversion into point_to_affine
- Kernels: Added HASHCAT_FORCE_NO_INLINE, which builds with -D FORCE_NO_INLINE for runtimes that inline the helpers into one slow-to-compile function
- Kernels: -m 18500 keeps a second hex table in shared memory in the byte order its SHA1 half wants, for +0.7% on a Radeon RX 7900 XTX
- Kernels: The AES decrypt key schedule inverts each round key through one table lookup instead of two in 8 modes, for +15% to +41% on a GeForce RTX 4090: -m 16600, -m 22500, -m 22931, -m 22941, -m 22951 and -m 23001 to -m 23003
- Kernels: A runtime with no byte alignment instruction gets the big endian byte alignment as one funnel shift instead of a chain of compares, for +4.1% on -m 100 on a Radeon RX 9070 XT under Mesa rusticl
- Kernels: Whirlpool takes the high half of the 64 bit word before shifting, for +3% on -m 6100 on a Radeon RX 9070 XT under Mesa rusticl
- Backends: Environment on/off switches share one hc_env_flag helper
- Feeds: Settings are written as key=value work arguments and one shared parser reads them, so a feed no longer writes its own
- PCFG: A ruleset may be one .tar.xz instead of a directory, or have single files compressed. One trained on example.dict is 3.2 MB as a directory and 275 KB as an archive
- PCFG: Naming no ruleset runs default-passwords, the one hashcat ships
- PCFG: Naming several rulesets runs them together, each with an equal share unless weights= says otherwise
- PCFG: A ruleset is named rather than pathed, the way a hash mode and a feed already are
- PCFG: A ruleset name is looked for in <profile>/pcfg and then <shared>/pcfg, and anything holding a slash is used as a path
- Feeds: A feed is given the shared folder, so one that ships data of its own can find it
- Files: Added hc_fopen_mem, which reads a file that is already in memory
- Hashes: Large hash lists without salts now sort and deduplicate with an in-place radix sort
- Kernels: Added the DEScrypt pure kernel for attack-mode 3, and both salt paths share one multi hash kernel
- Autotune: Only the leader of each device group is measured, and the answer is reused across association rounds
- Slow hashes: HASHCAT_SALT_INNER=1 tests each amplifier item against every active salt first, so an interrupted run favours the leading candidates
- Bridges: Hardware power is derived from the unit width, so kernel_accel counts waves and the status line reports Accel instead of Batch
- Build: bridge_scrypt_jane takes the SSE2 intrinsics path on ARM through sse2neon
- Build: A DEBUG=2 build links with -fsanitize=address instead of failing at the link
- Rule engine: A rule file is read into a buffer that grows geometrically instead of by a fixed 10000 rules, so a 4.9 million rule file loads in 1.7 seconds instead of 30
- Rule engine: One -r file is handed to the amplifier as it stands, instead of being copied into a second array of the same size, taking about 630 MB off the peak for a large ruleset
- Memory: Removed a 160 MiB event backlog that every event was copied into and nothing ever read
- Startup: A module that turns off the JiT kernel cache no longer turns it off for the shared, markov and amplifier kernels as well, which every other hash mode on the device shares
- Startup: The host candidate staging buffers are no longer zeroed on every round, since the producer fills every entry it hands over
- Hash lists: A run of digests whose top two words are equal is finished with a second radix pass instead of a single threaded qsort, which is the whole list on modes 200, 3000, 5100, 16000, 18700, 24700, 34201 and 34211
- Potfile: --show and --left no longer build, sort and free a copy of every selected line when -o is given, where hashcat has already written the line and nothing reads the copy
- --stdout: The candidate batch is no longer written to the device and read straight back, and the output buffer holds 64 KB instead of 8 KB
- Interface: Quit is noticed within 100 milliseconds instead of up to a second, without changing the once per second cadence the monitor counts in
- Build: MAINTAINER_MODE=1 now also reaches the Rust feeds and bridges and the Raspberry Pi flags, which were still built for the processor doing the building
- Potfile: A hash list is bucketed by its leading digest word before the potfile is matched against it, so each potfile line is looked up inside a narrow window instead of binary searching the whole list. The word is chosen from the first one that varies, because several unsalted modes leave the sorting word zero for every hash
- Cracked results: The outfile and the potfile are opened, locked and flushed once per launch rather than once per cracked hash. On a launch returning 50000 results that is 59000 system calls instead of 308000
- Interface: A paused run notices resume within 100 milliseconds instead of up to a second. The six loops that wait out a pause polled once a second, so a device could sit idle for most of a second after the key was pressed
- Interface: The status screen no longer prints one Restore.Sub row per device. What each device's position counts towards is the same on all of them, so the salt, the amplifier count and the iteration count moved up to Restore.Point, each shown only when there is more than one of it. What is left is where each device's amplifier and iteration start, three devices to a line, and which three is drawn again on every status so a few updates show them all
- Interface: The status screen no longer prints one Candidates row per device. One device's window is shown, and which device that is is drawn again on every status, so a few updates show them all. The windows cannot be folded into a single range because the devices do not take the keyspace in device id order, which would make the range run backwards
- The kernel cache is keyed with paw64 instead of one truncated word of an MD5, which gives the key its full 64 bits and drops the block padding that hashing with MD5 required. Existing cached kernels are rebuilt once on the first run after this
- Devices that would compile the same kernel now agree on one of them to do it. The cache file name already identifies which devices produce identical output, so it is what they agree on. Nothing changes while devices are set up one at a time, and it is what keeps them from all compiling the same kernel at once when they are not
- The task time breakdown now ends with the peak resident memory of the run
- Python Bridge: The hashcat context is dumped to a file that a plugin script reads back, instead of being printed for you to paste into the script by hand
- Build: The hashcat binary is now compiled for the processor doing the building, which MAINTAINER_MODE=1 turns off for a build that has to run on other machines
- Startup: The progress line shown while hashcat reads a wordlist for the first time, and the summary after it, now report a read speed in MiB/s
- Modules: -m 34300 is now named KeePass Argon2 (KDBX v4), which tells it apart from -m 34301, the KDBX v4 AESKDF mode
- Documentation: Added docs/packages.md, which tracks the downstream packages that ship hashcat and covers building one with MAINTAINER_MODE=1
- Startup: A parse error on a hash taken from the command line now says so, which is the usual sign of a mistyped hash file name
- Bridges: Autotune times the bridge itself rather than the empty placeholder left in place of the loop kernel it replaced, so -w and the status view now describe the unit doing the work
- Bridges: A bridge reports the sensors of the hardware its units run on, so the status line and --hwmon-temp-abort cover that hardware instead of the device that only feeds it candidates
- Candidates for the next batch are prepared on a thread of their own while the current batch runs on the device. The two used to take turns on one thread, so the device waited while the host built the next batch. A brain client keeps the serial path because its reserve, lookup and commit have to stay in order on one connection, and setting HASHCAT_PIPE_SYNC selects that path for every attack
- Brain: The hash database of a session is split into 1024 shards, each with its own lock, so a commit costs the size of the batch rather than the size of the whole database. Against 300 million entries a commit falls from 923 to 12 ms, a lookup from 598 to 45 ms, and taking in 300 million candidates falls from 1113 to 56 seconds
- Brain: The status screen, --machine-readable and --status-json now report Brain.Rejects, split into keyspace another client had already reserved and candidates the brain had already seen. The existing Rejected counter mixes both in with length and rule rejects, so it could not be read as what the brain saved
- Backends: HIP is loaded from a versioned libamdhip64 or libhiprtc soname when the unversioned name is absent, so the runtime package alone is enough without the development package that ships the symlink. A failure now names what was looked for
- Rule engine: A rule applied on the host no longer allocates and frees a copy of itself once per word
- Tuning Database: Added vector width tunings for the NVIDIA GB10, the GPU in the DGX Spark
- Kernels: A helper an OpenCL kernel never calls is no longer compiled into it, so a cold benchmark of -m 0 takes 8.2 seconds instead of 14.1 and --backend-info answers in 0.55 seconds instead of 1.84 on a Radeon RX 7900 XTX with ROCm 7.0.1
- Backend: OpenCL C 1.2 is now the minimum. A platform or a device reporting 1.0 or 1.1 is skipped at startup with a message naming the version, instead of being compiled as OpenCL C 1.1 and failing much later in the kernel build
- Kernels: The hand written byte swap and bit field extract assembly is gone, because the compiler produces the same or better code, for +0.4% to +0.7% on the byte swap heavy modes -m 0, -m 1700 and -m 10800 under HIP
- Hash lists: The bitmap filter in front of the digest search is sized from the hash count and the memory hierarchy of the device instead of being pinned between 16 and 18 bits, and its probes mix all four digest words instead of slicing bits from one. 50 million NTLM hashes run at 58.3 GH/s instead of 1.1 on a GeForce RTX 4090 and at 24.9 GH/s instead of 1.0 on a Radeon RX 7900 XTX, and 1000 NTLM hashes on the RTX 4090 rise from 93.3 to 129.0 GH/s
- Hash lists: A hash list is read, counted, parsed, sorted, deduplicated and turned into bitmaps on every core instead of one. On a 32 thread box, 50 million NTLM digests load in 1.7 seconds instead of 40.4, and a salted list of 5 million hashes in 1.2 seconds instead of 7.0
- Autotune: The launch size is now fitted from a few measured points instead of searched by running the kernel at every accel and loop step, which takes 32% off the time autotune spends across a sweep of 2025 mode and device pairs. -w now also decides how much of a gain a larger launch has to show before the tuner takes it, so the two lower profiles keep the batch short and the two upper ones take every gain there is
- Autotune: The tuning database now carries 13 measured kernel_accel rows, where no shipped row set that field before. PKZIP (-m 17200) rises from 1.3 to 16.7 GH/s on a GeForce RTX 4090 and by 87% on a Radeon RX 7900 XTX, and DPAPI masterkey file v2 (-m 15910) by 97% on the RX 7900 XTX and 19% on the RTX 4090
- Tuning database: Vendor tuning rows are matched from the backend vendor id rather than a list of 75 AMD and Intel card names, so hardware the list never named receives them, which on DPAPI masterkey v2 is worth 28% on a Radeon Pro W5700X and 162% on the integrated GPU of a Ryzen 9 7950X
- Fixed a device being dropped from the run when a tuning database row pinned the accelerator to a value that did not fit in its memory. The pinned value is now lowered, but only after every other fit has been tried and never below the minimum the hash-mode asks for, while an explicit --kernel-accel is still refused rather than quietly changed
- Backend: Free device memory is now measured wherever the runtime reports it, AMD devices reached through OpenCL included, and the 34 percent desktop reserve is applied only where the figure had to be estimated. A measured figure used to lose a third of the card anyway, which on a memory bound hash mode is a third of the speed
- Backend: The reserve for register spilling is sized from the work items a device keeps resident instead of from the whole launch, so a GeForce RTX 4090 running -m 0 holds back 51 MiB where it used to hold back 3774, leaving that memory for the attack
- Autotune: The PKZIP modes 17200, 17220 and 17225 now run one warp on NVIDIA and one wavefront on AMD, because the 77688 bytes of private memory each work item holds for inflate cap occupancy no matter how wide the workgroup, for 2.5 times the speed on a GeForce RTX 4090 and 3.2 times on a Radeon RX 7900 XTX
- Backend: An integrated GPU is disabled by default when a discrete GPU is also present, since it contributes about 1 percent of the combined speed while adding a second architecture to compile and another device to autotune. A cold -m 0 start on a Ryzen 9 7950X with 2 Radeon RX 7900 XTX cards drops from 6.28 to 4.62 seconds. A machine whose only GPU is integrated is unaffected, and -d overrides the rule
- Fixed a machine with the CUDA runtime but no NVIDIA GPU, or the HIP runtime but no AMD GPU, reporting a backend initialization error on every run, where hashcat closes that runtime and continues with the next backend anyway
- Encoding: An encoding name that hashcat cannot use is now reported by name, where a mistyped --encoding-from or --encoding-to used to end the run without printing anything
- Autotune: The thread count ceiling on Metal now comes from the compiled pipeline, as it already does on CUDA, HIP and OpenCL, instead of from the 32 thread SIMD width that capped every kernel
- Backend: HIP picks its ABI from the runtime it finds, so one binary drives both ROCm and the Hygon DTK runtime, where device initialization used to fail
- Potfile: A password found in the potfile is stored once per hash and handed to every copy of that hash after the file is read, instead of a new buffer being allocated for every copy on every matching line. A list of 200000 copies of one hash, against a potfile naming it 200000 times, took 67 seconds and then ran out of memory, and now takes about 0.1 seconds. --show is allowed with --username and --dynamic-x again
##
## Bugs
##
- Windows: The working directory is no longer searched for the libraries hashcat loads by name, so a DLL left beside a wordlist can no longer be loaded and run. Supplying one beside hashcat.exe is unaffected
- Windows: Fixed module 23800 not loading in a build made on MSYS2, where it depended on libstdc++-6.dll and libgcc_s_seh-1.dll being found on PATH
- Windows: Fixed the reason a plugin failed to load being reported as "The operation completed successfully", for modules, bridges and feeds alike
- Fixed chained rule files corrupting memory when 4 or more -r files are given and the chain runs past the 31 function limit, which also underflowed the rule count and broke the device memory estimate
- Fixed the rule file list in the status display writing past its 4 KB buffer, where the length snprintf reports it would have written ran the total past the end. The list is now truncated at the buffer
- Fixed the same counting mistake in the 7-Zip hash encoder for -m 11600, which no hash the parser accepts is long enough to reach
- Fixed a stored deflate block decoding to nothing in the PKZIP modes 17200, 17220 and 17225 on AMD GPUs, under HIP and OpenCL both, so an archive holding an already compressed file never cracked
- Fixed an association attack cracking nothing in modules 01100, 05300, 05400, 05600, 07300, 08000, 13800, 17200, 17210, 17220, 17225 and 17230, where one hash's salt was handed to every thread of the workgroup
- Fixed an association attack ignoring --keyboard-layout-mapping in the TrueCrypt modules 06211 to 06233 and the VeraCrypt modules 13711 to 13773, and reading another hash's page table in module 22100
- Fixed an association attack cracking only the first hash in modules 11600 and 23800, where the host side hook was given the salt of the launch
- Fixed combinator and hybrid attacks reporting a plaintext truncated to 256 characters, which did not match the cracked digest
- Fixed buffer overflows in the RC4 modules 33500, 33501 and 33502, where the plaintext token was not bounded by the field it decodes into
- Fixed a stack buffer overflow in the Kerberos etype 17 and 18 modules 19600, 19700, 19800, 19900, 28800, 28900, 32100 and 32200, where a realm longer than 128 characters was copied into a fixed local buffer
- Fixed encode buffer overflows in modules 16900, 19600, 19700, 32100 and 32200, seen with --show and --left at the maximum data length
- Fixed a 0x80 padding byte written one past a full buffer in modules 00111, 01411, 01711, 05300, 05400, 11400, 13100, 13600, 18200, 35300 and 35400
- Fixed a heap buffer overflow in the Kerberos etype 23 modules 13100, 18200, 35300 and 35400, where the account_info field was not bounded before it was copied
- Fixed a heap buffer overflow in module 34000, where a base64 target hash wrote past the digest
- Fixed a stack buffer overflow in module 23400, where a base64 salt wrote past its decode buffer
- Fixed buffer overflows in modules 11600, 17050 and 70000, where a token wrote past the field it decodes into
- Fixed a buffer overflow in generic_salt_decode(), where a base64 salt wrote past salt_buf for non optimized kernels
- Fixed a one byte buffer overflow in fgetl() when a line was as long as the caller's buffer
- Fixed an out-of-bounds read in the secp256k1 point_mul_xy() when the scalar is zero
- Fixed the secp256k1 inv_mod() looping forever on a zero input, which hangs clFinish on CPU devices
- Fixed missing libclang dependencies for Rust bridges in Ubuntu 20.04 and Arch containers
- Fixed the Windows Rust plugin failing to link in the Arch container because lld was missing
- Fixed Windows Python plugins disappearing when the bundled Python version was not 3.12
- Fixed bridge_scrypt_jane failing to link with LTO on older mingw-w64 versions
- Fixed bugs in several DES-based modules on CPU devices
- Fixed the MSYS2 build
- Fixed mask files not setting the mask length, causing --increment to misbehave
- Fixed incorrect results from hc_memchr_avx2 and hc_memchr_avx512
- Fixed the hash category for Mega.nz password-protected links
- Fixed KeePass 4 accepting truncated hash lines
- Fixed luks2hashcat.py generating invalid hash files
- Fixed luks2hashcat.py reporting unencrypted data segments
- Fixed an incorrect CRC include in m17220_a3-pure.cl
- Fixed FIXED_LOCAL_SIZE being undefined for module 18600
- Fixed kernel declarations for module 22800
- Fixed cross-platform incompatibilities between POSIX and Windows threads
- Fixed deprecated Bitcoin::Crypto symbols in the Bitcoin 2hashcat scripts
- Fixed OpenCL 1.2 platforms compiling as OpenCL C 1.1 and rejecting file-scope static data
- Fixed the NetBSD build conflict between its qsort_r declaration and sort_r.h
- Fixed a cpuset warning on NetBSD
- Fixed the status candidate line reading an unbounded length from device memory, risking a crash
- Fixed --slow-candidates skipping a rejected word instead of rejecting it, shifting later candidates
- Fixed -a 1 --slow-candidates not applying uppercase or encoding conversion to amplifier words
- Fixed -a 1 truncating an amplifier word after encoding conversion instead of rejecting it
- Fixed a file handle leak in -a 7 with the pure kernel, one per mask, dictionary and device
- Fixed a restored position beyond the keyspace wrapping the remaining work to a huge value
- Fixed --progress-only reporting a speed a factor of the measured chunk count too low
- Fixed brain attack identities not including the rules, so two different attacks shared a database
- Fixed a crash in autodetect and --identify when any hash-mode's module could not be loaded
- Fixed a memory leak in module_load() on the paths where the module file cannot be opened or has no module_init
- Fixed RAR3-p Compressed being unusable on Windows because module_23800.dll imported libstdc++-6.dll
- Fixed feeds/rust_random.dll shipping with no Windows version information
- Fixed cargo refusing a --locked, offline or vendored build after winresource was added without regenerating the lockfiles
- Fixed the packaged Rust bridge sources rebuilding without version information, because their build.rs was not copied
- Fixed the binaries container failing to build 7-Zip after its toolchain moved to GCC 16
- Fixed the binaries container packaging an incomplete archive when the build had failed
- Fixed redefinition warnings from the Python.h and _WIN32_WINNT include order
- Fixed "No devices found/left." not naming what removed the devices, nor that a bridge was left with units and nothing to drive them
- Fixed "No devices found/left." counting the virtualized device list, so a bridge run described the host device as the whole machine
- Fixed --backend-devices-virthost past the last device reporting that no device was found at all, instead of that the device number it asks for does not exist
- Fixed -I listing one backend device per bridge unit instead of one per physical device
- Fixed an edited kernel not being compiled again, because the kernel cache key said nothing about the kernel source
- Fixed 'make linux' building every module, bridge and feed against the native core instead of the Linux one
- Fixed 'make hashcat.exe' cross compiling with -march=native, which can put instructions in the binary that the target machine does not have
- Fixed attack-mode 8 dying before the first candidate when hashcat was built with ENABLE_BRAIN=0
- Fixed a failed build step leaving its half written output behind, which the next make then called up to date
- Fixed the brain giving two feed attacks one attack id when their arguments differed only in where one argument ended
- Fixed --restore printing a resume command line that cannot be run when the recorded command line contains '--'
- Fixed POSIXLY_CORRECT deciding which arguments hashcat reads as options, which silently handed hashcat's own options to the attack instead
- Fixed a 32 bit overflow in the digest, esalt and hook salt buffer offsets, which addressed the wrong hash once a list grew past what 32 bits can index
- Fixed a one byte write past the debug plain buffer, seen with a rule that produced a password of the maximum length
- Fixed a double free in the rule processor when the combined rule count of chained rule files exceeded 32 bits
- Fixed an undetected u32 overflow when chaining rule files, where two large files ran a keyspace of 65536 and exhausted as though complete
- Fixed module 10500 rejecting PDF hashes that carry an empty ID field
- Fixed the yescrypt kernels for modules 36100 and 36200 failing to build on Metal because of the address spaces they used
- Fixed random rule generation filling the first position operator table with no-ops, so -g never produced those operations
- Fixed modules 03710, 04010 and 04110 advertising a salt limit their optimized kernel cannot hold, which took a 24 to 51 byte salt with -O and never cracked
- Fixed the title case rule with a separator class leaving the separator character unchanged instead of lowercasing it
- Fixed --show corrupting LM output when a hash has an unusable right half, and made pairing the split halves much faster
- Fixed a stack buffer overflow in the 'convert to lower hex' and 'convert to upper hex' rules
- Fixed a stack buffer overflow in mangle_dupeblock_prepend, where a rule such as /Xyp on a long enough word asked for more bytes than the local buffer held
- Fixed a heap buffer overflow in the PKZIP modules 17200, 17210, 17220, 17225 and 17230, where the hex data token was decoded without a bound check
- Fixed a buffer overflow in modules 22000 and 22001, where the essid and eapol lengths taken from an hccapx file were used without a range check
- Fixed a GPU hang in modules 13400 and 29700, where a KeePass contents_len below 16, or not a multiple of 16, underflowed a loop bound
- Fixed a heap buffer overflow in module 34301, where a KeePass 4 header longer than the field it decodes into was accepted
- Fixed a stack use after scope in module 25400, and a '%s' that read past a line buffer which is length delimited rather than terminated
- Fixed an out-of-bounds read in is_hexify() for inputs shorter than the six bytes of '$HEX[]'
- Fixed an out-of-bounds read in the reject_contain rule, and bounded the rule buffer that a long rule line is copied into
- Fixed an out-of-bounds read of the markov css buffers on device, which also reserved 64 MiB per device for buffers a wordlist run never creates
- Fixed a rare race in --outfile-check
- Fixed a run that lost every device still exiting successfully, which was most visible in benchmark mode
- Fixed an unused variable warning on Android builds, and affinity failures there being blamed on pthread_setaffinity_np(), which does not exist on that platform
- Fixed --keyspace and --total-candidates being accepted with attack-mode 9, where the hash file was opened as a wordlist
- Fixed association autosplit trying pieces of an account name shorter than three characters, each of which cost a round against every account in the file
- Fixed 66 modules underflowing the salt iteration count when the hash carried a zero, which asked the device for about 4 billion iterations and hung
- Fixed 16 modules deriving a salt iteration count by shifting past the width of the type, where a value of 32 or more gave the wrong count
- Fixed the eight scrypt modules underflowing salt_repeats when the hash carried a parallelism of zero, which hung the kernel on launch
- Fixed --speed-only measuring with the bitmap flattened to a single entry, which misreported the speed for a list holding many hashes
- Fixed the PKZIP modes 17220 and 17225 overrunning the 4 GiB private aperture on AMD GPUs under HIP, which refused the launch on larger cards and cost 58 percent of throughput on smaller ones
- Fixed the VeraCrypt modes 13723, 13733, 13751, 13753, 13761 and 13763 failing their self test, and hanging on the password they had just found under --self-test-disable. The 15 XTS header helpers are now kept out of line, and TrueCrypt, DiskCryptor and LUKS were never affected
- Windows: Fixed a thread handle being leaked on every join, which for a hash mode with a host side hook is one handle per hook thread per kernel launch and grew by about 40 handles a second on -m 11600
- Fixed hashcat carrying on after a thread it needed failed to start, where the join that followed ran against a handle that was never set. A worker that will not start now does its own chunk on the calling thread, and a cracking, monitor or outfile-check thread that will not start is reported
- Fixed diagnostics being written to standard output under --stdout, where they landed in the middle of the candidate stream and were read back as candidates
- Fixed the seek database builder dereferencing a null pointer at four allocation sites, and never reporting a failed build to its caller
- Fixed the scanned induction dictionary paths being leaked on every rescan, which accumulates for the life of a --loopback run
- Fixed the backend session being left open when it failed to start outside a benchmark
- Fixed a failed --stdout write being silent, so a full disk or a closed pipe lost candidates without an error
- Fixed the available memory calculation underflowing on a u64 in the yescrypt, scrypt and argon2 modules when a device reports less memory than the reserve, which asked for far more memory than the device has
- Fixed the CUDA context created for each device being left on the main thread's context stack, since cuCtxCreate makes it current as well as creating it
- Fixed the per file rule buffers being leaked when a ruleset loaded, and bounded the class selector lookahead in the rule compiler
- Windows: Fixed hashcat failing to run from a folder whose name holds a character the system code page cannot represent, where its own pid, tuning and potfile paths were rejected as an invalid argument
- Windows: Fixed a mask, a rule or any other argument holding such a character arriving as a question mark, which for a mask silently ran a different keyspace because ? is the mask metacharacter
- Windows: Fixed a message printed to a console being rendered through the console code page rather than as UTF-8, which showed any such character as mojibake unless the user had run chcp 65001 first
- Windows: Fixed the colour of a message written to stderr being applied to whatever console stdout pointed at, and the terminal test answering for stdout no matter which stream was being written
- Windows: Fixed --loopback and --induction-dir never finishing, where the dictionary a round had just consumed was still open when hashcat tried to delete it. Windows refuses to delete an open file, so the next scan found it again and read it forever
- Fixed a checkpoint that had already stopped a device being cancellable, which cleared the flag the run needed to end as a checkpoint. The round was then booked as exhausted with its remaining keyspace never dispatched, and the restore file was deleted with it
- Interface: Fixed quitting with q taking up to a second longer than it needed to. The thread that reads the keyboard waited a full second for input and only noticed the shutdown between waits, and the main thread joins it on the way out
- Fixed about 0.7 seconds being added to the end of every run by the outfile check thread, which waited a flat second between checks and was joined at shutdown. It runs by default, so this was not limited to runs using --outfile-check-dir
- Fixed a compiled kernel being readable while it was still being written. The cache directory belongs to the user rather than to one run, so two hashcat processes share it, and the writer truncated the file before taking its lock while the reader took no lock at all. A second process could load a truncated kernel. We now write the kernel under a temporary name and rename it into place, which is atomic
- Fixed messages from different threads overwriting each other. Every message is formatted into one buffer shared by the whole run, and a log event deliberately does not take the event mutex, because handlers that already hold it log from inside. Autotune, self-test, the device threads and the monitor all log, one thread per device for the first three, so two devices reporting at the same moment could produce a truncated or mixed line. The buffer now has a lock of its own
- CUDA: Fixed the main thread making driver calls with no context current. Creating a context also makes it current, so the loop that recreates them between benchmark rounds left one stale entry per device on the main thread's stack every round, and releasing a session afterwards ran about fifty free and destroy calls against whatever was on top. Each of those discards its return, so the failures were silent. The main thread now pushes the device context around that work and pops it again, and every pop reads into a local rather than back into the handle a device thread writes from its own thread
- Fixed the pipeline instrument adding every device together. Its six buckets were one set of counters written by every device thread at once, so a multi device run reported their sum and raced while producing it. Each device now books its own launches and reports them under its own number
- Fixed a candidate being tried that was never a line of the input. A line longer than the buffer the stdin reader fills is cut, and the oversized piece is dropped later because no password is that long, but whatever followed the cut was published as a line of its own. Reading the same file as a wordlist skips the line instead, and the two now agree
- Fixed identical devices being aligned to an accelerator and thread count their own buffers were not sized for. Devices of one class are given a single tuning so that neighbouring cards do not run visibly different batch sizes, but the test for a class deliberately ignores memory, and a card driving a display sizes its buffers for less. The shared values are now clamped against each device's own ceilings
- Fixed modules 01800, 08300, 10700 and 16600 declaring the Register-Limit optimizer, which capped their CUDA kernels at 128 registers where it does not pay
- Fixed the example commands in --help and in docs/hashcat-brain.md naming rules/best64.rule, which hashcat has not shipped since the file was renamed to best66.rule, so copying one of them failed
- Fixed the GPG modes 17010, 17020 and 17030 printing uninitialized bytes after the encrypted data field with --show, --left and in the outfile, where the hex encoded field was never terminated
- Fixed a buffer overflow in the optimized kernels of module 32300, where a long salt plus the fixed string the module joins to it ran past the 256 bytes the kernel reserved. A salt too long for the optimized kernel is now refused
- Fixed the hardware monitor printing a line for every virtual device, so a single card run with -Y 4 reported its temperature, fan and clocks four times
- Fixed -n being accepted and then ignored in the bridged hash-modes, where the launch size was overwritten with the candidate count the bridge advertises
- Fixed -u above 1024 being refused, where 1024 is only the default ceiling and several hash-modes allow far more, up to 131072
- Fixed the module 74000 Rust bridge generic_hash.dll shipping with no Windows version information, which antivirus scanners report as a false positive
- Fixed the argon2id and scrypt bridges failing to build where -march=native resolves to a processor the compiler then rejects, which happens on DragonFly BSD and under some hypervisors
- Fixed both Python bridge makefiles defining two recipes for the same target, so make warned about an overriding recipe on every build made without the Python headers
- Fixed module 01500 cracking nothing in -a 3 when a hash list holds more than one hash and all of them carry the same salt, where the multi hash kernel of the compile time salt path was an empty stub
- Fixed module 17030 never cracking a GPG key protected with AES-128, where the AES key was read out of the SHA-256 state as though it held 64 bit words
- Fixed a heap buffer overflow when building the outfile line, where a long username, hash or plaintext was copied in without a bound check
- Fixed -d being ignored on bridged hash modes, where every bridge unit ran regardless of what was selected and an invalid device number was accepted without an error
- Fixed a brain client that could not reach the server running its whole attack without deduplication, which is now an error naming the host and port
- Fixed the brain server not writing its databases on SIGTERM, so kill, systemctl stop and a container stop lost the session that Ctrl-C would have saved
- Fixed the brain server log not being flushed after each line, so a redirected log showed nothing until a block filled and lost its tail on a crash
- Fixed a missing workgroup barrier in the module 22100 loop kernel, where a thread starting the next round could overwrite the shared precomputed salt data other threads were still reading, so a workgroup running out of lockstep could produce wrong results
- Fixed -a 1, and -a 7 with a pure kernel, launching the full amplifier count after a chunk lost words to a reject, so the slots it did not fill were tried again with the previous chunk's words
- Fixed an out-of-bounds write and a truncated SHA-1 message in the SAP CODVN F/G modes 7800 and 7801, where a long password and salt overran the 128 byte packing buffer and anything past byte 119 never reached the digest, so a matching candidate did not crack
- Fixed the SNMPv3 modules 25000, 25100, 25200, 26700, 26800, 26900 and 27300 rejecting an engine ID shorter than 13 bytes, and modules 26900 and 27300 zero padding every engine ID to 17 bytes before localizing the password, so a shorter one never cracked
- Fixed out-of-bounds reads in the hash parsers of modules 07100, 07900, 08500, 08501, 11600, 19600, 19700, 28800, 28900, 29100, 32100 and 32200, where a short or malformed hash line was read outside the line buffer, and bounded the module 10000 salt so its encoder leaves room for a terminator
- Fixed a password holding a euro sign, Japanese kana or most other 3 byte characters being discarded by the 41 hash modes that convert UTF-8 to UTF-16 inside the kernel, where only 4 of the 16 valid 3 byte lead bytes and 3 of the 5 valid 4 byte lead bytes were recognized
- Fixed modules 8500, 8501, 12400 and 14100 failing to build on OpenCL runtimes that report local memory as global
- Fixed the PKZIP mode 17230 rejecting a candidate whose first deflate block is a stored block, under -a 1 and -a 3, which the same fix for the other PKZIP modes had missed
- Fixed -a 3 never cracking a password outside ASCII in modules 00130, 00140, 00170, 01430, 01440, 01470, 01730, 01740, 01770, 10830, 10840, 10870, 13500, 13800, 29000 and 29200, where each UTF-8 byte was widened into a character of its own rather than decoded. On a CPU device this needs --backend-vector-width 1
- Fixed the GPG modes 17010, 17020 and 17030 never cracking the correct password at some combinations of iteration count and password length, where up to 3 stale salt bytes were left past the end of the repeated salt and password stream the key is derived from
- Fixed --progress-only measuring with the bitmap filter flattened to 1 bit, which understated the progress step for a list holding many hashes and left --bitmap-min and --bitmap-max with no effect
- Fixed a Metal device being disabled even when -d named it alongside an OpenCL device, and the message naming -d as the way to use Metal instead of OpenCL never being printed
- Fixed module 10900 crashing when the hash carried a zero salt iteration count, where the stored count underflowed to about 4 billion and choosing a kernel loop count from it divided by zero
- Fixed a buffer overflow in the brain, where a signed lookup length received from a peer was never checked for a negative value and became an enormous length at the receive, letting a peer write past the receive buffer on the client and the server alike
- Fixed the brain server reading more saved dumps at startup than its tables hold, where a working directory with more than 64 session dumps wrote past the end
- Fixed a damaged gzip, xz or zip file making hash list line counting, the brain attack hash and the custom charset reader scan far past the end of their buffers, where the error a failed decode reports was taken as the number of bytes read
- Fixed a heap buffer overflow in modules 22000 and 22001 with a gzip or xz compressed hccapx file, where the hash array was sized from the file size on disk but filled from the decompressed stream
- Fixed buffer overflows in modules 08900, 21500, 21501, 28200, 70100 and 70200, where a base64 token missing its padding decoded to more bytes than the field it decodes into
- Fixed a hash line longer than the buffer it is written into placing its terminator past the end, where the length snprintf reports it would have written was taken as the length it wrote. The outfile, --show, --left and the status display all encode a hash this way
- Fixed a one byte stack buffer overflow in 40 modules, where the terminator after an encoded salt landed just past a buffer sized exactly for the longest salt generic_salt_encode can return
- Fixed a module reporting an encoded hash longer than the buffer it was given, which made the caller write a terminating byte past the end of it. hash_encode() now clamps the length it returns, and the potfile and status display paths that do not go through it are bounded as well
- Fixed --username allocating the name only up to a NUL byte inside the field while recording the length of the whole field, so writing the name out with --show or --left ran past the allocation and put unrelated heap contents in the output
- Fixed a stack buffer overflow in --show for the split hash modes, where both halves of the plaintext were copied from the potfile into a 20 byte buffer without a length check
- Fixed a write past the end of the hash list when an LM hash file grew while it was being read, where one line adds two entries but only one free slot was checked
- Fixed a buffer overflow in modules 70100 and 70200, where an r or p taken from the hash walked the fixed 32 KiB scratch buffer out of bounds, and an N of 0 underflowed the block count
- Fixed the yescrypt bridge sizing its two scratch buffers in 32 bit arithmetic, where a large N off the hash line wrapped and left a buffer the mixer then wrote past, and neither it nor the argon2 bridge noticing that an allocation had failed
- Fixed the eight scrypt modules reporting an incompatible self-test or mixed configuration for a hash file holding a single hash, where a large r and p carried the buffer size derived from them into the values that report those errors. Such a hash is now refused for the memory it asks for instead
- Fixed 33 combinator kernels reading past their 256 byte candidate buffer, where two words of up to 256 bytes each were assembled with no check on their combined length. Such a pair is now skipped
- Fixed a buffer overflow in --keyboard-layout-mapping for the TrueCrypt and VeraCrypt modes, where a map entry longer than the character it replaces grew the password past the fixed buffer it is assembled in, in the kernels and on the host alike
- Fixed a buffer overflow in the mask file parser, where a mask or custom charset longer than 1023 characters wrote past the buffer it is copied into and then over the length used to index it
- Fixed an out-of-bounds read in the 4 rule rejection operators that test the first or last character, where an empty candidate has neither
- Fixed module 25400 adding one stray byte after a PDF user password of the full 32 characters, which reached the hash line and the potfile
##
## Other changes
##
- Raised MODULE_INTERFACE_VERSION to 720, so third-party modules have to be rebuilt
- Wordlist keyspace is now the line count, so Progress counts every line and rejects the unusable
- Brain attack identities now include --skip and --limit, so a partial run is its own attack
- Added SECURITY.md, which states which inputs are treated as coming from other people and how a report is handled
- Added CONTRIBUTING.md, which is what a reviewer holds a pull request against, and AGENTS.md, which is the part of it an AI coding agent needs. README.md was rewritten at the same time
- Removed deps/zlib and deps/LZMA-SDK, 410 files and 128252 lines, in favour of the system libraries
- Removed deps/unrar, 158 files, in favour of hashcat's own RAR3 decoder, and with it the ENABLE_UNRAR and USE_SYSTEM_UNRAR build switches
- A build no longer needs a C++ compiler or a C++ runtime, because UnRAR was the only C++ in the tree
- Removed the exported symbol hc_decompress_rar and the header include/ext_unrar.h that declared it, which nothing outside module_23800 called
- The Camellia kernel was rewritten from RFC 3713 and carries the tree's own license header, replacing the one file in hashcat that asserted a copyright and stated no terms. The 16 modes that use it compute exactly what they computed before
- tools/test_package.sh now reads a compressed wordlist back, so CI checks that the compression libraries load and decode rather than only that hashcat compiles
- Rust bridge sources moved from Rust/generic_hash to Rust/bridges/generic_hash, and a packaged release loads the built plugin from bridges/subs
* changes v7.1.1 -> v7.1.2
##
## New Algorithms
##
- Added hash-mode: Generic Hash [Bridged: Rust] with the new Rust Bridge
- Added hash-mode: Besder Authentication MD5
##
## Improvements
##
- CRC Libraries: CRC restructure
- GOST Libraries: GOST R 34.11-94 restructure
- SAP CODVN H: Raised the maximum salt length for hash-mode 35000 (isSHA512) from 16 to 192
##
## Bugs
##
- Argon2 Libraries: fixed call to vector helper functions when only using scalar buffers
- Argon2 Libraries: fixed esalt access pattern across Argon2, LUKS2, and KeePass KDBX4 kernels
- Argon2 Libraries: fixed false negatives for password and salt combinations longer than 64 characters
- Folders: fixed hc_mkdir_rec(), which was not creating directories correctly
- Status View: fixed broken backward compatibility in machine-readable mode introduced in v7.1.0
- sha224(sha224($pass)) and sha224(sha1($pass)): Fix hash category as unsalted
* changes v7.1.0 -> v7.1.1
##
## Improvements
##
Docker: Add initial support for AMD GPUs when running Hashcat inside Docker using HIP and OpenCL
Hardware Monitor: Suppress fan speed warnings for unified memory setups (typically internal GPUs)
Testing Framework: Enable hardware monitor to improve testing of memory-heavy algorithms
Unit tests: Updated install_modules.sh to use an external module for Digest::MD6
##
## Bugs
##
- Fixed multi-hash handling in LUKS2 and KeePass (KDBX4), while single-hash remained unaffected
* changes v7.0.0 -> v7.1.0
##
## New Algorithms
##
## Endpoint
- Added hash-mode: AS/400 DES
- Added hash-mode: AS/400 SSHA1
- Added hash-mode: Blockchain, My Wallet, Legacy Wallets
- Added hash-mode: Cisco-ISE Hashed Password (SHA256)
- Added hash-mode: Keepass4
- Added hash-mode: SAP CODVN H (PWDSALTEDHASH) isSHA512
- Added hash-mode: sm3crypt $sm3$, SM3 (Unix)
## Primitives, KDFs, Libraries
- Added hash-mode: BLAKE2b-256
- Added hash-mode: MD6 (256)
## Constructs
- Added hash-mode: BLAKE2b-256($pass.$salt)
- Added hash-mode: BLAKE2b-256($salt.$pass)
- Added hash-mode: sha224($pass.$salt)
- Added hash-mode: sha224($salt.$pass)
- Added hash-mode: sha224(sha1($pass))
- Added hash-mode: sha224(sha224($pass))
##
## Improvements
##
- Attack-Modes: Use 64-bit counters for amplifier keyspace
- Host Memory: Update method to query free host memory using /proc/meminfo when available
- Docker: Add initial support for running hashcat inside Docker
- Device Memory: Warn instead of waiting on high GPU memory usage
- Backends: Enhanced AMD Windows OpenCL and HIP compatibility for legacy models
- Rules: Add early syntax check for -j and -k rules
- Device Memory: Do not disable hwmon interface by default in speed-only and progress-only mode
- JSON output: Refactor Bridge unit reporting for clarity
- Backends: Ignore devices from Microsoft OpenCL D3D12 platform
- Building: Add MAINTAINER_MODE flag to disable hardcoded CPU optimization flags
- Bash: Add missing parameters to bash completion script
- Dependencies: Downgraded unrar source from 6.2.7 to 6.0.5
- Benchmark: Update default hash-mode selection
- Libraries: DES and Blowfish restructure
- Building: Add initial support for OpenBSD and DragonflyBSD
##
## Bugs
##
- Fix broken JSON formatting when using the --status-json flag
- Fix issue where -k single rules were ignored when used with -a 1 and -S
##
## Python Bridge
##
- Fix unsalted hashlist support
- Fix the esalt structure, it was too large
- Improve support from 1:1 password-to-hash to 1:N password-to-hashes
- Improve stand-alone debugging of Python Bridge stubs
- Improve salt/esalt debugging of Python Bridge stubs
- Enable potfile output by default for -m 73000 and 72000
##
## Other changes
##
- Argon2: Add argon2_init() wrappers to support private address space
- Change hash-category for hash-modes 25600, 25800, 28400 and 30600 to HASH_CATEGORY_RAW_HASH_SALTED
- Suppress optimization advice in final approach mode
- Backend: Split backend_session_begin() into smaller compute-runtime specific functions
- Sanity check: Abort if a custom-charset is defined on the command line and a mask file is used
- Building: Disable Argon2 optimized path on RISC-V
- Shared: improved 32-bit and 64-bit add and multiply overflow helper functions
* changes v6.2.6 -> v7.0.0
##
## New Algorithms
##
## Primitives, KDFs, Libraries
- Added hash-mode: AES-GCM
- Added hash-mode: Argon2 (Argon2i/d/id)
- Added hash-mode: BLAKE2s-256
- Added hash-mode: CAST
- Added hash-mode: PBKDF1-SHA1
- Added hash-mode: RC4-40/72/104/128
- Added hash-mode: RIPEMD-320
- Added hash-mode: ShangMi 3 (SM3)
- Added hash-mode: HMAC-BLAKE2S (key = $pass)
- Added hash-mode: HMAC-RIPEMD160 (key = $pass)
- Added hash-mode: HMAC-RIPEMD160 (key = $salt)
- Added hash-mode: HMAC-RIPEMD320 (key = $pass)
- Added hash-mode: HMAC-RIPEMD320 (key = $salt)
## Bridged
- Added hash-mode: argon2id [Bridged: reference implementation + tunings]
- Added hash-mode: scrypt [Bridged: Scrypt-Jane ROMix]
- Added hash-mode: scrypt [Bridged: Scrypt-Yescrypt]
- Added hash-mode: Generic Hash [Bridged: Python Interpreter free-threading]
- Added hash-mode: Generic Hash [Bridged: Python Interpreter with GIL]
## Endpoint
- Added hash-mode: 1Password, mobilekeychain (1Password 8)
- Added hash-mode: Adobe AEM (SSPR, SHA-256 with Salt)
- Added hash-mode: Adobe AEM (SSPR, SHA-512 with Salt)
- Added hash-mode: Anope IRC Services (enc_sha256)
- Added hash-mode: Apache Shiro 1 SHA-512
- Added hash-mode: BestCrypt v4 Volume Encryption
- Added hash-mode: Bisq .wallet (scrypt)
- Added hash-mode: Bitcoin raw private key (P2PKH), compressed
- Added hash-mode: Bitcoin raw private key (P2PKH), uncompressed
- Added hash-mode: Bitcoin raw private key (P2SH(P2WPKH)), compressed
- Added hash-mode: Bitcoin raw private key (P2SH(P2WPKH)), uncompressed
- Added hash-mode: Bitcoin raw private key (P2WPKH, Bech32), compressed
- Added hash-mode: Bitcoin raw private key (P2WPKH, Bech32), uncompressed
- Added hash-mode: Citrix NetScaler (PBKDF2-HMAC-SHA256)
- Added hash-mode: CubeCart (whirlpool($salt.$pass.$salt))
- Added hash-mode: DANE RFC7929/RFC8162 SHA2-256
- Added hash-mode: Dogechain.info Wallet
- Added hash-mode: Domain Cached Credentials 2 (DCC2), MS Cache 2, (NT)
- Added hash-mode: Domain Cached Credentials (DCC), MS Cache (NT)
- Added hash-mode: Empire CMS (Admin password)
- Added hash-mode: ENCsecurity Datavault (MD5/keychain)
- Added hash-mode: ENCsecurity Datavault (MD5/no keychain)
- Added hash-mode: ENCsecurity Datavault (PBKDF2/keychain)
- Added hash-mode: ENCsecurity Datavault (PBKDF2/no keychain)
- Added hash-mode: GPG (AES-128/AES-256 (SHA-256($pass)))
- Added hash-mode: GPG (AES-128/AES-256 (SHA-512($pass)))
- Added hash-mode: GPG (CAST5 (SHA-1($pass)))
- Added hash-mode: IPMI2 RAKP HMAC-MD5
- Added hash-mode: Kerberos 5, etype 17, AS-REP
- Added hash-mode: Kerberos 5, etype 18, AS-REP
- Added hash-mode: Kremlin Encrypt 3.0 w/NewDES
- Added hash-mode: mega.nz password-protected link (PBKDF2-HMAC-SHA512)
- Added hash-mode: MetaMask Mobile Wallet
- Added hash-mode: MetaMask Wallet (short hash, plaintext check)
- Added hash-mode: Microsoft Online Account (PBKDF2-HMAC-SHA256 + AES256)
- Added hash-mode: MS SNTP
- Added hash-mode: NetIQ SSPR (MD5)
- Added hash-mode: NetIQ SSPR (PBKDF2WithHmacSHA1)
- Added hash-mode: NetIQ SSPR (PBKDF2WithHmacSHA256)
- Added hash-mode: NetIQ SSPR (PBKDF2WithHmacSHA512)
- Added hash-mode: NetIQ SSPR (SHA1)
- Added hash-mode: NetIQ SSPR (SHA-1 with Salt)
- Added hash-mode: NetIQ SSPR (SHA-256 with Salt)
- Added hash-mode: NetIQ SSPR (SHA-512 with Salt)
- Added hash-mode: PDF 1.3 - 1.6 (Acrobat 4 - 8) w/ RC4-40
- Added hash-mode: Perl Mojolicious session cookie (HMAC-SHA256, >= v9.19)
- Added hash-mode: QNX 7 /etc/shadow (SHA512)
- Added hash-mode: RACF KDFAES
- Added hash-mode: RC4 104-bit DropN
- Added hash-mode: RC4 40-bit DropN
- Added hash-mode: RC4 72-bit DropN
- Added hash-mode: RSA Security Analytics / NetWitness (sha256)
- Added hash-mode: SecureCRT MasterPassphrase v2
- Added hash-mode: Veeam VBK
- Added hash-mode: WBB4 (Woltlab Burning Board) Plugin [bcrypt(bcrypt($pass))]
## Constructs
- Added hash-mode: bcrypt(sha256($pass)) / bcryptsha256
- Added hash-mode: bcrypt-sha256 v2 bcrypt(HMAC-SHA256($pass))
- Added hash-mode: md5($salt1.$pass.$salt2)
- Added hash-mode: md5($salt1.sha1($salt2.$pass))
- Added hash-mode: md5($salt1.strtoupper(md5($salt2.$pass)))
- Added hash-mode: md5($salt.md5($pass).$salt)
- Added hash-mode: md5(md5($pass.$salt))
- Added hash-mode: md5(md5($salt).md5(md5($pass)))
- Added hash-mode: md5(md5(md5($pass)).$salt)
- Added hash-mode: md5(md5(md5($pass).$salt1).$salt2)
- Added hash-mode: md5(md5(md5($pass.$salt1)).$salt2)
- Added hash-mode: md5(sha1($pass.$salt))
- Added hash-mode: md5(sha1($salt.$pass))
- Added hash-mode: md5(sha1(md5($pass)))
- Added hash-mode: sha256(sha256($pass.$salt))
- Added hash-mode: sha512(sha512($pass).$salt)
- Added hash-mode: sha512(sha512_bin($pass).$salt)
## Backends
- New: HIP (an OpenCL alternative for AMD on both Linux and Windows)
- New: Metal (an OpenCL alternative on macOS, supporting both ARM and x64)
- New: Microsoft OpenCL D3D12 platform
- Improved handling of devices with unified memory (iGPU, APU, etc.)
- Switched all asynchronous and non-blocking calls to synchronous and blocking ones. This prevents race conditions, such as the one fixed in the previous commit, without any performance impact.
- Revisited the Apple OpenCL 2 GiB bug (still present)
- Added support for longer OpenCL device names
- New: Hardware Monitor support for AMD GPUs via sysfs (Linux)
- New: Hardware Monitor support for CPUs via sysfs (Linux)
- New: Hardware Monitor support for Intel GPUs via sysfs (Linux)
##
## Features
##
## Assimilation Bridge
- Added Assimilation Bridge (See forum post or added documentation for more details)
- Virtual Devices
- Embedded Python interpreter
- Comprehensive documentation
## Docker Support
- Add Dockerfiles for binary compilation
- Compiles both Linux and Windows binaries
- Used to produce official releases for hashcat.net
- Includes Dockerfiles for Ubuntu 20.04 and Arch-based environments
- Supports optional user patches via docker/patches/
## User Features
- Increased custom charset count from 4 to 8
- Added XML support for KeePass keyfiles
- Added true UTF-8 password support for RAR3
- Added JSON format support for backend-info, hash-info, status-screen, progress-info, speed-info, and outfiles
- Added --increment-inverse option
- Added new charset files: Romanian, Russian
- Added support for using --debug-mode in attack-mode 9 (Association Attack)
- Added display of password length mininum and maximum in the Kernel.Feature status line
- Added new feature (-Y) that creates N virtual instances for each device in your system at the cost of N times the device memory consumption
- Added new feature (--bypass-delay / --bypass-threshold) that skips an attack if it does not produce enough cracks per $timeframe
- Added options --benchmark-min and --benchmark-max to set a hash-mode range to be used during the benchmark
- Added option --total-candidates to provide the total candidate count for an attack instead of the internal "--keyspace" value
- Added option --backend-devices-keepfree to configure X percentage of device memory available to keep free
- Added options --benchmark-min and --benchmark-max to set a hash-mode range to be used during the benchmark
- Added the 'edge' test type to test.pl and the corresponding tool test_edge.sh
## Developer Features
- Added support to the tokenizer for multiple signatures per hash mode
- Added option OPTS_TYPE_THREAD_MULTI_DISABLE: allows plugin developers to disable scaling the candidate batch size based on device thread count. Useful for very slow algorithms that parallelize differently
- Added options OPTI_TYPE_SLOW_HASH_DIMY_INIT/LOOP/COMP: enables 2D kernel launches for slow hashes. Y dimension must be set via salt->salt_dimy
- Removed deprecated attribute: OPTS_TYPE_MAXIMUM_ACCEL
- Added KERNEL_FA: a new kernel macro to inform the JIT compiler of thread limits for thread-optimized kernels
- Introduced hashes_init_stage5(), which now calls module_extra_tmp_size(). Self-test hash is fully initialized at this stage
- Improved kernel compiler behavior using hints for register spilling, max threads, and warnings for excessive thread counts
- Improved mapping of functions like hc_bytealign_be(), hc_swap32(), etc., using intrinsics or inline assembly to match hardware capabilities
- Re-enabled USE_BITSELECT, USE_ROTATE, and USE_SWIZZLE for OpenCL
- Improved get_opencl_kernel_wgs() to better derive base values from compute runtimes before autotuning
- Removed --device-as-default-execution-space from nvrtc for hiprtc compatibility. Re-added __device__ to DECLSPEC
- Added support for funnelshift and warp shuffle instructions, including runtime detection and kernel disabling if unsupported
- Added autotune attribute "overtune_unfriendly": allows overtuning thread count under specific conditions
- Added next_power_of_two() and moved both next_power_of_two() and previous_power_of_two() into shared utilities
- Removed default 'rocm-smi' call from benchmark_deep.pl to prevent skewed results
- Reduced default runtime in benchmark_deep.pl due to improved benchmark accuracy
- Redesigned "4-buffer" strategy to prevent excessive memory use from naive division by four, especially in high scrypt configs (e.g., 256k:8:1)
- Added CPU SIMD detection at runtime, relevant for bridge plugins
- Status Code: added specific return code for self-test failure (-11)
- Prepared an enum type to represent final return codes
- Added hcmalloc_aligned() and hcfree_aligned()
## Test framework
- Added new offline testing framework (Test-Edge)
- Added GitHub Actions support for automated build scripts
- Completed large-scale test runs with rarely used combinations (e.g., attack-mode 1 with vector size 16 in ChaCha20)
- Fully reworked install_modules.sh script to automate installation of required Perl and Python modules for the test framework
- Removed many outdated and unstable warnings from existing plugins
- Created repositories to maintain discontinued Perl modules used in the testing framework
- Improved unit test for -m 8300: optimized mode now supports longer passwords, domain names, and salts; both modes enforce a domain name limit of 63 characters
- Fixed SNMPv3 unit test to ensure passwords are at least 8 characters, as required by RFC 3414
- Removed PHP from unit tests entirely
- Added workaround for Net::SSLeay on Apple
- Removed Crypt::GCrypt from the test suite
- Updated install_modules.sh to use cpanm instead of cpan
- Fixed invalid module_constraints for hash-modes 15000, 11100, 10100, 8700, 7801, 7800, 20712, 14400, 21100, 400, and 3100
## Extraction tools
- Added: apfs2hashcat.py
- Added: bisq2hashcat.py
- Added: bitlocker2hashcat.py
- Added: bitwarden2hashcat.py
- Added: cache2data2hashcat.py
- Added: cryptoloop2hashcat.py
- Added: exodus2hashcat.py
- Added: gitea2hashcat.py
- Added: keybag2hashcat.py
- Added: kremlin2hashcat.py
- Added: lastpass2hashcat.py
- Added: luks2hashcat.py
- Added: metamask2hashcat.py
- Added: radmin3_to_hashcat.pl
- Added: shiro1-to-hashcat.py
- Added: truecrypt2hashcat.py
- Added: veeamvbk2hashcat.py
- Added: veracrypt2hashcat.py
- Added: virtualbox2hashcat.py
- Added: vmwarevmx2hashcat.py
- Promoted extraction tools to be installed alongside hashcat when installing system-wide
##
## Improvements
##
## Feature Improvements
- Refactored internal code for Hardware Monitor
- Improved accuracy of benchmark mode (-b)
- Gracefully handle corrupted .gz archives
- Changed benchmark mask to prevent failures during UTF-8 to UTF-16 conversion
- Implemented missing XZ file seeking functionality
- Added workaround to eliminate internal runtime memory leaks
## Rule Engine Improvements
- Added support for character class rules
- Improved many existing rules by removing duplicates and adding new operators, including character class support
- Fixed existing rules to work correctly with the new Purge (@) rule handling
- Updated -j / -k validation to check for ':' instead of NULL
- Optimized the following rule files: generated.rule, generated2.rule, dive.rule, T0XlCv2.rule, T0XlC-insert_00-99_1950-2050_toprules_0_F.rule, T0XlC-insert_space_and_special_0_F.rule, d3ad0ne.rule
- Added new rule files: T0XlC_3_rule.rule, T0XlC_insert_HTML_entities_0_Z.rule, T0XlCv2.rule, stacking58.rule, top10_2025.rule
## Existing Plugin and Crypto Library Improvements
- Improved ASN.1 checks for RSA/DSA/EC/OpenSSH private key modules (22911, 22921, 22931, 22941, 22951)
- AuthMe: updated token length
- VeraCrypt and TrueCrypt: general code cleanup with backported fixes and improvements across both legacy and new modes
- Bitwarden: increased iteration limit
- NSEC3: added support for salt length up to the standard limit; updated max domain and salt lengths in pure kernel to 256
- GOST R 34.11-94: fixed false negative in optimized mode in attack mode 3 for passwords of length 16 or 32
- Fixed hash encoding issue in WinZip format
- Renamed multiple CAST cipher defines to match C++ language naming conventions
- Recommended using --keep-guessing for -m 20510
- Fixed false positive and false negative in -m 21800 multihash mode, where only the first hash was marked as cracked regardless of which was actually cracked (affected only beta versions)
- Fixed encoder bugs in hash-modes 29920 and 29940, where the output string was not properly terminated
- Electrum: added support to detect more private key prefixes
- Metamask: added support for dynamic iteration counts
- TOTP: added support for multiple codes
- Blake2: removed redundant casts and corrected parameter types for FINAL value
- VeraCrypt: set minimum loop count to 250 for all modes with PIM brute-force support
- Fixed thread count issue in -m 10700 on NVIDIA OpenCL (4 bytes were lost per thread for unknown reasons)
- Fixed missing entries in switch_buffer_by_offset_8x4_le_S()
- Applied OPTS_TYPE_NATIVE_THREADS tuning to many hash modes after benchmarking: 770x, 780x, 8900, 9000, 9300, 14000, 14900, 15700, 22700, 2300x, 23900, 24000, 25000, 25100, 25200, 26700, 26800, 26900, 27300, 27700, 28200, 29800, 70000, 70100, 70200, 72000, 73000
- Applied OPTI_TYPE_REGISTER_LIMIT tuning to many hash modes after benchmarking: 20, 1300, 1500, 1800, 6400, 6800, 7700, 7900, 8200, 8300, 10700, 12400, 1375x, 1376x, 14800, 14900, 15600, 16300, 16600, 16700, 16900, 18100, 20800, 21300, 21500, 21700, 22300, 2292x, 2294x, 23400, 23600, 23800, 24200, 24420, 25500, 25900, 26000, 26100, 26600, 26700, 26800, 26900, 27300, 27400, 27500, 27600, 2945x, 2946x
- Improved shared memory handling in -m 10700: removed the 256-thread hard limit and now adapt based on device memory pool
- Check UnpackSize to reduce false positives in hc_decompress_rar
- Added support for zero-length salts in Electrum $4 and $5 formats
- Switched Metamask hashmodes to use TOKEN_ATTR_OPTIONAL_ROUNDS
- Added new hashmodes 26620 and 26630 with dynamic iteration counts
- Added new function count_bits_32() in inc_common.cl
- Simplified module_hash_decode() in -m 32700
- Removed OPTS_TYPE_HASH_COPY from -m 19210
- Fixed missing AES_GCM_decrypt implementation in inc_cipher_aes-gcm.cl
- Optimized same-salt cracking in -m 7400 and -m 500 by marking them as compatible with OPTS_TYPE_DEEP_COMP_KERNEL
- Reduced false positive reports in -m 21800
- WPA: allow users to override nonce_error_corrections even if message_pair suggests otherwise
- Updated Flask session payload max length to 2047
- Added IV support to LastPass hash-mode (-m 6800)
- VeraCrypt: added support for keyfiles and keyfile cascades
## User Interaction Improvements
- Added additional backend information with the new -II parameter
- Set --benchmark to true automatically when --benchmark-all is used
- Improved error message when using --skip/--limit with an invalid attack configuration
- Display the number of base words hashcat expects
- Improved error messages for module_ctx_t validation failures, especially when outdated plugin interfaces are detected
- Added a warning when the user sets a thread count higher than what the runtime recommends (based on available registers and shared memory)
- Silenced selected warning lines when using --quiet
- Added immediate check for --outfile-check-timer