/run/john.conf
Config | 3086 lines | 2693 code | 393 blank | 0 comment | 0 complexity | fcf9420b32ab2f5b351a9b9aec3a73b0 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, AGPL-1.0
- #
- # This file is part of John the Ripper password cracker,
- # Copyright (c) 1996-2006,2008-2013 by Solar Designer
- #
- # Redistribution and use in source and binary forms, with or without
- # modification, are permitted.
- #
- # There's ABSOLUTELY NO WARRANTY, express or implied.
- #
- # Please note that although this configuration file is under the cut-down BSD
- # license above, many source files in John the Ripper are under GPLv2.
- # For licensing terms for John the Ripper as a whole, see doc/LICENSE.
- #
- # ...with changes in the jumbo patch, by various authors
- #
- # The [Options] section is for general options only.
- # Note that MPI specific options have been moved
- # to [Options.MPI]
- # There is also a new section [Options.OpenCL]
- # for OpenCL specific options
- # Default settings for Markov mode have been moved
- # to [Markov.Default], but you can define other
- # Markov modes as well, see ../doc/MARKOV
- [Options]
- # Default wordlist file name (including in batch mode)
- Wordlist = $JOHN/password.lst
- # Use idle cycles only
- Idle = Y
- # Crash recovery file saving delay in seconds
- Save = 60
- # Beep when a password is found (who needs this anyway?)
- Beep = N
- # if set to Y then dynamic format will always work with bare hashes. Normally
- # dynamic only uses bare hashes if a single dynamic type is selected with
- # the -format= (so -format=dynamic_0 would use valid bare hashes).
- DynamicAlwaysUseBareHashes = N
- # Default Single mode rules
- SingleRules = Single
- # Default batch mode Wordlist rules
- BatchModeWordlistRules = Wordlist
- # Default wordlist mode rules when not in batch mode (if any)
- # If this is set and you want to run once without rules, use --rules:none
- #WordlistRules = Wordlist
- # Default loopback mode rules (if any)
- # If this is set and you want to run once without rules, use --rules:none
- LoopbackRules = Loopback
- # Default/batch mode Incremental mode
- # Warning: changing these might currently break resume on existing sessions
- DefaultIncremental = ASCII
- #DefaultIncrementalUTF8 = UTF8
- DefaultIncrementalLM = LM_ASCII
- # Time formatting string used in status ETA.
- #
- # TimeFormat24 is used when ETA is within 24h, so it is possible to omit
- # the date then if you like, and show seconds instead.
- #
- # %c means 'local' specific canonical form, such as:
- # 05/06/11 18:10:34
- #
- # Other examples
- # %d/%m/%y %H:%M (day/mon/year hour:min)
- # %m/%d/%y %H:%M (mon/day/year hour:min)
- # %Y-%m-%d %H:%M (ISO 8601 style, 2011-05-06 18:10)
- TimeFormat = %Y-%m-%d %H:%M
- TimeFormat24 = %H:%M:%S
- # For single mode, load the full GECOS field (before splitting) as one
- # additional candidate. Normal behavior is to only load individual words
- # from that field. Enabling this can help when this field contains email
- # addresses or other strings that are better used unsplit, but it increases
- # the number of words tried so it may also slow things down. If enabling this
- # you might want to bump SingleWordsPairMax too, below, to 10 or more.
- PristineGecos = N
- # Over-ride SINGLE_WORDS_PAIR_MAX in params.h. This may slow down Single mode
- # but it may also help cracking a few more candidates. Default in core John
- # is 4 while the Jumbo default is 6.
- SingleWordsPairMax = 6
- # Emit a status line whenever a password is cracked (this is the same as
- # passing the --crack-status option flag to john). NOTE: if this is set
- # to true here, --crack-status will toggle it back to false.
- CrackStatus = N
- # When printing status, show number of candidates tried (eg. 123456p). Note
- # that the number *is* now equal to "words tried" and nothing else.
- # This is added to the "+ Cracked" line in the log as well.
- StatusShowCandidates = N
- # Write cracked passwords to the log file (default is just the user name)
- LogCrackedPasswords = N
- # Disable the dupe checking when loading hashes. For testing purposes only!
- NoLoaderDupeCheck = N
- # Default --encoding for input files (ie. login/GECOS fields) and wordlists
- # etc. If this is not set here (you need to uncomment it) and --encoding is
- # not used either, the default is ISO-8859-1 for Unicode conversions and 7-bit
- # ASCII encoding is assumed for rules - so eg. uppercasing of letters other
- # than a-z will not work at all!
- #DefaultEncoding = UTF-8
- # Default --target-encoding for Microsoft hashes (LM, NETLM et al) when input
- # encoding is UTF-8. CP850 would be a universal choice for covering most
- # "latin" countries.
- #DefaultMSCodepage = CP850
- # Default --intermediate-encoding to be used within the rules engine when both
- # input and "target" encodings are Unicode (eg. UTF-8 wordlist and NT hashes).
- # This may hit performance but lets us do things like case conversions for
- # UTF-8. You can pick any supported codepage that has as much support for the
- # input data as possible - eg. for "latin" language passwords you can use
- # CP850, ISO-8859-1 or CP1252 and it will probably not make a difference.
- #DefaultIntermediateEncoding = CP1252
- # Warn if seeing UTF-8 when expecting some other encoding, or vice versa.
- #WarnEncoding = Y
- # Always report (to screen and log) cracked passwords as UTF-8, regardless of
- # input encoding. This is recommended if you have your terminal set for UTF-8.
- #AlwaysReportUTF8 = Y
- # Always store Unicode (UTF-16) passwords as UTF-8 in john.pot, regardless
- # of input encoding. This prevents john.pot from being filled with mixed
- # and eventually unknown encodings. This is recommended if you have your
- # terminal set for UTF-8 and/or you want to run --loopback for LM->NT
- # including non-ASCII.
- #UnicodeStoreUTF8 = Y
- # Always report/store non-Unicode formats as UTF-8, regardless of input
- # encoding. Note: The actual codepage that was used is not stored anywhere
- # except in the log file. This is needed eg. for --loopback to crack LM->NT
- # including non-ASCII.
- #CPstoreUTF8 = Y
- # Default verbosity is 3, valid figures are 1-5 right now.
- # 4-5 enables some extra output
- # 2 mutes rules & incremental output in logs (LOTS of lines)
- # 1 even mutes printing (to screen) of cracked passwords
- Verbosity = 3
- # If set to Y, do not output, log or store cracked passwords verbatim.
- # This implies a different default .pot database file "secure.pot" instead
- # of "john.pot" but it can still be overridden using --pot=FILE.
- # This also overrides other options, eg. LogCrackedPasswords.
- SecureMode = N
- # If set to Y, a session using --fork or MPI will signal to other nodes when
- # it has written cracks to the pot file (note that this writing is delayed
- # by buffers and the "Save" timer above), so they will re-sync.
- ReloadAtCrack = Y
- # If set to Y, resync pot file when saving session.
- ReloadAtSave = Y
- # If this file exists, john will abort cleanly
- AbortFile = /var/run/john/abort
- # While this file exists, john will pause
- PauseFile = /var/run/john/pause
- [Options:MPI]
- # Automagically disable OMP if MPI is used (set to N if
- # you want to run one MPI process per multi-core host)
- MPIOMPmutex = Y
- # Print a notice if disabling OMP (when MPIOMPmutex = Y)
- # or when running OMP and MPI at the same time
- MPIOMPverbose = Y
- [Options:OpenCL]
- # Set default OpenCL platform and/or device. Command line options will
- # override these. If neither is set, we will search for a GPU or fall-back
- # to platform 0, device 0.
- #Platform = 0
- #Device = 0
- # Some formats vectorize their kernels in case the device says it's a good
- # idea. Some devices give "improper" hints which means we vectorize but get
- # a performance drop. If you have such a device, uncommenting the below
- # will disable vectorizing globally.
- # With this set to N (or commented out) you can force it per session with
- # the --force-scalar command-line option instead.
- #ForceScalar = Y
- # Format-specific settings for Local Work Size and Global Work Size call.
- # An LWS or GWS of zero will initiate auto enumeration. The environment
- # variables LWS and/or GWS will override these figures.
- #ssha_LWS = 512
- #ssha_GWS = 8192
- # For RAR format.
- #rar_LWS = 128
- #rar_GWS = 8192
- # For SHA-2.
- #sha512crypt_LWS = 64
- #sha512crypt_GWS = 8192
- #sha256crypt_LWS = xxx
- #sha256crypt_GWS = xxx
- #rawsha256_LWS = xxx
- #rawsha256_GWS = xxx
- #rawsha512_LWS = xxx
- #rawsha512_GWS = xxx
- #xsha512_LWS = xxx
- #xsha512_GWS = xxx
- # For office formats.
- #office2007_LWS = 64
- #office2007_GWS = 8192
- #office2010_LWS = 64
- #office2010_GWS = 8192
- #office2013_LWS = 64
- #office2013_GWS = 8192
- # For NTLMv2 format
- #ntlmv2_LWS = 1024
- #ntlmv2_GWS = 32768
- # WPA-PSK
- #wpapsk_LWS = xxx
- #wpapsk_GWS = xxx
- # For raw
- #rawmd4_LWS = xxx
- #rawmd4_GWS = xxx
- # Markov modes, see ../doc/MARKOV for more information
- [Markov:Default]
- # Default Markov mode settings
- #
- # Statsfile cannot be specified on the command line, so
- # specifying it here is mandatory
- Statsfile = $JOHN/stats
- # MkvLvl and MkvMaxLen should also be specified here, as a fallback for
- # --markov usage without specifying LEVEL and/or LENGTH on the command line
- MkvLvl = 200
- MkvMaxLen = 12
- # MkvMinLvl and MkvMinLen should not be specified at all in [Markov:Default],
- # or they should be equal to 0 (which is the default if not specified.
- # MkvMinLvl and MkvMinLen can be used in other Markov mode sections
- # except [Markov:Default]
- ; MkvMinLvl = 0
- ; MkvMinLen = 0
- # A user defined character class is named with a single digit, ie. 0..9. After
- # the equal-sign, just list all characters that this class should match. You
- # can specify ranges within brackets, much like pre-processor ranges in rules.
- # BEWARE of encoding if using non-ASCII characters. If you put UTF-8 characters
- # here, it will *not* work! You must use a singlebyte encoding and it should
- # be the same here as you intend to use for your dictionary.
- # You can however put characters here in \xA3 format (for codepoint 0xA3 - in
- # many iso-8859 codepages that would mean a pound sign). This works in ranges
- # too. Using \x00 is not supported though - it will not be parsed as null.
- #
- # This is a couple of example classes:
- # ?0 matches (one version of) base64 characters
- # ?1 matches hex digits
- # ?2 matches the TAB character (never try to use \x00!)
- [UserClasses]
- 0 = [a-zA-Z0-9/.]
- 1 = [0-9a-fA-F]
- 2 = \x09
- # these are user defined character sets. There purpose is to allow custom salt
- # values to be used within the salt_regen logic. These will be the characters
- # to use for this character within the salt. So if we had a salt that was 4
- # characters, and 0-9a-m, we can easily do this by 0 = [0-9a-m] If this is used,
- # the regen salt value would be ?0?0?0?0 and salts such as a47m 2kd5 would be valid.
- [Regen_Salts_UserClasses]
- 1 = [1-9]
- # A "no rules" rule for super fast Single mode (use with --single=none)
- [List.Rules:None]
- :
- # A "drop all" rule for even faster Single mode (debugging :)
- [List.Rules:Drop]
- <1'0
- # "Single crack" mode rules
- [List.Rules:Single]
- # Simple rules come first...
- :
- -s x**
- -c (?a c Q
- -c l Q
- -s-c x** /?u l
- # These were not included in crackers I've seen, but are pretty efficient,
- # so I include them near the beginning
- >6 '6
- >7 '7 l
- -c >6 '6 /?u l
- >5 '5
- # Weird order, eh? Can't do anything about it, the order is based on the
- # number of successful cracks...
- <* d
- r c
- -c <* (?a d c
- -c >5 '5 /?u l
- -c u Q
- -c )?a r l
- -[:c] <* !?A \p1[lc] p
- -c <* c Q d
- -c >7 '7 /?u
- >4 '4 l
- -c <+ (?l c r
- -c <+ )?l l Tm
- >3 '3
- -c >4 '4 /?u
- -c >3 '3 /?u l
- -c u Q r
- <* d M 'l f Q
- -c <* l Q d M 'l f Q
- # About 50% of single-mode-crackable passwords get cracked by now...
- # >2 x12 ... >8 x18
- >[2-8] x1\1
- >9 \[
- # >3 x22 ... >9 x28
- >[3-9] x2\p[2-8]
- # >4 x32 ... >9 x37
- >[4-9] x3\p[2-7]
- # >2 x12 /?u l ... >8 x18 /?u l
- -c >[2-8] x1\1 /?u l
- -c >9 \[ /?u l
- # >3 x22 /?u l ... >9 x28 /?u l
- -c >[3-9] x2\p[2-8] /?u l
- # >4 x32 /?u l ... >9 x37 /?u l
- -c >[4-9] x3\p[2-7] /?u l
- # Now to the suffix stuff...
- <* l $[1-9!0a-rt-z"-/:-@\[-`{-~]
- -c <* (?a c $[1-9!0a-rt-z"-/:-@\[-`{-~]
- -[:c] <* !?A (?\p1[za] \p1[lc] $s M 'l p Q X0z0 'l $s
- -[:c] <* /?A (?\p1[za] \p1[lc] $s
- <* l r $[1-9!]
- -c <* /?a u $[1-9!]
- -[:c] <- (?\p1[za] \p1[lc] Az"'s"
- -[:c] <- (?\p1[za] \p1[lc] Az"!!"
- -[:c] (?\p1[za] \p1[lc] $! <- Az"!!"
- # Removing vowels...
- -[:c] /?v @?v >2 (?\p1[za] \p1[lc]
- /?v @?v >2 <* d
- # crack -> cracked, crack -> cracking
- <* l [PI]
- -c <* l [PI] (?a c
- # mary -> marie
- -[:c] <* (?\p1[za] \p1[lc] )y omi $e
- # marie -> mary
- -[:c] <* (?\p1[za] \p1[lc] )e \] )i val1 oay
- # The following are some 3l33t rules
- -[:c] l /[aelos] s\0\p[4310$] (?\p1[za] \p1[:c]
- -[:c] l /a /[elos] sa4 s\0\p[310$] (?\p1[za] \p1[:c]
- -[:c] l /e /[los] se3 s\0\p[10$] (?\p1[za] \p1[:c]
- -[:c] l /l /[os] sl1 s\0\p[0$] (?\p1[za] \p1[:c]
- -[:c] l /o /s so0 ss$ (?\p1[za] \p1[:c]
- -[:c] l /a /e /[los] sa4 se3 s\0\p[10$] (?\p1[za] \p1[:c]
- -[:c] l /a /l /[os] sa4 sl1 s\0\p[0$] (?\p1[za] \p1[:c]
- -[:c] l /a /o /s sa4 so0 ss$ (?\p1[za] \p1[:c]
- -[:c] l /e /l /[os] se3 sl1 s\0\p[0$] (?\p1[za] \p1[:c]
- -[:c] l /[el] /o /s s\0\p[31] so0 ss$ (?\p1[za] \p1[:c]
- -[:c] l /a /e /l /[os] sa4 se3 sl1 s\0\p[0$] (?\p1[za] \p1[:c]
- -[:c] l /a /[el] /o /s sa4 s\0\p[31] so0 ss$ (?\p1[za] \p1[:c]
- -[:c] l /e /l /o /s se3 sl1 so0 ss$ (?\p1[za] \p1[:c]
- -[:c] l /a /e /l /o /s sa4 se3 sl1 so0 ss$ (?\p1[za] \p1[:c]
- # Now to the prefix stuff...
- l ^[1a-z2-90]
- -c l Q ^[A-Z]
- ^[A-Z]
- l ^["-/:-@\[-`{-~]
- -[:c] <9 (?a \p1[lc] A0"[tT]he"
- -[:c] <9 (?a \p1[lc] A0"[aA]my"
- -[:c] <9 (?a \p1[lc] A0"[mdMD]r"
- -[:c] <9 (?a \p1[lc] A0"[mdMD]r."
- -[:c] <9 (?a \p1[lc] A0"__"
- <- !?A l p ^[240-9]
- # Some word pair rules...
- # johnsmith -> JohnSmith, johnSmith
- -p-c (?a 2 (?a c 1 [cl]
- # JohnSmith -> john smith, john_smith, john-smith
- -p 1 <- $[ _\-] + l
- # JohnSmith -> John smith, John_smith, John-smith
- -p-c 1 <- (?a c $[ _\-] 2 l
- # JohnSmith -> john Smith, john_Smith, john-Smith
- -p-c 1 <- l $[ _\-] 2 (?a c
- # johnsmith -> John Smith, John_Smith, John-Smith
- -p-c 1 <- (?a c $[ _\-] 2 (?a c
- # Applying different simple rules to each of the two words
- -p-[c:] 1 \p1[ur] 2 l
- -p-c 2 (?a c 1 [ur]
- -p-[c:] 1 l 2 \p1[ur]
- -p-c 1 (?a c 2 [ur]
- # jsmith -> smithj, etc...
- -[:c] (?a \p1[lc] [{}]
- -[:c] (?a \p1[lc] [{}] \0
- # Toggle case...
- -c <+ )?u l Tm
- -c T0 Q M c Q l Q u Q C Q X0z0 'l
- -c T[1-9A-E] Q M l Tm Q C Q u Q l Q c Q X0z0 'l
- -c l Q T[1-9A-E] Q M T\0 Q l Tm Q C Q u Q X0z0 'l
- -c >2 <G %2?a [lu] T0 M T2 T4 T6 T8 TA TC TE Q M l Tm Q X0z0 'l
- -c >2 /?l /?u t Q M c Q C Q l Tm Q X0z0 'l
- # Deleting chars...
- >[2-8] D\p[1-7]
- >[8-9A-E] D\1
- -c /?u >[2-8] D\p[1-7] l
- -c /?u >[8-9A-E] D\1 l
- =1?a \[ M c Q
- -c (?a >[1-9A-E] D\1 c
- # Inserting a dot...
- -[:c] >3 (?a \p1[lc] i[12].
- # More suffix stuff...
- <- l Az"[190][0-9]"
- -c <- (?a c Az"[190][0-9]"
- <- l Az"[782][0-9]"
- -c <- (?a c Az"[782][0-9]"
- <* l $[A-Z]
- -c <* (?a c $[A-Z]
- # cracking -> CRACKiNG
- -c u /I sIi
- # Crack96 -> cRACK96
- %2?a C Q
- # Crack96 -> cRACK(^
- /?A S Q
- # Crack96 -> CRaCK96
- -c /?v V Q
- # Really weird charset conversions, like "england" -> "rmh;smf"
- :[RL] Q
- l Q [RL]
- -c (?a c Q [RL]
- :[RL] \0 Q
- # Both prefixing and suffixing...
- <- l ^[1!@#$%^&*\-=_+.?|:'"] $\1
- <- l ^[({[<] $\p[)}\]>]
- # The rest of two-digit suffix stuff, less common numbers...
- <- l Az"[63-5][0-9]"
- -c <- (?a c Az"[63-5][0-9]"
- # Some multi-digit numbers...
- -[:c] (?a \p1[lc] Az"007" <+
- -[:c] (?a \p1[lc] Az"123" <+
- -[:c] (?a \p1[lc] Az"[0-9]\0\0" <+
- -[:c] (?a \p1[lc] Az"1234" <+
- -[:c] (?a \p1[lc] Az"[0-9]\0\0\0" <+
- -[:c] (?a \p1[lc] Az"12345" <+
- -[:c] (?a \p1[lc] Az"[0-9]\0\0\0\0" <+
- -[:c] (?a \p1[lc] Az"123456" <+
- -[:c] (?a \p1[lc] Az"[0-9]\0\0\0\0\0" <+
- # Some [birth] years...
- l Az"19[7-96-0]" <+ >-
- l Az"20[01]" <+ >-
- l Az"19[7-9][0-9]" <+
- l Az"20[01][0-9]" <+
- l Az"19[6-0][9-0]" <+
- [List.Rules:Extra]
- # Insert/overstrike some characters...
- !?A >[1-6] l i\0[a-z]
- !?A l o0[a-z]
- !?A >[1-7] l o\0[a-z]
- # Toggle case everywhere (up to length 8), assuming that certain case
- # combinations were already tried.
- -c T1 Q M T0 Q
- -c T2 Q M T[z0] T[z1] Q
- -c T3 Q M T[z0] T[z1] T[z2] Q
- -c T4 Q M T[z0] T[z1] T[z2] T[z3] Q
- -c T5 Q M T[z0] T[z1] T[z2] T[z3] T[z4] Q
- -c T6 Q M T[z0] T[z1] T[z2] T[z3] T[z4] T[z5] Q
- -c T7 Q M T[z0] T[z1] T[z2] T[z3] T[z4] T[z5] T[z6] Q
- # Very slow stuff...
- l Az"[1-90][0-9][0-9]" <+
- -c (?a c Az"[1-90][0-9][0-9]" <+
- <[\-9] l A\p[z0]"[a-z][a-z]"
- <- l ^[a-z] $[a-z]
- # Wordlist mode rules
- [List.Rules:Wordlist]
- # Try words as they are
- :
- # Lowercase every pure alphanumeric word
- -c >3 !?X l Q
- # Capitalize every pure alphanumeric word
- -c (?a >2 !?X c Q
- # Lowercase and pluralize pure alphabetic words
- <* >2 !?A l p
- # Lowercase pure alphabetic words and append '1'
- <* >2 !?A l $1
- # Capitalize pure alphabetic words and append '1'
- -c <* >2 !?A c $1
- # Duplicate reasonably short pure alphabetic words (fred -> fredfred)
- <7 >1 !?A l d
- # Lowercase and reverse pure alphabetic words
- >3 !?A l M r Q
- # Prefix pure alphabetic words with '1'
- >2 !?A l ^1
- # Uppercase pure alphanumeric words
- -c >2 !?X u Q M c Q u
- # Lowercase pure alphabetic words and append a digit or simple punctuation
- <* >2 !?A l $[2!37954860.?]
- # Words containing punctuation, which is then squeezed out, lowercase
- /?p @?p >3 l
- # Words with vowels removed, lowercase
- /?v @?v >3 l
- # Words containing whitespace, which is then squeezed out, lowercase
- /?w @?w >3 l
- # Capitalize and duplicate short pure alphabetic words (fred -> FredFred)
- -c <7 >1 !?A c d
- # Capitalize and reverse pure alphabetic words (fred -> derF)
- -c <+ >2 !?A c r
- # Reverse and capitalize pure alphabetic words (fred -> Derf)
- -c >2 !?A l M r Q c
- # Lowercase and reflect pure alphabetic words (fred -> fredderf)
- <7 >1 !?A l d M 'l f Q
- # Uppercase the last letter of pure alphabetic words (fred -> freD)
- -c <+ >2 !?A l M r Q c r
- # Prefix pure alphabetic words with '2' or '4'
- >2 !?A l ^[24]
- # Capitalize pure alphabetic words and append a digit or simple punctuation
- -c <* >2 !?A c $[2!3957468.?0]
- # Prefix pure alphabetic words with digits
- >2 !?A l ^[379568]
- # Capitalize and pluralize pure alphabetic words of reasonable length
- -c <* >2 !?A c p
- # Lowercase/capitalize pure alphabetic words of reasonable length and convert:
- # crack -> cracked, crack -> cracking
- -[:c] <* >2 !?A \p1[lc] M [PI] Q
- # Try the second half of split passwords
- -s x**
- -s-c x** M l Q
- # Case toggler for cracking MD4-based NTLM hashes (with the contributed patch)
- # given already cracked DES-based LM hashes.
- # Use --rules=NT to use this
- [List.Rules:NT]
- :
- -c T0Q
- -c T1QT[z0]
- -c T2QT[z0]T[z1]
- -c T3QT[z0]T[z1]T[z2]
- -c T4QT[z0]T[z1]T[z2]T[z3]
- -c T5QT[z0]T[z1]T[z2]T[z3]T[z4]
- -c T6QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]
- -c T7QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]
- -c T8QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]
- -c T9QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]
- -c TAQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]
- -c TBQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]T[zA]
- -c TCQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]T[zA]T[zB]
- -c 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]
- # Some Office <=2003 files have passwords truncated at 15
- [List.Rules:OldOffice]
- :
- ->F>F'F
- # Rules from Hash Runner 2014
- [List.Rules:o1]
- o[0-9A-Z][ -~]
- [List.Rules:o2]
- o[0-9A-E][ -~] Q M o[0-9A-E][ -~] Q
- [List.Rules:o3]
- o[0-9][ -~] Q M o[0-9][ -~] Q M o[0-9][ -~] Q
- [List.Rules:o]
- o[0-9A-Z][ -~]
- o[0-9A-E][ -~] Q M o[0-9A-E][ -~] Q
- [List.Rules:i1]
- i[0-9A-Z][ -~]
- [List.Rules:i2]
- i[0-9A-E][ -~] i[0-9A-E][ -~]
- [List.Rules:i3]
- i[0-9][ -~] i[0-9][ -~] i[0-9][ -~]
- [List.Rules:i]
- i[0-9A-Z][ -~]
- i[0-9A-E][ -~] i[0-9A-E][ -~]
- [List.Rules:oi]
- o[0-9A-Z][ -~]
- i[0-9A-Z][ -~]
- o[0-9A-E][ -~] Q M o[0-9A-E][ -~] Q
- i[0-9A-E][ -~] i[0-9A-E][ -~]
- # Default Loopback mode rules.
- [List.Rules:Loopback]
- .include [List.Rules:NT]
- .include [List.Rules:Wordlist]
- # For Single Mode against fast hashes
- [List.Rules:Single-Extra]
- .include [List.Rules:Single]
- .include [List.Rules:Extra]
- .include [List.Rules:OldOffice]
- # For Wordlist mode and very fast hashes
- [List.Rules:Jumbo]
- .include [List.Rules:Wordlist]
- .include [List.Rules:OldOffice]
- .include [List.Rules:Single]
- .include [List.Rules:Extra]
- .include [List.Rules:NT]
- # KoreLogic rules
- .include "$JOHN/korelogic.conf"
- # Everything, including all KoreLogic rules. Only for very fast hashes
- # and/or Single mode.
- [List.Rules:All]
- .include [List.Rules:Jumbo]
- .include [List.Rules:KoreLogic]
- # Incremental modes
- # This is for one-off uses (make your own custom.chr)
- [Incremental:Custom]
- File = $JOHN/custom.chr
- MinLen = 0
- # The theoretical CharCount is 211, we've got 196.
- [Incremental:UTF8]
- File = $JOHN/utf8.chr
- MinLen = 0
- CharCount = 196
- # This is CP1252, a super-set of ISO-8859-1.
- # The theoretical CharCount is 219, we've got 203.
- [Incremental:Latin1]
- File = $JOHN/latin1.chr
- MinLen = 0
- CharCount = 203
- [Incremental:ASCII]
- File = $JOHN/ascii.chr
- MinLen = 0
- MaxLen = 13
- CharCount = 95
- [Incremental:LM_ASCII]
- File = $JOHN/lm_ascii.chr
- MinLen = 0
- MaxLen = 7
- CharCount = 69
- # This is CP858 (CP850 + Euro sign, superset of CP437).
- # The theoretical CharCount is 209 minus lowercase, we've got 132.
- [Incremental:LanMan]
- File = $JOHN/lanman.chr
- MinLen = 0
- MaxLen = 7
- CharCount = 132
- # This is alnum (upper & lower case) as well as space.
- [Incremental:Alnumspace]
- File = $JOHN/alnumspace.chr
- MinLen = 1
- MaxLen = 13
- CharCount = 63
- [Incremental:Alnum]
- File = $JOHN/alnum.chr
- MinLen = 1
- MaxLen = 13
- CharCount = 62
- [Incremental:Alpha]
- File = $JOHN/alpha.chr
- MinLen = 1
- MaxLen = 13
- CharCount = 52
- [Incremental:LowerNum]
- File = $JOHN/lowernum.chr
- MinLen = 1
- MaxLen = 13
- CharCount = 36
- [Incremental:UpperNum]
- File = $JOHN/uppernum.chr
- MinLen = 1
- MaxLen = 13
- CharCount = 36
- [Incremental:LowerSpace]
- File = $JOHN/lowerspace.chr
- MinLen = 1
- MaxLen = 13
- CharCount = 27
- [Incremental:Lower]
- File = $JOHN/lower.chr
- MinLen = 1
- MaxLen = 13
- CharCount = 26
- [Incremental:Upper]
- File = $JOHN/upper.chr
- MinLen = 1
- MaxLen = 13
- CharCount = 26
- [Incremental:Digits]
- File = $JOHN/digits.chr
- MinLen = 1
- MaxLen = 20
- CharCount = 10
- # Some pre-defined word filters as used to generate the supplied .chr files
- [List.External:Filter_ASCII]
- void filter()
- {
- int i, c;
- i = 0;
- while (c = word[i++])
- if (c < 0x20 || c > 0x7e || i > 13) {
- word = 0; return;
- }
- }
- [List.External:Filter_LanMan]
- void filter()
- {
- int i, c;
- i = 0;
- while (c = word[i]) {
- if (i >= 14) { // of up to 14 characters long
- word = 0; return;
- }
- if (c >= 'a' && c <= 'z') // Convert to uppercase
- word[i] &= 0xDF;
- i++;
- }
- word[7] = 0; // Truncate at 7 characters
- }
- [List.External:Filter_LM_ASCII]
- void filter()
- {
- int i, c;
- i = 0;
- while (c = word[i]) {
- if (c < 0x20 || c > 0x7e || // Require ASCII-only
- i >= 14) { // of up to 14 characters long
- word = 0; return;
- }
- if (c >= 'a' && c <= 'z') // Convert to uppercase
- word[i] &= 0xDF;
- i++;
- }
- word[7] = 0; // Truncate at 7 characters
- }
- [List.External:Filter_Alnumspace]
- void filter()
- {
- int i, c;
- i = 0;
- while (c = word[i++])
- if (c != ' ' && (((c < '0' || c > '9') &&
- ((c &= 0xDF) < 'A' || c > 'Z'))) || i > 13) {
- word = 0; return;
- }
- }
- [List.External:Filter_Alnum]
- void filter()
- {
- int i, c;
- i = 0;
- while (c = word[i++])
- if (((c < '0' || c > '9') && ((c &= 0xDF) < 'A' || c > 'Z')) ||
- i > 13) {
- word = 0; return;
- }
- }
- [List.External:Filter_Alpha]
- void filter()
- {
- int i, c;
- i = 0;
- while (c = word[i++])
- if ((c &= 0xDF) < 'A' || c > 'Z' || i > 13) {
- word = 0; return;
- }
- }
- [List.External:Filter_LowerNum]
- void filter()
- {
- int i, c;
- i = 0;
- while (c = word[i++])
- if (((c < 'a' || c > 'z') && (c < '0' || c > '9')) || i > 13) {
- word = 0; return;
- }
- }
- [List.External:Filter_UpperNum]
- void filter()
- {
- int i, c;
- i = 0;
- while (c = word[i++])
- if (((c < 'A' || c > 'Z') && (c < '0' || c > '9')) || i > 13) {
- word = 0; return;
- }
- }
- [List.External:Filter_LowerSpace]
- void filter()
- {
- int i, c;
- i = 0;
- while (c = word[i++])
- if (((c < 'a' || c > 'z') && c != ' ') || i > 13) {
- word = 0; return;
- }
- }
- [List.External:Filter_Lower]
- void filter()
- {
- int i, c;
- i = 0;
- while (c = word[i++])
- if (c < 'a' || c > 'z' || i > 13) {
- word = 0; return;
- }
- }
- [List.External:Filter_Upper]
- void filter()
- {
- int i, c;
- i = 0;
- while (c = word[i++])
- if (c < 'A' || c > 'Z' || i > 13) {
- word = 0; return;
- }
- }
- [List.External:Filter_Digits]
- void filter()
- {
- int i, c;
- i = 0;
- while (c = word[i++])
- if (c < '0' || c > '9' || i > 20) {
- word = 0; return;
- }
- }
- [List.External:Filter_No_Cap_or_Symbols]
- void filter()
- {
- int i, c;
- i = 0;
- while (c = word[i++])
- if ((c < 'a' || c > 'z') && (c < '0' || c > '9')) {
- return;
- }
- word = 0; return;
- }
- # Reject words that are illegal UTF-8
- # We obviously let pure ASCII through too
- [List.External:Filter_UTF8]
- void filter()
- {
- int s, a, p;
- p = 0;
- while (s = word[p++] & 0xff) {
- if (s > 0x7f) {
- if (s < 0xc2 || s > 0xf7) { // illegal single-byte
- word = 0; return;
- }
- // two-byte c2..df
- a = word[p++] & 0xff;
- if (a < 0x80 || a > 0xbf) {
- word = 0; return;
- }
- if (s > 0xdf) { // three-byte e0..ef
- if (s == 0xe0 && a < 0xa0) {
- word = 0; return;
- }
- if (s == 0xed && a > 0x9f) {
- word = 0; return;
- }
- if (s == 0xf0 && a < 0x90) {
- word = 0; return;
- }
- if (s == 0xf4 && a > 0x8f) {
- word = 0; return;
- }
- a = word[p++] & 0xff;
- if (a < 0x80 || a > 0xbf) {
- word = 0; return;
- }
- if (s > 0xef) { // four-byte f0..f7
- a = word[p++] & 0xff;
- if (a < 0x80 || a > 0xbf) {
- word = 0; return;
- }
- }
- }
- }
- }
- }
- # Reject words that are LEGAL UTF-8 (also rejects pure ASCII)
- [List.External:Filter_non-UTF8]
- void filter()
- {
- int s, a, p;
- p = 0;
- while (s = word[p++] & 0xff) {
- if (s > 0x7f) {
- if (s < 0xc2 || s > 0xf7) { // illegal single-byte
- return;
- }
- // two-byte c2..df
- a = word[p++] & 0xff;
- if (a < 0x80 || a > 0xbf) {
- return;
- }
- if (s > 0xdf) { // three-byte e0..ef
- if (s == 0xe0 && a < 0xa0) {
- return;
- }
- if (s == 0xed && a > 0x9f) {
- return;
- }
- if (s == 0xf0 && a < 0x90) {
- return;
- }
- if (s == 0xf4 && a > 0x8f) {
- return;
- }
- a = word[p++] & 0xff;
- if (a < 0x80 || a > 0xbf) {
- return;
- }
- if (s > 0xef) { // four-byte f0..f7
- a = word[p++] & 0xff;
- if (a < 0x80 || a > 0xbf) {
- return;
- }
- }
- }
- }
- }
- word = 0;
- }
- # A simple cracker for LM hashes
- [List.External:LanMan]
- int length; // Current length
- int maxlength;
- void init()
- {
- if (req_minlen)
- length = req_minlen;
- else
- length = 1;
- if (req_maxlen)
- maxlength = req_maxlen;
- else // the format's limit
- maxlength = cipher_limit;
- word[0] = 'A' - 1; // Start with "A"
- word[length] = 0;
- }
- void generate()
- {
- int i;
- i = length - 1; // Start from the last character
- while (++word[i] > 'Z') // Try to increase it
- if (i) // Overflow here, any more positions?
- word[i--] = 'A'; // Yes, move to the left, and repeat
- else // No
- if (length < maxlength) {
- word[i = ++length] = 0; // Switch to the next length
- while (i--)
- word[i] = 'A';
- return;
- } else {
- word = 0; return; // We're done
- }
- }
- void restore()
- {
- length = 0; // Calculate the length
- while (word[length]) length++;
- }
- # Simple and well-commented, yet useful external mode example
- # NOTE, this has now been 'split' up into a base extern, 'base', and then
- # multiple External:double functions. It still has same code as original
- # double, but now can be easily expanded.
- [List.External_base:Double]
- /*
- * This cracking mode tries all the possible duplicated lowercase alphabetic
- * "words" of up to 8 characters long. Since word halves are the same, it
- * only has to try about 500,000 words.
- */
- /* Global variables: current length and word */
- /* make this 'long' enough for other externs that include this one */
- /* (up to 125 bytes long) */
- int length, current[126], max;
- /* this new 'type' variable, is used to tell double what character set to
- * use. It can use the original (alpha). If type is 0 (i.e. unset), then
- * a-z (alpha) character set is used. If type is '0' (a zero ascii byte)
- * then alnum charset is used, a-z0-9. If type is a space char, then all
- * charset is used [space - tilde] or [ -~]. This required setting the
- * type var in the init() of alnum or all doubles (it can be left unset
- * in the alpha versions). It also requires some if logic in generate.
- * other than that, it works the same, with almost no performance hit */
- int type;
- /* Generates a new word */
- void generate()
- {
- int i;
- /* Export last generated word, duplicating it at the same time; here "word"
- * is a pre-defined external variable. */
- word[(i = length) << 1] = 0;
- while (i--) word[length + i] = word[i] = current[i];
- /* Generate a new word */
- i = length - 1; // Start from the last character
- if (type == 0) {
- /* alpha */
- while (++current[i] > 'z') // Try to increase it
- if (i) // Overflow here, any more positions?
- current[i--] = 'a'; // Yes, move to the left, and repeat
- else { // No
- current = 0; // Request a length switch
- break; // Break out of the loop
- }
- } else if (type == '0') {
- /* alnum */
- if (current[i] == 'z') current[i] = '0'-1;
- while (++current[i] == '9') { // Try to increase it
- if (i) // Overflow here, any more positions?
- current[i--] = 'a'; // Yes, move to the left, and repeat
- else { // No
- current = 0; // Request a length switch
- break; // Break out of the loop
- }
- if (current[i] == 'z') current[i] = '0'-1;
- }
- } else if (type == ' ') {
- /* all */
- while (++current[i] > '~') { // Try to increase it
- if (i) // Overflow here, any more positions?
- current[i--] = ' '; // Yes, move to the left, and repeat
- else { // No
- current = 0; // Request a length switch
- break; // Break out of the loop
- }
- }
- }
- /* else ????? wtf?? */
- /* Switch to the next length, unless we were generating 8 character long
- * words already. */
- if (!current && length < max) {
- i = ++length;
- if (type == 0 || type == '0')
- while (i--) current[i] = 'a';
- else if (type == ' ')
- while (i--) current[i] = ' ';
- }
- }
- /* Called when restoring an interrupted session */
- void restore()
- {
- int i;
- /* Import the word back */
- i = 0;
- while (current[i] = word[i]) i++;
- /* ...and calculate the half-word length */
- length = i >> 1;
- }
- [List.External:Double]
- .include [List.External_base:Double]
- /* Called at startup to initialize the global variables */
- void init()
- {
- int i;
- if (req_minlen)
- i = length = (req_minlen + 1) / 2;
- else
- i = length = 2; // Start with 4 character long words
- while (i--) current[i] = 'a'; // Set our half-word to "aa"
- if (req_maxlen)
- max = (req_maxlen + 1) / 2;
- else if (length > 4)
- max = length;
- else
- max = 4;
- }
- [List.External:Double_alnum]
- .include [List.External_base:Double]
- /* Called at startup to initialize the global variables */
- void init()
- {
- int i;
- if (req_minlen)
- i = length = (req_minlen + 1) / 2;
- else
- i = length = 2; // Start with 4 character long words
- while (i--) current[i] = 'a'; // Set our half-word to "aa"
- if (req_maxlen)
- max = (req_maxlen + 1) / 2;
- else if (length > 4)
- max = length;
- else
- max = 4;
- type = '0';
- }
- [List.External:Double_all]
- .include [List.External_base:Double]
- void init()
- {
- int i;
- if (req_minlen)
- i = length = (req_minlen + 1) / 2;
- else
- i = length = 2; // Start with 4 character long words
- while (i--) current[i] = ' '; // Set our half-word to " "
- if (req_maxlen)
- max = (req_maxlen + 1) / 2;
- else if (length > 4)
- max = length;
- else
- max = 4;
- type = ' ';
- }
- # Strip 0.5 ("Secure Tool for Recalling Important Passwords") cracker,
- # based on analysis done by Thomas Roessler and Ian Goldberg. This will
- # crack passwords you may have generated with Strip; other uses of Strip
- # are unaffected.
- [List.External:Strip]
- int minlength, maxlength, mintype, maxtype;
- int crack_seed, length, type;
- int count, charset[128];
- void init()
- {
- int c;
- /* Password lengths to try; Strip can generate passwords of 4 to 16
- * characters, but traditional crypt(3) hashes are limited to 8. */
- minlength = req_minlen;
- if (minlength < 4)
- minlength = 4;
- if (req_maxlen)
- maxlength = req_maxlen;
- else // the format's limit
- maxlength = cipher_limit;
- if (maxlength >16) maxlength = 16;
- /* Password types to try (Numeric, Alpha-Num, Alpha-Num w/ Meta). */
- mintype = 0; // 0
- maxtype = 2; // 2
- crack_seed = 0x10000;
- length = minlength - 1;
- type = mintype;
- count = 0;
- c = '0'; while (c <= '9') charset[count++] = c++;
- }
- void generate()
- {
- int seed, random;
- int i, c;
- if (crack_seed > 0xffff) {
- crack_seed = 0;
- if (++length > maxlength) {
- length = minlength;
- if (++type > maxtype) {
- word[0] = 0;
- return;
- }
- }
- count = 10;
- if (type >= 1) {
- c = 'a'; while (c <= 'f') charset[count++] = c++;
- c = 'h'; while (c <= 'z') charset[count++] = c++;
- c = 'A'; while (c <= 'Z') charset[count++] = c++;
- }
- if (type == 2) {
- charset[count++] = '!';
- c = '#'; while (c <= '&') charset[count++] = c++;
- c = '('; while (c <= '/') charset[count++] = c++;
- c = '<'; while (c <= '>') charset[count++] = c++;
- charset[count++] = '?'; charset[count++] = '@';
- charset[count++] = '['; charset[count++] = ']';
- charset[count++] = '^'; charset[count++] = '_';
- c = '{'; while (c <= '~') charset[count++] = c++;
- }
- }
- seed = (crack_seed++ << 16 >> 16) * 22695477 + 1;
- i = 0;
- while (i < length) {
- random = ((seed = seed * 22695477 + 1) >> 16) & 0x7fff;
- word[i++] = charset[random % count];
- }
- word[i] = 0;
- }
- # A variation of KnownForce configured to try all the 385641000 possible
- # auto-generated passwords of DokuWiki versions up to at least 2013-05-10.
- [List.External:DokuWiki]
- int last; // Last character position, zero-based
- int lastofs; // Last character position offset into charset[]
- int lastid; // Current character index in the last position
- int id[0x7f]; // Current character indices for other positions
- int charset[0x7f00]; // Character sets, 0x100 elements for each position
- void init()
- {
- int A[26], C[26], V[26];
- int length;
- int pos, ofs, i, c;
- i = 0; while (i < 26) { A[i] = C[i] = 1; V[i++] = 0; }
- i = 'a' - 'a'; C[i] = 0; V[i] = 1;
- i = 'e' - 'a'; C[i] = 0; V[i] = 1;
- i = 'i' - 'a'; C[i] = 0; V[i] = 1;
- i = 'o' - 'a'; C[i] = 0; V[i] = 1;
- i = 'u' - 'a'; C[i] = 0; V[i] = 1;
- i = 'q' - 'a'; A[i] = C[i] = 0;
- i = 'x' - 'a'; A[i] = C[i] = 0;
- i = 'y' - 'a'; A[i] = C[i] = 0;
- length = 8;
- /* This defines the character sets for different character positions */
- pos = 0;
- while (pos < 6) {
- ofs = pos++ << 8;
- i = 0;
- c = 'a' - 1;
- while (++c <= 'z')
- if (C[c - 'a'])
- charset[ofs + i++] = c;
- charset[ofs + i] = 0;
- ofs = pos++ << 8;
- i = 0;
- c = 'a' - 1;
- while (++c <= 'z')
- if (V[c - 'a'])
- charset[ofs + i++] = c;
- charset[ofs + i] = 0;
- ofs = pos++ << 8;
- i = 0;
- c = 'a' - 1;
- while (++c <= 'z')
- if (A[c - 'a'])
- charset[ofs + i++] = c;
- charset[ofs + i] = 0;
- }
- c = '1';
- while (pos < length) {
- ofs = pos++ << 8;
- i = 0;
- while (c <= '9')
- charset[ofs + i++] = c++;
- charset[ofs + i] = 0;
- c = '0';
- }
- last = length - 1;
- pos = -1;
- while (++pos <= last)
- word[pos] = charset[id[pos] = pos << 8];
- lastid = (lastofs = last << 8) - 1;
- word[pos] = 0;
- }
- void generate()
- {
- int pos;
- /* Handle the typical case specially */
- if (word[last] = charset[++lastid]) return;
- word[pos = last] = charset[lastid = lastofs];
- while (pos--) { // Have a preceding position?
- if (word[pos] = charset[++id[pos]]) return;
- word[pos] = charset[id[pos] = pos << 8];
- }
- word = 0; // We're done
- }
- void restore()
- {
- int i, c;
- /* Calculate the current length and infer the character indices */
- last = 0;
- while (c = word[last]) {
- i = lastofs = last << 8;
- while (charset[i] != c && charset[i]) i++;
- if (!charset[i]) i = lastofs; // Not found
- id[last++] = i;
- }
- lastid = id[--last];
- }
- /*
- * This takes advantage of CVE-2013-2120 to find seeds that KDE Paste applet
- * uses to generate passwords.
- *
- * This software is Copyright (c) Michael Samuel <mik@miknet.net>,
- * and it is hereby released to the general public under the following terms:
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted.
- */
- [List.External:KDEPaste]
- int charset[95];
- int charset_length, password_length, endTime, startTime, msec;
- void init()
- {
- password_length = 8; /* Change this to match config */
- endTime = session_start_time;
- startTime = 1343743200; /* Aug 1 2012 - Change this as necessary */
- msec = 1; /* msec is never 0 - it would crash the applet */
- charset_length = 0;
- int c;
- /* Comment out classes that you don't need, but keep the order the same */
- /* Lowers */
- c = 'a'; while (c <= 'z') charset[charset_length++] = c++;
- /* Uppers */
- c = 'A'; while (c <= 'Z') charset[charset_length++] = c++;
- /* Numbers */
- c = '0'; while (c <= '9') charset[charset_length++] = c++;
- charset[charset_length++] = '0'; /* Yep, it's there twice */
- /* Symbols */
- c = '!'; while (c <= '/') charset[charset_length++] = c++;
- c = ':'; while (c <= '@') charset[charset_length++] = c++;
- c = '['; while (c <= '`') charset[charset_length++] = c++;
- c = '{'; while (c <= '~') charset[charset_length++] = c++;
- }
- void generate()
- {
- int i, rand_seed, rand_result;
- /* Terminate once we've generated for all *
- * of the time range (Plus a bit more...) */
- if (endTime + 1000 < startTime) {
- word = 0;
- return;
- }
- /* Skip msecs that would generate dupes */
- while (endTime % msec != 0) {
- if (++msec > 999) {
- endTime--;
- msec = 1;
- }
- }
- rand_seed = endTime / msec;
- i = 0;
- while (i < password_length) {
- /* this works like rand_r() from eglibc */
- rand_seed = rand_seed * 1103515245 + 12345;
- rand_result = (rand_seed >> 16) & 2047;
- rand_seed = rand_seed * 1103515245 + 12345;
- rand_result <<= 10;
- rand_result ^= (rand_seed >> 16) & 1023;
- rand_seed = rand_seed * 1103515245 + 12345;
- rand_result <<= 10;
- rand_result ^= (rand_seed >> 16) & 1023;
- word[i++] = charset[rand_result % charset_length];
- }
- word[i] = 0;
- if (++msec > 999) {
- endTime--;
- msec = 1;
- }
- }
- void restore()
- {
- int i, rand_seed, rand_result;
- i = 0;
- /* Very crude restore, just dry-run until we hit last word */
- while (i != password_length) {
- while (endTime % msec != 0) {
- if (++msec > 999) {
- endTime--;
- msec = 1;
- }
- }
- rand_seed = endTime / msec;
- i = 0;
- while (i < password_length) {
- /* this works like rand_r() from eglibc */
- rand_seed = rand_seed * 1103515245 + 12345;
- rand_result = (rand_seed >> 16) & 2047;
- rand_seed = rand_seed * 1103515245 + 12345;
- rand_result <<= 10;
- rand_result ^= (rand_seed >> 16) & 1023;
- rand_seed = rand_seed * 1103515245 + 12345;
- rand_result <<= 10;
- rand_result ^= (rand_seed >> 16) & 1023;
- if (charset[rand_result % charset_length] != word[i++])
- break;
- }
- if (++msec > 999) {
- endTime--;
- msec = 1;
- }
- }
- }
- /* Awesome Password Generator RNG replay
- * Written by Michael Samuel <mik@miknet.net>
- * Public Domain.
- *
- * This takes advantage of a subtle bug, where a crypto RNG is used to
- * seed the C# System.Random() class, which takes a 32-bit input, but
- * converts negative numbers into non-negative numbers, resulting in
- * only 31 bits of security.
- *
- * This only implements "easy to type" being *unticked*, and numbers,
- * lowers, uppers and symbols being ticked, in random password mode.
- * Changing the password length is easy, anything else is left as an
- * exercise to the reader.
- *
- * Running Awesome Password Generator (1.3.2 or lower) in Mono is still
- * vulnerable, but uses a different RNG, so this mode isn't compatible.
- */
- /* Awesome Password Generator 1.3.2 does a two-pass run, selecting which
- * charset each position will have, then picking the character. This
- * leads to heavy bias, and is fixed in 1.4.0 (along with many other
- * fixes). If you have been using Awesome Password Generator, you should
- * upgrade immediately and change your passwords.
- */
- [List.External:AwesomePasswordGenerator]
- int numbers[10];
- int lowers[26];
- int uppers[26];
- int symbols[32];
- /* Since we don't have a double datatype, I simply pre-calculated the
- * transition numbers calculating the scale formula:
- * (double)randNum * 4.656612873077393e-10 * {4/10/26/32}
- */
- int boundaries_charclass[4];
- int boundaries_numbers[10];
- int boundaries_letters[26];
- int boundaries_symbols[32];
- /* This is the bug we're exploiting - the seed for the RNG is 32 bits
- * from the crypto rng. The non-crypto RNG converts negative numbers
- * into non-negative numbers, so there's only 2^31 possible seeds.
- */
- int seed;
- int password_length;
- void init()
- {
- password_length = 16; /* Change this to match config */
- int c, i;
- c = '0'; i = 0; while (c <= '9') numbers[i++] = c++;
- c = 'a'; i = 0; while (c <= 'z') lowers[i++] = c++;
- c = 'A'; i = 0; while (c <= 'Z') uppers[i++] = c++;
- /* Symbols */
- i = 0;
- symbols[i++] = '!'; symbols[i++] = '@'; symbols[i++] = '#'; symbols[i++] = '$';
- symbols[i++] = '%'; symbols[i++] = '^'; symbols[i++] = '&'; symbols[i++] = '*';
- symbols[i++] = '('; symbols[i++] = ')'; symbols[i++] = '~'; symbols[i++] = '-';
- symbols[i++] = '_'; symbols[i++] = '='; symbols[i++] = '+'; symbols[i++] = '\\';
- symbols[i++] = '|'; symbols[i++] = '/'; symbols[i++] = '['; symbols[i++] = ']';
- symbols[i++] = '{'; symbols[i++] = '}'; symbols[i++] = ';'; symbols[i++] = ':';
- symbols[i++] = '`'; symbols[i++] = '\''; symbols[i++] = '"'; symbols[i++] = ',';
- symbols[i++] = '.'; symbols[i++] = '<'; symbols[i++] = '>'; symbols[i++] = '?';
- i = 0;
- boundaries_charclass[i++] = 536870912; boundaries_charclass[i++] = 1073741824;
- boundaries_charclass[i++] = 1610612736; boundaries_charclass[i++] = 2147483647;
- i = 0;
- boundaries_numbers[i++] = 214748365; boundaries_numbers[i++] = 429496730;
- boundaries_numbers[i++] = 644245095; boundaries_numbers[i++] = 858993460;
- boundaries_numbers[i++] = 1073741824; boundaries_numbers[i++] = 1288490189;
- boundaries_numbers[i++] = 1503238554; boundaries_numbers[i++] = 1717986919;
- boundaries_numbers[i++] = 1932735284; boundaries_numbers[i++] = 2147483647;
- i = 0;
- boundaries_letters[i++] = 82595525; boundaries_letters[i++] = 165191050;
- boundaries_letters[i++] = 247786575; boundaries_letters[i++] = 330382100;
- boundaries_letters[i++] = 412977625; boundaries_letters[i++] = 495573150;
- boundaries_letters[i++] = 578168675; boundaries_letters[i++] = 660764200;
- boundaries_letters[i++] = 743359725; boundaries_letters[i++] = 825955250;
- boundaries_letters[i++] = 908550775; boundaries_letters[i++] = 991146300;
- boundaries_letters[i++] = 1073741824; boundaries_letters[i++] = 1156337349;
- boundaries_letters[i++] = 1238932874; boundaries_letters[i++] = 1321528399;
- boundaries_letters[i++] = 1404123924; boundaries_letters[i++] = 1486719449;
- boundaries_letters[i++] = 1569314974; boundaries_letters[i++] = 1651910499;
- boundaries_letters[i++] = 1734506024; boundaries_letters[i++] = 1817101549;
- boundaries_letters[i++] = 1899697074; boundaries_letters[i++] = 1982292599;
- boundaries_letters[i++] = 2064888124; boundaries_letters[i++] = 2147483647;
- i = 0;
- boundaries_symbols[i++] = 67108864; boundaries_symbols[i++] = 134217728;
- boundaries_symbols[i++] = 201326592; boundaries_symbols[i++] = 268435456;
- boundaries_symbols[i++] = 335544320; boundaries_symbols[i++] = 402653184;
- boundaries_symbols[i++] = 469762048; boundaries_symbols[i++] = 536870912;
- boundaries_symbols[i++] = 603979776; boundaries_symbols[i++] = 671088640;
- boundaries_symbols[i++] = 738197504; boundaries_symbols[i++] = 805306368;
- boundaries_symbols[i++] = 872415232; boundaries_symbols[i++] = 939524096;
- boundaries_symbols[i++] = 1006632960; boundaries_symbols[i++] = 1073741824;
- boundaries_symbols[i++] = 1140850688; boundaries_symbols[i++] = 1207959552;
- boundaries_symbols[i++] = 1275068416; boundaries_symbols[i++] = 1342177280;
- boundaries_symbols[i++] = 1409286144; boundaries_symbols[i++] = 1476395008;
- boundaries_symbols[i++] = 1543503872; boundaries_symbols[i++] = 1610612736;
- boundaries_symbols[i++] = 1677721600; boundaries_symbols[i++] = 1744830464;
- boundaries_symbols[i++] = 1811939328; boundaries_symbols[i++] = 1879048192;
- boundaries_symbols[i++] = 1946157056; boundaries_symbols[i++] = 2013265920;
- boundaries_symbols[i++] = 2080374784; boundaries_symbols[i++] = 2147483647;
- seed = 0;
- }
- void generate()
- {
- int i, j, s, next, nextp, val, bucket, randnum, used_charsets;
- int seedarray[56];
- /* BEGIN System.Random(seed) */
- if(seed < 0) {
- /* Only bother with non-negative integers */
- word = 0;
- return;
- }
- s = 161803398 - seed++;
- seedarray[55] = s;
- i = val = 1;
- while(i < 55) {
- bucket = 21 * i % 55;
- seedarray[bucket] = val;
- val = s - val;
- if(val < 0) val += 2147483647;
- s = seedarray[bucket];
- i++;
- }
- i = 1;
- while(i < 5) {
- j = 1;
- while(j < 56) {
- seedarray[j] -= seedarray[1 + (j + 30) % 55];
- if(seedarray[j] < 0) seedarray[j] += 2147483647;
- j++;
- }
- i++;
- }
- next = 0;
- nextp = 21;
- /* END System.Random(seed) */
- used_charsets = 0;
- while(used_charsets != 15) {
- i = 0;
- while(i < password_length) {
- /* BEGIN Random.Sample() */
- if (++next >= 56) next = 1;
- if (++nextp >= 56) nextp = 1;
- randnum = seedarray[next] - seedarray[nextp];
- if (randnum == 2147483647) randnum--;
- if (randnum < 0) randnum += 2147483647;
- seedarray[next] = randnum;
- /* END Random.Sample() */
- j = 0;
- while(boundaries_charclass[j] < randnum) j++;
- word[i] = j; /* Temporarily store in word[] */
- used_charsets |= (1 << j);
- i++;
- }
- }
- i = 0;
- while(i < password_length) {
- /* BEGIN Random.Sample() */
- if (++next >= 56) next = 1;
- if (++nextp >= 56) nextp = 1;
- randnum = seedarray[next] - seedarray[nextp];
- if (randnum == 2147483647) randnum--;
- if (randnum < 0) randnum += 2147483647;
- seedarray[next] = randnum;
- /* END Random.Sample() */
- j = 0;
- if(word[i] == 0) {
- while(boundaries_letters[j] < randnum) j++;
- word[i++] = lowers[j];
- } else if (word[i] == 1) {
- while(boundaries_letters[j] < randnum) j++;
- word[i++] = uppers[j];
- } else if (word[i] == 2) {
- while(boundaries_numbers[j] < randnum) j++;
- word[i++] = numbers[j];
- } else { /* if (word[i] == 3) */
- while(boundaries_symbols[j] < randnum) j++;
- word[i++] = symbols[j];
- }
- }
- word[i] = 0;
- }
- void restore()
- {
- int i, j, s, next, nextp, val, bucket, randnum, used_charsets;
- int seedarray[56];
- int candidate[32]; /* This needs to be at-least as big as password-length */
- seed = 0;
- while(seed > 0) {
- /* BEGIN System.Random(seed) */
- s = 161803398 - seed++;
- seedarray[55] = s;
- i = val = 1;
- while(i < 55) {
- bucket = 21 * i % 55;
- seedarray[bucket] = val;
- val = s - val;
- if(val < 0) val += 2147483647;
- s = seedarray[bucket];
- i++;
- }
- i = 1;
- while(i < 5) {
- j = 1;
- while(j < 56) {
- seedarray[j] -= seedarray[1 + (j + 30) % 55];
- if(seedarray[j] < 0) seedarray[j] += 2147483647;
- j++;
- }
- i++;
- }
- next = 0;
- nextp = 21;
- /* END System.Random(seed) */
- used_charsets = 0;
- while(used_charsets != 15) {
- i = 0;
- while(i < password_length) {
- /* BEGIN Random.Sample() */
- if (++next >= 56) next = 1;
- if (++nextp >= 56) nextp = 1;
- randnum = seedarray[next] - seedarray[nextp];
- if (randnum == 2147483647) randnum--;
- if (randnum < 0) randnum += 2147483647;
- seedarray[next] = randnum;
- /* END Random.Sample() */
- j = 0;
- while(boundaries_charclass[j] < randnum) j++;
- candidate[i] = j;
- used_charsets |= (1 << j);
- i++;
- }
- }
- i = 0;
- while(i < password_length) {
- /* BEGIN Random.Sample() */
- if (++next >= 56) next = 1;
- if (++nextp >= 56) nextp = 1;
- randnum = seedarray[next] - seedarray[nextp];
- if (randnum == 2147483647) randnum--;
- if (randnum < 0) randnum += 2147483647;
- seedarray[next] = randnum;
- /* END Random.Sample() */
- j = 0;
- if(candidate[i] == 0) {
- while(boundaries_letters[j] < randnum) j++;
- if(lowers[j] != word[i++]) break;
- } else if (candidate[i] == 1) {
- while(boundaries_letters[j] < randnum) j++;
- if(uppers[j] != word[i++]) break;
- } else if (candidate[i] == 2) {
- while(boundaries_numbers[j] < randnum) j++;
- if(numbers[j] != word[i++]) break;
- } else { /* if (word[i] == 3) */
- while(boundaries_symbols[j] < randnum) j++;
- if(symbols[j] != word[i++]) break;
- }
- }
- if(i == password_length) return;
- }
- }
- # Try sequences of adjacent keys on a keyboard as candidate passwords
- [List.External:Keyboard]
- int maxlength, length; // Maximum password length to try, current length
- int fuzz; // The desired "fuzz factor", either 0 or 1
- int id[15]; // Current character indices for each position
- int m[0x800]; // The keys matrix
- int mc[0x100]; // Counts of adjacent keys
- int f[0x40], fc; // Characters for the first position, their count
- void init()
- {
- int minlength;
- int i, j, c, p;
- int k[0x40];
- // Initial password length to try
- if (req_minlen)
- minlength = req_minlen;
- else
- minlength = 1;
- if (req_maxlen)
- maxlength = req_maxlen;
- else
- maxlength = cipher_limit; // the format's limit
- fuzz = 1; // "Fuzz factor", set to 0 for much quicker runs
- /*
- * This defines the keyboard layout, by default for a QWERTY keyboard.
- */
- i = 0; while (i < 0x40) k[i++] = 0;
- k[0] = '`';
- i = 0; while (++i <= 9) k[i] = '0' + i;
- k[10] = '0'; k[11] = '-'; k[12] = '=';
- k[0x11] = 'q'; k[0x12] = 'w'; k[0x13] = 'e'; k[0x14] = 'r';
- k[0x15] = 't'; k[0x16] = 'y'; k[0x17] = 'u'; k[0x18] = 'i';
- k[0x19] = 'o'; k[0x1a] = 'p'; k[0x1b] = '['; k[0x1c] = ']';
- k[0x1d] = '\\';
- k[0x21] = 'a'; k[0x22] = 's'; k[0x23] = 'd'; k[0x24] = 'f';
- k[0x25] = 'g'; k[0x26] = 'h'; k[0x27] = 'j'; k[0x28] = 'k';
- k[0x29] = 'l'; k[0x2a] = ';'; k[0x2b] = '\'';
- k[0x31] = 'z'; k[0x32] = 'x'; k[0x33] = 'c'; k[0x34] = 'v';
- k[0x35] = 'b'; k[0x36] = 'n'; k[0x37] = 'm'; k[0x38] = ',';
- k[0x39] = '.'; k[0x3a] = '/';
- i = 0; while (i < 0x100) mc[i++] = 0;
- fc = 0;
- /* rows */
- c = 0;
- i = 0;
- while (i < 0x40) {
- p = c;
- c = k[i++] & 0xff;
- if (!c) continue;
- f[fc++] = c;
- if (!p) continue;
- m[(c << 3) + mc[c]++] = p;
- m[(p << 3) + mc[p]++] = c;
- }
- f[fc] = 0;
- /* columns */
- i = 0;
- while (i < 0x30) {
- p = k[i++] & 0xff;
- if (!p) continue;
- j = 1 - fuzz;
- while (j <= 1 + fuzz) {
- c = k[i + 0x10 - j++] & 0xff;
- if (!c) continue;
- m[(c << 3) + mc[c]++] = p;
- m[(p << 3) + mc[p]++] = c;
- }
- }
- length = 0;
- while (length < minlength)
- id[length++] = 0;
- }
- void generate()
- {
- int i, p, maxcount;
- word[i = 0] = p = f[id[0]];
- while (++i < length)
- word[i] = p = m[(p << 3) + id[i]];
- word[i--] = 0;
- if (i) maxcount = mc[word[i - 1]]; else maxcount = fc;
- while (++id[i] >= maxcount) {
- if (!i) {
- if (length < maxlength) {
- id[0] = 0;
- id[length++] = 0;
- }
- return;
- }
- id[i--] = 0;
- if (i) maxcount = mc[word[i - 1]]; else maxcount = fc;
- }
- }
- void restore()
- {
- int i;
- /* Calculate the length */
- length = 0;
- while (word[length])
- id[length++] = 0;
- /* Infer the first character index */
- i = -1;
- while (++i < fc) {
- if (f[i] == word[0]) {
- id[0] = i;
- break;
- }
- }
- /* This sample can be enhanced to infer the rest of the indices here */
- }
- # Simplest (fastest?) possible dumb exhaustive search, demonstrating a
- # mode that does not need any special restore() handling.
- # Defaults to printable ASCII.
- [List.External:DumbDumb]
- void init()
- {
- word[0] = ' ' - 1;
- word[1] = 0;
- }
- void generate()
- {
- int i;
- if (++word < 0x7f)
- return;
- i = 0;
- while (word[i] > 0x7e) {
- word[i++] = ' ';
- if (!word[i]) {
- word[i] = ' ';
- word[i + 1] = 0;
- } else
- word[i]++;
- }
- if (i > cipher_limit)
- word = 0;
- }
- /*
- * This mode will resume correctly without any restore handing.
- * The empty function just confirms to John that everything is in order.
- */
- void restore()
- {
- }
- # Generic implementation of "dumb" exhaustive search, given a range of lengths
- # and an arbitrary charset. This is pre-configured to try 8-bit characters
- # against LM hashes, which is only reasonable to do for very short password
- # half lengths.
- [List.External:DumbForce]
- int maxlength; // Maximum password length to try
- int last; // Last character position, zero-based
- int lastid; // Character index in the last position
- int id[0x7f]; // Current character indices for other positions
- int charset[0x100], c0; // Character set
- void init()
- {
- int minlength;
- int i, c;
- // Initial password length to try, must be at least 1
- if (req_minlen)
- minlength = req_minlen;
- else
- minlength = 1;
- if (req_maxlen)
- maxlength = req_maxlen;
- else
- maxlength = cipher_limit; // the format's limit
- /*
- * This defines the character set.
- *
- * Let's say, we want to try TAB, all non-control ASCII characters, and all
- * 8-bit characters, including the 8-bit terminal controls range (as these are
- * used as regular national characters with some 8-bit encodings), but except
- * for known terminal controls (risky for the terminal we may be running on).
- *
- * Also, let's say our hashes are case-insensitive, so skip lowercase letters
- * (this is right for LM hashes).
- */
- i = 0;
- charset[i++] = 9; // Add horizontal TAB (ASCII 9), then
- c = ' '; // start with space (ASCII 32) and
- while (c < 'a') // proceed till lowercase 'a'
- charset[i++] = c++;
- c = 'z' + 1; // Skip lowercase letters and
- while (c <= 0x7e) // proceed for all printable ASCII
- charset[i++] = c++;
- c++; // Skip DEL (ASCII 127) and
- while (c < 0x84) // proceed over 8-bit codes till IND
- charset[i++] = c++;
- charset[i++] = 0x86; // Skip IND (84 hex) and NEL (85 hex)
- charset[i++] = 0x87;
- c = 0x89; // Skip HTS (88 hex)
- while (c < 0x8d) // Proceed till RI (8D hex)
- charset[i++] = c++;
- c = 0x91; // Skip RI, SS2, SS3, DCS
- while (c < 0x96) // Proceed till SPA (96 hex)
- charset[i++] = c++;
- charset[i++] = 0x99; // Skip SPA, EPA, SOS
- c = 0xa0; // Skip DECID, CSI, ST, OSC, PM, APC
- while (c <= 0xff) // Proceed with the rest of 8-bit codes
- charset[i++] = c++;
- /* Zero-terminate it, and cache the first character */
- charset[i] = 0;
- c0 = charset[0];
- last = minlength - 1;
- i = 0;
- while (i <= last) {
- id[i] = 0;
- word[i++] = c0;
- }
- lastid = -1;
- word[i] = 0;
- }
- void generate()
- {
- int i;
- /* Handle the typical case specially */
- if (word[last] = charset[++lastid]) return;
- lastid = 0;
- word[i = last] = c0;
- while (i--) { // Have a preceding position?
- if (word[i] = charset[++id[i]]) return;
- id[i] = 0;
- word[i] = c0;
- }
- if (++last < maxlength) { // Next length?
- id[last] = lastid = 0;
- word[last] = c0;
- word[last + 1] = 0;
- } else // We're done
- word = 0;
- }
- void restore()
- {
- int i, c;
- /* Calculate the current length and infer the character indices */
- last = 0;
- while (c = word[last]) {
- i = 0; while (charset[i] != c && charset[i]) i++;
- if (!charset[i]) i = 0; // Not found
- id[last++] = i;
- }
- lastid = id[--last];
- }
- # Generic implementation of exhaustive search for a partially-known password.
- # This is pre-configured for length 8, lowercase and uppercase letters in the
- # first 4 positions (52 different characters), and digits in the remaining 4
- # positions - however, the corresponding part of init() may be modified to use
- # arbitrary character sets or even fixed characters for each position.
- [List.External:KnownForce]
- int last; // Last character position, zero-based
- int lastofs; // Last character position offset into charset[]
- int lastid; // Current character index in the last position
- int id[0x7f]; // Current character indices for other positions
- int charset[0x7f00]; // Character sets, 0x100 elements for each position
- void init()
- {
- int length, maxlength;
- int pos, ofs, i, c;
- if (req_minlen)
- length = req_minlen;
- else
- length = 8; // Password length to try (NOTE: other [eg. shorter]
- // lengths will not be tried!)
- if (req_maxlen)
- maxlength = req_maxlen;
- else
- maxlength = cipher_limit; // the format's limit
- /* This defines the character sets for different character positions */
- if (length > maxlength)
- length = maxlength;
- pos = 0;
- while (pos < 4) {
- ofs = pos++ << 8;
- i = 0;
- c = 'a';
- while (c <= 'z')
- charset[ofs + i++] = c++;
- c = 'A';
- while (c <= 'Z')
- charset[ofs + i++] = c++;
- charset[ofs + i] = 0;
- }
- while (pos < length) {
- ofs = pos++ << 8;
- i = 0;
- c = '0';
- while (c <= '9')
- charset[ofs + i++] = c++;
- charset[ofs + i] = 0;
- }
- last = length - 1;
- pos = -1;
- while (++pos <= last)
- word[pos] = charset[id[pos] = pos << 8];
- lastid = (lastofs = last << 8) - 1;
- word[pos] = 0;
- }
- void generate()
- {
- int pos;
- /* Handle the typical case specially */
- if (word[last] = charset[++lastid]) return;
- word[pos = last] = charset[lastid = lastofs];
- while (pos--) { // Have a preceding position?
- if (word[pos] = charset[++id[pos]]) return;
- word[pos] = charset[id[pos] = pos << 8];
- }
- word = 0; // We're done
- }
- void restore()
- {
- int i, c;
- /* Calculate the current length and infer the character indices */
- last = 0;
- while (c = word[last]) {
- i = lastofs = last << 8;
- while (charset[i] != c && charset[i]) i++;
- if (!charset[i]) i = lastofs; // Not found
- id[last++] = i;
- }
- lastid = id[--last];
- }
- # A variation of KnownForce configured to try likely date and time strings.
- [List.External:DateTime]
- int last; // Last character position, zero-based
- int lastofs; // Last character position offset into charset[]
- int lastid; // Current character index in the last position
- int id[0x7f]; // Current character indices for other positions
- int charset[0x7f00]; // Character sets, 0x100 elements for each position
- void init()
- {
- int length;
- int pos, ofs, i, c;
- length = 8; // Must be one of: 4, 5, 7, 8
- /* This defines the character sets for different character positions */
- pos = 0;
- while (pos < length - 6) {
- ofs = pos++ << 8;
- i = 0;
- c = '0';
- while (c <= '9')
- charset[ofs + i++] = c++;
- charset[ofs + i] = 0;
- }
- if (pos) {
- ofs = pos++ << 8;
- charset[ofs] = '/';
- charset[ofs + 1] = '.';
- charset[ofs + 2] = ':';
- charset[ofs + 3] = 0;
- }
- while (pos < length - 3) {
- ofs = pos++ << 8;
- i = 0;
- c = '0';
- while (c <= '9')
- charset[ofs + i++] = c++;
- charset[ofs + i] = 0;
- }
- ofs = pos++ << 8;
- charset[ofs] = '/';
- charset[ofs + 1] = '.';
- charset[ofs + 2] = ':';
- charset[ofs + 3] = 0;
- while (pos < length) {
- ofs = pos++ << 8;
- i = 0;
- c = '0';
- while (c <= '9')
- charset[ofs + i++] = c++;
- charset[ofs + i] = 0;
- }
- last = length - 1;
- pos = -1;
- while (++pos <= last)
- word[pos] = charset[id[pos] = pos << 8];
- lastid = (lastofs = last << 8) - 1;
- word[pos] = 0;
- }
- void generate()
- {
- int pos;
- /* Handle the typical case specially */
- if (word[last] = charset[++lastid]) return;
- word[pos = last] = charset[lastid = lastofs];
- while (pos--) { // Have a preceding position?
- if (word[pos] = charset[++id[pos]]) return;
- word[pos] = charset[id[pos] = pos << 8];
- }
- word = 0; // We're done
- }
- void restore()
- {
- int i, c;
- /* Calculate the current length and infer the character indices */
- last = 0;
- while (c = word[last]) {
- i = lastofs = last << 8;
- while (charset[i] != c && charset[i]) i++;
- if (!charset[i]) i = lastofs; // Not found
- id[last++] = i;
- }
- lastid = id[--last];
- }
- # Try strings of repeated characters.
- #
- # This is the code which is common for all [List.External:Repeats*]
- # sections which include this External_base section.
- # The generate() function will limit the maximum length of generated
- # candidates to either the format's limit (maximum password length)
- # or to the limit specified with --stdout=LENGTH (Default: 125),
- # thus avoiding duplicate candidates for formats with limited maximum
- # passwortd length.
- # The comparison of the current length and the limit is only done
- # after switching to a new length.
- # So, if the minimum length specified already exceeds this limit,
- # then all the candidates for the minimum length will be generated
- # nevertheless.
- [List.External_base:Repeats]
- int minlength, maxlength, minc, maxc, length, c;
- void generate()
- {
- int i;
- i = 0;
- while (i < length)
- word[i++] = c;
- word[i] = 0;
- if (c++ < maxc)
- return;
- c = minc;
- if (++length > maxlength)
- c = 0; // Will NUL out the next "word" and thus terminate
- }
- # Try strings of repeated characters (range: space - 0xff).
- [List.External:Repeats]
- .include [List.External_base:Repeats]
- void init()
- {
- if (req_minlen)
- minlength = req_minlen;
- else
- minlength = 1;
- if (req_maxlen)
- maxlength = req_maxlen;
- else
- maxlength = cipher_limit; // the format's limit
- minc = 0x20;
- maxc = 0xff;
- length = minlength; c = minc;
- }
- # Try strings of repeated digits (range: '0' - '9').
- [List.External:Repeats_digits]
- .include [List.External_base:Repeats]
- void init()
- {
- if (req_minlen)
- minlength = req_minlen;
- else
- minlength = 1;
- if (req_maxlen)
- maxlength = req_maxlen;
- else
- maxlength = cipher_limit; // the format's limit
- minc = '0';
- maxc = '9';
- length = minlength; c = minc;
- }
- # Try strings of repeated lowercase letters (range: 'a' - 'z').
- [List.External:Repeats_lowercase]
- .include [List.External_base:Repeats]
- void init()
- {
- if (req_minlen)
- minlength = req_minlen;
- else
- minlength = 1;
- if (req_maxlen)
- maxlength = req_maxlen;
- else
- maxlength = cipher_limit; // the format's limit
- minc = 'a';
- maxc = 'z';
- length = minlength; c = minc;
- }
- # Try strings of repeated printable ASCII characters
- # (range: ' ' - '~').
- [List.External:Repeats_printable_ASCII]
- .include [List.External_base:Repeats]
- void init()
- {
- if (req_minlen)
- minlength = req_minlen;
- else
- minlength = 1;
- if (req_maxlen)
- maxlength = req_maxlen;
- else
- maxlength = cipher_limit; // the format's limit
- minc = ' ';
- maxc = '~';
- length = minlength; c = minc;
- }
- # Try character sequences ("0123456", "acegikmoqs", "ZYXWVU", etc.).
- #
- # The generate() function will limit the maximum length of generated
- # candidates to either the format's limit (maximum password length)
- # or to the limit specified with --stdout=LENGTH (Default: 125),
- # thus avoiding duplicate candidates for formats with limited maximum
- # passwortd length.
- # The comparison of the current length and the limit is only done
- # after switching to a new length.
- # So, if the minimum length specified already exceeds this limit,
- # then all the candidates for the minimum length will be generated
- # nevertheless.
- # External modes reusing this External_base mode should only need to
- # adjust the init() function.
- # In the init() function, a minimum length which is > 1 should be
- # specified.
- # Otherwise, the generated candidates will not depend on the increment
- # specified.
- # For length = 1, the candidates will be the same as for external mode
- # Repeats with length 1.
- # Actually, Repeats is a special case of Sequence, using increment = 0.
- # External modes reusing this External_base mode should also make sure
- # that the number of different characters (specified as a range from "from"
- # to "to") is not smaller than the minimum length ("minlength"),
- # if the start increment "inc" is 1.
- # For a start increment > 1, the number of different characters in the
- # range "from" - "to" must be greater than or equal to
- # (1 + ("minlength" - 1) * "inc").
- # Otherwise you might get unexpected results.
- # The range of characters to be used for the sequences needs to be
- # specified by adjusting the "from" and "to" variables.
- # To generate sequences which decrement characters ("987654"),
- # "from" must be > "to".
- # Otherwise, the generated sequences will increment characters ("abcdef").
- #
- # Variables to be used and the generate() function are common
- # for all sections which include this External_base section.
- [List.External_base:Sequence]
- /*
- * See the [List.External:Sequence_0-9] section to learn more about
- * the meaning of these variables which can be adjusted to define
- * new external modes based on an existing one:
- */
- int minlength, from, to, maxlength, inc, direction;
- /*
- * The value of these variables shouldn't be changed when copying
- * an existing external mode:
- */
- int length, first;
- void generate()
- {
- int i;
- i = 0;
- while (i < length) {
- word[i] = first + (i * inc * direction);
- ++i;
- }
- word[i] = 0;
- // start the next sequence of the same length
- // with the next character
- first = first + direction;
- // But check that a sequence of the current length
- // is still possible (without leaving the range of
- // characters allowed
- if ((direction > 0 && first + (length - 1) * inc > to) ||
- (direction < 0 && first - (length - 1) * inc < to)) {
- // No more sequence is possible. Reset start character
- first = from;
- // Now try the next length.
- // But just in case an individual External mode reusing
- // this External_base mode did specify a maxlength
- // which is larger than the one supported by the format
- // or by --stdout=LENGTH, make sure no more candidates
- // are generated.
- // Checking this just once per length per increment
- // doen't really hurt performance.
- if (maxlength > cipher_limit)
- maxlength = cipher_limit;
- // For a similar reason, the maximum length of a
- // sequence is limited by the number of different
- // characters and by the increment.
- // The larger the increment, the smaller
- // the maximum possible length for a given
- // character range.
- while (inc * (maxlength - 1) > direction * (to - from))
- --maxlength;
- if (++length > maxlength) {
- // The maximum length for this increment has been reached.
- // Restart at minimum length with the next possible
- // increment
- ++inc;
- // Unfortunately, we have to check again
- // if the maximum length needs to be reduced
- // for the new increment
- while (inc * (maxlength - 1) > direction * (to - from))
- --maxlength;
- length = minlength;
- }
- if (maxlength < minlength)
- // With the current increment, we can't even generate
- // sequences of the minimum required length.
- // So we need to stop here.
- // This will make sure that no more candidiates
- // will be generated:
- first = 0;
- }
- }
- # Try sequences of digits (range: '0' - '9').
- #
- # Aditional comments can be found in the
- # section [List.External_base:Sequence]
- #
- # This external mode is thoroughly commented,
- # to make it easier to copy and adjust it as needed.
- [List.External:Sequence_0-9]
- .include [List.External_base:Sequence]
- void init()
- {
- // Adjust the following 4 variables if you want to define
- // a different external mode.
- // This is the start character for the generated sequence
- // if "from" is smaller than "to", the increment from
- // first to second character ... will be positive ("0123456789").
- // Otherwise, it will be negative ("987654321").
- from = '0';
- to = '9';
- // minimum length of the sequence
- // make sure it is not larger than the number of different characters
- // in the range between "from" and "to" specified above
- minlength = 2;
- // start increment for generating the sequence, usually 1
- // if it is larger than 1, you need even more characters
- // in the range between "from" and "to"
- // Don't specify a negative value here.
- // If you want to generate sequences like "zyxwvu" or "86420",
- // adjust "from" and "to" so that "from" is larger than "to".
- // (A start increment of 0 is also possible, in that case the first
- // sequences will be candidates which just repeat the same character.)
- inc = 1;
- // For copied external modes, no further changes should be required
- // in the statements following this comment
- length = minlength;
- first = from;
- if (from <= to) {
- maxlength = to - from + 1;
- direction = 1;
- } else {
- // We have to create sequences which decrement the previous character
- maxlength = from - to + 1;
- direction = -1;
- }
- }
- # Try sequence of lower case letters (range: 'a' - 'z').
- # This external mode is not very well documented.
- # Refer to [List.External:Sequence_0-9] for more detailed information.
- [List.External:Sequence_a-z]
- .include [List.External_base:Sequence]
- void init()
- {
- from = 'a';
- to = 'z';
- minlength = 2;
- inc = 1;
- length = minlength;
- first = from;
- if (from <= to) {
- maxlength = to - from + 1;
- direction = 1;
- } else {
- maxlength = from - to + 1;
- direction = -1;
- }
- }
- # Try sequence of lower case letters (range: 'a' - 'z'), but reversed
- # ("zxywvu").
- # This external mode is not very well documented.
- # Refer to [List.External:Sequence_0-9] for more detailed information.
- [List.External:Sequence_z-a]
- .include [List.External_base:Sequence]
- void init()
- {
- from = 'z';
- to = 'a';
- minlength = 2;
- inc = 1;
- length = minlength;
- first = from;
- if (from <= to) {
- maxlength = to - from + 1;
- direction = 1;
- } else {
- maxlength = from - to + 1;
- direction = -1;
- }
- }
- # Try sequence of printable ASCII characters (range: ' ' - '~').
- # This external mode is not very well documented.
- # Refer to [List.External:Sequence_0-9] for more detailed information.
- [List.External:Sequence_printable_ascii]
- .include [List.External_base:Sequence]
- void init()
- {
- from = ' ';
- to = '~';
- minlength = 2;
- inc = 1;
- length = minlength;
- first = from;
- if (from <= to) {
- maxlength = to - from + 1;
- direction = 1;
- } else {
- maxlength = from - to + 1;
- direction = -1;
- }
- }
- # Try sequence of printable ASCII characters (range: ' ' - '~'),
- # but decrementing characters ("fedcba") instead of incrementing.
- # This external mode is not very well documented.
- # Refer to [List.External:Sequence_0-9] for more detailed information.
- [List.External:Sequence_reversed_ascii]
- .include [List.External_base:Sequence]
- void init()
- {
- from = '~';
- to = ' ';
- minlength = 2;
- inc = 1;
- length = minlength;
- first = from;
- if (from <= to) {
- maxlength = to - from + 1;
- direction = 1;
- } else {
- maxlength = from - to + 1;
- direction = -1;
- }
- }
- # Try sequence of characters (range: space - 0xff).
- # This external mode is not very well documented.
- # Refer to [List.External:Sequence_0-9] for more detailed information.
- [List.External:Sequence]
- .include [List.External_base:Sequence]
- void init()
- {
- from = ' ';
- to = 0xff;
- minlength = 2;
- inc = 1;
- length = minlength;
- first = from;
- if (from <= to) {
- maxlength = to - from + 1;
- direction = 1;
- } else {
- maxlength = from - to + 1;
- direction = -1;
- }
- }
- # Generate candidate passwords from many small subsets of characters from a
- # much larger full character set. This will test for passwords containing too
- # few different characters. As currently implemented, this code will produce
- # some duplicates, although their number is relatively small when the maximum
- # number of different characters (the maxdiff setting) is significantly lower
- # than the maximum length (the maxlength setting). Nevertheless, you may want
- # to pass the resulting candidate passwords through "unique" if you intend to
- # test them against hashes that are salted and/or of a slow to compute type.
- [List.External:Subsets]
- int minlength; // Minimum password length to try
- int maxlength; // Maximum password length to try
- int startdiff; // Initial number of characters in a subset to try
- int maxdiff; // Maximum number of characters in a subset to try
- int last; // Last character position, zero-based
- int lastid; // Character index in the last position
- int id[0x7f]; // Current character indices for other positions
- int subset[0x100], c0; // Current subset
- int subcount; // Number of characters in the current subset
- int subid[0x100]; // Indices into charset[] of characters in subset[]
- int charset[0x100]; // Full character set
- int charcount; // Number of characters in the full charset
- void init()
- {
- int i, c;
- // Minimum password length to try, must be at least 1
- if (req_minlen)
- minlength = req_minlen;
- else
- minlength = 1;
- // Maximum password length to try, must be at least same as minlength
- // This external mode's default maximum length can be adjusted
- // using --max-length= on the command line
- if (req_maxlen)
- maxlength = req_maxlen;
- else
- maxlength = 8;
- // "cipher_limit" is the variable which contains the format's
- // maximum password length
- if (maxlength > cipher_limit)
- maxlength = cipher_limit;
- startdiff = 1; // Initial number of different characters to try
- maxdiff = 3; // Maximum number of different characters to try
- /* This defines the character set */
- i = 0;
- c = 0x20;
- while (c <= 0x7e)
- charset[i++] = c++;
- if (maxdiff > (charcount = i))
- maxdiff = i;
- if (maxdiff > maxlength)
- maxdiff = maxlength;
- /*
- * Initialize the variables such that generate() gets to its "next subset"
- * code, which will initialize everything for real.
- */
- subcount = (i = startdiff) - 1;
- while (i--)
- subid[i] = charcount;
- subset[0] = c0 = 0;
- last = maxlength - 1;
- lastid = -1;
- }
- void generate()
- {
- int i;
- /* Handle the typical case specially */
- if (word[last] = subset[++lastid]) return;
- lastid = 0;
- word[i = last] = c0;
- while (i--) { // Have a preceding position?
- if (word[i] = subset[++id[i]]) return;
- id[i] = 0;
- word[i] = c0;
- }
- if (++last < maxlength) { // Next length?
- id[last] = lastid = 0;
- word[last] = c0;
- word[last + 1] = 0;
- return;
- }
- /* Next subset */
- if (subcount) {
- int j;
- i = subcount - 1;
- j = charcount;
- while (++subid[i] >= j) {
- if (i--) {
- j--;
- continue;
- }
- subid[i = 0] = 0;
- subset[++subcount] = 0;
- break;
- }
- } else {
- subid[i = 0] = 0;
- subset[++subcount] = 0;
- }
- subset[i] = charset[subid[i]];
- while (++i < subcount)
- subset[i] = charset[subid[i] = subid[i - 1] + 1];
- if (subcount > maxdiff) {
- word = 0; // Done
- return;
- }
- /*
- * We won't be able to fully use the subset if the length is smaller than the
- * character count. We assume that we've tried all smaller subsets before, so
- * we don't bother with such short lengths.
- */
- if (minlength < subcount)
- last = subcount - 1;
- else
- last = minlength - 1;
- c0 = subset[0];
- i = 0;
- while (i <= last) {
- id[i] = 0;
- word[i++] = c0;
- }
- lastid = 0;
- word[i] = 0;
- }
- # Simple password policy matching: require at least one digit.
- [List.External:AtLeast1-Simple]
- void filter()
- {
- int i, c;
- i = 0;
- while (c = word[i++])
- if (c >= '0' && c <= '9')
- return; // Found at least one suitable character, good
- word = 0; // No suitable characters found, skip this "word"
- }
- # The same password policy implemented in a more efficient and more generic
- # fashion (easy to expand to include other "sufficient" characters as well).
- [List.External:AtLeast1-Generic]
- int mask[0x100];
- void init()
- {
- int c;
- mask[0] = 0; // Terminate the loop in filter() on NUL
- c = 1;
- while (c < 0x100)
- mask[c++] = 1; // Continue looping in filter() on most chars
- c = '0';
- while (c <= '9')
- mask[c++] = 0; // Terminate the loop in filter() on digits
- }
- void filter()
- {
- int i;
- i = -1;
- while (mask[word[++i]])
- continue;
- if (word[i])
- return; // Found at least one suitable character, good
- word = 0; // No suitable characters found, skip this "word"
- }
- # An efficient and fairly generic password policy matcher. The policy to match
- # is specified in the check at the end of filter() and in mask[]. For example,
- # lowercase and uppercase letters may be treated the same by initializing the
- # corresponding mask[] elements to the same value, then adjusting the value to
- # check "seen" for accordingly.
- [List.External:Policy]
- int mask[0x100];
- void init()
- {
- int c;
- mask[0] = 0x100;
- c = 1;
- while (c < 0x100)
- mask[c++] = 0x200;
- c = 'a';
- while (c <= 'z')
- mask[c++] = 1;
- c = 'A';
- while (c <= 'Z')
- mask[c++] = 2;
- c = '0';
- while (c <= '9')
- mask[c++] = 4;
- }
- void filter()
- {
- int i, seen;
- /*
- * This loop ends when we see NUL (sets 0x100) or a disallowed character
- * (sets 0x200).
- */
- i = -1; seen = 0;
- while ((seen |= mask[word[++i]]) < 0x100)
- continue;
- /*
- * We should have seen at least one character of each type (which "add up"
- * to 7) and then a NUL (adds 0x100), but not any other characters (would
- * add 0x200). The length must be 8.
- */
- if (seen != 0x107 || i != 8)
- word = 0; // Does not conform to policy
- }
- # Append the Luhn algorithm digit to arbitrary all-digit strings. Optimized
- # for speed, not for size nor simplicity. The primary optimization trick is to
- # compute the length and four sums in parallel (in two SIMD'ish variables).
- # Then whether the length is even or odd determines which two of the four sums
- # are actually used. Checks for non-digits and for NUL are packed into the
- # SIMD'ish bitmasks as well.
- [List.External:AppendLuhn]
- int map1[0x100], map2[0x1fff];
- void init()
- {
- int i;
- map1[0] = ~0x7fffffff;
- i = 1;
- while (i < 0x100)
- map1[i++] = ~0x7effffff;
- i = -1;
- while (++i < 10)
- map1['0' + i] = i + ((i * 2 % 10 + i / 5) << 12);
- i = -1;
- while (++i < 0x1fff) {
- if (i % 10)
- map2[i] = '9' + 1 - i % 10;
- else
- map2[i] = '0';
- }
- }
- void filter()
- {
- int i, o, e;
- i = o = e = 0;
- while ((o += map1[word[i++]]) >= 0) {
- if ((e += map1[word[i++]]) >= 0)
- continue;
- if (e & 0x01000000)
- return; // Not all-digit, leave unmodified
- word[i--] = 0;
- word[i] = map2[(e & 0xfff) + (o >> 12)];
- return;
- }
- if (o & 0x01000000)
- return; // Not all-digit, leave unmodified
- word[i--] = 0;
- word[i] = map2[(o & 0xfff) + (e >> 12)];
- }
- # Trivial Rotate function, which rotates letters in a word
- # by a given number of places (like 13 in case of ROT13).
- # Words which don't contain any letters (and thus wouldn't be changed
- # by this filter) are skipped, because these unchanged words probably
- # should have been tried before trying a mangled version.
- [List.External_base:Filter_Rotate]
- int rot; // The number of places to rotate each letter in a word
- void filter()
- {
- int i, j, c;
- i = 0;
- j = 0; // j counts the number of changed characters
- while (c = word[i]) {
- if (c >= 'a' && c <= 'z') {
- c = c - 26 + rot;
- if (c < 'a') c += 26;
- word[i] = c;
- j++;
- } else if (c >= 'A' && c <= 'Z' ) {
- c = c - 26 + rot;
- if (c < 'A') c += 26;
- word[i] = c;
- j++;
- }
- i++;
- }
- if (j == 0)
- // Noting changed. Reject this word.
- word = 0;
- }
- # ROT13 Example
- [List.External:Filter_ROT13]
- .include [List.External_base:Filter_Rotate]
- void init()
- {
- // Just in case someone wants to "rotate" by other values,
- // adjust the value of the rot variable
- // (may be in a copied external mode):
- // 13: "abcABCxyzXYZ" -> "nopNOPklmKLM"
- // 1: "abcABCxyzXYZ" -> "bcdBCDyzaYZA"
- // 25: "abcABCxyzXYZ" -> "zabZABwxyWXY"
- // -1: "abcABCxyzXYZ" -> "zabZABwxyWXY"
- // and so on
- // Allowed range: -25 <= rot <= -1, or 1 <= rot <= 25
- rot = 13;
- // Don't change the following statement.
- // It is supposed to "sanitize" the value to be in the
- // range
- rot = (rot + 26) % 26;
- }
- # Trivial parallel processing example (obsoleted by the "--node" option)
- [List.External:Parallel]
- /*
- * This word filter makes John process some of the words only, for running
- * multiple instances on different CPUs. It can be used with any cracking
- * mode except for "single crack". Note: this is not a good solution, but
- * is just an example of what can be done with word filters.
- */
- int node, total; // This node's number, and node count
- int number; // Current word number
- void init()
- {
- node = 1; total = 2; // Node 1 of 2, change as appropriate
- number = node - 1; // Speedup the filter a bit
- }
- void filter()
- {
- if (number++ % total) // Word for a different node?
- word = 0; // Yes, skip it
- }
- # Interrupt the cracking session after "max" words tried
- [List.External:AutoAbort]
- int max; // Maximum number of words to try
- int number; // Current word number
- void init()
- {
- max = 1000;
- number = 0;
- }
- void filter()
- {
- if (++number > max)
- abort = 1; // Interrupt the cracking session
- }
- # Print the status line after every "interval" words tried
- [List.External:AutoStatus]
- int interval; // How often to print the status
- int number; // Current word number
- void init()
- {
- interval = 1000;
- number = 0;
- }
- void filter()
- {
- if (number++ % interval)
- return;
- status = 1; // Print the status line
- }
- # dumb-force UTF-16, in an external file
- .include "$JOHN/dumb16.conf"
- # dumb-force UTF-32, in an external file
- .include "$JOHN/dumb32.conf"
- # repeats UTF-16, in an external file
- .include "$JOHN/repeats16.conf"
- # repeats UTF-32, in an external file
- .include "$JOHN/repeats32.conf"
- # Dynamic ($dynamic_n$) scripting code, in an external file
- # also shows/tests that .include <file> works the same as .include "$JOHN/file"
- .include <dynamic.conf>
- # Regex alphabets
- .include <regex_alphabets.conf>
- # include john.local.conf (defaults to being empty, but never overwritten)
- .include "$JOHN/john.local.conf"
- # End of john.conf file.
- # Keep this comment, and blank line above it, to make sure a john.local.conf
- # that does not end with \n is properly loaded.