CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/data/jtr/john.conf
Views: 11766
1
#
2
# This file is part of John the Ripper password cracker,
3
# Copyright (c) 1996-2006,2008-2013,2019 by Solar Designer
4
#
5
# Redistribution and use in source and binary forms, with or without
6
# modification, are permitted.
7
#
8
# There's ABSOLUTELY NO WARRANTY, express or implied.
9
#
10
# Please note that although this configuration file is under the cut-down BSD
11
# license above, many source files in John the Ripper are under GPLv2.
12
# For licensing terms for John the Ripper as a whole, see doc/LICENSE.
13
#
14
# ...with changes in the jumbo patch, by various authors
15
#
16
17
# The [Options] section is for general options only.
18
# Note that MPI specific options have been moved
19
# to [Options.MPI]
20
# There is also a new section [Options.OpenCL]
21
# for OpenCL specific options
22
# Default settings for Markov mode have been moved
23
# to [Markov.Default], but you can define other
24
# Markov modes as well, see ../doc/MARKOV
25
[Options]
26
# Default wordlist file name (including in batch mode)
27
Wordlist = $JOHN/password.lst
28
# Use idle cycles only
29
Idle = Y
30
# Crash recovery file saving delay in seconds
31
Save = 60
32
# Beep when a password is found (who needs this anyway?)
33
Beep = N
34
# if set to Y then dynamic format will always work with bare hashes. Normally
35
# dynamic only uses bare hashes if a single dynamic type is selected with
36
# the -format= (so -format=dynamic_0 would use valid bare hashes).
37
DynamicAlwaysUseBareHashes = N
38
39
# Default Single mode rules
40
SingleRules = Single
41
42
# Default batch mode Wordlist rules
43
BatchModeWordlistRules = Wordlist
44
45
# Default wordlist mode rules when not in batch mode (if any). If this is
46
# changed from an 'empty list' to have default rules applied, and you later
47
# DO want to perform a run once without rules, use --rules:none on the
48
# command line. The default is 'empty' or NO rules run at all.
49
WordlistRules =
50
51
# Default loopback mode rules (if any)
52
# If this is set and you want to run once without rules, use --rules:none
53
LoopbackRules = Loopback
54
55
# Max. number of times to warn about crypting suboptimally small batches,
56
# before suppressing the warnings.
57
MaxKPCWarnings = 10
58
59
# Default/batch mode Incremental mode
60
# Warning: changing these might currently break resume on existing sessions
61
# one option frequently changed (with above caveat) is setting DefaultIncrementalUTF8 = UTF8
62
DefaultIncremental = ASCII
63
DefaultIncrementalUTF8 = ASCII
64
DefaultIncrementalLM = LM_ASCII
65
66
# Time formatting string used in status ETA.
67
#
68
# TimeFormat24 is used when ETA is within 24h, so it is possible to omit
69
# the date then if you like, and show seconds instead.
70
#
71
# %c means 'local' specific canonical form, such as:
72
# 05/06/11 18:10:34
73
#
74
# Other examples
75
# %d/%m/%y %H:%M (day/mon/year hour:min)
76
# %m/%d/%y %H:%M (mon/day/year hour:min)
77
# %Y-%m-%d %H:%M (ISO 8601 style, 2011-05-06 18:10)
78
TimeFormat = %Y-%m-%d %H:%M
79
TimeFormat24 = %H:%M:%S
80
81
#
82
# optional add a date timestamp in front of every logged line.
83
# the default is no timestamp logging. See the docs for
84
# strftime for more information:
85
# http://en.cppreference.com/w/c/chrono/strftime
86
#
87
# examples:
88
# 2016-02-20T22:35:38+01:00 would be %Y-%m-%dT%H:%M:%S%z
89
# Feb 20 22:35:38 would be %b %d %H:%M:%S
90
LogDateFormat =
91
92
# if log date is being used, the time will default to local
93
# time. But if the next line is changed to 'Y', date output
94
# in UTC. Note, if LogDateFormat is not set, this option
95
# is ignored.
96
LogDateFormatUTC = N
97
98
# if logging to stderr (--log-stderr command line switch used),
99
# then use date format when outputting to the stderr.
100
#
101
# example
102
# Feb 20 22:35:38 would be %b %d %H:%M:%S
103
LogDateStderrFormat =
104
105
# If this is given, it will be printed in the end on any cracked password
106
# output. In case some 8-bit passwords upset your terminal, putting an
107
# ANSI "SGR Reset/Normal" here might be a cure. Any "^" characters will be
108
# parsed as ESC for use in ANSI codes (like in the default)
109
TerminalReset = ^[0m
110
111
# This can be used to colorize (on screen) or otherwise emphasize (in log
112
# files) output whenever a supposed administrator password gets cracked.
113
#
114
# Set this to N or comment it out to disable all "MarkAdmin" stuff.
115
MarkAdminCracks = Y
116
117
# If MarkAdminCracks = Y above, the below will be used (if defined) for
118
# terminal output. The default is to change color to red before the username
119
# and reset to normal after it. Any "^" characters will be parsed as ESC for
120
# use in ANSI codes (like in the defaults).
121
# The "MarkOther" entries will make non-admin stuff brown.
122
MarkAdminStart = ^[0;31m
123
MarkAdminEnd = ^[0m
124
MarkOtherStart = ^[0;33m
125
MarkOtherEnd = ^[0m
126
127
# If MarkAdminCracks = Y above, the below will be used (if defined) for logs.
128
# This literal string will be printed after the " + Cracked: root" line.
129
MarkAdminString = (ADMIN ACCOUNT)
130
131
# Permissions to set for session.log file
132
# Default is 0600
133
LogFilePermissions = 0600
134
135
# Permissions to set for POT file
136
# Default is 0600
137
PotFilePermissions = 0600
138
139
# John exits if another user owns log or pot file because CHMOD fails,
140
# If this is set John prints a warning and continues
141
# Default is N
142
IgnoreChmodErrors = N
143
144
# This figure is in MiB. The default is to memory map wordlists not larger
145
# than one GiB.
146
# Set this to 0 to disable any use of memory-mapping in wordlist mode.
147
WordlistMemoryMapMaxSize = 1024
148
149
# For single mode, load the full GECOS field (before splitting) as one
150
# additional candidate. Normal behavior is to only load individual words
151
# from that field. Enabling this can help when this field contains email
152
# addresses or other strings that are better used unsplit, but it increases
153
# the number of words tried so it may also slow things down.
154
PristineGecos = N
155
156
# Add an extra pass when loading Single words, that tries to parse things
157
# like JEdgarHoover to J Edgar Hoover and so on.
158
JumboSingleWords = N
159
160
# For single mode, ignore the login field.
161
# Normal behavior is to use the login field for single mode.
162
# Skipping the login field should only be enabled if previous single mode
163
# sessions did already make use of the login field, but no other information,
164
# and now you want to use other information, skip the login field, but still
165
# want the login field to be reported on successful cracks or with --show.
166
SingleSkipLogin = N
167
168
# Over-ride SINGLE_WORDS_PAIR_MAX in params.h. This may slow down Single mode
169
# but it may also help cracking a few more candidates. Default in core John
170
# is 4 while the Jumbo default is 6. This limit is automagically increased
171
# by word seed options --single-seed and/or --single-wordlist if needed.
172
SingleWordsPairMax = 6
173
174
# Setting this to false stops Single mode from re-testing guessed plaintexts
175
# with all other salts. This is deprecated: Use command-line per-session
176
# option --single-retest-guess=no instead.
177
SingleRetestGuessed = Y
178
179
# Max recursion depth for SingleRetestGuessed, so we don't blow the stack
180
SingleMaxRecursionDepth = 10000
181
182
# Set the maximum word buffer size used by Single mode. The default is
183
# 4 GB. Note that you may want to set SingleMaxBufferAvailMem (below) to
184
# true instead.
185
#
186
# If this figure is explicitly set to zero, and SingleMaxBufferAvailMem
187
# is false, there will be NO LIMIT!
188
SingleMaxBufferSize = 4
189
190
# If true, the actual amount of physical memory at runtime, if known, will
191
# override the figure from SingleMaxBufferSize (may increase or decrease!).
192
SingleMaxBufferAvailMem = N
193
194
# When running single mode with a GPU or accelerator, we prioritize speed
195
# (saturating buffers) over resume ability: When resuming such a session
196
# it may take longer to catch up. Set this option to Y to prioritize
197
# resuming instead, at the cost of max. speed.
198
SinglePrioResume = N
199
200
# Protect the restore files (*.rec) from being overwritten. The default
201
# mode is "Disabled". This mode will provide no protection, but has been
202
# the default mode in JtR forever, so to not change behavior, that mode
203
# has been kept as default. You can change this to "Named" or "Always"
204
# If this option is changed to "Named", then any restore file created
205
# with a --session=xxxx will be protected from being overwritten. If
206
# the option is set to "Always", then all .rec files will be kept from
207
# being overwritten, even ${JOHN}/john.rec file
208
SessionFileProtect = Disabled
209
210
# Protect the log files (*.log) from being reused by new sessons.
211
# The default mode is "Disabled". That means, a nee session will just append
212
# to an existing log file.
213
# With "Named", a new session will not be allowed to append to an existing
214
# log file, except if the --session=NAME option hasn't been used.
215
# With "Always", not even the default log file ${JOHN}/john.log can be
216
# reused by a new session.
217
# (Of course, a restored session will always be allowed to append to an
218
# existing log file.)
219
# Unless you use the --no-log option, setting LogFileProtect will also
220
# prevent overwriting existing session files.
221
LogFileProtect = Disabled
222
223
# Emit a status line whenever a password is cracked (this is the same as
224
# passing the --crack-status option flag to john). NOTE: if this is set
225
# to true here, --crack-status will toggle it back to false.
226
CrackStatus = N
227
228
# When printing status, show number of candidates tried (eg. 123456p).
229
# This is added to the "+ Cracked" line in the log as well (and that figure
230
# will be exact while the screen output will be a multiple of batch size).
231
StatusShowCandidates = N
232
233
# Show updated "Remaining" counts when we got rid of any salt(s).
234
ShowSaltProgress = N
235
236
# Show updated "Remaining" counts on status output (if it changed).
237
ShowRemainOnStatus = N
238
239
# Write cracked passwords to the log file (default is just the user name)
240
LogCrackedPasswords = N
241
242
# Disable the dupe checking when loading hashes. For testing purposes only!
243
# This is deprecated: Use per-session option --loader-dupecheck=no instead.
244
NoLoaderDupeCheck = N
245
246
# Default encoding for input files (ie. login/GECOS fields) and wordlists
247
# etc. If this is not set here and --encoding is not used either, the default
248
# is ISO-8859-1 for Unicode conversions and 7-bit ASCII encoding is assumed
249
# for rules, e.g., uppercasing of letters other than a-z will not work at all!
250
DefaultEncoding = UTF-8
251
252
# Default --target-encoding for Microsoft hashes (LM, NETLM et al) when input
253
# encoding is UTF-8. CP850 would be a universal choice for covering most
254
# "Latin-1" countries.
255
DefaultMSCodepage = CP850
256
257
# Default internal legacy codepage to be used by mask mode and within the
258
# rules engine, when both input and target encodings are Unicode (eg. UTF-8
259
# wordlist and NT hashes). In some cases this hits performance but lets us
260
# do things like Unicode case conversions. You can pick any supported
261
# legacy codepage that has as much support for the input data as possible,
262
# e.g., for "Latin-1" language passwords you can use ISO-8859-1, CP850 or
263
# CP1252 and it will hardly make any difference but in some cases, ISO-8859-1
264
# is fastest. Using "UTF-8" (which is not a legacy codepage!) will disable.
265
#
266
# The default is to NOT use any internal codepage.
267
DefaultInternalCodepage =
268
269
# Warn if seeing UTF-8 when expecting some other encoding, or vice versa.
270
# This is disabled for ASCII or RAW encodings, for performance.
271
WarnEncoding = Y
272
273
# Always report (to screen and log) cracked passwords as UTF-8, regardless of
274
# input encoding. This is recommended if you have your terminal set for UTF-8.
275
AlwaysReportUTF8 = Y
276
277
# Always store Unicode (UTF-16) passwords as UTF-8 in john.pot, regardless
278
# of input encoding. This prevents john.pot from being filled with mixed
279
# and eventually unknown encodings. This is recommended if you have your
280
# terminal set for UTF-8 and/or you want to run --loopback for LM->NT
281
# including non-ASCII.
282
UnicodeStoreUTF8 = Y
283
284
# Always report/store non-Unicode formats as UTF-8, regardless of input
285
# encoding. Note: The actual codepage that was used is not stored anywhere
286
# except in the log file.
287
# This is needed e.g. for --loopback to crack LM->NT including non-ASCII.
288
CPstoreUTF8 = Y
289
290
# Normally, we try to handle Unicode characters not in our selected codepage
291
# with best effort. Enabling this option will instead translate any such
292
# character to "?" (default), to meet certain formats' behavior.
293
EmulateBrokenEncoding = N
294
ReplacementCharacter = ?
295
296
# Default verbosity is 3, valid figures are 1-5 right now.
297
# 4-5 enables some extra output and diagnostics.
298
# 4 is same verbosity as "john proper" aka. non-jumbo.
299
# 3 mutes rules & incremental output in logs (LOTS of lines).
300
# 2 mutes some other diagnostics.
301
# 1 even mutes printing (to screen) of cracked passwords.
302
Verbosity = 3
303
304
# If set to Y, do not output, log or store cracked passwords verbatim.
305
# This implies a different default .pot database file "secure.pot" instead
306
# of "john.pot" but it can still be overridden using --pot=FILE.
307
# This also overrides other options, e.g. LogCrackedPasswords.
308
SecureMode = N
309
310
# If set to Y, a session using --fork or MPI will signal to other nodes when
311
# it has written cracks to the pot file, so they will re-sync. Note that this
312
# may be delayed by buffers and the "Save" timer setting near top of this file.
313
ReloadAtCrack = N
314
315
# If set to Y, a session using --fork or MPI will signal to other nodes when
316
# it has cracked all hashes (there's nothing more to do!). This is ignored
317
# when ReloadAtCrack = Y because it's redundant.
318
ReloadAtDone = Y
319
320
# If set to Y, resync pot file when saving session. This does not involve any
321
# signalling, we just detect that someone else wrote to the pot file.
322
# This will sync with concurrent sessions even when not using --fork or MPI
323
# but it may be delayed by the "Save" timer setting near top of this file.
324
ReloadAtSave = Y
325
326
# If this file exists, john will abort cleanly (uncomment to enable)
327
#AbortFile = /var/run/john/abort
328
329
# While this file exists, john will pause (uncomment to enable)
330
#PauseFile = /var/run/john/pause
331
332
# If set to true, the uid will be appended to user name on cracks
333
# With: password123 (Administrator:500)
334
# Without password123 (Administrator)
335
# This is disabled by --save-memory.
336
# NOTE: For WPAPSK, this will actually show gid instead, which is the MAC
337
# address of the access point.
338
ShowUIDinCracks = N
339
340
# This sets the "grace time" for --max-run-time=N. If john has not finished
341
# this long after the initial abort signal, it will send another one (similar
342
# to pressing ctrl-c a second time) which will stop john immediately and not
343
# wait further for an optimal resume point.
344
# Setting this to 0 means NO grace time - immediately abort. Setting it to
345
# a negative number means UNLIMITED grace time - never hard abort.
346
AbortGraceTime = 30
347
348
# Setting this to true allows SAP-B and SAP-G "half hashes" to be cracked.
349
# These are taken from RFC_READ_TABLE and padded with nulls to correct length.
350
# This may produce some false positives if enabled, at least for SAP-B.
351
SAPhalfHashes = N
352
353
[Options:CPUtune]
354
# If preset is given, use it and skip autotune (NOTE: non-intel archs will
355
# currently ignore this option and always autotune)
356
UsePreset = Y
357
# Performance sample time, default 10 ms
358
AutoTuneSampleTime = 10
359
# Required gain to consider this scale better. Default is 1 %
360
AutoTuneReqGain = 1
361
# Max crypt_all() duration for trying a higher scale, default 100 ms
362
AutoTuneMaxDuration = 100
363
# If we tried this many increases of scale w/o gain, give up. Default 3.
364
AutoTuneMaxNoProgress = 3
365
366
[Options:MPI]
367
# Automagically disable OMP if MPI is used (set to N if
368
# you want to run one MPI process per multi-core host)
369
MPIOMPmutex = Y
370
371
# Print a notice if disabling OMP (when MPIOMPmutex = Y)
372
# or when running OMP and MPI at the same time
373
MPIOMPverbose = Y
374
375
# Assume all MPI nodes are homogenous; Enforce same OpenCL workgroup sizes.
376
MPIAllGPUsSame = N
377
378
# Options that may affect both GPUs and other accelerators (eg. FPGA)
379
[Options:GPU]
380
# Show GPU temperature, fan and utilization along with normal status output
381
SensorsStatus = Y
382
383
# If SensorsStatus is true, individual ones can be turned off
384
TempStatus = Y
385
UtilStatus = N
386
FanStatus = N
387
388
# Abort the process or sleep for a while if a GPU hits this temperature (in C)
389
AbortTemperature = 95
390
391
# Instead of aborting, sleep for this many seconds to cool the GPU down when
392
# the temperature hits the AbortTemperature value, then re-test the temperature
393
# and either wake up or go to sleep again. Set this to 0 to actually abort.
394
# Suppress repeated sleep/wakeup messages when SleepOnTemperature = 1, which we
395
# interpret as intent to keep the GPU temperature around the limit.
396
SleepOnTemperature = 1
397
398
[Options:OpenCL]
399
# Set default OpenCL device(s). Command line option will override this.
400
# If not set, we will search for a GPU or fall-back to the most
401
# powerful device. Syntax is same as --device option.
402
Device =
403
404
# *Always* show local/global work sizes (LWS/GWS). This is mostly for
405
# debugging, we try to show them when reasonable.
406
AlwaysShowWorksizes = N
407
408
# If set to true, store LWS and GWS in session file for later resume.
409
# Note that when resuming, this option is ignored: If the session file
410
# was written with this option set, it will still be used.
411
ResumeWS = N
412
413
# Global max. single kernel invocation duration, in ms. Setting this low
414
# (eg. 10-100 ms) gives you a better responding desktop but lower performance.
415
# Setting it high (eg. 200-500 ms) will maximize performance but your desktop
416
# may lag. Really high values may trip watchdogs (eg. 5 seconds). Some versions
417
# of AMD Catalyst may hang if you go above 200 ms, and in general any good
418
# kernel will perform optimally at 100-200 ms anyway.
419
Global_MaxDuration =
420
421
# Some formats vectorize their kernels in case the device says it's a good
422
# idea. Some devices give "improper" hints which means we vectorize but get
423
# a performance drop. If you have such a device, uncommenting the below
424
# will disable vectorizing globally.
425
# With this set to N (or commented out) you can force it per session with
426
# the --force-scalar command-line option instead.
427
ForceScalar = N
428
429
# Global build options. Format-specific build options below may be
430
# concatenated to this.
431
GlobalBuildOpts = -cl-mad-enable
432
433
# Initial local work-size for auto-tune (CPU devices excepted).
434
# 0 means let the OpenCL implementation pick a suitable value.
435
# 1 means query for "best multiple" (usually corresponds to "warp size").
436
# Any other value (eg. 64) will be taken verbatim.
437
AutotuneLWS = 1
438
439
# Format-specific settings:
440
441
# Uncomment the below for nvidia sm_30 and beyond.
442
# Please, check if it is really better.
443
#sha512crypt_BuildOpts = -cl-nv-maxrregcount=80
444
445
# Best configuration value to be used at runtime.
446
sha512crypt_Bonaire = -DUNROLL_LOOP=132104
447
448
# Example: Override auto-tune for RAR format.
449
#rar_LWS = 128
450
#rar_GWS = 8192
451
452
[List.OpenCL:Drivers]
453
#Driver ; Description ; Recommendation
454
#AMD driver versions
455
938 , 2 ; 12.8 ;
456
1084, 4 ; 13.1 ;
457
1124, 2 ; 13.4 ;
458
1214, 3 ; 13.6 beta ;
459
1311, 2 ; 13.11 beta-1 ;
460
1348, 5 ; 13.12 ;
461
1445, 5 ; 14.4 (Mantle) ;
462
1526, 3 ; 14.6 beta (Mantle) ;
463
1573, 4 ; 14.9 (Mantle) ; VGL S
464
1642, 5 ; 14.12 (Omega) ; VGL S
465
1702, 3 ; 15.5 beta ; T
466
1729, 3 ; 15.5 ;
467
1800, 5 ; 15.7 ; VG* R
468
1800, 8 ; 15.7.1 ; VGW R
469
1800, 11; 15.9 ; VGL S
470
1912, 5 ; 15.12 ;
471
#NVIDIA driver versions
472
346, 0 ; ; N* R
473
319, 0 ; ; N* S
474
#End
475
0, 0 ; ;
476
477
#Labels
478
# * -> all OS
479
# N -> NVIDIA
480
# G -> GCN
481
# V -> VLIW4 and VLIW5
482
# W -> Windows
483
# L -> Linux
484
# R -> recommended
485
# S -> supported
486
# T -> not recommended: really bad software. I mean "trash".
487
488
# ZTEX specific settings
489
[List.ZTEX:Devices]
490
# If you list Serial Numbers (SN) of ZTEX boards here, it will display
491
# numbers (starting from 1) instead of factory programmed SN's.
492
# These numbers can be used in --dev command-line option.
493
#04A36E0000
494
#04A36D0000
495
496
[ZTEX:descrypt]
497
# The design has programmable clock. Design tools reported possible
498
# frequency to be 221 MHz. Tested boards work reliably at 190.
499
Frequency = 190
500
501
[ZTEX:bcrypt]
502
# Define typical setting of hashes it's going to process. It allows
503
# to adjust for best performance.
504
TargetSetting = 5
505
# Design tools reported possible frequency to be 141.5 MHz.
506
# Tested boards work reliably at 150, so that's what we use by default.
507
Frequency = 150
508
# For any algorithm it's possible to set frequency on per-board and
509
# per-FPGA basis, but the lowest frequency will determine performance.
510
#Frequency_04A36E0FD6 = 142
511
#Frequency_04A36E0FD6_1 = 143
512
#Frequency_04A36E0FD6_4 = 144
513
514
[ZTEX:sha512crypt]
515
#TargetRounds = 5000
516
# Design tools reported possible frequency to be 215 MHz.
517
# We never encountered a board where this worked anywhere close
518
# to such high frequency. Default frequency is set to 160 MHz.
519
# Some lucky boards might run at some higher frequency.
520
Frequency = 160
521
#Config1 = \x00\x00
522
523
[ZTEX:Drupal7]
524
#TargetRounds = 16384
525
# Drupal7 uses same bitstream as sha512crypt, see comment regarding
526
# default frequency in sha512crypt section.
527
#Frequency = 160
528
# Some bitstreams accept runtime configuration.
529
# In sha512crypt/Drupal7, configuration is 2 bytes. That's interpreted
530
# as a bitmask. By setting any of the lowest 12 bits to 1 it turns off
531
# the corresponding unit (there are 12 units in the bitstream).
532
# This turns off units 0 and 1.
533
#Config1 = \x03\x00
534
# This turns off all 12 units (resulting in a timeout).
535
#Config1_04A36E0FD6_0 = \xff\x0f
536
537
[ZTEX:sha256crypt]
538
# Design tools reported possible frequency is 241 MHz but tested boards
539
# miss guesses, often fail unless frequency is decreased.
540
# Tested boards work reliably at 175.
541
Frequency = 175
542
#TargetRounds = 500000
543
544
# md5crypt and phpass use same bitstream. Design tools reported
545
# possible frequency is 202 MHz. Tested boards run OK at 180 MHz.
546
[ZTEX:md5crypt]
547
Frequency = 180
548
549
[ZTEX:phpass]
550
Frequency = 180
551
#TargetRounds = 2048
552
553
# These formats are disabled from listing or self-test/benchmark unless
554
# specifically requested. You can use them as long as you add them out with
555
# the --format option. Or you can delete a line, comment it out, or change
556
# to 'N' and the format will be enabled again.
557
[Disabled:Formats]
558
#formatname = Y
559
.include '$JOHN/dynamic_disabled.conf'
560
561
[Formats:7z]
562
# With this enabled, the 7z formats check padding after AES decryption which
563
# more or less guarantees we don't get any false positives, and also makes
564
# the formats faster (in some cases a LOT faster). We've had one (1) report
565
# of getting a false negative having this enabled though, so if you fail to
566
# crack some archive you may want to disable this and re-try all attacks.
567
TrustPadding = Y
568
569
# This allows you to list a few words/names that will be used by single mode
570
# as if they were included in every GECOS field. Use sparingly! Please note
571
# that the example words are commented out, so the list is empty!
572
[List.Single:SeedWords]
573
#Pass
574
#Secret
575
#Test
576
577
# This allows you to read extra pot files when loading hashes. Nothing will
578
# ever be written to these files, they are just read. Any directory in this
579
# list will be traversed and files in it with an extension of .pot will be
580
# read. However there will NOT be any recursion down further directory levels.
581
# Any entries that don't exist will be silently ignored.
582
[List.Extra:Potfiles]
583
#somefile.pot
584
#somedirectory
585
#$JOHN/my.pot
586
587
[Debug]
588
# Changing this to Yes will enable legacy-style benchmarks, for comparisons
589
Benchmarks_1_8 = N
590
# Changing this to Yes will test salted formats as one/many salts, for debug
591
BenchmarkMany = N
592
593
[PRINCE]
594
# Default wordlist file name. Will fall back to standard wordlist if not
595
# defined.
596
Wordlist =
597
598
# Markov modes, see ../doc/MARKOV for more information
599
[Markov:Default]
600
# Default Markov mode settings
601
#
602
# Statsfile cannot be specified on the command line, so
603
# specifying it here is mandatory
604
Statsfile = $JOHN/stats
605
# MkvLvl and MkvMaxLen should also be specified here, as a fallback for
606
# --markov usage without specifying LEVEL and/or --max-length on the
607
# command line.
608
MkvLvl = 200
609
MkvMaxLen = 12
610
# MkvMinLvl and MkvMinLen should not be specified at all in [Markov:Default],
611
# or they should be equal to 0 (which is the default if not specified.
612
# MkvMinLvl and MkvMinLen can be used in other Markov mode sections
613
# except [Markov:Default]
614
; MkvMinLvl = 0
615
; MkvMinLen = 0
616
617
# A user defined character class is named with a single digit, ie. 0..9. After
618
# the equal-sign, just list all characters that this class should match. You
619
# can specify ranges within brackets, much like pre-processor ranges in rules.
620
# BEWARE of encoding if using non-ASCII characters. If you put UTF-8 characters
621
# here, it will *not* work! You must use a singlebyte encoding and it should
622
# be the same here as you intend to use for your dictionary.
623
# You can however put characters here in \xA3 format (for codepoint 0xA3 - in
624
# many iso-8859 codepages that would mean a pound sign). This works in ranges
625
# too. Using \x00 is not supported though - it will not be parsed as null.
626
#
627
# This is a couple of example classes:
628
# ?0 matches (one version of) base64 characters
629
# ?1 matches hex digits
630
# ?2 matches the TAB character (never try to use \x00!)
631
[UserClasses]
632
0 = [a-zA-Z0-9/.]
633
1 = [0-9a-fA-F]
634
2 = \x09
635
636
[Mask]
637
# When iterating over length, emit a status line after each length is done
638
MaskLengthIterStatus = Y
639
640
# Default mask for -mask if none is given. This is same as hashcat's default.
641
DefaultMask = ?1?2?2?2?2?2?2?3?3?3?3?d?d?d?d
642
643
# Default mask for Hybrid mask mode if none is given.
644
DefaultHybridMask = ?w?d?d?d?d
645
646
# Mask mode have custom placeholders ?1..?9 that look similar to user classes
647
# but are a different thing. They are merely defaults for the -1..-9 command
648
# line options. As delivered, they resemble hashcat's defaults.
649
1 = ?l?d?u
650
2 = ?l?d
651
3 = ?l?d*!$@_
652
4 =
653
5 =
654
6 =
655
7 =
656
8 =
657
9 =
658
659
[Subsets]
660
# When iterating over length, emit a status line after each length is done
661
LengthIterStatus = Y
662
663
# Min/Max number of unique characters. MaxDiff can't be set larger than 16.
664
MinDiff = 1
665
MaxDiff = 7
666
667
# Default charset, either a literal string or a single-digit number pointing
668
# to one of the sets below. If not defined, all printable ASCII is used.
669
DefaultCharset =
670
671
# Subsets mode charsets 0-9. These are literal strings. TAB and space
672
# characters can be used as long as they do not come first or last. The only
673
# "magic" used here is \U+HHHH or \U+HHHHH for any Unicode character (except
674
# the very highest private area that has six hex digits). For example, you
675
# could say \U+1F600 for a "Grinning Face".
676
0 = 0123456789abcdef
677
1 = ABCDEF0123456789
678
2 = 0123456789abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿
679
3 = 0123456789άέήίαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώΆΈΉΊΌΎΏΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫ !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
680
4 = 0123456789абвгдежзийклмнопрстуфхцчшщъыьэюяёЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
681
5 =
682
6 =
683
7 =
684
8 =
685
9 =
686
687
[Regen_Salts_UserClasses]
688
# These are user defined character sets. Their purpose is to allow custom salt
689
# values to be used within the salt_regen logic. These will be the characters
690
# to use for this character within the salt. So if we had a salt that was 4
691
# characters, and 0-9a-m, we can easily do this by 0 = [0-9a-m]. If this is
692
# used, the regen salt value would be ?0?0?0?0 and salts such as a47m 2kd5
693
# would be valid.
694
1 = [1-9]
695
696
# A "no rules" rule for eg. super-fast Single mode (use with --single=none)
697
[List.Rules:None]
698
:
699
700
# A "drop all" rule for even faster Single mode (debugging :)
701
[List.Rules:Drop]
702
<1'0
703
704
# These are good rules on larger sites where a user ID may already be used,
705
# so a user simply appends numbers to create his loginID, but then uses the
706
# login name he wanted as basis for password. Just strip off digits and treat
707
# the base-word to some manipulation. These rules found from the 2015 A-M
708
# leak. Only adds 30-50 permutations and only applied to user names that have
709
# digits contained within them, and cracks quite a few.
710
# These are currently Jumbo-specific.
711
[List.Rules:JumboSingle]
712
/?d @?d >4
713
/?d @?d M @?A >4 Q
714
-c /?d @?d >4 M [lc] Q
715
-c /?d @?d M @?A >4 Q M [lc] Q
716
@?D Q >4
717
/?d @?d >3 <* $[0-9] Q
718
-c /?d @?d >3 <* M [lc] Q $[0-9]
719
/?d @?d >3 <- Az"12" <+ Q
720
-c /?d @?d >3 <- M [lc] Q Az"12" <+
721
/?d @?d >3 Az"123" <+ Q
722
-c /?d @?d >3 M [lc] Q Az"123" <+
723
/?d @?d >2 al d
724
-c /?d @?d >2 al M [lc] Q d
725
(?a )?d /?d a0 'p Xpz0
726
)?a (?d /?a a0 'p Xpz0
727
728
# "Single crack" mode rules
729
[List.Rules:Single]
730
# Simple rules come first...
731
:
732
-s x**
733
-c (?a c Q
734
-c l Q
735
-s-c x** /?u l
736
# These were not included in crackers I've seen, but are pretty efficient,
737
# so I include them near the beginning
738
-<6 >6 '6
739
-<7 >7 '7 l
740
-<6 -c >6 '6 /?u l
741
-<5 >5 '5
742
743
# Wedge the Jumbo-specific addons in here!
744
.include [List.Rules:JumboSingle]
745
746
# Weird order, eh? Can't do anything about it, the order is based on the
747
# number of successful cracks...
748
<* d
749
r c
750
-c <* (?a d c
751
-<5 -c >5 '5 /?u l
752
-c u Q
753
-c )?a r l
754
-[:c] <* !?A \p1[lc] p
755
-c <* c Q d
756
-<7 -c >7 '7 /?u
757
-<4 >4 '4 l
758
-c <+ (?l c r
759
-c <+ )?l l Tm
760
-<3 >3 '3
761
-<4 -c >4 '4 /?u
762
-<3 -c >3 '3 /?u l
763
-c u Q r
764
<* d M 'l f Q
765
-c <* l Q d M 'l f Q
766
# About 50% of single-mode-crackable passwords get cracked by now...
767
# >2 x12 ... >8 x18
768
>[2-8] x1\1
769
>9 \[
770
# >3 x22 ... >9 x28
771
>[3-9] x2\p[2-8]
772
# >4 x32 ... >9 x37
773
>[4-9] x3\p[2-7]
774
# >2 x12 /?u l ... >8 x18 /?u l
775
-c >[2-8] x1\1 /?u l
776
-c >9 \[ /?u l
777
# >3 x22 /?u l ... >9 x28 /?u l
778
-c >[3-9] x2\p[2-8] /?u l
779
# >4 x32 /?u l ... >9 x37 /?u l
780
-c >[4-9] x3\p[2-7] /?u l
781
# Now to the suffix stuff...
782
<* l $[1-9!0a-rt-z"-/:-@\[-`{-~]
783
-c <* (?a c $[1-9!0a-rt-z"-/:-@\[-`{-~]
784
-[:c] <* !?A (?\p1[za] \p1[lc] $s M 'l p Q X0z0 'l $s
785
-[:c] <* /?A (?\p1[za] \p1[lc] $s
786
<* l r $[1-9!]
787
-c <* /?a u $[1-9!]
788
-[:c] <- (?\p1[za] \p1[lc] Az"'s"
789
-[:c] <- (?\p1[za] \p1[lc] Az"!!"
790
-[:c] (?\p1[za] \p1[lc] $! <- Az"!!"
791
# Removing vowels...
792
-[:c] /?v @?v >2 (?\p1[za] \p1[lc]
793
/?v @?v >2 <* d
794
# crack -> cracked, crack -> cracking
795
<* l [PI]
796
-c <* l [PI] (?a c
797
# mary -> marie
798
-[:c] <* (?\p1[za] \p1[lc] )y omi $e
799
# marie -> mary
800
-[:c] (?\p1[za] \p1[lc] )e \] <+ )i val1 oay
801
# The following are some 3l33t rules
802
-[:c] l /[aelos] s\0\p[4310$] (?\p1[za] \p1[:c]
803
-[:c] l /a /[elos] sa4 s\0\p[310$] (?\p1[za] \p1[:c]
804
-[:c] l /e /[los] se3 s\0\p[10$] (?\p1[za] \p1[:c]
805
-[:c] l /l /[os] sl1 s\0\p[0$] (?\p1[za] \p1[:c]
806
-[:c] l /o /s so0 ss$ (?\p1[za] \p1[:c]
807
-[:c] l /a /e /[los] sa4 se3 s\0\p[10$] (?\p1[za] \p1[:c]
808
-[:c] l /a /l /[os] sa4 sl1 s\0\p[0$] (?\p1[za] \p1[:c]
809
-[:c] l /a /o /s sa4 so0 ss$ (?\p1[za] \p1[:c]
810
-[:c] l /e /l /[os] se3 sl1 s\0\p[0$] (?\p1[za] \p1[:c]
811
-[:c] l /[el] /o /s s\0\p[31] so0 ss$ (?\p1[za] \p1[:c]
812
-[:c] l /a /e /l /[os] sa4 se3 sl1 s\0\p[0$] (?\p1[za] \p1[:c]
813
-[:c] l /a /[el] /o /s sa4 s\0\p[31] so0 ss$ (?\p1[za] \p1[:c]
814
-[:c] l /e /l /o /s se3 sl1 so0 ss$ (?\p1[za] \p1[:c]
815
-[:c] l /a /e /l /o /s sa4 se3 sl1 so0 ss$ (?\p1[za] \p1[:c]
816
# Now to the prefix stuff...
817
l ^[1a-z2-90]
818
-c l Q ^[A-Z]
819
^[A-Z]
820
l ^["-/:-@\[-`{-~]
821
-[:c] <9 (?a \p1[lc] A0"[tT]he"
822
-[:c] <9 (?a \p1[lc] A0"[aA]my"
823
-[:c] <9 (?a \p1[lc] A0"[mdMD]r"
824
-[:c] <9 (?a \p1[lc] A0"[mdMD]r."
825
-[:c] <9 (?a \p1[lc] A0"__"
826
<- !?A l p ^[240-9]
827
# Some word pair rules...
828
# johnsmith -> JohnSmith, johnSmith
829
-p-c (?a 2 (?a c 1 [cl]
830
# JohnSmith -> john smith, john_smith, john-smith
831
-p 1 <- $[ _\-] + l
832
# JohnSmith -> John smith, John_smith, John-smith
833
-p-c 1 <- (?a c $[ _\-] 2 l
834
# JohnSmith -> john Smith, john_Smith, john-Smith
835
-p-c 1 <- l $[ _\-] 2 (?a c
836
# johnsmith -> John Smith, John_Smith, John-Smith
837
-p-c 1 <- (?a c $[ _\-] 2 (?a c
838
# Applying different simple rules to each of the two words
839
-p-[c:] 1 \p1[ur] 2 l
840
-p-c 2 (?a c 1 [ur]
841
-p-[c:] 1 l 2 \p1[ur]
842
-p-c 1 (?a c 2 [ur]
843
# jsmith -> smithj, etc...
844
-[:c] (?a \p1[lc] [{}]
845
-[:c] (?a \p1[lc] [{}] \0
846
# Toggle case...
847
-c <+ )?u l Tm
848
-c T0 Q M c Q l Q u Q C Q X0z0 'l
849
-c T[1-9A-E] Q M l Tm Q C Q u Q l Q c Q X0z0 'l
850
-c l Q T[1-9A-E] Q M T\0 Q l Tm Q C Q u Q X0z0 'l
851
-c >2 <G %2?a [lu] T0 M T2 T4 T6 T8 TA TC TE Q M l Tm Q X0z0 'l
852
-c >2 /?l /?u t Q M c Q C Q l Tm Q X0z0 'l
853
# Deleting chars...
854
>[2-8] D\p[1-7]
855
>[8-9A-E] D\1
856
-c /?u >[2-8] D\p[1-7] l
857
-c /?u >[8-9A-E] D\1 l
858
=1?a \[ M c Q
859
-c (?a >[1-9A-E] D\1 c
860
# Inserting a dot...
861
-[:c] >3 (?a \p1[lc] i[12].
862
# More suffix stuff...
863
<- l Az"[190][0-9]"
864
-c <- (?a c Az"[190][0-9]"
865
<- l Az"[782][0-9]"
866
-c <- (?a c Az"[782][0-9]"
867
<* l $[A-Z]
868
-c <* (?a c $[A-Z]
869
# cracking -> CRACKiNG
870
-c u /I sIi
871
# Crack96 -> cRACK96
872
%2?a C Q
873
# Crack96 -> cRACK(^
874
/?A S Q
875
# Crack96 -> CRaCK96
876
-c /?v V Q
877
# Really weird charset conversions, like "england" -> "rmh;smf"
878
:[RL] Q
879
l Q [RL]
880
-c (?a c Q [RL]
881
:[RL] \0 Q
882
# Both prefixing and suffixing...
883
<- l ^[1!@#$%^&*\-=_+.?|:'"] $\1
884
<- l ^[({[<] $\p[)}\]>]
885
# The rest of two-digit suffix stuff, less common numbers...
886
<- l Az"[63-5][0-9]"
887
-c <- (?a c Az"[63-5][0-9]"
888
# Some multi-digit numbers...
889
-[:c] (?a \p1[lc] Az"007" <+
890
-[:c] (?a \p1[lc] Az"123" <+
891
-[:c] (?a \p1[lc] Az"[0-9]\0\0" <+
892
-[:c] (?a \p1[lc] Az"1234" <+
893
-[:c] (?a \p1[lc] Az"[0-9]\0\0\0" <+
894
-[:c] (?a \p1[lc] Az"12345" <+
895
-[:c] (?a \p1[lc] Az"[0-9]\0\0\0\0" <+
896
-[:c] (?a \p1[lc] Az"123456" <+
897
-[:c] (?a \p1[lc] Az"[0-9]\0\0\0\0\0" <+
898
# Some [birth] years...
899
l Az"19[7-96-0]" <+ >-
900
l Az"20[012]" <+ >-
901
l Az"19[7-9][0-9]" <+
902
l Az"20[012][0-9]" <+
903
l Az"19[6-0][9-0]" <+
904
905
[List.Rules:Extra]
906
# Insert/overstrike some characters...
907
!?A >[1-6] l i\0[a-z]
908
!?A l o0[a-z]
909
!?A >[1-7] l o\0[a-z]
910
# Toggle case everywhere (up to length 8), assuming that certain case
911
# combinations were already tried.
912
-c T1 Q M T0 Q
913
-c T2 Q M T[z0] T[z1] Q
914
-c T3 Q M T[z0] T[z1] T[z2] Q
915
-c T4 Q M T[z0] T[z1] T[z2] T[z3] Q
916
-c T5 Q M T[z0] T[z1] T[z2] T[z3] T[z4] Q
917
-c T6 Q M T[z0] T[z1] T[z2] T[z3] T[z4] T[z5] Q
918
-c T7 Q M T[z0] T[z1] T[z2] T[z3] T[z4] T[z5] T[z6] Q
919
# Very slow stuff...
920
l Az"[1-90][0-9][0-9]" <+
921
-c (?a c Az"[1-90][0-9][0-9]" <+
922
<[\-9] l A\p[z0]"[a-z][a-z]"
923
<- l ^[a-z] $[a-z]
924
925
# Wordlist mode rules
926
[List.Rules:Wordlist]
927
# Try words as they are
928
:
929
# Lowercase every pure alphanumeric word
930
-c >3 !?X l Q
931
# Capitalize every pure alphanumeric word
932
-c (?a >2 !?X c Q
933
# Lowercase and pluralize pure alphabetic words
934
<* >2 !?A l p
935
# Lowercase pure alphabetic words and append '1'
936
<* >2 !?A l $1
937
# Capitalize pure alphabetic words and append '1'
938
-c <* >2 !?A c $1
939
# Duplicate reasonably short pure alphabetic words (fred -> fredfred)
940
<7 >1 !?A l d
941
# Lowercase and reverse pure alphabetic words
942
>3 !?A l M r Q
943
# Prefix pure alphabetic words with '1'
944
>2 !?A l ^1
945
# Uppercase pure alphanumeric words
946
-c >2 !?X u Q M c Q u
947
# Lowercase pure alphabetic words and append a digit or simple punctuation
948
<* >2 !?A l $[2!37954860.?]
949
# Words containing punctuation, which is then squeezed out, lowercase
950
/?p @?p >3 l
951
# Words with vowels removed, lowercase
952
/?v @?v >3 l
953
# Words containing whitespace, which is then squeezed out, lowercase
954
/?w @?w >3 l
955
# Capitalize and duplicate short pure alphabetic words (fred -> FredFred)
956
-c <7 >1 !?A c d
957
# Capitalize and reverse pure alphabetic words (fred -> derF)
958
-c <+ >2 !?A c r
959
# Reverse and capitalize pure alphabetic words (fred -> Derf)
960
-c >2 !?A l M r Q c
961
# Lowercase and reflect pure alphabetic words (fred -> fredderf)
962
<7 >1 !?A l d M 'l f Q
963
# Uppercase the last letter of pure alphabetic words (fred -> freD)
964
-c <+ >2 !?A l M r Q c r
965
# Prefix pure alphabetic words with '2' or '4'
966
>2 !?A l ^[24]
967
# Capitalize pure alphabetic words and append a digit or simple punctuation
968
-c <* >2 !?A c $[2!3957468.?0]
969
# Prefix pure alphabetic words with digits
970
>2 !?A l ^[379568]
971
# Capitalize and pluralize pure alphabetic words of reasonable length
972
-c <* >2 !?A c p
973
# Lowercase/capitalize pure alphabetic words of reasonable length and convert:
974
# crack -> cracked, crack -> cracking
975
-[:c] <* >2 !?A \p1[lc] M [PI] Q
976
# Try the second half of split passwords
977
-s x**
978
-s-c x** M l Q
979
980
# Case toggler for cracking MD4-based NTLM hashes (with the contributed patch)
981
# given already cracked DES-based LM hashes. Use --rules=NT to use this.
982
[List.Rules:NT]
983
:
984
-c T0Q
985
-c ->2 a0 T1QT[z0]
986
-c ->3 a0 T2QT[z0]T[z1]
987
-c ->4 a0 T3QT[z0]T[z1]T[z2]
988
-c ->5 a0 T4QT[z0]T[z1]T[z2]T[z3]
989
-c ->6 a0 T5QT[z0]T[z1]T[z2]T[z3]T[z4]
990
-c ->7 a0 T6QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]
991
-c ->8 a0 T7QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]
992
-c ->9 a0 T8QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]
993
-c ->A a0 T9QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]
994
-c ->B a0 TAQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]
995
-c ->C a0 TBQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]T[zA]
996
-c ->D a0 TCQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]T[zA]T[zB]
997
-c ->E a0 TDQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]T[zA]T[zB]T[zC]
998
999
# Shift toggler, up to length 16
1000
[List.Rules:ShiftToggle]
1001
:
1002
W0Q
1003
->2 a0 W1QW[z0]
1004
->3 a0 W2QW[z0]W[z1]
1005
->4 a0 W3QW[z0]W[z1]W[z2]
1006
->5 a0 W4QW[z0]W[z1]W[z2]W[z3]
1007
->6 a0 W5QW[z0]W[z1]W[z2]W[z3]W[z4]
1008
->7 a0 W6QW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]
1009
->8 a0 W7QW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]W[z6]
1010
->9 a0 W8QW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]W[z6]W[z7]
1011
->A a0 W9QW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]W[z6]W[z7]W[z8]
1012
->B a0 WAQW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]W[z6]W[z7]W[z8]W[z9]
1013
->C a0 WBQW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]W[z6]W[z7]W[z8]W[z9]W[zA]
1014
->D a0 WCQW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]W[z6]W[z7]W[z8]W[z9]W[zA]W[zB]
1015
->E a0 WDQW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]W[z6]W[z7]W[z8]W[z9]W[zA]W[zB]W[zC]
1016
->F a0 WEQW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]W[z6]W[z7]W[z8]W[z9]W[zA]W[zB]W[zC]W[zD]
1017
->G a0 WFQW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]W[z6]W[z7]W[z8]W[z9]W[zA]W[zB]W[zC]W[zD]W[zE]
1018
1019
# This ruleset partially overlaps with some Phrase* rulesets below, but it was
1020
# historically introduced and made part of the jumbo ruleset first, so it stays
1021
[List.Rules:Multiword]
1022
-c / Dp l
1023
-c / Dp c Tp
1024
-c / Dp / Dp l
1025
-c / Dp c Tp / Dp Tp
1026
-c %4[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M %3[ ] vbpa Tb Q M %2[ ] vbpa Tb Q M /[ ] vbpa Tb Q @?[Zw]
1027
-c %3[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M %2[ ] vbpa Tb Q M /[ ] vbpa Tb Q @?[Zw]
1028
-c %2[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M /[ ] vbpa Tb Q @?[Zw]
1029
-c /[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q @?[Zw]
1030
-c %2[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q @?[Zw]
1031
-c %3[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q @?[Zw]
1032
-c %4[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q @?[Zw]
1033
-c %2[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M /[ ] vbpa Tb Q @?[Zw]
1034
-c %3[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M /[ ] vbpa Tb Q @?[Zw]
1035
-c %4[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M /[ ] vbpa Tb Q @?[Zw]
1036
-c %2[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M %3[ ] vbpa Tb Q @?[Zw]
1037
-c %2[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M %4[ ] vbpa Tb Q @?[Zw]
1038
-c %3[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M %4[ ] vbpa Tb Q @?[Zw]
1039
-c %4[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M %3[ ] vbpa Tb Q M %2[ ] vbpa Tb Q @?[Zw]
1040
-c %4[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M %2[ ] vbpa Tb Q M /[ ] vbpa Tb Q @?[Zw]
1041
-c %4[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M %3[ ] vbpa Tb Q M /[ ] vbpa Tb Q @?[Zw]
1042
1043
# A special ruleset intended for stacking before other Phrase* rules below,
1044
# such that you have the option to run its output through "unique" first
1045
[List.Rules:PhrasePreprocess]
1046
/[ ] :
1047
-c /[ ] l Q
1048
/[ ] @' Q
1049
-c /[ ] @' Q M l Q
1050
1051
# The main optimized Phrase ruleset, almost no duplicates with proper input
1052
[List.Rules:Phrase]
1053
# This one rule cracks ~1050 HIBP v7 passwords per million with sequences of
1054
# 2 to 6 words occurring 2+ times across Project Gutenberg Australia books
1055
# when our sequence list includes them in both their original case and
1056
# all-lowercase, as well as both with apostrophes intact and removed (these
1057
# variations are not implemented in this ruleset not to produce duplicates)
1058
@?w Q
1059
# Sorted separator characters: 1_24 -.3785690@,&+*!'$/?:=#~^%;`>"[)<]|({}\
1060
# (the apostrophe is probably overrated since it also occurs inside words)
1061
# Each character in 1_24 cracks ~82 to ~61 passwords per million
1062
s[ ][1_24] Q
1063
# Leaving the space separators intact cracks ~59 passwords per million
1064
/[ ]
1065
# Each character in -.3785690@ cracks ~53 to ~12 passwords per million
1066
s[ ][\-.3785690@] Q
1067
# Each character in ,&+*!'$/?:=#~ cracks ~10 to ~1 passwords per million
1068
s[ ][,&+*!'$/?:=#~] Q
1069
1070
# Toggle capitalization of words 1 to 6 individually
1071
[List.Rules:PhraseCaseOne]
1072
-c /[ ] T0 Q
1073
-c /[ ] va01 vapa Ta Q
1074
-c %2[ ] va01 vapa Ta Q
1075
-c %3[ ] va01 vapa Ta Q
1076
-c %4[ ] va01 vapa Ta Q
1077
-c %5[ ] va01 vapa Ta Q
1078
1079
# Move first word to be after last word
1080
[List.Rules:PhraseWrap]
1081
/[ ] ^[ ] Xpz0 \[ 'l
1082
# Other ways to write this rule
1083
#/[ ] xpz \[ $[ ] X0pz 'l
1084
#/[ ] 'p ^[ ] va01 vapa Xaz0
1085
1086
# Used for loopback. This rule will produce candidates "PASSWOR" and "D" for
1087
# an input of "PASSWORD" (assuming LM, which has halves of length 7).
1088
[List.Rules:Split]
1089
:
1090
-s x**
1091
1092
# Some Office <=2003 files have passwords truncated at 15
1093
[List.Rules:OldOffice]
1094
:
1095
->F -<F >F 'F
1096
1097
# Rules from Hash Runner 2014
1098
[List.Rules:o1]
1099
# o[0-9A-Z][ -~]
1100
->\r[1-9A-ZZ] >\p[0-9A-Z] o\0[ -~] Q
1101
1102
[List.Rules:o2]
1103
# o[0-9A-E][ -~] Q M o[0-9A-E][ -~] Q
1104
->[1-9A-F] ->[1-9A-F] >\p1[0-9A-E] >\p2[0-9A-E] o\3[ -~] Q M o\4[ -~] Q
1105
1106
[List.Rules:o3]
1107
# o[0-9][ -~] Q M o[0-9][ -~] Q M o[0-9][ -~] Q
1108
->[1-9A] ->[1-9A] ->[1-9A] >\p1[0-9] >\p2[0-9] >\p3[0-9] o\4[ -~] Q M o\5[ -~] Q M o\6[ -~] Q
1109
1110
[List.Rules:o]
1111
.include [List.Rules:o1]
1112
.include [List.Rules:o2]
1113
1114
[List.Rules:i1]
1115
# i[0-9A-Z][ -~]
1116
->\r[2-9A-ZZZ] >\p1[0-9A-Z] i\0[ -~]
1117
1118
[List.Rules:i2]
1119
# i[0-9A-E][ -~] i[0-9A-E][ -~]
1120
->[2-9A-G] ->[2-9A-G] >\p1[0-9A-E] >\p2[0-9A-E] i\3[ -~] i\4[ -~]
1121
1122
[List.Rules:i3]
1123
# i[0-9][ -~] i[0-9][ -~] i[0-9][ -~]
1124
->[4-9A-D] ->[4-9A-D] ->[4-9A-D] >\p1[0-9] >\p2[0-9] >\p3[0-9] i\4[ -~] i\5[ -~] i\6[ -~]
1125
1126
[List.Rules:i]
1127
.include [List.Rules:i1]
1128
.include [List.Rules:i2]
1129
1130
[List.Rules:oi]
1131
.include [List.Rules:o1]
1132
.include [List.Rules:i1]
1133
.include [List.Rules:o2]
1134
.include [List.Rules:i2]
1135
1136
[List.Rules:T9]
1137
a0 /?D l sa2 sb2 sc2 sd3 se3 sf3 sg4 sh4 si4 sj5 sk5 sl5 sm6 sn6 so6 sp7 sq7 sr7 ss7 st8 su8 sv8 sw9 sx9 sy9 sz9 s?D*
1138
a0 /?D l sa2 sb2 sc2 sd3 se3 sf3 sg4 sh4 si4 sj5 sk5 sl5 sm6 sn6 so6 sp7 sq7 sr7 ss7 st8 su8 sv8 sw9 sx9 sy9 sz9 /?D s?D#
1139
1140
# A few rule sets from hashcat (taken as-is from https://github.com/hashcat/)
1141
#
1142
# Note that these are very poorly optimized with our measure, as they lack
1143
# rule-rejection flags. Also, they don't use the preprocessor so are a lot
1144
# harder to digest (for a human looking at them that is, for JtR there's
1145
# virtually no difference).
1146
#
1147
[List.Rules:best64]
1148
!! hashcat logic ON
1149
.include <rules/best64.rule>
1150
!! hashcat logic OFF
1151
1152
[List.Rules:d3ad0ne]
1153
!! hashcat logic ON
1154
.include <rules/d3ad0ne.rule>
1155
!! hashcat logic OFF
1156
1157
[List.Rules:dive]
1158
!! hashcat logic ON
1159
.include <rules/dive.rule>
1160
!! hashcat logic OFF
1161
1162
[List.Rules:InsidePro]
1163
!! hashcat logic ON
1164
.include <rules/InsidePro-PasswordsPro.rule>
1165
!! hashcat logic OFF
1166
1167
[List.Rules:T0XlC]
1168
!! hashcat logic ON
1169
.include <rules/T0XlC.rule>
1170
.include <rules/T0XlCv1.rule>
1171
.include <rules/T0XlC-insert_top_100_passwords_1_G.rule>
1172
!! hashcat logic OFF
1173
1174
[List.Rules:rockyou-30000]
1175
!! hashcat logic ON
1176
.include <rules/rockyou-30000.rule>
1177
!! hashcat logic OFF
1178
1179
[List.Rules:specific]
1180
!! hashcat logic ON
1181
.include <rules/specific.rule>
1182
!! hashcat logic OFF
1183
1184
[List.Rules:hashcat]
1185
.include [List.Rules:best64]
1186
.include [List.Rules:d3ad0ne]
1187
.include [List.Rules:dive]
1188
.include [List.Rules:InsidePro]
1189
.include [List.Rules:T0XlC]
1190
.include [List.Rules:rockyou-30000]
1191
.include [List.Rules:specific]
1192
1193
# These are for phrase wordlists w/ spaces
1194
[List.Rules:passphrase-rule1]
1195
.include <rules/passphrase-rule1.rule>
1196
1197
[List.Rules:passphrase-rule2]
1198
.include <rules/passphrase-rule2.rule>
1199
1200
# Default Loopback mode rules.
1201
[List.Rules:Loopback]
1202
.include [List.Rules:ShiftToggle]
1203
.include [List.Rules:Split]
1204
!! hashcat logic ON
1205
+m
1206
-m
1207
!! hashcat logic OFF
1208
b1 ]
1209
1210
# For Single Mode against fast hashes
1211
[List.Rules:Single-Extra]
1212
.include [List.Rules:Single]
1213
.include [List.Rules:Extra]
1214
.include [List.Rules:OldOffice]
1215
1216
# Unicode substitution rules
1217
.include <unisubst.conf>
1218
1219
# For Wordlist mode and very fast hashes
1220
[List.Rules:Jumbo]
1221
.include [List.Rules:Single-Extra]
1222
.include [List.Rules:Wordlist]
1223
.include [List.Rules:ShiftToggle]
1224
.include [List.Rules:Multiword]
1225
.include [List.Rules:best64]
1226
.include [List.Rules:UnicodeSubstitution]
1227
1228
# KoreLogic rules
1229
.include <korelogic.conf>
1230
1231
# Everything, including all KoreLogic and the rest of included hashcat rules.
1232
# Only for very fast hashes and/or Single mode. Some of these rules are of
1233
# ridiculous quality and lack optimizations - you have been warned.
1234
[List.Rules:All]
1235
.include [List.Rules:Jumbo]
1236
.include [List.Rules:KoreLogic]
1237
.include [List.Rules:T9]
1238
.include [List.Rules:hashcat]
1239
1240
# Incremental modes
1241
1242
# This is for one-off uses (make your own custom.chr).
1243
# A charset can now also be named directly from command-line, so no config
1244
# entry needed: --incremental=whatever.chr
1245
[Incremental:Custom]
1246
File = $JOHN/custom.chr
1247
MinLen = 0
1248
1249
# The theoretical CharCount is 211, we've got 196.
1250
[Incremental:UTF8]
1251
File = $JOHN/utf8.chr
1252
MinLen = 0
1253
CharCount = 196
1254
1255
# This is CP1252, a super-set of ISO-8859-1.
1256
# The theoretical CharCount is 219, we've got 203.
1257
[Incremental:Latin1]
1258
File = $JOHN/latin1.chr
1259
MinLen = 0
1260
CharCount = 203
1261
1262
[Incremental:ASCII]
1263
File = $JOHN/ascii.chr
1264
MinLen = 0
1265
MaxLen = 13
1266
CharCount = 95
1267
1268
[Incremental:LM_ASCII]
1269
File = $JOHN/lm_ascii.chr
1270
MinLen = 0
1271
MaxLen = 7
1272
CharCount = 69
1273
1274
# This is CP858 (CP850 + Euro sign, superset of CP437).
1275
# The theoretical CharCount is 209 minus lowercase, we've got 132.
1276
[Incremental:LanMan]
1277
File = $JOHN/lanman.chr
1278
MinLen = 0
1279
MaxLen = 7
1280
CharCount = 132
1281
1282
# This is alnum (upper & lower case) as well as space.
1283
[Incremental:Alnumspace]
1284
File = $JOHN/alnumspace.chr
1285
MinLen = 1
1286
MaxLen = 13
1287
CharCount = 63
1288
1289
[Incremental:Alnum]
1290
File = $JOHN/alnum.chr
1291
MinLen = 1
1292
MaxLen = 13
1293
CharCount = 62
1294
1295
[Incremental:Alpha]
1296
File = $JOHN/alpha.chr
1297
MinLen = 1
1298
MaxLen = 13
1299
CharCount = 52
1300
1301
[Incremental:LowerNum]
1302
File = $JOHN/lowernum.chr
1303
MinLen = 1
1304
MaxLen = 13
1305
CharCount = 36
1306
1307
[Incremental:UpperNum]
1308
File = $JOHN/uppernum.chr
1309
MinLen = 1
1310
MaxLen = 13
1311
CharCount = 36
1312
1313
[Incremental:LowerSpace]
1314
File = $JOHN/lowerspace.chr
1315
MinLen = 1
1316
MaxLen = 13
1317
CharCount = 27
1318
1319
[Incremental:Lower]
1320
File = $JOHN/lower.chr
1321
MinLen = 1
1322
MaxLen = 13
1323
CharCount = 26
1324
1325
[Incremental:Upper]
1326
File = $JOHN/upper.chr
1327
MinLen = 1
1328
MaxLen = 13
1329
CharCount = 26
1330
1331
[Incremental:Digits]
1332
File = $JOHN/digits.chr
1333
MinLen = 1
1334
MaxLen = 20
1335
CharCount = 10
1336
1337
# Some pre-defined word filters as used to generate the supplied .chr files
1338
[List.External:Filter_ASCII]
1339
void filter()
1340
{
1341
int i, c;
1342
1343
i = 0;
1344
while (c = word[i++])
1345
if (c < 0x20 || c > 0x7e || i > 13) {
1346
word = 0; return;
1347
}
1348
}
1349
1350
[List.External:Filter_LanMan]
1351
void filter()
1352
{
1353
int i, c;
1354
1355
i = 0;
1356
while (c = word[i]) {
1357
if (i >= 14) { // of up to 14 characters long
1358
word = 0; return;
1359
}
1360
if (c >= 'a' && c <= 'z') // Convert to uppercase
1361
word[i] &= 0xDF;
1362
i++;
1363
}
1364
1365
word[7] = 0; // Truncate at 7 characters
1366
}
1367
1368
[List.External:Filter_LM_ASCII]
1369
void filter()
1370
{
1371
int i, c;
1372
1373
i = 0;
1374
while (c = word[i]) {
1375
if (c < 0x20 || c > 0x7e || // Require ASCII-only
1376
i >= 14) { // of up to 14 characters long
1377
word = 0; return;
1378
}
1379
if (c >= 'a' && c <= 'z') // Convert to uppercase
1380
word[i] &= 0xDF;
1381
i++;
1382
}
1383
1384
word[7] = 0; // Truncate at 7 characters
1385
}
1386
1387
[List.External:Filter_Alnumspace]
1388
void filter()
1389
{
1390
int i, c;
1391
1392
i = 0;
1393
while (c = word[i++])
1394
if (c != ' ' && (((c < '0' || c > '9') &&
1395
((c &= 0xDF) < 'A' || c > 'Z'))) || i > 13) {
1396
word = 0; return;
1397
}
1398
}
1399
1400
[List.External:Filter_Alnum]
1401
void filter()
1402
{
1403
int i, c;
1404
1405
i = 0;
1406
while (c = word[i++])
1407
if (((c < '0' || c > '9') && ((c &= 0xDF) < 'A' || c > 'Z')) ||
1408
i > 13) {
1409
word = 0; return;
1410
}
1411
}
1412
1413
[List.External:Filter_Alpha]
1414
void filter()
1415
{
1416
int i, c;
1417
1418
i = 0;
1419
while (c = word[i++])
1420
if ((c &= 0xDF) < 'A' || c > 'Z' || i > 13) {
1421
word = 0; return;
1422
}
1423
}
1424
1425
[List.External:Filter_LowerNum]
1426
void filter()
1427
{
1428
int i, c;
1429
1430
i = 0;
1431
while (c = word[i++])
1432
if (((c < 'a' || c > 'z') && (c < '0' || c > '9')) || i > 13) {
1433
word = 0; return;
1434
}
1435
}
1436
1437
[List.External:Filter_UpperNum]
1438
void filter()
1439
{
1440
int i, c;
1441
1442
i = 0;
1443
while (c = word[i++])
1444
if (((c < 'A' || c > 'Z') && (c < '0' || c > '9')) || i > 13) {
1445
word = 0; return;
1446
}
1447
}
1448
1449
[List.External:Filter_LowerSpace]
1450
void filter()
1451
{
1452
int i, c;
1453
1454
i = 0;
1455
while (c = word[i++])
1456
if (((c < 'a' || c > 'z') && c != ' ') || i > 13) {
1457
word = 0; return;
1458
}
1459
}
1460
1461
[List.External:Filter_Lower]
1462
void filter()
1463
{
1464
int i, c;
1465
1466
i = 0;
1467
while (c = word[i++])
1468
if (c < 'a' || c > 'z' || i > 13) {
1469
word = 0; return;
1470
}
1471
}
1472
1473
[List.External:Filter_Upper]
1474
void filter()
1475
{
1476
int i, c;
1477
1478
i = 0;
1479
while (c = word[i++])
1480
if (c < 'A' || c > 'Z' || i > 13) {
1481
word = 0; return;
1482
}
1483
}
1484
1485
[List.External:Filter_Digits]
1486
void filter()
1487
{
1488
int i, c;
1489
1490
i = 0;
1491
while (c = word[i++])
1492
if (c < '0' || c > '9' || i > 20) {
1493
word = 0; return;
1494
}
1495
}
1496
1497
[List.External:Filter_No_Cap_or_Symbols]
1498
void filter()
1499
{
1500
int i, c;
1501
1502
i = 0;
1503
while (c = word[i++])
1504
if ((c < 'a' || c > 'z') && (c < '0' || c > '9')) {
1505
return;
1506
}
1507
word = 0; return;
1508
}
1509
1510
1511
# Reject words that are illegal UTF-8
1512
# We obviously let pure ASCII through too
1513
[List.External:Filter_UTF8]
1514
void filter()
1515
{
1516
int s, a, p;
1517
1518
p = 0;
1519
while (s = word[p++] & 0xff) {
1520
if (s > 0x7f) {
1521
if (s < 0xc2 || s > 0xf7) { // illegal single-byte
1522
word = 0; return;
1523
}
1524
// two-byte c2..df
1525
a = word[p++] & 0xff;
1526
if (a < 0x80 || a > 0xbf) {
1527
word = 0; return;
1528
}
1529
if (s > 0xdf) { // three-byte e0..ef
1530
if (s == 0xe0 && a < 0xa0) {
1531
word = 0; return;
1532
}
1533
if (s == 0xed && a > 0x9f) {
1534
word = 0; return;
1535
}
1536
if (s == 0xf0 && a < 0x90) {
1537
word = 0; return;
1538
}
1539
if (s == 0xf4 && a > 0x8f) {
1540
word = 0; return;
1541
}
1542
a = word[p++] & 0xff;
1543
if (a < 0x80 || a > 0xbf) {
1544
word = 0; return;
1545
}
1546
if (s > 0xef) { // four-byte f0..f7
1547
a = word[p++] & 0xff;
1548
if (a < 0x80 || a > 0xbf) {
1549
word = 0; return;
1550
}
1551
}
1552
}
1553
}
1554
}
1555
}
1556
1557
# Reject words that are LEGAL UTF-8 (also rejects pure ASCII)
1558
[List.External:Filter_non-UTF8]
1559
void filter()
1560
{
1561
int s, a, p;
1562
1563
p = 0;
1564
while (s = word[p++] & 0xff) {
1565
if (s > 0x7f) {
1566
if (s < 0xc2 || s > 0xf7) { // illegal single-byte
1567
return;
1568
}
1569
// two-byte c2..df
1570
a = word[p++] & 0xff;
1571
if (a < 0x80 || a > 0xbf) {
1572
return;
1573
}
1574
if (s > 0xdf) { // three-byte e0..ef
1575
if (s == 0xe0 && a < 0xa0) {
1576
return;
1577
}
1578
if (s == 0xed && a > 0x9f) {
1579
return;
1580
}
1581
if (s == 0xf0 && a < 0x90) {
1582
return;
1583
}
1584
if (s == 0xf4 && a > 0x8f) {
1585
return;
1586
}
1587
a = word[p++] & 0xff;
1588
if (a < 0x80 || a > 0xbf) {
1589
return;
1590
}
1591
if (s > 0xef) { // four-byte f0..f7
1592
a = word[p++] & 0xff;
1593
if (a < 0x80 || a > 0xbf) {
1594
return;
1595
}
1596
}
1597
}
1598
}
1599
}
1600
word = 0;
1601
}
1602
1603
# Skip candidate passwords that contain the same character more than once
1604
[List.External:Filter_NoRepeats]
1605
int seen[0x100], now;
1606
1607
void init()
1608
{
1609
now = 1;
1610
}
1611
1612
void filter()
1613
{
1614
int i, c;
1615
1616
if (!--now) {
1617
i = 0;
1618
while (i < 0x100)
1619
seen[i++] = 0;
1620
now = 1000000000;
1621
}
1622
1623
i = 0;
1624
while (c = word[i++]) {
1625
if (seen[c] == now) {
1626
word = 0; return;
1627
}
1628
seen[c] = now;
1629
}
1630
}
1631
1632
# Keep only candidate passwords that contain the same character more than once
1633
[List.External:Filter_Repeats]
1634
int seen[0x100], now;
1635
1636
void init()
1637
{
1638
now = 1;
1639
}
1640
1641
void filter()
1642
{
1643
int i, c;
1644
1645
if (!--now) {
1646
i = 0;
1647
while (i < 0x100)
1648
seen[i++] = 0;
1649
now = 1000000000;
1650
}
1651
1652
i = 0;
1653
while (c = word[i++]) {
1654
if (seen[c] == now)
1655
return;
1656
seen[c] = now;
1657
}
1658
1659
word = 0;
1660
}
1661
1662
# A simple cracker for LM hashes
1663
[List.External:LanMan]
1664
int length; // Current length
1665
int maxlength;
1666
1667
void init()
1668
{
1669
if (req_minlen)
1670
length = req_minlen;
1671
else
1672
length = 1;
1673
if (req_maxlen)
1674
maxlength = req_maxlen;
1675
else // the format's limit
1676
maxlength = cipher_limit;
1677
word[0] = 'A' - 1; // Start with "A"
1678
word[length] = 0;
1679
}
1680
1681
void generate()
1682
{
1683
int i;
1684
1685
i = length - 1; // Start from the last character
1686
while (++word[i] > 'Z') // Try to increase it
1687
if (i) // Overflow here, any more positions?
1688
word[i--] = 'A'; // Yes, move to the left, and repeat
1689
else // No
1690
1691
if (length < maxlength) {
1692
word[i = ++length] = 0; // Switch to the next length
1693
while (i--)
1694
word[i] = 'A';
1695
return;
1696
} else {
1697
word = 0; return; // We're done
1698
}
1699
}
1700
1701
void restore()
1702
{
1703
length = 0; // Calculate the length
1704
while (word[length]) length++;
1705
}
1706
1707
# Simple and well-commented, yet useful external mode example
1708
# NOTE, this has now been 'split' up into a base extern, 'base', and then
1709
# multiple External:double functions. It still has same code as original
1710
# double, but now can be easily expanded.
1711
[List.External_base:Double]
1712
/*
1713
* This cracking mode tries all the possible duplicated lowercase alphabetic
1714
* "words" of up to 8 characters long. Since word halves are the same, it
1715
* only has to try about 500,000 words.
1716
*/
1717
1718
/* Global variables: current length and word */
1719
/* make this 'long' enough for other externs that include this one */
1720
/* (up to 125 bytes long) */
1721
1722
int length, current[126], max;
1723
1724
/* this new 'type' variable, is used to tell double what character set to
1725
* use. It can use the original (alpha). If type is 0 (i.e. unset), then
1726
* a-z (alpha) character set is used. If type is '0' (a zero ascii byte)
1727
* then alnum charset is used, a-z0-9. If type is a space char, then all
1728
* charset is used [space - tilde] or [ -~]. This required setting the
1729
* type var in the init() of alnum or all doubles (it can be left unset
1730
* in the alpha versions). It also requires some if logic in generate.
1731
* other than that, it works the same, with almost no performance hit */
1732
int type;
1733
1734
/* Generates a new word */
1735
void generate()
1736
{
1737
int i;
1738
1739
/* Export last generated word, duplicating it at the same time; here "word"
1740
* is a pre-defined external variable. */
1741
word[(i = length) << 1] = 0;
1742
while (i--) word[length + i] = word[i] = current[i];
1743
1744
/* Generate a new word */
1745
i = length - 1; // Start from the last character
1746
if (type == 0) {
1747
/* alpha */
1748
while (++current[i] > 'z') // Try to increase it
1749
if (i) // Overflow here, any more positions?
1750
current[i--] = 'a'; // Yes, move to the left, and repeat
1751
else { // No
1752
current = 0; // Request a length switch
1753
break; // Break out of the loop
1754
}
1755
} else if (type == '0') {
1756
/* alnum */
1757
if (current[i] == 'z') current[i] = '0'-1;
1758
while (++current[i] == '9') { // Try to increase it
1759
if (i) // Overflow here, any more positions?
1760
current[i--] = 'a'; // Yes, move to the left, and repeat
1761
else { // No
1762
current = 0; // Request a length switch
1763
break; // Break out of the loop
1764
}
1765
if (current[i] == 'z') current[i] = '0'-1;
1766
}
1767
} else if (type == ' ') {
1768
/* all */
1769
while (++current[i] > '~') { // Try to increase it
1770
if (i) // Overflow here, any more positions?
1771
current[i--] = ' '; // Yes, move to the left, and repeat
1772
else { // No
1773
current = 0; // Request a length switch
1774
break; // Break out of the loop
1775
}
1776
}
1777
}
1778
/* else ????? wtf?? */
1779
1780
/* Switch to the next length, unless we were generating 8 character long
1781
* words already. */
1782
if (!current && length < max) {
1783
i = ++length;
1784
if (type == 0 || type == '0')
1785
while (i--) current[i] = 'a';
1786
else if (type == ' ')
1787
while (i--) current[i] = ' ';
1788
}
1789
}
1790
1791
/* Called when restoring an interrupted session */
1792
void restore()
1793
{
1794
int i;
1795
1796
/* Import the word back */
1797
i = 0;
1798
while (current[i] = word[i]) i++;
1799
1800
/* ...and calculate the half-word length */
1801
length = i >> 1;
1802
}
1803
1804
[List.External:Double]
1805
.include [List.External_base:Double]
1806
1807
/* Called at startup to initialize the global variables */
1808
void init()
1809
{
1810
int i;
1811
1812
if (req_minlen)
1813
i = length = (req_minlen + 1) / 2;
1814
else
1815
i = length = 2; // Start with 4 character long words
1816
while (i--) current[i] = 'a'; // Set our half-word to "aa"
1817
if (req_maxlen)
1818
max = (req_maxlen + 1) / 2;
1819
else if (length > 4)
1820
max = length;
1821
else
1822
max = 4;
1823
}
1824
1825
[List.External:Double_alnum]
1826
.include [List.External_base:Double]
1827
1828
/* Called at startup to initialize the global variables */
1829
void init()
1830
{
1831
int i;
1832
1833
if (req_minlen)
1834
i = length = (req_minlen + 1) / 2;
1835
else
1836
i = length = 2; // Start with 4 character long words
1837
while (i--) current[i] = 'a'; // Set our half-word to "aa"
1838
if (req_maxlen)
1839
max = (req_maxlen + 1) / 2;
1840
else if (length > 4)
1841
max = length;
1842
else
1843
max = 4;
1844
1845
type = '0';
1846
}
1847
1848
[List.External:Double_all]
1849
.include [List.External_base:Double]
1850
void init()
1851
{
1852
int i;
1853
1854
if (req_minlen)
1855
i = length = (req_minlen + 1) / 2;
1856
else
1857
i = length = 2; // Start with 4 character long words
1858
while (i--) current[i] = ' '; // Set our half-word to " "
1859
if (req_maxlen)
1860
max = (req_maxlen + 1) / 2;
1861
else if (length > 4)
1862
max = length;
1863
else
1864
max = 4;
1865
1866
type = ' ';
1867
}
1868
1869
# Try strings of repeated characters.
1870
#
1871
# This is the code which is common for all [List.External:Repeats*]
1872
# sections which include this External_base section.
1873
# The generate() function will limit the maximum length of generated
1874
# candidates to either the format's limit (maximum password length)
1875
# or to the limit specified with --stdout=LENGTH (Default: 125),
1876
# thus avoiding duplicate candidates for formats with limited maximum
1877
# passwortd length.
1878
# The comparison of the current length and the limit is only done
1879
# after switching to a new length.
1880
# So, if the minimum length specified already exceeds this limit,
1881
# then all the candidates for the minimum length will be generated
1882
# nevertheless.
1883
[List.External_base:Repeats]
1884
int minlength, maxlength, minc, maxc, length, c;
1885
1886
void generate()
1887
{
1888
int i;
1889
1890
i = 0;
1891
while (i < length)
1892
word[i++] = c;
1893
word[i] = 0;
1894
1895
if (c++ < maxc)
1896
return;
1897
1898
c = minc;
1899
1900
if (++length > maxlength)
1901
c = 0; // Will NUL out the next "word" and thus terminate
1902
}
1903
1904
# Try strings of repeated characters (range: space - 0xff).
1905
[List.External:Repeats]
1906
.include [List.External_base:Repeats]
1907
void init()
1908
{
1909
if (req_minlen)
1910
minlength = req_minlen;
1911
else
1912
minlength = 1;
1913
if (req_maxlen)
1914
maxlength = req_maxlen;
1915
else
1916
maxlength = cipher_limit; // the format's limit
1917
minc = 0x20;
1918
maxc = 0xff;
1919
1920
length = minlength; c = minc;
1921
}
1922
1923
# Try strings of repeated digits (range: '0' - '9').
1924
[List.External:Repeats_digits]
1925
.include [List.External_base:Repeats]
1926
void init()
1927
{
1928
if (req_minlen)
1929
minlength = req_minlen;
1930
else
1931
minlength = 1;
1932
if (req_maxlen)
1933
maxlength = req_maxlen;
1934
else
1935
maxlength = cipher_limit; // the format's limit
1936
minc = '0';
1937
maxc = '9';
1938
1939
length = minlength; c = minc;
1940
}
1941
1942
# Try strings of repeated lowercase letters (range: 'a' - 'z').
1943
[List.External:Repeats_lowercase]
1944
.include [List.External_base:Repeats]
1945
void init()
1946
{
1947
if (req_minlen)
1948
minlength = req_minlen;
1949
else
1950
minlength = 1;
1951
if (req_maxlen)
1952
maxlength = req_maxlen;
1953
else
1954
maxlength = cipher_limit; // the format's limit
1955
minc = 'a';
1956
maxc = 'z';
1957
1958
length = minlength; c = minc;
1959
}
1960
1961
# Try strings of repeated printable ASCII characters
1962
# (range: ' ' - '~').
1963
[List.External:Repeats_printable_ASCII]
1964
.include [List.External_base:Repeats]
1965
void init()
1966
{
1967
if (req_minlen)
1968
minlength = req_minlen;
1969
else
1970
minlength = 1;
1971
if (req_maxlen)
1972
maxlength = req_maxlen;
1973
else
1974
maxlength = cipher_limit; // the format's limit
1975
minc = ' ';
1976
maxc = '~';
1977
1978
length = minlength; c = minc;
1979
}
1980
1981
# Try character sequences ("0123456", "acegikmoqs", "ZYXWVU", etc.).
1982
#
1983
# The generate() function will limit the maximum length of generated
1984
# candidates to either the format's limit (maximum password length)
1985
# or to the limit specified with --stdout=LENGTH (Default: 125),
1986
# thus avoiding duplicate candidates for formats with limited maximum
1987
# passwortd length.
1988
# The comparison of the current length and the limit is only done
1989
# after switching to a new length.
1990
# So, if the minimum length specified already exceeds this limit,
1991
# then all the candidates for the minimum length will be generated
1992
# nevertheless.
1993
# External modes reusing this External_base mode should only need to
1994
# adjust the init() function.
1995
# In the init() function, a minimum length which is > 1 should be
1996
# specified.
1997
# Otherwise, the generated candidates will not depend on the increment
1998
# specified.
1999
# For length = 1, the candidates will be the same as for external mode
2000
# Repeats with length 1.
2001
# Actually, Repeats is a special case of Sequence, using increment = 0.
2002
# External modes reusing this External_base mode should also make sure
2003
# that the number of different characters (specified as a range from "from"
2004
# to "to") is not smaller than the minimum length ("minlength"),
2005
# if the start increment "inc" is 1.
2006
# For a start increment > 1, the number of different characters in the
2007
# range "from" - "to" must be greater than or equal to
2008
# (1 + ("minlength" - 1) * "inc").
2009
# Otherwise you might get unexpected results.
2010
# The range of characters to be used for the sequences needs to be
2011
# specified by adjusting the "from" and "to" variables.
2012
# To generate sequences which decrement characters ("987654"),
2013
# "from" must be > "to".
2014
# Otherwise, the generated sequences will increment characters ("abcdef").
2015
#
2016
# Variables to be used and the generate() function are common
2017
# for all sections which include this External_base section.
2018
[List.External_base:Sequence]
2019
/*
2020
* See the [List.External:Sequence_0-9] section to learn more about
2021
* the meaning of these variables which can be adjusted to define
2022
* new external modes based on an existing one:
2023
*/
2024
int minlength, from, to, maxlength, inc, direction;
2025
2026
/*
2027
* The value of these variables shouldn't be changed when copying
2028
* an existing external mode:
2029
*/
2030
int length, first;
2031
2032
void generate()
2033
{
2034
int i;
2035
2036
i = 0;
2037
2038
while (i < length) {
2039
word[i] = first + (i * inc * direction);
2040
++i;
2041
}
2042
word[i] = 0;
2043
2044
// start the next sequence of the same length
2045
// with the next character
2046
first = first + direction;
2047
2048
// But check that a sequence of the current length
2049
// is still possible (without leaving the range of
2050
// characters allowed
2051
if ((direction > 0 && first + (length - 1) * inc > to) ||
2052
(direction < 0 && first - (length - 1) * inc < to)) {
2053
// No more sequence is possible. Reset start character
2054
first = from;
2055
// Now try the next length.
2056
// But just in case an individual External mode reusing
2057
// this External_base mode did specify a maxlength
2058
// which is larger than the one supported by the format
2059
// or by --stdout=LENGTH, make sure no more candidates
2060
// are generated.
2061
// Checking this just once per length per increment
2062
// doen't really hurt performance.
2063
if (maxlength > cipher_limit)
2064
maxlength = cipher_limit;
2065
2066
// For a similar reason, the maximum length of a
2067
// sequence is limited by the number of different
2068
// characters and by the increment.
2069
// The larger the increment, the smaller
2070
// the maximum possible length for a given
2071
// character range.
2072
while (inc * (maxlength - 1) > direction * (to - from))
2073
--maxlength;
2074
2075
if (++length > maxlength) {
2076
// The maximum length for this increment has been reached.
2077
// Restart at minimum length with the next possible
2078
// increment
2079
++inc;
2080
// Unfortunately, we have to check again
2081
// if the maximum length needs to be reduced
2082
// for the new increment
2083
while (inc * (maxlength - 1) > direction * (to - from))
2084
--maxlength;
2085
2086
length = minlength;
2087
}
2088
if (maxlength < minlength)
2089
// With the current increment, we can't even generate
2090
// sequences of the minimum required length.
2091
// So we need to stop here.
2092
// This will make sure that no more candidiates
2093
// will be generated:
2094
first = 0;
2095
}
2096
}
2097
2098
# Try sequences of digits (range: '0' - '9').
2099
#
2100
# Aditional comments can be found in the
2101
# section [List.External_base:Sequence]
2102
#
2103
# This external mode is thoroughly commented,
2104
# to make it easier to copy and adjust it as needed.
2105
[List.External:Sequence_0-9]
2106
.include [List.External_base:Sequence]
2107
void init()
2108
{
2109
// Adjust the following 4 variables if you want to define
2110
// a different external mode.
2111
2112
// This is the start character for the generated sequence
2113
// if "from" is smaller than "to", the increment from
2114
// first to second character ... will be positive ("0123456789").
2115
// Otherwise, it will be negative ("987654321").
2116
from = '0';
2117
to = '9';
2118
2119
// minimum length of the sequence
2120
// make sure it is not larger than the number of different characters
2121
// in the range between "from" and "to" specified above
2122
minlength = 2;
2123
2124
// start increment for generating the sequence, usually 1
2125
// if it is larger than 1, you need even more characters
2126
// in the range between "from" and "to"
2127
// Don't specify a negative value here.
2128
// If you want to generate sequences like "zyxwvu" or "86420",
2129
// adjust "from" and "to" so that "from" is larger than "to".
2130
// (A start increment of 0 is also possible, in that case the first
2131
// sequences will be candidates which just repeat the same character.)
2132
inc = 1;
2133
2134
// For copied external modes, no further changes should be required
2135
// in the statements following this comment
2136
2137
length = minlength;
2138
first = from;
2139
2140
if (from <= to) {
2141
maxlength = to - from + 1;
2142
direction = 1;
2143
} else {
2144
// We have to create sequences which decrement the previous character
2145
maxlength = from - to + 1;
2146
direction = -1;
2147
}
2148
}
2149
2150
# Try sequence of lower case letters (range: 'a' - 'z').
2151
# This external mode is not very well documented.
2152
# Refer to [List.External:Sequence_0-9] for more detailed information.
2153
[List.External:Sequence_a-z]
2154
.include [List.External_base:Sequence]
2155
void init()
2156
{
2157
from = 'a';
2158
to = 'z';
2159
minlength = 2;
2160
inc = 1;
2161
2162
length = minlength;
2163
first = from;
2164
2165
if (from <= to) {
2166
maxlength = to - from + 1;
2167
direction = 1;
2168
} else {
2169
maxlength = from - to + 1;
2170
direction = -1;
2171
}
2172
}
2173
2174
# Try sequence of lower case letters (range: 'a' - 'z'), but reversed
2175
# ("zxywvu").
2176
# This external mode is not very well documented.
2177
# Refer to [List.External:Sequence_0-9] for more detailed information.
2178
[List.External:Sequence_z-a]
2179
.include [List.External_base:Sequence]
2180
void init()
2181
{
2182
from = 'z';
2183
to = 'a';
2184
minlength = 2;
2185
inc = 1;
2186
2187
length = minlength;
2188
first = from;
2189
2190
if (from <= to) {
2191
maxlength = to - from + 1;
2192
direction = 1;
2193
} else {
2194
maxlength = from - to + 1;
2195
direction = -1;
2196
}
2197
}
2198
2199
# Try sequence of printable ASCII characters (range: ' ' - '~').
2200
# This external mode is not very well documented.
2201
# Refer to [List.External:Sequence_0-9] for more detailed information.
2202
[List.External:Sequence_printable_ascii]
2203
.include [List.External_base:Sequence]
2204
void init()
2205
{
2206
from = ' ';
2207
to = '~';
2208
minlength = 2;
2209
inc = 1;
2210
2211
length = minlength;
2212
first = from;
2213
2214
if (from <= to) {
2215
maxlength = to - from + 1;
2216
direction = 1;
2217
} else {
2218
maxlength = from - to + 1;
2219
direction = -1;
2220
}
2221
}
2222
2223
# Try sequence of printable ASCII characters (range: ' ' - '~'),
2224
# but decrementing characters ("fedcba") instead of incrementing.
2225
# This external mode is not very well documented.
2226
# Refer to [List.External:Sequence_0-9] for more detailed information.
2227
[List.External:Sequence_reversed_ascii]
2228
.include [List.External_base:Sequence]
2229
void init()
2230
{
2231
from = '~';
2232
to = ' ';
2233
minlength = 2;
2234
inc = 1;
2235
2236
length = minlength;
2237
first = from;
2238
2239
if (from <= to) {
2240
maxlength = to - from + 1;
2241
direction = 1;
2242
} else {
2243
maxlength = from - to + 1;
2244
direction = -1;
2245
}
2246
}
2247
2248
# Try sequence of characters (range: space - 0xff).
2249
# This external mode is not very well documented.
2250
# Refer to [List.External:Sequence_0-9] for more detailed information.
2251
[List.External:Sequence]
2252
.include [List.External_base:Sequence]
2253
void init()
2254
{
2255
from = ' ';
2256
to = 0xff;
2257
minlength = 2;
2258
inc = 1;
2259
2260
length = minlength;
2261
first = from;
2262
2263
if (from <= to) {
2264
maxlength = to - from + 1;
2265
direction = 1;
2266
} else {
2267
maxlength = from - to + 1;
2268
direction = -1;
2269
}
2270
}
2271
2272
2273
# Generate candidate passwords from many small subsets of characters from a
2274
# much larger full character set. This will test for passwords containing too
2275
# few different characters. As currently implemented, this code will produce
2276
# some duplicates, although their number is relatively small when the maximum
2277
# number of different characters (the maxdiff setting) is significantly lower
2278
# than the maximum length (the maxlength setting). Nevertheless, you may want
2279
# to pass the resulting candidate passwords through "unique" if you intend to
2280
# test them against hashes that are salted and/or of a slow to compute type.
2281
#
2282
# Note that we now have a full blown cracking mode --subsets that is way faster
2283
# than this code and never produce a duplicate. See doc/SUBSETS
2284
[List.External:Subsets]
2285
int minlength; // Minimum password length to try
2286
int maxlength; // Maximum password length to try
2287
int startdiff; // Initial number of characters in a subset to try
2288
int maxdiff; // Maximum number of characters in a subset to try
2289
int last; // Last character position, zero-based
2290
int lastid; // Character index in the last position
2291
int id[0x7f]; // Current character indices for other positions
2292
int subset[0x100], c0; // Current subset
2293
int subcount; // Number of characters in the current subset
2294
int subid[0x100]; // Indices into charset[] of characters in subset[]
2295
int charset[0x100]; // Full character set
2296
int charcount; // Number of characters in the full charset
2297
2298
void init()
2299
{
2300
int i, c;
2301
2302
// Minimum password length to try, must be at least 1
2303
if (req_minlen)
2304
minlength = req_minlen;
2305
else
2306
minlength = 1;
2307
2308
// Maximum password length to try, must be at least same as minlength
2309
// This external mode's default maximum length can be adjusted
2310
// using --max-length= on the command line
2311
if (req_maxlen)
2312
maxlength = req_maxlen;
2313
else
2314
maxlength = 8;
2315
2316
// "cipher_limit" is the variable which contains the format's
2317
// maximum password length
2318
if (maxlength > cipher_limit)
2319
maxlength = cipher_limit;
2320
2321
startdiff = 1; // Initial number of different characters to try
2322
maxdiff = 3; // Maximum number of different characters to try
2323
2324
/* This defines the character set */
2325
i = 0;
2326
c = 0x20;
2327
while (c <= 0x7e)
2328
charset[i++] = c++;
2329
2330
if (maxdiff > (charcount = i))
2331
maxdiff = i;
2332
if (maxdiff > maxlength)
2333
maxdiff = maxlength;
2334
2335
/*
2336
* Initialize the variables such that generate() gets to its "next subset"
2337
* code, which will initialize everything for real.
2338
*/
2339
subcount = (i = startdiff) - 1;
2340
while (i--)
2341
subid[i] = charcount;
2342
subset[0] = c0 = 0;
2343
last = maxlength - 1;
2344
lastid = -1;
2345
}
2346
2347
void generate()
2348
{
2349
int i;
2350
2351
/* Handle the typical case specially */
2352
if (word[last] = subset[++lastid]) return;
2353
2354
lastid = 0;
2355
word[i = last] = c0;
2356
while (i--) { // Have a preceding position?
2357
if (word[i] = subset[++id[i]]) return;
2358
id[i] = 0;
2359
word[i] = c0;
2360
}
2361
2362
if (++last < maxlength) { // Next length?
2363
id[last] = lastid = 0;
2364
word[last] = c0;
2365
word[last + 1] = 0;
2366
return;
2367
}
2368
2369
/* Next subset */
2370
if (subcount) {
2371
int j;
2372
i = subcount - 1;
2373
j = charcount;
2374
while (++subid[i] >= j) {
2375
if (i--) {
2376
j--;
2377
continue;
2378
}
2379
subid[i = 0] = 0;
2380
subset[++subcount] = 0;
2381
break;
2382
}
2383
} else {
2384
subid[i = 0] = 0;
2385
subset[++subcount] = 0;
2386
}
2387
subset[i] = charset[subid[i]];
2388
while (++i < subcount)
2389
subset[i] = charset[subid[i] = subid[i - 1] + 1];
2390
2391
if (subcount > maxdiff) {
2392
word = 0; // Done
2393
return;
2394
}
2395
2396
/*
2397
* We won't be able to fully use the subset if the length is smaller than the
2398
* character count. We assume that we've tried all smaller subsets before, so
2399
* we don't bother with such short lengths.
2400
*/
2401
if (minlength < subcount)
2402
last = subcount - 1;
2403
else
2404
last = minlength - 1;
2405
c0 = subset[0];
2406
i = 0;
2407
while (i <= last) {
2408
id[i] = 0;
2409
word[i++] = c0;
2410
}
2411
lastid = 0;
2412
word[i] = 0;
2413
}
2414
2415
# Try sequences of adjacent keys on a keyboard as candidate passwords
2416
[List.External:Keyboard]
2417
int maxlength, length; // Maximum password length to try, current length
2418
int fuzz; // The desired "fuzz factor", either 0 or 1
2419
int id[15]; // Current character indices for each position
2420
int m[0x800]; // The keys matrix
2421
int mc[0x100]; // Counts of adjacent keys
2422
int f[0x40], fc; // Characters for the first position, their count
2423
2424
void init()
2425
{
2426
int minlength;
2427
int i, j, c, p;
2428
int k[0x40];
2429
2430
// Initial password length to try
2431
if (req_minlen)
2432
minlength = req_minlen;
2433
else
2434
minlength = 1;
2435
if (req_maxlen)
2436
maxlength = req_maxlen;
2437
else
2438
maxlength = cipher_limit; // the format's limit
2439
fuzz = 1; // "Fuzz factor", set to 0 for much quicker runs
2440
2441
/*
2442
* This defines the keyboard layout, by default for a QWERTY keyboard.
2443
*/
2444
i = 0; while (i < 0x40) k[i++] = 0;
2445
k[0] = '`';
2446
i = 0; while (++i <= 9) k[i] = '0' + i;
2447
k[10] = '0'; k[11] = '-'; k[12] = '=';
2448
k[0x11] = 'q'; k[0x12] = 'w'; k[0x13] = 'e'; k[0x14] = 'r';
2449
k[0x15] = 't'; k[0x16] = 'y'; k[0x17] = 'u'; k[0x18] = 'i';
2450
k[0x19] = 'o'; k[0x1a] = 'p'; k[0x1b] = '['; k[0x1c] = ']';
2451
k[0x1d] = '\\';
2452
k[0x21] = 'a'; k[0x22] = 's'; k[0x23] = 'd'; k[0x24] = 'f';
2453
k[0x25] = 'g'; k[0x26] = 'h'; k[0x27] = 'j'; k[0x28] = 'k';
2454
k[0x29] = 'l'; k[0x2a] = ';'; k[0x2b] = '\'';
2455
k[0x31] = 'z'; k[0x32] = 'x'; k[0x33] = 'c'; k[0x34] = 'v';
2456
k[0x35] = 'b'; k[0x36] = 'n'; k[0x37] = 'm'; k[0x38] = ',';
2457
k[0x39] = '.'; k[0x3a] = '/';
2458
2459
i = 0; while (i < 0x100) mc[i++] = 0;
2460
fc = 0;
2461
2462
/* rows */
2463
c = 0;
2464
i = 0;
2465
while (i < 0x40) {
2466
p = c;
2467
c = k[i++] & 0xff;
2468
if (!c) continue;
2469
f[fc++] = c;
2470
if (!p) continue;
2471
m[(c << 3) + mc[c]++] = p;
2472
m[(p << 3) + mc[p]++] = c;
2473
}
2474
f[fc] = 0;
2475
2476
/* columns */
2477
i = 0;
2478
while (i < 0x30) {
2479
p = k[i++] & 0xff;
2480
if (!p) continue;
2481
j = 1 - fuzz;
2482
while (j <= 1 + fuzz) {
2483
c = k[i + 0x10 - j++] & 0xff;
2484
if (!c) continue;
2485
m[(c << 3) + mc[c]++] = p;
2486
m[(p << 3) + mc[p]++] = c;
2487
}
2488
}
2489
2490
length = 0;
2491
while (length < minlength)
2492
id[length++] = 0;
2493
}
2494
2495
void generate()
2496
{
2497
int i, p, maxcount;
2498
2499
word[i = 0] = p = f[id[0]];
2500
while (++i < length)
2501
word[i] = p = m[(p << 3) + id[i]];
2502
word[i--] = 0;
2503
2504
if (i) maxcount = mc[word[i - 1]]; else maxcount = fc;
2505
while (++id[i] >= maxcount) {
2506
if (!i) {
2507
if (length < maxlength) {
2508
id[0] = 0;
2509
id[length++] = 0;
2510
}
2511
return;
2512
}
2513
id[i--] = 0;
2514
if (i) maxcount = mc[word[i - 1]]; else maxcount = fc;
2515
}
2516
}
2517
2518
void restore()
2519
{
2520
int i;
2521
2522
/* Calculate the length */
2523
length = 0;
2524
while (word[length])
2525
id[length++] = 0;
2526
2527
/* Infer the first character index */
2528
i = -1;
2529
while (++i < fc) {
2530
if (f[i] == word[0]) {
2531
id[0] = i;
2532
break;
2533
}
2534
}
2535
2536
/* This sample can be enhanced to infer the rest of the indices here */
2537
}
2538
2539
# Simplest (fastest?) possible dumb exhaustive search, demonstrating a
2540
# mode that does not need any special restore() handling.
2541
# Defaults to printable ASCII.
2542
[List.External:DumbDumb]
2543
int maxlength; // Maximum password length to try
2544
int startchar, endchar; // Range of characters (inclusive)
2545
2546
void init()
2547
{
2548
int i;
2549
2550
startchar = ' '; // Start with space
2551
endchar = '~'; // End with tilde
2552
2553
// Create first word, honoring --min-len
2554
if (!(i = req_minlen))
2555
i++;
2556
word[i] = 0;
2557
while (i--)
2558
word[i] = startchar;
2559
word[0] = startchar - 1;
2560
2561
if (req_maxlen)
2562
maxlength = req_maxlen; // --max-len
2563
else
2564
maxlength = cipher_limit; // format's limit
2565
}
2566
2567
void generate()
2568
{
2569
int i;
2570
2571
if (++word <= endchar)
2572
return;
2573
2574
i = 0;
2575
2576
while (word[i] > endchar) {
2577
word[i++] = startchar;
2578
if (!word[i]) {
2579
word[i] = startchar;
2580
word[i + 1] = 0;
2581
} else
2582
word[i]++;
2583
}
2584
2585
if (i >= maxlength)
2586
word = 0;
2587
}
2588
2589
/*
2590
* This mode will resume correctly without any restore handing.
2591
* The empty function just confirms to John that everything is in order.
2592
*/
2593
void restore()
2594
{
2595
}
2596
2597
# Generic implementation of "dumb" exhaustive search, given a range of lengths
2598
# and an arbitrary charset. This is pre-configured to try 8-bit characters
2599
# against LM hashes, which is only reasonable to do for very short password
2600
# half lengths.
2601
[List.External:DumbForce]
2602
int maxlength; // Maximum password length to try
2603
int last; // Last character position, zero-based
2604
int lastid; // Character index in the last position
2605
int id[0x7f]; // Current character indices for other positions
2606
int charset[0x100], c0; // Character set
2607
2608
void init()
2609
{
2610
int minlength;
2611
int i, c;
2612
2613
// Initial password length to try, must be at least 1
2614
if (req_minlen)
2615
minlength = req_minlen;
2616
else
2617
minlength = 1;
2618
if (req_maxlen)
2619
maxlength = req_maxlen;
2620
else
2621
maxlength = cipher_limit; // the format's limit
2622
2623
/*
2624
* This defines the character set.
2625
*
2626
* Let's say, we want to try TAB, all non-control ASCII characters, and all
2627
* 8-bit characters, including the 8-bit terminal controls range (as these are
2628
* used as regular national characters with some 8-bit encodings), but except
2629
* for known terminal controls (risky for the terminal we may be running on).
2630
*
2631
* Also, let's say our hashes are case-insensitive, so skip lowercase letters
2632
* (this is right for LM hashes).
2633
*/
2634
i = 0;
2635
charset[i++] = 9; // Add horizontal TAB (ASCII 9), then
2636
c = ' '; // start with space (ASCII 32) and
2637
while (c < 'a') // proceed till lowercase 'a'
2638
charset[i++] = c++;
2639
c = 'z' + 1; // Skip lowercase letters and
2640
while (c <= 0x7e) // proceed for all printable ASCII
2641
charset[i++] = c++;
2642
c++; // Skip DEL (ASCII 127) and
2643
while (c < 0x84) // proceed over 8-bit codes till IND
2644
charset[i++] = c++;
2645
charset[i++] = 0x86; // Skip IND (84 hex) and NEL (85 hex)
2646
charset[i++] = 0x87;
2647
c = 0x89; // Skip HTS (88 hex)
2648
while (c < 0x8d) // Proceed till RI (8D hex)
2649
charset[i++] = c++;
2650
c = 0x91; // Skip RI, SS2, SS3, DCS
2651
while (c < 0x96) // Proceed till SPA (96 hex)
2652
charset[i++] = c++;
2653
charset[i++] = 0x99; // Skip SPA, EPA, SOS
2654
c = 0xa0; // Skip DECID, CSI, ST, OSC, PM, APC
2655
while (c <= 0xff) // Proceed with the rest of 8-bit codes
2656
charset[i++] = c++;
2657
2658
/* Zero-terminate it, and cache the first character */
2659
charset[i] = 0;
2660
c0 = charset[0];
2661
2662
last = minlength - 1;
2663
i = 0;
2664
while (i <= last) {
2665
id[i] = 0;
2666
word[i++] = c0;
2667
}
2668
lastid = -1;
2669
word[i] = 0;
2670
}
2671
2672
void generate()
2673
{
2674
int i;
2675
2676
/* Handle the typical case specially */
2677
if (word[last] = charset[++lastid]) return;
2678
2679
lastid = 0;
2680
word[i = last] = c0;
2681
while (i--) { // Have a preceding position?
2682
if (word[i] = charset[++id[i]]) return;
2683
id[i] = 0;
2684
word[i] = c0;
2685
}
2686
2687
if (++last < maxlength) { // Next length?
2688
id[last] = lastid = 0;
2689
word[last] = c0;
2690
word[last + 1] = 0;
2691
} else // We're done
2692
word = 0;
2693
}
2694
2695
void restore()
2696
{
2697
int i, c;
2698
2699
/* Calculate the current length and infer the character indices */
2700
last = 0;
2701
while (c = word[last]) {
2702
i = 0; while (charset[i] != c && charset[i]) i++;
2703
if (!charset[i]) i = 0; // Not found
2704
id[last++] = i;
2705
}
2706
lastid = id[--last];
2707
}
2708
2709
# Generic implementation of exhaustive search for a partially-known password.
2710
# This is pre-configured for length 8, lowercase and uppercase letters in the
2711
# first 4 positions (52 different characters), and digits in the remaining 4
2712
# positions - however, the corresponding part of init() may be modified to use
2713
# arbitrary character sets or even fixed characters for each position.
2714
[List.External:KnownForce]
2715
int last; // Last character position, zero-based
2716
int lastofs; // Last character position offset into charset[]
2717
int lastid; // Current character index in the last position
2718
int id[0x7f]; // Current character indices for other positions
2719
int charset[0x7f00]; // Character sets, 0x100 elements for each position
2720
2721
void init()
2722
{
2723
int length, maxlength;
2724
int pos, ofs, i, c;
2725
2726
if (req_minlen)
2727
length = req_minlen;
2728
else
2729
length = 8; // Password length to try (NOTE: other [eg. shorter]
2730
// lengths will not be tried!)
2731
if (req_maxlen)
2732
maxlength = req_maxlen;
2733
else
2734
maxlength = cipher_limit; // the format's limit
2735
2736
/* This defines the character sets for different character positions */
2737
if (length > maxlength)
2738
length = maxlength;
2739
pos = 0;
2740
while (pos < 4) {
2741
ofs = pos++ << 8;
2742
i = 0;
2743
c = 'a';
2744
while (c <= 'z')
2745
charset[ofs + i++] = c++;
2746
c = 'A';
2747
while (c <= 'Z')
2748
charset[ofs + i++] = c++;
2749
charset[ofs + i] = 0;
2750
}
2751
while (pos < length) {
2752
ofs = pos++ << 8;
2753
i = 0;
2754
c = '0';
2755
while (c <= '9')
2756
charset[ofs + i++] = c++;
2757
charset[ofs + i] = 0;
2758
}
2759
2760
last = length - 1;
2761
pos = -1;
2762
while (++pos <= last)
2763
word[pos] = charset[id[pos] = pos << 8];
2764
lastid = (lastofs = last << 8) - 1;
2765
word[pos] = 0;
2766
}
2767
2768
void generate()
2769
{
2770
int pos;
2771
2772
/* Handle the typical case specially */
2773
if (word[last] = charset[++lastid]) return;
2774
2775
word[pos = last] = charset[lastid = lastofs];
2776
while (pos--) { // Have a preceding position?
2777
if (word[pos] = charset[++id[pos]]) return;
2778
word[pos] = charset[id[pos] = pos << 8];
2779
}
2780
2781
word = 0; // We're done
2782
}
2783
2784
void restore()
2785
{
2786
int i, c;
2787
2788
/* Calculate the current length and infer the character indices */
2789
last = 0;
2790
while (c = word[last]) {
2791
i = lastofs = last << 8;
2792
while (charset[i] != c && charset[i]) i++;
2793
if (!charset[i]) i = lastofs; // Not found
2794
id[last++] = i;
2795
}
2796
lastid = id[--last];
2797
}
2798
2799
# A variation of KnownForce configured to try likely date and time strings.
2800
[List.External:DateTime]
2801
int last; // Last character position, zero-based
2802
int lastofs; // Last character position offset into charset[]
2803
int lastid; // Current character index in the last position
2804
int id[0x7f]; // Current character indices for other positions
2805
int charset[0x7f00]; // Character sets, 0x100 elements for each position
2806
2807
void init()
2808
{
2809
int length;
2810
int pos, ofs, i, c;
2811
2812
length = 8; // Must be one of: 4, 5, 7, 8
2813
2814
/* This defines the character sets for different character positions */
2815
pos = 0;
2816
while (pos < length - 6) {
2817
ofs = pos++ << 8;
2818
i = 0;
2819
c = '0';
2820
while (c <= '9')
2821
charset[ofs + i++] = c++;
2822
charset[ofs + i] = 0;
2823
}
2824
if (pos) {
2825
ofs = pos++ << 8;
2826
charset[ofs] = '/';
2827
charset[ofs + 1] = '.';
2828
charset[ofs + 2] = ':';
2829
charset[ofs + 3] = 0;
2830
}
2831
while (pos < length - 3) {
2832
ofs = pos++ << 8;
2833
i = 0;
2834
c = '0';
2835
while (c <= '9')
2836
charset[ofs + i++] = c++;
2837
charset[ofs + i] = 0;
2838
}
2839
ofs = pos++ << 8;
2840
charset[ofs] = '/';
2841
charset[ofs + 1] = '.';
2842
charset[ofs + 2] = ':';
2843
charset[ofs + 3] = 0;
2844
while (pos < length) {
2845
ofs = pos++ << 8;
2846
i = 0;
2847
c = '0';
2848
while (c <= '9')
2849
charset[ofs + i++] = c++;
2850
charset[ofs + i] = 0;
2851
}
2852
2853
last = length - 1;
2854
pos = -1;
2855
while (++pos <= last)
2856
word[pos] = charset[id[pos] = pos << 8];
2857
lastid = (lastofs = last << 8) - 1;
2858
word[pos] = 0;
2859
}
2860
2861
void generate()
2862
{
2863
int pos;
2864
2865
/* Handle the typical case specially */
2866
if (word[last] = charset[++lastid]) return;
2867
2868
word[pos = last] = charset[lastid = lastofs];
2869
while (pos--) { // Have a preceding position?
2870
if (word[pos] = charset[++id[pos]]) return;
2871
word[pos] = charset[id[pos] = pos << 8];
2872
}
2873
2874
word = 0; // We're done
2875
}
2876
2877
void restore()
2878
{
2879
int i, c;
2880
2881
/* Calculate the current length and infer the character indices */
2882
last = 0;
2883
while (c = word[last]) {
2884
i = lastofs = last << 8;
2885
while (charset[i] != c && charset[i]) i++;
2886
if (!charset[i]) i = lastofs; // Not found
2887
id[last++] = i;
2888
}
2889
lastid = id[--last];
2890
}
2891
2892
# A variation of KnownForce configured to try all the 385641000 possible
2893
# auto-generated passwords of DokuWiki versions up to at least 2013-05-10.
2894
[List.External:DokuWiki]
2895
int last; // Last character position, zero-based
2896
int lastofs; // Last character position offset into charset[]
2897
int lastid; // Current character index in the last position
2898
int id[0x7f]; // Current character indices for other positions
2899
int charset[0x7f00]; // Character sets, 0x100 elements for each position
2900
2901
void init()
2902
{
2903
int A[26], C[26], V[26];
2904
int length;
2905
int pos, ofs, i, c;
2906
2907
i = 0; while (i < 26) { A[i] = C[i] = 1; V[i++] = 0; }
2908
i = 'a' - 'a'; C[i] = 0; V[i] = 1;
2909
i = 'e' - 'a'; C[i] = 0; V[i] = 1;
2910
i = 'i' - 'a'; C[i] = 0; V[i] = 1;
2911
i = 'o' - 'a'; C[i] = 0; V[i] = 1;
2912
i = 'u' - 'a'; C[i] = 0; V[i] = 1;
2913
i = 'q' - 'a'; A[i] = C[i] = 0;
2914
i = 'x' - 'a'; A[i] = C[i] = 0;
2915
i = 'y' - 'a'; A[i] = C[i] = 0;
2916
2917
length = 8;
2918
2919
/* This defines the character sets for different character positions */
2920
pos = 0;
2921
while (pos < 6) {
2922
ofs = pos++ << 8;
2923
i = 0;
2924
c = 'a' - 1;
2925
while (++c <= 'z')
2926
if (C[c - 'a'])
2927
charset[ofs + i++] = c;
2928
charset[ofs + i] = 0;
2929
ofs = pos++ << 8;
2930
i = 0;
2931
c = 'a' - 1;
2932
while (++c <= 'z')
2933
if (V[c - 'a'])
2934
charset[ofs + i++] = c;
2935
charset[ofs + i] = 0;
2936
ofs = pos++ << 8;
2937
i = 0;
2938
c = 'a' - 1;
2939
while (++c <= 'z')
2940
if (A[c - 'a'])
2941
charset[ofs + i++] = c;
2942
charset[ofs + i] = 0;
2943
}
2944
c = '1';
2945
while (pos < length) {
2946
ofs = pos++ << 8;
2947
i = 0;
2948
while (c <= '9')
2949
charset[ofs + i++] = c++;
2950
charset[ofs + i] = 0;
2951
c = '0';
2952
}
2953
2954
last = length - 1;
2955
pos = -1;
2956
while (++pos <= last)
2957
word[pos] = charset[id[pos] = pos << 8];
2958
lastid = (lastofs = last << 8) - 1;
2959
word[pos] = 0;
2960
}
2961
2962
void generate()
2963
{
2964
int pos;
2965
2966
/* Handle the typical case specially */
2967
if (word[last] = charset[++lastid]) return;
2968
2969
word[pos = last] = charset[lastid = lastofs];
2970
while (pos--) { // Have a preceding position?
2971
if (word[pos] = charset[++id[pos]]) return;
2972
word[pos] = charset[id[pos] = pos << 8];
2973
}
2974
2975
word = 0; // We're done
2976
}
2977
2978
void restore()
2979
{
2980
int i, c;
2981
2982
/* Calculate the current length and infer the character indices */
2983
last = 0;
2984
while (c = word[last]) {
2985
i = lastofs = last << 8;
2986
while (charset[i] != c && charset[i]) i++;
2987
if (!charset[i]) i = lastofs; // Not found
2988
id[last++] = i;
2989
}
2990
lastid = id[--last];
2991
}
2992
2993
# Strip 0.5 ("Secure Tool for Recalling Important Passwords") cracker,
2994
# based on analysis done by Thomas Roessler and Ian Goldberg. This will
2995
# crack passwords you may have generated with Strip; other uses of Strip
2996
# are unaffected.
2997
[List.External:Strip]
2998
int minlength, maxlength, mintype, maxtype;
2999
int crack_seed, length, type;
3000
int count, charset[128];
3001
3002
void init()
3003
{
3004
int c;
3005
3006
/* Password lengths to try; Strip can generate passwords of 4 to 16
3007
* characters, but traditional crypt(3) hashes are limited to 8. */
3008
minlength = req_minlen;
3009
if (minlength < 4)
3010
minlength = 4;
3011
if (req_maxlen)
3012
maxlength = req_maxlen;
3013
else // the format's limit
3014
maxlength = cipher_limit;
3015
if (maxlength >16) maxlength = 16;
3016
3017
/* Password types to try (Numeric, Alpha-Num, Alpha-Num w/ Meta). */
3018
mintype = 0; // 0
3019
maxtype = 2; // 2
3020
3021
crack_seed = 0x10000;
3022
length = minlength - 1;
3023
type = mintype;
3024
3025
count = 0;
3026
c = '0'; while (c <= '9') charset[count++] = c++;
3027
}
3028
3029
void generate()
3030
{
3031
int seed, random;
3032
int i, c;
3033
3034
if (crack_seed > 0xffff) {
3035
crack_seed = 0;
3036
3037
if (++length > maxlength) {
3038
length = minlength;
3039
3040
if (++type > maxtype) {
3041
word[0] = 0;
3042
return;
3043
}
3044
}
3045
3046
count = 10;
3047
if (type >= 1) {
3048
c = 'a'; while (c <= 'f') charset[count++] = c++;
3049
c = 'h'; while (c <= 'z') charset[count++] = c++;
3050
c = 'A'; while (c <= 'Z') charset[count++] = c++;
3051
}
3052
if (type == 2) {
3053
charset[count++] = '!';
3054
c = '#'; while (c <= '&') charset[count++] = c++;
3055
c = '('; while (c <= '/') charset[count++] = c++;
3056
c = '<'; while (c <= '>') charset[count++] = c++;
3057
charset[count++] = '?'; charset[count++] = '@';
3058
charset[count++] = '['; charset[count++] = ']';
3059
charset[count++] = '^'; charset[count++] = '_';
3060
c = '{'; while (c <= '~') charset[count++] = c++;
3061
}
3062
}
3063
3064
seed = (crack_seed++ << 16 >> 16) * 22695477 + 1;
3065
3066
i = 0;
3067
while (i < length) {
3068
random = ((seed = seed * 22695477 + 1) >> 16) & 0x7fff;
3069
word[i++] = charset[random % count];
3070
}
3071
3072
word[i] = 0;
3073
}
3074
3075
/*
3076
* This takes advantage of CVE-2013-2120 to find seeds that KDE Paste applet
3077
* uses to generate passwords.
3078
*
3079
* This software is Copyright (c) Michael Samuel <[email protected]>,
3080
* and it is hereby released to the general public under the following terms:
3081
* Redistribution and use in source and binary forms, with or without
3082
* modification, are permitted.
3083
*/
3084
[List.External:KDEPaste]
3085
int charset[95];
3086
int charset_length, password_length, endTime, startTime, msec;
3087
3088
void init()
3089
{
3090
password_length = 8; /* Change this to match config */
3091
endTime = session_start_time;
3092
startTime = 1343743200; /* Aug 1 2012 - Change this as necessary */
3093
3094
msec = 1; /* msec is never 0 - it would crash the applet */
3095
3096
charset_length = 0;
3097
int c;
3098
3099
/* Comment out classes that you don't need, but keep the order the same */
3100
/* Lowers */
3101
c = 'a'; while (c <= 'z') charset[charset_length++] = c++;
3102
3103
/* Uppers */
3104
c = 'A'; while (c <= 'Z') charset[charset_length++] = c++;
3105
3106
/* Numbers */
3107
c = '0'; while (c <= '9') charset[charset_length++] = c++;
3108
charset[charset_length++] = '0'; /* Yep, it's there twice */
3109
3110
/* Symbols */
3111
c = '!'; while (c <= '/') charset[charset_length++] = c++;
3112
c = ':'; while (c <= '@') charset[charset_length++] = c++;
3113
c = '['; while (c <= '`') charset[charset_length++] = c++;
3114
c = '{'; while (c <= '~') charset[charset_length++] = c++;
3115
}
3116
3117
void generate()
3118
{
3119
int i, rand_seed, rand_result;
3120
3121
/* Terminate once we've generated for all *
3122
* of the time range (Plus a bit more...) */
3123
if (endTime + 1000 < startTime) {
3124
word = 0;
3125
return;
3126
}
3127
3128
/* Skip msecs that would generate dupes */
3129
while (endTime % msec != 0) {
3130
if (++msec > 999) {
3131
endTime--;
3132
msec = 1;
3133
}
3134
}
3135
3136
rand_seed = endTime / msec;
3137
3138
i = 0;
3139
while (i < password_length) {
3140
/* this works like rand_r() from eglibc */
3141
rand_seed = rand_seed * 1103515245 + 12345;
3142
rand_result = (rand_seed >> 16) & 2047;
3143
3144
rand_seed = rand_seed * 1103515245 + 12345;
3145
rand_result <<= 10;
3146
rand_result ^= (rand_seed >> 16) & 1023;
3147
3148
rand_seed = rand_seed * 1103515245 + 12345;
3149
rand_result <<= 10;
3150
rand_result ^= (rand_seed >> 16) & 1023;
3151
3152
word[i++] = charset[rand_result % charset_length];
3153
}
3154
word[i] = 0;
3155
3156
if (++msec > 999) {
3157
endTime--;
3158
msec = 1;
3159
}
3160
}
3161
3162
void restore()
3163
{
3164
int i, rand_seed, rand_result;
3165
3166
i = 0;
3167
3168
/* Very crude restore, just dry-run until we hit last word */
3169
while (i != password_length) {
3170
3171
while (endTime % msec != 0) {
3172
if (++msec > 999) {
3173
endTime--;
3174
msec = 1;
3175
}
3176
}
3177
3178
rand_seed = endTime / msec;
3179
3180
i = 0;
3181
while (i < password_length) {
3182
/* this works like rand_r() from eglibc */
3183
rand_seed = rand_seed * 1103515245 + 12345;
3184
rand_result = (rand_seed >> 16) & 2047;
3185
3186
rand_seed = rand_seed * 1103515245 + 12345;
3187
rand_result <<= 10;
3188
rand_result ^= (rand_seed >> 16) & 1023;
3189
3190
rand_seed = rand_seed * 1103515245 + 12345;
3191
rand_result <<= 10;
3192
rand_result ^= (rand_seed >> 16) & 1023;
3193
3194
if (charset[rand_result % charset_length] != word[i++])
3195
break;
3196
}
3197
3198
if (++msec > 999) {
3199
endTime--;
3200
msec = 1;
3201
}
3202
}
3203
}
3204
3205
/* Awesome Password Generator RNG replay
3206
* Written by Michael Samuel <[email protected]>
3207
* Public Domain.
3208
*
3209
* This takes advantage of a subtle bug, where a crypto RNG is used to
3210
* seed the C# System.Random() class, which takes a 32-bit input, but
3211
* converts negative numbers into non-negative numbers, resulting in
3212
* only 31 bits of security.
3213
*
3214
* This only implements "easy to type" being *unticked*, and numbers,
3215
* lowers, uppers and symbols being ticked, in random password mode.
3216
* Changing the password length is easy, anything else is left as an
3217
* exercise to the reader.
3218
*
3219
* Running Awesome Password Generator (1.3.2 or lower) in Mono is still
3220
* vulnerable, but uses a different RNG, so this mode isn't compatible.
3221
*/
3222
3223
/* Awesome Password Generator 1.3.2 does a two-pass run, selecting which
3224
* charset each position will have, then picking the character. This
3225
* leads to heavy bias, and is fixed in 1.4.0 (along with many other
3226
* fixes). If you have been using Awesome Password Generator, you should
3227
* upgrade immediately and change your passwords.
3228
*/
3229
[List.External:AwesomePasswordGenerator]
3230
int numbers[10];
3231
int lowers[26];
3232
int uppers[26];
3233
int symbols[32];
3234
3235
/* Since we don't have a double datatype, I simply pre-calculated the
3236
* transition numbers calculating the scale formula:
3237
* (double)randNum * 4.656612873077393e-10 * {4/10/26/32}
3238
*/
3239
int boundaries_charclass[4];
3240
int boundaries_numbers[10];
3241
int boundaries_letters[26];
3242
int boundaries_symbols[32];
3243
3244
/* This is the bug we're exploiting - the seed for the RNG is 32 bits
3245
* from the crypto rng. The non-crypto RNG converts negative numbers
3246
* into non-negative numbers, so there's only 2^31 possible seeds.
3247
*/
3248
int seed;
3249
3250
int password_length;
3251
3252
void init()
3253
{
3254
password_length = 16; /* Change this to match config */
3255
3256
int c, i;
3257
3258
c = '0'; i = 0; while (c <= '9') numbers[i++] = c++;
3259
c = 'a'; i = 0; while (c <= 'z') lowers[i++] = c++;
3260
c = 'A'; i = 0; while (c <= 'Z') uppers[i++] = c++;
3261
3262
/* Symbols */
3263
i = 0;
3264
symbols[i++] = '!'; symbols[i++] = '@'; symbols[i++] = '#'; symbols[i++] = '$';
3265
symbols[i++] = '%'; symbols[i++] = '^'; symbols[i++] = '&'; symbols[i++] = '*';
3266
symbols[i++] = '('; symbols[i++] = ')'; symbols[i++] = '~'; symbols[i++] = '-';
3267
symbols[i++] = '_'; symbols[i++] = '='; symbols[i++] = '+'; symbols[i++] = '\\';
3268
symbols[i++] = '|'; symbols[i++] = '/'; symbols[i++] = '['; symbols[i++] = ']';
3269
symbols[i++] = '{'; symbols[i++] = '}'; symbols[i++] = ';'; symbols[i++] = ':';
3270
symbols[i++] = '`'; symbols[i++] = '\''; symbols[i++] = '"'; symbols[i++] = ',';
3271
symbols[i++] = '.'; symbols[i++] = '<'; symbols[i++] = '>'; symbols[i++] = '?';
3272
3273
i = 0;
3274
boundaries_charclass[i++] = 536870912; boundaries_charclass[i++] = 1073741824;
3275
boundaries_charclass[i++] = 1610612736; boundaries_charclass[i++] = 2147483647;
3276
3277
i = 0;
3278
boundaries_numbers[i++] = 214748365; boundaries_numbers[i++] = 429496730;
3279
boundaries_numbers[i++] = 644245095; boundaries_numbers[i++] = 858993460;
3280
boundaries_numbers[i++] = 1073741824; boundaries_numbers[i++] = 1288490189;
3281
boundaries_numbers[i++] = 1503238554; boundaries_numbers[i++] = 1717986919;
3282
boundaries_numbers[i++] = 1932735284; boundaries_numbers[i++] = 2147483647;
3283
3284
i = 0;
3285
boundaries_letters[i++] = 82595525; boundaries_letters[i++] = 165191050;
3286
boundaries_letters[i++] = 247786575; boundaries_letters[i++] = 330382100;
3287
boundaries_letters[i++] = 412977625; boundaries_letters[i++] = 495573150;
3288
boundaries_letters[i++] = 578168675; boundaries_letters[i++] = 660764200;
3289
boundaries_letters[i++] = 743359725; boundaries_letters[i++] = 825955250;
3290
boundaries_letters[i++] = 908550775; boundaries_letters[i++] = 991146300;
3291
boundaries_letters[i++] = 1073741824; boundaries_letters[i++] = 1156337349;
3292
boundaries_letters[i++] = 1238932874; boundaries_letters[i++] = 1321528399;
3293
boundaries_letters[i++] = 1404123924; boundaries_letters[i++] = 1486719449;
3294
boundaries_letters[i++] = 1569314974; boundaries_letters[i++] = 1651910499;
3295
boundaries_letters[i++] = 1734506024; boundaries_letters[i++] = 1817101549;
3296
boundaries_letters[i++] = 1899697074; boundaries_letters[i++] = 1982292599;
3297
boundaries_letters[i++] = 2064888124; boundaries_letters[i++] = 2147483647;
3298
3299
i = 0;
3300
boundaries_symbols[i++] = 67108864; boundaries_symbols[i++] = 134217728;
3301
boundaries_symbols[i++] = 201326592; boundaries_symbols[i++] = 268435456;
3302
boundaries_symbols[i++] = 335544320; boundaries_symbols[i++] = 402653184;
3303
boundaries_symbols[i++] = 469762048; boundaries_symbols[i++] = 536870912;
3304
boundaries_symbols[i++] = 603979776; boundaries_symbols[i++] = 671088640;
3305
boundaries_symbols[i++] = 738197504; boundaries_symbols[i++] = 805306368;
3306
boundaries_symbols[i++] = 872415232; boundaries_symbols[i++] = 939524096;
3307
boundaries_symbols[i++] = 1006632960; boundaries_symbols[i++] = 1073741824;
3308
boundaries_symbols[i++] = 1140850688; boundaries_symbols[i++] = 1207959552;
3309
boundaries_symbols[i++] = 1275068416; boundaries_symbols[i++] = 1342177280;
3310
boundaries_symbols[i++] = 1409286144; boundaries_symbols[i++] = 1476395008;
3311
boundaries_symbols[i++] = 1543503872; boundaries_symbols[i++] = 1610612736;
3312
boundaries_symbols[i++] = 1677721600; boundaries_symbols[i++] = 1744830464;
3313
boundaries_symbols[i++] = 1811939328; boundaries_symbols[i++] = 1879048192;
3314
boundaries_symbols[i++] = 1946157056; boundaries_symbols[i++] = 2013265920;
3315
boundaries_symbols[i++] = 2080374784; boundaries_symbols[i++] = 2147483647;
3316
3317
seed = 0;
3318
}
3319
3320
void generate()
3321
{
3322
int i, j, s, next, nextp, val, bucket, randnum, used_charsets;
3323
int seedarray[56];
3324
3325
/* BEGIN System.Random(seed) */
3326
if(seed < 0) {
3327
/* Only bother with non-negative integers */
3328
word = 0;
3329
return;
3330
}
3331
3332
s = 161803398 - seed++;
3333
seedarray[55] = s;
3334
i = val = 1;
3335
3336
while(i < 55) {
3337
bucket = 21 * i % 55;
3338
seedarray[bucket] = val;
3339
val = s - val;
3340
if(val < 0) val += 2147483647;
3341
s = seedarray[bucket];
3342
i++;
3343
}
3344
3345
i = 1;
3346
while(i < 5) {
3347
j = 1;
3348
while(j < 56) {
3349
seedarray[j] -= seedarray[1 + (j + 30) % 55];
3350
if(seedarray[j] < 0) seedarray[j] += 2147483647;
3351
j++;
3352
}
3353
i++;
3354
}
3355
next = 0;
3356
nextp = 21;
3357
/* END System.Random(seed) */
3358
3359
used_charsets = 0;
3360
while(used_charsets != 15) {
3361
i = 0;
3362
while(i < password_length) {
3363
/* BEGIN Random.Sample() */
3364
if (++next >= 56) next = 1;
3365
if (++nextp >= 56) nextp = 1;
3366
randnum = seedarray[next] - seedarray[nextp];
3367
if (randnum == 2147483647) randnum--;
3368
if (randnum < 0) randnum += 2147483647;
3369
seedarray[next] = randnum;
3370
/* END Random.Sample() */
3371
3372
j = 0;
3373
while(boundaries_charclass[j] < randnum) j++;
3374
3375
word[i] = j; /* Temporarily store in word[] */
3376
used_charsets |= (1 << j);
3377
i++;
3378
}
3379
}
3380
3381
i = 0;
3382
while(i < password_length) {
3383
/* BEGIN Random.Sample() */
3384
if (++next >= 56) next = 1;
3385
if (++nextp >= 56) nextp = 1;
3386
randnum = seedarray[next] - seedarray[nextp];
3387
if (randnum == 2147483647) randnum--;
3388
if (randnum < 0) randnum += 2147483647;
3389
seedarray[next] = randnum;
3390
/* END Random.Sample() */
3391
j = 0;
3392
3393
if(word[i] == 0) {
3394
while(boundaries_letters[j] < randnum) j++;
3395
word[i++] = lowers[j];
3396
} else if (word[i] == 1) {
3397
while(boundaries_letters[j] < randnum) j++;
3398
word[i++] = uppers[j];
3399
} else if (word[i] == 2) {
3400
while(boundaries_numbers[j] < randnum) j++;
3401
word[i++] = numbers[j];
3402
} else { /* if (word[i] == 3) */
3403
while(boundaries_symbols[j] < randnum) j++;
3404
word[i++] = symbols[j];
3405
}
3406
}
3407
word[i] = 0;
3408
}
3409
3410
3411
void restore()
3412
{
3413
int i, j, s, next, nextp, val, bucket, randnum, used_charsets;
3414
int seedarray[56];
3415
int candidate[32]; /* This needs to be at-least as big as password-length */
3416
3417
seed = 0;
3418
3419
while(seed > 0) {
3420
/* BEGIN System.Random(seed) */
3421
s = 161803398 - seed++;
3422
seedarray[55] = s;
3423
i = val = 1;
3424
3425
while(i < 55) {
3426
bucket = 21 * i % 55;
3427
seedarray[bucket] = val;
3428
val = s - val;
3429
if(val < 0) val += 2147483647;
3430
s = seedarray[bucket];
3431
i++;
3432
}
3433
3434
i = 1;
3435
while(i < 5) {
3436
j = 1;
3437
while(j < 56) {
3438
seedarray[j] -= seedarray[1 + (j + 30) % 55];
3439
if(seedarray[j] < 0) seedarray[j] += 2147483647;
3440
j++;
3441
}
3442
i++;
3443
}
3444
next = 0;
3445
nextp = 21;
3446
/* END System.Random(seed) */
3447
3448
used_charsets = 0;
3449
while(used_charsets != 15) {
3450
i = 0;
3451
while(i < password_length) {
3452
/* BEGIN Random.Sample() */
3453
if (++next >= 56) next = 1;
3454
if (++nextp >= 56) nextp = 1;
3455
randnum = seedarray[next] - seedarray[nextp];
3456
if (randnum == 2147483647) randnum--;
3457
if (randnum < 0) randnum += 2147483647;
3458
seedarray[next] = randnum;
3459
/* END Random.Sample() */
3460
3461
j = 0;
3462
while(boundaries_charclass[j] < randnum) j++;
3463
3464
candidate[i] = j;
3465
used_charsets |= (1 << j);
3466
i++;
3467
}
3468
}
3469
3470
i = 0;
3471
while(i < password_length) {
3472
/* BEGIN Random.Sample() */
3473
if (++next >= 56) next = 1;
3474
if (++nextp >= 56) nextp = 1;
3475
randnum = seedarray[next] - seedarray[nextp];
3476
if (randnum == 2147483647) randnum--;
3477
if (randnum < 0) randnum += 2147483647;
3478
seedarray[next] = randnum;
3479
/* END Random.Sample() */
3480
j = 0;
3481
3482
if(candidate[i] == 0) {
3483
while(boundaries_letters[j] < randnum) j++;
3484
if(lowers[j] != word[i++]) break;
3485
} else if (candidate[i] == 1) {
3486
while(boundaries_letters[j] < randnum) j++;
3487
if(uppers[j] != word[i++]) break;
3488
} else if (candidate[i] == 2) {
3489
while(boundaries_numbers[j] < randnum) j++;
3490
if(numbers[j] != word[i++]) break;
3491
} else { /* if (word[i] == 3) */
3492
while(boundaries_symbols[j] < randnum) j++;
3493
if(symbols[j] != word[i++]) break;
3494
}
3495
}
3496
if(i == password_length) return;
3497
}
3498
}
3499
3500
# generate all possible wps pins
3501
[List.External:wpspin]
3502
int pin;
3503
void init() {
3504
pin = 0;
3505
}
3506
void generate() {
3507
if (pin > 9999999) {
3508
word = 0;
3509
return;
3510
}
3511
int i, p;
3512
i = 0;
3513
while (i < 8) word[i++] = '0';
3514
word[8] = 0;
3515
p = pin;
3516
i = 6;
3517
while (p) {
3518
word[i] = '0' + p % 10;
3519
p /= 10;
3520
--i;
3521
}
3522
p = pin;
3523
i = 0;
3524
while (p) {
3525
i += 3 * (p % 10);
3526
p /= 10;
3527
i += p % 10;
3528
p /= 10;
3529
}
3530
word[7] = '0' + ((10 - i % 10) % 10);
3531
++pin;
3532
}
3533
3534
# Append the Luhn algorithm digit to arbitrary all-digit strings. Optimized
3535
# for speed, not for size nor simplicity. The primary optimization trick is to
3536
# compute the length and four sums in parallel (in two SIMD'ish variables).
3537
# Then whether the length is even or odd determines which two of the four sums
3538
# are actually used. Checks for non-digits and for NUL are packed into the
3539
# SIMD'ish bitmasks as well.
3540
[List.External:AppendLuhn]
3541
int map1[0x100], map2[0x1fff];
3542
3543
void init()
3544
{
3545
int i;
3546
3547
map1[0] = ~0x7fffffff;
3548
i = 1;
3549
while (i < 0x100)
3550
map1[i++] = ~0x7effffff;
3551
i = -1;
3552
while (++i < 10)
3553
map1['0' + i] = i + ((i * 2 % 10 + i / 5) << 12);
3554
i = -1;
3555
while (++i < 0x1fff) {
3556
if (i % 10)
3557
map2[i] = '9' + 1 - i % 10;
3558
else
3559
map2[i] = '0';
3560
}
3561
}
3562
3563
void filter()
3564
{
3565
int i, o, e;
3566
3567
i = o = e = 0;
3568
while ((o += map1[word[i++]]) >= 0) {
3569
if ((e += map1[word[i++]]) >= 0)
3570
continue;
3571
if (e & 0x01000000)
3572
return; // Not all-digit, leave unmodified
3573
word[i--] = 0;
3574
word[i] = map2[(e & 0xfff) + (o >> 12)];
3575
return;
3576
}
3577
if (o & 0x01000000)
3578
return; // Not all-digit, leave unmodified
3579
word[i--] = 0;
3580
word[i] = map2[(o & 0xfff) + (e >> 12)];
3581
}
3582
3583
# Simple password policy matching: require at least one digit.
3584
[List.External:AtLeast1-Simple]
3585
void filter()
3586
{
3587
int i, c;
3588
3589
i = 0;
3590
while (c = word[i++])
3591
if (c >= '0' && c <= '9')
3592
return; // Found at least one suitable character, good
3593
3594
word = 0; // No suitable characters found, skip this "word"
3595
}
3596
3597
# The same password policy implemented in a more efficient and more generic
3598
# fashion (easy to expand to include other "sufficient" characters as well).
3599
[List.External:AtLeast1-Generic]
3600
int mask[0x100];
3601
3602
void init()
3603
{
3604
int c;
3605
3606
mask[0] = 0; // Terminate the loop in filter() on NUL
3607
c = 1;
3608
while (c < 0x100)
3609
mask[c++] = 1; // Continue looping in filter() on most chars
3610
3611
c = '0';
3612
while (c <= '9')
3613
mask[c++] = 0; // Terminate the loop in filter() on digits
3614
}
3615
3616
void filter()
3617
{
3618
int i;
3619
3620
i = -1;
3621
while (mask[word[++i]])
3622
continue;
3623
if (word[i])
3624
return; // Found at least one suitable character, good
3625
3626
word = 0; // No suitable characters found, skip this "word"
3627
}
3628
3629
# An efficient and fairly generic password policy matcher. The policy to match
3630
# is specified in the check at the end of filter() and in mask[]. For example,
3631
# lowercase and uppercase letters may be treated the same by initializing the
3632
# corresponding mask[] elements to the same value, then adjusting the value to
3633
# check "seen" for accordingly.
3634
[List.External:Policy]
3635
int mask[0x100];
3636
3637
void init()
3638
{
3639
int c;
3640
3641
mask[0] = 0x100;
3642
c = 1;
3643
while (c < 0x100)
3644
mask[c++] = 0x200;
3645
3646
c = 'a';
3647
while (c <= 'z')
3648
mask[c++] = 1;
3649
c = 'A';
3650
while (c <= 'Z')
3651
mask[c++] = 2;
3652
c = '0';
3653
while (c <= '9')
3654
mask[c++] = 4;
3655
}
3656
3657
void filter()
3658
{
3659
int i, seen;
3660
3661
/*
3662
* This loop ends when we see NUL (sets 0x100) or a disallowed character
3663
* (sets 0x200).
3664
*/
3665
i = -1; seen = 0;
3666
while ((seen |= mask[word[++i]]) < 0x100)
3667
continue;
3668
3669
/*
3670
* We should have seen at least one character of each type (which "add up"
3671
* to 7) and then a NUL (adds 0x100), but not any other characters (would
3672
* add 0x200). The length must be 8.
3673
*/
3674
if (seen != 0x107 || i != 8)
3675
word = 0; // Does not conform to policy
3676
}
3677
3678
# Trivial Rotate function, which rotates letters in a word
3679
# by a given number of places (like 13 in case of ROT13).
3680
# Words which don't contain any letters (and thus wouldn't be changed
3681
# by this filter) are skipped, because these unchanged words probably
3682
# should have been tried before trying a mangled version.
3683
[List.External_base:Filter_Rotate]
3684
3685
int rot; // The number of places to rotate each letter in a word
3686
3687
void filter()
3688
{
3689
int i, j, c;
3690
3691
i = 0;
3692
j = 0; // j counts the number of changed characters
3693
3694
while (c = word[i]) {
3695
if (c >= 'a' && c <= 'z') {
3696
c = c - 26 + rot;
3697
if (c < 'a') c += 26;
3698
word[i] = c;
3699
j++;
3700
} else if (c >= 'A' && c <= 'Z' ) {
3701
c = c - 26 + rot;
3702
if (c < 'A') c += 26;
3703
word[i] = c;
3704
j++;
3705
}
3706
i++;
3707
}
3708
if (j == 0)
3709
// Nothing changed. Reject this word.
3710
word = 0;
3711
}
3712
3713
# ROT13 Example
3714
[List.External:Filter_ROT13]
3715
.include [List.External_base:Filter_Rotate]
3716
void init()
3717
{
3718
// Just in case someone wants to "rotate" by other values,
3719
// adjust the value of the rot variable
3720
// (may be in a copied external mode):
3721
// 13: "abcABCxyzXYZ" -> "nopNOPklmKLM"
3722
// 1: "abcABCxyzXYZ" -> "bcdBCDyzaYZA"
3723
// 25: "abcABCxyzXYZ" -> "zabZABwxyWXY"
3724
// -1: "abcABCxyzXYZ" -> "zabZABwxyWXY"
3725
// and so on
3726
// Allowed range: -25 <= rot <= -1, or 1 <= rot <= 25
3727
rot = 13;
3728
3729
// Don't change the following statement.
3730
// It is supposed to "sanitize" the value to be in the
3731
// range
3732
rot = (rot + 26) % 26;
3733
}
3734
3735
# Trivial parallel processing example (obsoleted by the "--node" option)
3736
[List.External:Parallel]
3737
/*
3738
* This word filter makes John process some of the words only, for running
3739
* multiple instances on different CPUs. It can be used with any cracking
3740
* mode except for "single crack". Note: this is not a good solution, but
3741
* is just an example of what can be done with word filters.
3742
*/
3743
3744
int node, total; // This node's number, and node count
3745
int number; // Current word number
3746
3747
void init()
3748
{
3749
node = 1; total = 2; // Node 1 of 2, change as appropriate
3750
number = node - 1; // Speedup the filter a bit
3751
}
3752
3753
void filter()
3754
{
3755
if (number++ % total) // Word for a different node?
3756
word = 0; // Yes, skip it
3757
}
3758
3759
# Interrupt the cracking session after "max" words tried
3760
[List.External:AutoAbort]
3761
int max; // Maximum number of words to try
3762
int number; // Current word number
3763
3764
void init()
3765
{
3766
max = 1000;
3767
number = 0;
3768
}
3769
3770
void filter()
3771
{
3772
if (++number > max)
3773
abort = 1; // Interrupt the cracking session
3774
}
3775
3776
# Print the status line after every "interval" words tried
3777
[List.External:AutoStatus]
3778
int interval; // How often to print the status
3779
int number; // Current word number
3780
3781
void init()
3782
{
3783
interval = 1000;
3784
number = 0;
3785
}
3786
3787
void filter()
3788
{
3789
if (number++ % interval)
3790
return;
3791
status = 1; // Print the status line
3792
}
3793
3794
#
3795
# Reference example hybrid-mode external. same as jtr-rule: $[0-9]$[0-9]
3796
# this format is to be used similar to a filter, in that it requires some
3797
# other word generator (markov, wordlist, etc). However, this type external
3798
# will get new() called with each word, and then have next() called, until
3799
# the word[0]=0 is seen (meaning all candidates for the base word have been
3800
# generated. Prior to new() or restore(), word[] is the 'base' word.
3801
# if the script is able to properly resume, then it should set the global
3802
# variable hybrid_total to the count of candidates that will be generated
3803
# for this word (in new() / restore(), then in the body of restore() there
3804
# is a global variable set 'hybrid_resume' that was the prior number of
3805
# canidates generated for this base-word. Resume should start at the NEXT
3806
# If the script is not able to easily resume, then simply do NOT set the
3807
# global hybrid_total to anything either function. JtR will 'still' resume
3808
# propery, but it will do so by calling new()/next()/next().../next() until
3809
# back to the proper resume location.
3810
#
3811
# script changed to append a _ character before the number, each time within
3812
# the next() function. Done this way to better validate that -restore within
3813
# jtr is working properly.
3814
#
3815
[List.External:Hybrid_example]
3816
/* static vars for the script */
3817
int cnt, length, total;
3818
3819
void init()
3820
{
3821
/* in this simple example, we always generate 100 candidates per word */
3822
total = 100;/* this is a VERY simple example */
3823
}
3824
3825
/* new word */
3826
void new()
3827
{
3828
/* get the word length) */
3829
length = 0; while (word[length++]) ; --length;
3830
3831
/*
3832
* If this was a more complex script, we would compute total candidates
3833
* at this location, if we can. If we can not compute total candidates
3834
* then it is likely we can not resume 'easily', so if that is the
3835
* case, we would simply set hybrid_total to -1, or do nothing, since
3836
* do_external_hybrid_crack() sets it to -1 before calling this function.
3837
*/
3838
hybrid_total = total;
3839
3840
/* Reset or counter for THIS word. */
3841
cnt = 0;
3842
3843
/*
3844
* word will be too long to be used, or too short to be used. If so
3845
* then set hybrid_total to 0 and this entire word will be skipped.
3846
*/
3847
if (req_minlen > length - 2 || (req_maxlen && req_maxlen < length + 2))
3848
hybrid_total = 0;
3849
}
3850
3851
void next()
3852
{
3853
/* in this simple script, if cnt is 100, this word is DONE */
3854
if (cnt == 100) {
3855
word[0] = 0;
3856
return;
3857
}
3858
3859
/* set word[] to the next candidate */
3860
word[length++] = '_';
3861
word[length ] = '0' + cnt / 10;
3862
word[length+1] = '0' + cnt % 10;
3863
word[length+2] = 0;
3864
++cnt;
3865
}
3866
3867
/* Called when restoring an interrupted session */
3868
void restore()
3869
{
3870
int i;
3871
3872
length = 0; while (word[length++]) ; --length;
3873
3874
/* for this simple script, simply setting cnt resumes */
3875
cnt = hybrid_resume + 1; if (cnt > 100) cnt=100;
3876
i = 0;
3877
while (i++ < cnt) word[length++] = '_';
3878
word[length] = 0;
3879
3880
/* tell john that we have properly 'resumed', by setting a 'proper' total */
3881
hybrid_total = total;
3882
}
3883
3884
# External hybrid 'leet code
3885
[List.External:Leet]
3886
/*
3887
* 1337 language in this script:
3888
* a -> a4@
3889
* b -> b8
3890
* e -> e3
3891
* g -> g9
3892
* i -> i1!
3893
* l -> l1
3894
* o -> o0
3895
* s -> s$5
3896
* t -> t7
3897
*/
3898
3899
int rotor[626]; /* max length input is 125 bytes [125*5+1]; */
3900
int rotors[125];
3901
int rotor_ptr[125];
3902
int rotor_idx[125];
3903
int rotor_cnt[125];
3904
int current_word_count;
3905
int max_mangle; /* controls how many bytes we run through our 'leet' code */
3906
int max_mangle_letters;
3907
int original_word; /* if set to 1 then we start with original word. If 0, then start with first mangled word */
3908
3909
void init()
3910
{
3911
/* note, 3^10 is 59k so aaaaaaaaaa will produce that many words! */
3912
max_mangle_letters = 10; /* only mangle 10 characters max */
3913
max_mangle = 4000; /* Stop building new letters if our count goes over this value */
3914
original_word = 0;
3915
}
3916
3917
/* new word */
3918
void new()
3919
{
3920
int rotor_off, idx, wlen;
3921
idx = rotor_off = wlen = 0;
3922
hybrid_total = 1;
3923
while (word[wlen++]) ; --wlen;
3924
if (req_minlen > wlen || (req_maxlen && req_maxlen < wlen )) {
3925
hybrid_total = 0;
3926
return;
3927
}
3928
wlen = 0;
3929
while (word[wlen] && idx < max_mangle_letters && hybrid_total < max_mangle) {
3930
rotor_cnt[wlen] = rotor_idx[wlen] = 0;
3931
rotor_ptr[wlen] = rotor_off;
3932
if (word[wlen] == 'a') {
3933
rotor[rotor_off++] = 'a';
3934
rotor[rotor_off++] = '4';
3935
rotor[rotor_off++] = '@';
3936
}
3937
else if (word[wlen] == 'b') {
3938
rotor[rotor_off++] = 'b';
3939
rotor[rotor_off++] = '8';
3940
}
3941
else if (word[wlen] == 'e') {
3942
rotor[rotor_off++] = 'e';
3943
rotor[rotor_off++] = '3';
3944
}
3945
else if (word[wlen] == 'g') {
3946
rotor[rotor_off++] = 'g';
3947
rotor[rotor_off++] = '9';
3948
}
3949
else if (word[wlen] == 'i') {
3950
rotor[rotor_off++] = 'i';
3951
rotor[rotor_off++] = '1';
3952
rotor[rotor_off++] = '!';
3953
}
3954
else if (word[wlen] == 'l') {
3955
rotor[rotor_off++] = 'l';
3956
rotor[rotor_off++] = '1';
3957
}
3958
else if (word[wlen] == 'o') {
3959
rotor[rotor_off++] = 'o';
3960
rotor[rotor_off++] = '0';
3961
}
3962
else if (word[wlen] == 's') {
3963
rotor[rotor_off++] = 's';
3964
rotor[rotor_off++] = '$';
3965
rotor[rotor_off++] = '5';
3966
}
3967
else if (word[wlen] == 't') {
3968
rotor[rotor_off++] = 't';
3969
rotor[rotor_off++] = '7';
3970
}
3971
if (rotor_off > rotor_ptr[wlen]) {
3972
rotor_cnt[wlen] = rotor_off-rotor_ptr[wlen];
3973
hybrid_total *= rotor_cnt[wlen];
3974
rotors[idx++] = wlen;
3975
}
3976
++wlen;
3977
}
3978
/* hybrid_total+666 is our indicator that this is the original word */
3979
if (original_word)
3980
current_word_count = hybrid_total+666;
3981
else {
3982
current_word_count = 1; /* skip the 'original' word */
3983
}
3984
}
3985
3986
/* next iteration of this word word */
3987
void next()
3988
{
3989
int idx, idx2;
3990
if (current_word_count >= hybrid_total) {
3991
if (current_word_count == hybrid_total+666) {
3992
/* first word (starting word) we leave alone */
3993
/* by making it > hybrid_total, we avoid a 2nd if statement */
3994
current_word_count = 1;
3995
return;
3996
}
3997
word[0] = 0;
3998
return;
3999
}
4000
idx = rotors[idx2=0];
4001
while (++rotor_idx[idx] >= rotor_cnt[idx]) {
4002
rotor_idx[idx] = 0;
4003
word[idx] = rotor[ rotor_ptr[idx] ];
4004
idx = rotors[++idx2];
4005
}
4006
word[idx] = rotor[ rotor_ptr[idx]+rotor_idx[idx] ];
4007
++current_word_count;
4008
}
4009
/* restore() not needed. john properly restores fast enough without it */
4010
4011
# Shared base code for External hybrid CaSE and Wordcase mutation code
4012
[List.External_base:Case]
4013
4014
int rotor[251]; /* max length input is 125 bytes [125*5+1]; */
4015
int rotors[125];
4016
int rotor_ptr[125];
4017
int rotor_idx[125];
4018
int rotor_cnt[125];
4019
int current_word_count;
4020
int max_mangle; /* controls how many bytes we run through our 'leet' code */
4021
int original_word; /* if set to 1 then we start with original word. If 0, then start with first mangled word */
4022
int word_mode; /* if set to 1, only first character of each space-separated word is case-toggled, else every character */
4023
4024
/* new word */
4025
void new()
4026
{
4027
int rotor_off, idx, wlen, ch, prevch;
4028
idx = rotor_off = wlen = 0;
4029
hybrid_total = 1;
4030
while (word[wlen++]) ; --wlen;
4031
if (req_minlen > wlen || (req_maxlen && req_maxlen < wlen )) {
4032
hybrid_total = 0;
4033
return;
4034
}
4035
wlen = 0;
4036
prevch = ' '; /* at word start, behave as if previous char was space for wordcase mode */
4037
while (word[wlen] && idx < max_mangle) {
4038
rotor_cnt[wlen] = rotor_idx[wlen] = 0;
4039
rotor_ptr[wlen] = rotor_off;
4040
ch = word[wlen];
4041
/* traditionally, this block was always executed, with Wordcase
4042
mode added we execute it either always when word_mode isn't
4043
used or at the beginning of a word or when the previous char
4044
was space */
4045
if (!word_mode || prevch == ' ') {
4046
if (ch >= 'A' && ch <= 'Z') {
4047
ch += 0x20;
4048
word[wlen] = ch;
4049
rotor[rotor_off++] = ch;
4050
rotor[rotor_off++] = ch-0x20;
4051
}
4052
if (ch >= 'a' && ch <= 'z') {
4053
rotor[rotor_off++] = ch;
4054
rotor[rotor_off++] = ch-0x20;
4055
rotor_cnt[wlen] = 2;
4056
hybrid_total *= 2;
4057
rotors[idx++] = wlen;
4058
}
4059
}
4060
++wlen;
4061
prevch = ch;
4062
}
4063
/* hybrid_total+666 is our indicator that this is the original word */
4064
if (original_word)
4065
current_word_count = hybrid_total+666;
4066
else {
4067
current_word_count = 1; /* skip the 'original' word */
4068
}
4069
}
4070
4071
/* next iteration of this word word */
4072
void next()
4073
{
4074
int idx, idx2;
4075
if (current_word_count >= hybrid_total) {
4076
if (current_word_count == hybrid_total+666) {
4077
/* first word (starting word) we leave alone */
4078
/* by making it > hybrid_total, we avoid a 2nd if statement */
4079
current_word_count = 1;
4080
return;
4081
}
4082
word[0] = 0;
4083
return;
4084
}
4085
idx = rotors[idx2=0];
4086
while (++rotor_idx[idx] >= rotor_cnt[idx]) {
4087
rotor_idx[idx] = 0;
4088
word[idx] = rotor[ rotor_ptr[idx] ];
4089
idx = rotors[++idx2];
4090
}
4091
word[idx] = rotor[ rotor_ptr[idx]+rotor_idx[idx] ];
4092
++current_word_count;
4093
}
4094
/* restore() not needed. john properly restores fast enough without it */
4095
4096
# External hybrid CaSE mutation code
4097
[List.External:Case]
4098
.include [List.External_base:Case]
4099
4100
void init()
4101
{
4102
max_mangle = 20; /* only mangle 20 characters max (2^20 is 1 million) */
4103
original_word = 1; /* for case mangle, unless the data is 100% lower case, we really can not skip the original word */
4104
word_mode = 0;
4105
}
4106
4107
4108
# external mode toggling case in all word combinations, e.g:
4109
# foo bar -> foo bar, foo Bar, Foo bar, Foo Bar
4110
[List.External:Wordcase]
4111
.include [List.External_base:Case]
4112
4113
void init()
4114
{
4115
max_mangle = 20; /* only mangle 20 characters max (2^20 is 1 million) */
4116
original_word = 1; /* for case mangle, unless the data is 100% lower case, we really can not skip the original word */
4117
word_mode = 1;
4118
}
4119
4120
# Alternate hybrid external 'leet' mode (HybridLeet)
4121
.include <hybrid.conf>
4122
4123
# Note that the (newer) cracking mode --subsets=full-unicode is way faster than
4124
# the external dumb/repeats modes below, although not as easy to adapt to smaller
4125
# portions of the Unicode space. See doc/SUBSETS
4126
4127
# dumb-force UTF-16, in an external file
4128
.include <dumb16.conf>
4129
4130
# dumb-force UTF-32, in an external file
4131
.include <dumb32.conf>
4132
4133
# repeats UTF-16, in an external file
4134
.include <repeats16.conf>
4135
4136
# repeats UTF-32, in an external file
4137
.include <repeats32.conf>
4138
4139
# Dynamic ($dynamic_n$) scripting code, in an external file
4140
.include <dynamic.conf>
4141
4142
# Regex alphabets
4143
.include <regex_alphabets.conf>
4144
4145
# NOTE, this file (john.local.conf) is deprecated. If you had any modified logic in this
4146
# file, please create and move it to john-local.conf. The file simply can be renamed to
4147
# the new john-local.conf if you so choose.
4148
.include '$JOHN/john.local.conf'
4149
4150
# include john-local.conf (This file can be created by user, to override defaults in this john.conf file)
4151
.include '$JOHN/john-local.conf'
4152
4153
# include john-local.conf in local dir, it can override john.conf, john-local.conf (or any other conf file loaded)
4154
# This is disabled by default since it's a security risk in case JtR is ever run with untrusted current directory
4155
#.include './john-local.conf'
4156
4157
# End of john.conf file.
4158
# Keep this comment, and blank line above it, to make sure a john-local.conf
4159
# that does not end with \n is properly loaded.
4160
4161