PageRenderTime 72ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/run/john.conf

https://github.com/bilzor/JohnTheRipper
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
  1. #
  2. # This file is part of John the Ripper password cracker,
  3. # Copyright (c) 1996-2006,2008-2013 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. # The [Options] section is for general options only.
  17. # Note that MPI specific options have been moved
  18. # to [Options.MPI]
  19. # There is also a new section [Options.OpenCL]
  20. # for OpenCL specific options
  21. # Default settings for Markov mode have been moved
  22. # to [Markov.Default], but you can define other
  23. # Markov modes as well, see ../doc/MARKOV
  24. [Options]
  25. # Default wordlist file name (including in batch mode)
  26. Wordlist = $JOHN/password.lst
  27. # Use idle cycles only
  28. Idle = Y
  29. # Crash recovery file saving delay in seconds
  30. Save = 60
  31. # Beep when a password is found (who needs this anyway?)
  32. Beep = N
  33. # if set to Y then dynamic format will always work with bare hashes. Normally
  34. # dynamic only uses bare hashes if a single dynamic type is selected with
  35. # the -format= (so -format=dynamic_0 would use valid bare hashes).
  36. DynamicAlwaysUseBareHashes = N
  37. # Default Single mode rules
  38. SingleRules = Single
  39. # Default batch mode Wordlist rules
  40. BatchModeWordlistRules = Wordlist
  41. # Default wordlist mode rules when not in batch mode (if any)
  42. # If this is set and you want to run once without rules, use --rules:none
  43. #WordlistRules = Wordlist
  44. # Default loopback mode rules (if any)
  45. # If this is set and you want to run once without rules, use --rules:none
  46. LoopbackRules = Loopback
  47. # Default/batch mode Incremental mode
  48. # Warning: changing these might currently break resume on existing sessions
  49. DefaultIncremental = ASCII
  50. #DefaultIncrementalUTF8 = UTF8
  51. DefaultIncrementalLM = LM_ASCII
  52. # Time formatting string used in status ETA.
  53. #
  54. # TimeFormat24 is used when ETA is within 24h, so it is possible to omit
  55. # the date then if you like, and show seconds instead.
  56. #
  57. # %c means 'local' specific canonical form, such as:
  58. # 05/06/11 18:10:34
  59. #
  60. # Other examples
  61. # %d/%m/%y %H:%M (day/mon/year hour:min)
  62. # %m/%d/%y %H:%M (mon/day/year hour:min)
  63. # %Y-%m-%d %H:%M (ISO 8601 style, 2011-05-06 18:10)
  64. TimeFormat = %Y-%m-%d %H:%M
  65. TimeFormat24 = %H:%M:%S
  66. # For single mode, load the full GECOS field (before splitting) as one
  67. # additional candidate. Normal behavior is to only load individual words
  68. # from that field. Enabling this can help when this field contains email
  69. # addresses or other strings that are better used unsplit, but it increases
  70. # the number of words tried so it may also slow things down. If enabling this
  71. # you might want to bump SingleWordsPairMax too, below, to 10 or more.
  72. PristineGecos = N
  73. # Over-ride SINGLE_WORDS_PAIR_MAX in params.h. This may slow down Single mode
  74. # but it may also help cracking a few more candidates. Default in core John
  75. # is 4 while the Jumbo default is 6.
  76. SingleWordsPairMax = 6
  77. # Emit a status line whenever a password is cracked (this is the same as
  78. # passing the --crack-status option flag to john). NOTE: if this is set
  79. # to true here, --crack-status will toggle it back to false.
  80. CrackStatus = N
  81. # When printing status, show number of candidates tried (eg. 123456p). Note
  82. # that the number *is* now equal to "words tried" and nothing else.
  83. # This is added to the "+ Cracked" line in the log as well.
  84. StatusShowCandidates = N
  85. # Write cracked passwords to the log file (default is just the user name)
  86. LogCrackedPasswords = N
  87. # Disable the dupe checking when loading hashes. For testing purposes only!
  88. NoLoaderDupeCheck = N
  89. # Default --encoding for input files (ie. login/GECOS fields) and wordlists
  90. # etc. If this is not set here (you need to uncomment it) and --encoding is
  91. # not used either, the default is ISO-8859-1 for Unicode conversions and 7-bit
  92. # ASCII encoding is assumed for rules - so eg. uppercasing of letters other
  93. # than a-z will not work at all!
  94. #DefaultEncoding = UTF-8
  95. # Default --target-encoding for Microsoft hashes (LM, NETLM et al) when input
  96. # encoding is UTF-8. CP850 would be a universal choice for covering most
  97. # "latin" countries.
  98. #DefaultMSCodepage = CP850
  99. # Default --intermediate-encoding to be used within the rules engine when both
  100. # input and "target" encodings are Unicode (eg. UTF-8 wordlist and NT hashes).
  101. # This may hit performance but lets us do things like case conversions for
  102. # UTF-8. You can pick any supported codepage that has as much support for the
  103. # input data as possible - eg. for "latin" language passwords you can use
  104. # CP850, ISO-8859-1 or CP1252 and it will probably not make a difference.
  105. #DefaultIntermediateEncoding = CP1252
  106. # Warn if seeing UTF-8 when expecting some other encoding, or vice versa.
  107. #WarnEncoding = Y
  108. # Always report (to screen and log) cracked passwords as UTF-8, regardless of
  109. # input encoding. This is recommended if you have your terminal set for UTF-8.
  110. #AlwaysReportUTF8 = Y
  111. # Always store Unicode (UTF-16) passwords as UTF-8 in john.pot, regardless
  112. # of input encoding. This prevents john.pot from being filled with mixed
  113. # and eventually unknown encodings. This is recommended if you have your
  114. # terminal set for UTF-8 and/or you want to run --loopback for LM->NT
  115. # including non-ASCII.
  116. #UnicodeStoreUTF8 = Y
  117. # Always report/store non-Unicode formats as UTF-8, regardless of input
  118. # encoding. Note: The actual codepage that was used is not stored anywhere
  119. # except in the log file. This is needed eg. for --loopback to crack LM->NT
  120. # including non-ASCII.
  121. #CPstoreUTF8 = Y
  122. # Default verbosity is 3, valid figures are 1-5 right now.
  123. # 4-5 enables some extra output
  124. # 2 mutes rules & incremental output in logs (LOTS of lines)
  125. # 1 even mutes printing (to screen) of cracked passwords
  126. Verbosity = 3
  127. # If set to Y, do not output, log or store cracked passwords verbatim.
  128. # This implies a different default .pot database file "secure.pot" instead
  129. # of "john.pot" but it can still be overridden using --pot=FILE.
  130. # This also overrides other options, eg. LogCrackedPasswords.
  131. SecureMode = N
  132. # If set to Y, a session using --fork or MPI will signal to other nodes when
  133. # it has written cracks to the pot file (note that this writing is delayed
  134. # by buffers and the "Save" timer above), so they will re-sync.
  135. ReloadAtCrack = Y
  136. # If set to Y, resync pot file when saving session.
  137. ReloadAtSave = Y
  138. # If this file exists, john will abort cleanly
  139. AbortFile = /var/run/john/abort
  140. # While this file exists, john will pause
  141. PauseFile = /var/run/john/pause
  142. [Options:MPI]
  143. # Automagically disable OMP if MPI is used (set to N if
  144. # you want to run one MPI process per multi-core host)
  145. MPIOMPmutex = Y
  146. # Print a notice if disabling OMP (when MPIOMPmutex = Y)
  147. # or when running OMP and MPI at the same time
  148. MPIOMPverbose = Y
  149. [Options:OpenCL]
  150. # Set default OpenCL platform and/or device. Command line options will
  151. # override these. If neither is set, we will search for a GPU or fall-back
  152. # to platform 0, device 0.
  153. #Platform = 0
  154. #Device = 0
  155. # Some formats vectorize their kernels in case the device says it's a good
  156. # idea. Some devices give "improper" hints which means we vectorize but get
  157. # a performance drop. If you have such a device, uncommenting the below
  158. # will disable vectorizing globally.
  159. # With this set to N (or commented out) you can force it per session with
  160. # the --force-scalar command-line option instead.
  161. #ForceScalar = Y
  162. # Format-specific settings for Local Work Size and Global Work Size call.
  163. # An LWS or GWS of zero will initiate auto enumeration. The environment
  164. # variables LWS and/or GWS will override these figures.
  165. #ssha_LWS = 512
  166. #ssha_GWS = 8192
  167. # For RAR format.
  168. #rar_LWS = 128
  169. #rar_GWS = 8192
  170. # For SHA-2.
  171. #sha512crypt_LWS = 64
  172. #sha512crypt_GWS = 8192
  173. #sha256crypt_LWS = xxx
  174. #sha256crypt_GWS = xxx
  175. #rawsha256_LWS = xxx
  176. #rawsha256_GWS = xxx
  177. #rawsha512_LWS = xxx
  178. #rawsha512_GWS = xxx
  179. #xsha512_LWS = xxx
  180. #xsha512_GWS = xxx
  181. # For office formats.
  182. #office2007_LWS = 64
  183. #office2007_GWS = 8192
  184. #office2010_LWS = 64
  185. #office2010_GWS = 8192
  186. #office2013_LWS = 64
  187. #office2013_GWS = 8192
  188. # For NTLMv2 format
  189. #ntlmv2_LWS = 1024
  190. #ntlmv2_GWS = 32768
  191. # WPA-PSK
  192. #wpapsk_LWS = xxx
  193. #wpapsk_GWS = xxx
  194. # For raw
  195. #rawmd4_LWS = xxx
  196. #rawmd4_GWS = xxx
  197. # Markov modes, see ../doc/MARKOV for more information
  198. [Markov:Default]
  199. # Default Markov mode settings
  200. #
  201. # Statsfile cannot be specified on the command line, so
  202. # specifying it here is mandatory
  203. Statsfile = $JOHN/stats
  204. # MkvLvl and MkvMaxLen should also be specified here, as a fallback for
  205. # --markov usage without specifying LEVEL and/or LENGTH on the command line
  206. MkvLvl = 200
  207. MkvMaxLen = 12
  208. # MkvMinLvl and MkvMinLen should not be specified at all in [Markov:Default],
  209. # or they should be equal to 0 (which is the default if not specified.
  210. # MkvMinLvl and MkvMinLen can be used in other Markov mode sections
  211. # except [Markov:Default]
  212. ; MkvMinLvl = 0
  213. ; MkvMinLen = 0
  214. # A user defined character class is named with a single digit, ie. 0..9. After
  215. # the equal-sign, just list all characters that this class should match. You
  216. # can specify ranges within brackets, much like pre-processor ranges in rules.
  217. # BEWARE of encoding if using non-ASCII characters. If you put UTF-8 characters
  218. # here, it will *not* work! You must use a singlebyte encoding and it should
  219. # be the same here as you intend to use for your dictionary.
  220. # You can however put characters here in \xA3 format (for codepoint 0xA3 - in
  221. # many iso-8859 codepages that would mean a pound sign). This works in ranges
  222. # too. Using \x00 is not supported though - it will not be parsed as null.
  223. #
  224. # This is a couple of example classes:
  225. # ?0 matches (one version of) base64 characters
  226. # ?1 matches hex digits
  227. # ?2 matches the TAB character (never try to use \x00!)
  228. [UserClasses]
  229. 0 = [a-zA-Z0-9/.]
  230. 1 = [0-9a-fA-F]
  231. 2 = \x09
  232. # these are user defined character sets. There purpose is to allow custom salt
  233. # values to be used within the salt_regen logic. These will be the characters
  234. # to use for this character within the salt. So if we had a salt that was 4
  235. # characters, and 0-9a-m, we can easily do this by 0 = [0-9a-m] If this is used,
  236. # the regen salt value would be ?0?0?0?0 and salts such as a47m 2kd5 would be valid.
  237. [Regen_Salts_UserClasses]
  238. 1 = [1-9]
  239. # A "no rules" rule for super fast Single mode (use with --single=none)
  240. [List.Rules:None]
  241. :
  242. # A "drop all" rule for even faster Single mode (debugging :)
  243. [List.Rules:Drop]
  244. <1'0
  245. # "Single crack" mode rules
  246. [List.Rules:Single]
  247. # Simple rules come first...
  248. :
  249. -s x**
  250. -c (?a c Q
  251. -c l Q
  252. -s-c x** /?u l
  253. # These were not included in crackers I've seen, but are pretty efficient,
  254. # so I include them near the beginning
  255. >6 '6
  256. >7 '7 l
  257. -c >6 '6 /?u l
  258. >5 '5
  259. # Weird order, eh? Can't do anything about it, the order is based on the
  260. # number of successful cracks...
  261. <* d
  262. r c
  263. -c <* (?a d c
  264. -c >5 '5 /?u l
  265. -c u Q
  266. -c )?a r l
  267. -[:c] <* !?A \p1[lc] p
  268. -c <* c Q d
  269. -c >7 '7 /?u
  270. >4 '4 l
  271. -c <+ (?l c r
  272. -c <+ )?l l Tm
  273. >3 '3
  274. -c >4 '4 /?u
  275. -c >3 '3 /?u l
  276. -c u Q r
  277. <* d M 'l f Q
  278. -c <* l Q d M 'l f Q
  279. # About 50% of single-mode-crackable passwords get cracked by now...
  280. # >2 x12 ... >8 x18
  281. >[2-8] x1\1
  282. >9 \[
  283. # >3 x22 ... >9 x28
  284. >[3-9] x2\p[2-8]
  285. # >4 x32 ... >9 x37
  286. >[4-9] x3\p[2-7]
  287. # >2 x12 /?u l ... >8 x18 /?u l
  288. -c >[2-8] x1\1 /?u l
  289. -c >9 \[ /?u l
  290. # >3 x22 /?u l ... >9 x28 /?u l
  291. -c >[3-9] x2\p[2-8] /?u l
  292. # >4 x32 /?u l ... >9 x37 /?u l
  293. -c >[4-9] x3\p[2-7] /?u l
  294. # Now to the suffix stuff...
  295. <* l $[1-9!0a-rt-z"-/:-@\[-`{-~]
  296. -c <* (?a c $[1-9!0a-rt-z"-/:-@\[-`{-~]
  297. -[:c] <* !?A (?\p1[za] \p1[lc] $s M 'l p Q X0z0 'l $s
  298. -[:c] <* /?A (?\p1[za] \p1[lc] $s
  299. <* l r $[1-9!]
  300. -c <* /?a u $[1-9!]
  301. -[:c] <- (?\p1[za] \p1[lc] Az"'s"
  302. -[:c] <- (?\p1[za] \p1[lc] Az"!!"
  303. -[:c] (?\p1[za] \p1[lc] $! <- Az"!!"
  304. # Removing vowels...
  305. -[:c] /?v @?v >2 (?\p1[za] \p1[lc]
  306. /?v @?v >2 <* d
  307. # crack -> cracked, crack -> cracking
  308. <* l [PI]
  309. -c <* l [PI] (?a c
  310. # mary -> marie
  311. -[:c] <* (?\p1[za] \p1[lc] )y omi $e
  312. # marie -> mary
  313. -[:c] <* (?\p1[za] \p1[lc] )e \] )i val1 oay
  314. # The following are some 3l33t rules
  315. -[:c] l /[aelos] s\0\p[4310$] (?\p1[za] \p1[:c]
  316. -[:c] l /a /[elos] sa4 s\0\p[310$] (?\p1[za] \p1[:c]
  317. -[:c] l /e /[los] se3 s\0\p[10$] (?\p1[za] \p1[:c]
  318. -[:c] l /l /[os] sl1 s\0\p[0$] (?\p1[za] \p1[:c]
  319. -[:c] l /o /s so0 ss$ (?\p1[za] \p1[:c]
  320. -[:c] l /a /e /[los] sa4 se3 s\0\p[10$] (?\p1[za] \p1[:c]
  321. -[:c] l /a /l /[os] sa4 sl1 s\0\p[0$] (?\p1[za] \p1[:c]
  322. -[:c] l /a /o /s sa4 so0 ss$ (?\p1[za] \p1[:c]
  323. -[:c] l /e /l /[os] se3 sl1 s\0\p[0$] (?\p1[za] \p1[:c]
  324. -[:c] l /[el] /o /s s\0\p[31] so0 ss$ (?\p1[za] \p1[:c]
  325. -[:c] l /a /e /l /[os] sa4 se3 sl1 s\0\p[0$] (?\p1[za] \p1[:c]
  326. -[:c] l /a /[el] /o /s sa4 s\0\p[31] so0 ss$ (?\p1[za] \p1[:c]
  327. -[:c] l /e /l /o /s se3 sl1 so0 ss$ (?\p1[za] \p1[:c]
  328. -[:c] l /a /e /l /o /s sa4 se3 sl1 so0 ss$ (?\p1[za] \p1[:c]
  329. # Now to the prefix stuff...
  330. l ^[1a-z2-90]
  331. -c l Q ^[A-Z]
  332. ^[A-Z]
  333. l ^["-/:-@\[-`{-~]
  334. -[:c] <9 (?a \p1[lc] A0"[tT]he"
  335. -[:c] <9 (?a \p1[lc] A0"[aA]my"
  336. -[:c] <9 (?a \p1[lc] A0"[mdMD]r"
  337. -[:c] <9 (?a \p1[lc] A0"[mdMD]r."
  338. -[:c] <9 (?a \p1[lc] A0"__"
  339. <- !?A l p ^[240-9]
  340. # Some word pair rules...
  341. # johnsmith -> JohnSmith, johnSmith
  342. -p-c (?a 2 (?a c 1 [cl]
  343. # JohnSmith -> john smith, john_smith, john-smith
  344. -p 1 <- $[ _\-] + l
  345. # JohnSmith -> John smith, John_smith, John-smith
  346. -p-c 1 <- (?a c $[ _\-] 2 l
  347. # JohnSmith -> john Smith, john_Smith, john-Smith
  348. -p-c 1 <- l $[ _\-] 2 (?a c
  349. # johnsmith -> John Smith, John_Smith, John-Smith
  350. -p-c 1 <- (?a c $[ _\-] 2 (?a c
  351. # Applying different simple rules to each of the two words
  352. -p-[c:] 1 \p1[ur] 2 l
  353. -p-c 2 (?a c 1 [ur]
  354. -p-[c:] 1 l 2 \p1[ur]
  355. -p-c 1 (?a c 2 [ur]
  356. # jsmith -> smithj, etc...
  357. -[:c] (?a \p1[lc] [{}]
  358. -[:c] (?a \p1[lc] [{}] \0
  359. # Toggle case...
  360. -c <+ )?u l Tm
  361. -c T0 Q M c Q l Q u Q C Q X0z0 'l
  362. -c T[1-9A-E] Q M l Tm Q C Q u Q l Q c Q X0z0 'l
  363. -c l Q T[1-9A-E] Q M T\0 Q l Tm Q C Q u Q X0z0 'l
  364. -c >2 <G %2?a [lu] T0 M T2 T4 T6 T8 TA TC TE Q M l Tm Q X0z0 'l
  365. -c >2 /?l /?u t Q M c Q C Q l Tm Q X0z0 'l
  366. # Deleting chars...
  367. >[2-8] D\p[1-7]
  368. >[8-9A-E] D\1
  369. -c /?u >[2-8] D\p[1-7] l
  370. -c /?u >[8-9A-E] D\1 l
  371. =1?a \[ M c Q
  372. -c (?a >[1-9A-E] D\1 c
  373. # Inserting a dot...
  374. -[:c] >3 (?a \p1[lc] i[12].
  375. # More suffix stuff...
  376. <- l Az"[190][0-9]"
  377. -c <- (?a c Az"[190][0-9]"
  378. <- l Az"[782][0-9]"
  379. -c <- (?a c Az"[782][0-9]"
  380. <* l $[A-Z]
  381. -c <* (?a c $[A-Z]
  382. # cracking -> CRACKiNG
  383. -c u /I sIi
  384. # Crack96 -> cRACK96
  385. %2?a C Q
  386. # Crack96 -> cRACK(^
  387. /?A S Q
  388. # Crack96 -> CRaCK96
  389. -c /?v V Q
  390. # Really weird charset conversions, like "england" -> "rmh;smf"
  391. :[RL] Q
  392. l Q [RL]
  393. -c (?a c Q [RL]
  394. :[RL] \0 Q
  395. # Both prefixing and suffixing...
  396. <- l ^[1!@#$%^&*\-=_+.?|:'"] $\1
  397. <- l ^[({[<] $\p[)}\]>]
  398. # The rest of two-digit suffix stuff, less common numbers...
  399. <- l Az"[63-5][0-9]"
  400. -c <- (?a c Az"[63-5][0-9]"
  401. # Some multi-digit numbers...
  402. -[:c] (?a \p1[lc] Az"007" <+
  403. -[:c] (?a \p1[lc] Az"123" <+
  404. -[:c] (?a \p1[lc] Az"[0-9]\0\0" <+
  405. -[:c] (?a \p1[lc] Az"1234" <+
  406. -[:c] (?a \p1[lc] Az"[0-9]\0\0\0" <+
  407. -[:c] (?a \p1[lc] Az"12345" <+
  408. -[:c] (?a \p1[lc] Az"[0-9]\0\0\0\0" <+
  409. -[:c] (?a \p1[lc] Az"123456" <+
  410. -[:c] (?a \p1[lc] Az"[0-9]\0\0\0\0\0" <+
  411. # Some [birth] years...
  412. l Az"19[7-96-0]" <+ >-
  413. l Az"20[01]" <+ >-
  414. l Az"19[7-9][0-9]" <+
  415. l Az"20[01][0-9]" <+
  416. l Az"19[6-0][9-0]" <+
  417. [List.Rules:Extra]
  418. # Insert/overstrike some characters...
  419. !?A >[1-6] l i\0[a-z]
  420. !?A l o0[a-z]
  421. !?A >[1-7] l o\0[a-z]
  422. # Toggle case everywhere (up to length 8), assuming that certain case
  423. # combinations were already tried.
  424. -c T1 Q M T0 Q
  425. -c T2 Q M T[z0] T[z1] Q
  426. -c T3 Q M T[z0] T[z1] T[z2] Q
  427. -c T4 Q M T[z0] T[z1] T[z2] T[z3] Q
  428. -c T5 Q M T[z0] T[z1] T[z2] T[z3] T[z4] Q
  429. -c T6 Q M T[z0] T[z1] T[z2] T[z3] T[z4] T[z5] Q
  430. -c T7 Q M T[z0] T[z1] T[z2] T[z3] T[z4] T[z5] T[z6] Q
  431. # Very slow stuff...
  432. l Az"[1-90][0-9][0-9]" <+
  433. -c (?a c Az"[1-90][0-9][0-9]" <+
  434. <[\-9] l A\p[z0]"[a-z][a-z]"
  435. <- l ^[a-z] $[a-z]
  436. # Wordlist mode rules
  437. [List.Rules:Wordlist]
  438. # Try words as they are
  439. :
  440. # Lowercase every pure alphanumeric word
  441. -c >3 !?X l Q
  442. # Capitalize every pure alphanumeric word
  443. -c (?a >2 !?X c Q
  444. # Lowercase and pluralize pure alphabetic words
  445. <* >2 !?A l p
  446. # Lowercase pure alphabetic words and append '1'
  447. <* >2 !?A l $1
  448. # Capitalize pure alphabetic words and append '1'
  449. -c <* >2 !?A c $1
  450. # Duplicate reasonably short pure alphabetic words (fred -> fredfred)
  451. <7 >1 !?A l d
  452. # Lowercase and reverse pure alphabetic words
  453. >3 !?A l M r Q
  454. # Prefix pure alphabetic words with '1'
  455. >2 !?A l ^1
  456. # Uppercase pure alphanumeric words
  457. -c >2 !?X u Q M c Q u
  458. # Lowercase pure alphabetic words and append a digit or simple punctuation
  459. <* >2 !?A l $[2!37954860.?]
  460. # Words containing punctuation, which is then squeezed out, lowercase
  461. /?p @?p >3 l
  462. # Words with vowels removed, lowercase
  463. /?v @?v >3 l
  464. # Words containing whitespace, which is then squeezed out, lowercase
  465. /?w @?w >3 l
  466. # Capitalize and duplicate short pure alphabetic words (fred -> FredFred)
  467. -c <7 >1 !?A c d
  468. # Capitalize and reverse pure alphabetic words (fred -> derF)
  469. -c <+ >2 !?A c r
  470. # Reverse and capitalize pure alphabetic words (fred -> Derf)
  471. -c >2 !?A l M r Q c
  472. # Lowercase and reflect pure alphabetic words (fred -> fredderf)
  473. <7 >1 !?A l d M 'l f Q
  474. # Uppercase the last letter of pure alphabetic words (fred -> freD)
  475. -c <+ >2 !?A l M r Q c r
  476. # Prefix pure alphabetic words with '2' or '4'
  477. >2 !?A l ^[24]
  478. # Capitalize pure alphabetic words and append a digit or simple punctuation
  479. -c <* >2 !?A c $[2!3957468.?0]
  480. # Prefix pure alphabetic words with digits
  481. >2 !?A l ^[379568]
  482. # Capitalize and pluralize pure alphabetic words of reasonable length
  483. -c <* >2 !?A c p
  484. # Lowercase/capitalize pure alphabetic words of reasonable length and convert:
  485. # crack -> cracked, crack -> cracking
  486. -[:c] <* >2 !?A \p1[lc] M [PI] Q
  487. # Try the second half of split passwords
  488. -s x**
  489. -s-c x** M l Q
  490. # Case toggler for cracking MD4-based NTLM hashes (with the contributed patch)
  491. # given already cracked DES-based LM hashes.
  492. # Use --rules=NT to use this
  493. [List.Rules:NT]
  494. :
  495. -c T0Q
  496. -c T1QT[z0]
  497. -c T2QT[z0]T[z1]
  498. -c T3QT[z0]T[z1]T[z2]
  499. -c T4QT[z0]T[z1]T[z2]T[z3]
  500. -c T5QT[z0]T[z1]T[z2]T[z3]T[z4]
  501. -c T6QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]
  502. -c T7QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]
  503. -c T8QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]
  504. -c T9QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]
  505. -c TAQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]
  506. -c TBQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]T[zA]
  507. -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]
  508. -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]
  509. # Some Office <=2003 files have passwords truncated at 15
  510. [List.Rules:OldOffice]
  511. :
  512. ->F>F'F
  513. # Rules from Hash Runner 2014
  514. [List.Rules:o1]
  515. o[0-9A-Z][ -~]
  516. [List.Rules:o2]
  517. o[0-9A-E][ -~] Q M o[0-9A-E][ -~] Q
  518. [List.Rules:o3]
  519. o[0-9][ -~] Q M o[0-9][ -~] Q M o[0-9][ -~] Q
  520. [List.Rules:o]
  521. o[0-9A-Z][ -~]
  522. o[0-9A-E][ -~] Q M o[0-9A-E][ -~] Q
  523. [List.Rules:i1]
  524. i[0-9A-Z][ -~]
  525. [List.Rules:i2]
  526. i[0-9A-E][ -~] i[0-9A-E][ -~]
  527. [List.Rules:i3]
  528. i[0-9][ -~] i[0-9][ -~] i[0-9][ -~]
  529. [List.Rules:i]
  530. i[0-9A-Z][ -~]
  531. i[0-9A-E][ -~] i[0-9A-E][ -~]
  532. [List.Rules:oi]
  533. o[0-9A-Z][ -~]
  534. i[0-9A-Z][ -~]
  535. o[0-9A-E][ -~] Q M o[0-9A-E][ -~] Q
  536. i[0-9A-E][ -~] i[0-9A-E][ -~]
  537. # Default Loopback mode rules.
  538. [List.Rules:Loopback]
  539. .include [List.Rules:NT]
  540. .include [List.Rules:Wordlist]
  541. # For Single Mode against fast hashes
  542. [List.Rules:Single-Extra]
  543. .include [List.Rules:Single]
  544. .include [List.Rules:Extra]
  545. .include [List.Rules:OldOffice]
  546. # For Wordlist mode and very fast hashes
  547. [List.Rules:Jumbo]
  548. .include [List.Rules:Wordlist]
  549. .include [List.Rules:OldOffice]
  550. .include [List.Rules:Single]
  551. .include [List.Rules:Extra]
  552. .include [List.Rules:NT]
  553. # KoreLogic rules
  554. .include "$JOHN/korelogic.conf"
  555. # Everything, including all KoreLogic rules. Only for very fast hashes
  556. # and/or Single mode.
  557. [List.Rules:All]
  558. .include [List.Rules:Jumbo]
  559. .include [List.Rules:KoreLogic]
  560. # Incremental modes
  561. # This is for one-off uses (make your own custom.chr)
  562. [Incremental:Custom]
  563. File = $JOHN/custom.chr
  564. MinLen = 0
  565. # The theoretical CharCount is 211, we've got 196.
  566. [Incremental:UTF8]
  567. File = $JOHN/utf8.chr
  568. MinLen = 0
  569. CharCount = 196
  570. # This is CP1252, a super-set of ISO-8859-1.
  571. # The theoretical CharCount is 219, we've got 203.
  572. [Incremental:Latin1]
  573. File = $JOHN/latin1.chr
  574. MinLen = 0
  575. CharCount = 203
  576. [Incremental:ASCII]
  577. File = $JOHN/ascii.chr
  578. MinLen = 0
  579. MaxLen = 13
  580. CharCount = 95
  581. [Incremental:LM_ASCII]
  582. File = $JOHN/lm_ascii.chr
  583. MinLen = 0
  584. MaxLen = 7
  585. CharCount = 69
  586. # This is CP858 (CP850 + Euro sign, superset of CP437).
  587. # The theoretical CharCount is 209 minus lowercase, we've got 132.
  588. [Incremental:LanMan]
  589. File = $JOHN/lanman.chr
  590. MinLen = 0
  591. MaxLen = 7
  592. CharCount = 132
  593. # This is alnum (upper & lower case) as well as space.
  594. [Incremental:Alnumspace]
  595. File = $JOHN/alnumspace.chr
  596. MinLen = 1
  597. MaxLen = 13
  598. CharCount = 63
  599. [Incremental:Alnum]
  600. File = $JOHN/alnum.chr
  601. MinLen = 1
  602. MaxLen = 13
  603. CharCount = 62
  604. [Incremental:Alpha]
  605. File = $JOHN/alpha.chr
  606. MinLen = 1
  607. MaxLen = 13
  608. CharCount = 52
  609. [Incremental:LowerNum]
  610. File = $JOHN/lowernum.chr
  611. MinLen = 1
  612. MaxLen = 13
  613. CharCount = 36
  614. [Incremental:UpperNum]
  615. File = $JOHN/uppernum.chr
  616. MinLen = 1
  617. MaxLen = 13
  618. CharCount = 36
  619. [Incremental:LowerSpace]
  620. File = $JOHN/lowerspace.chr
  621. MinLen = 1
  622. MaxLen = 13
  623. CharCount = 27
  624. [Incremental:Lower]
  625. File = $JOHN/lower.chr
  626. MinLen = 1
  627. MaxLen = 13
  628. CharCount = 26
  629. [Incremental:Upper]
  630. File = $JOHN/upper.chr
  631. MinLen = 1
  632. MaxLen = 13
  633. CharCount = 26
  634. [Incremental:Digits]
  635. File = $JOHN/digits.chr
  636. MinLen = 1
  637. MaxLen = 20
  638. CharCount = 10
  639. # Some pre-defined word filters as used to generate the supplied .chr files
  640. [List.External:Filter_ASCII]
  641. void filter()
  642. {
  643. int i, c;
  644. i = 0;
  645. while (c = word[i++])
  646. if (c < 0x20 || c > 0x7e || i > 13) {
  647. word = 0; return;
  648. }
  649. }
  650. [List.External:Filter_LanMan]
  651. void filter()
  652. {
  653. int i, c;
  654. i = 0;
  655. while (c = word[i]) {
  656. if (i >= 14) { // of up to 14 characters long
  657. word = 0; return;
  658. }
  659. if (c >= 'a' && c <= 'z') // Convert to uppercase
  660. word[i] &= 0xDF;
  661. i++;
  662. }
  663. word[7] = 0; // Truncate at 7 characters
  664. }
  665. [List.External:Filter_LM_ASCII]
  666. void filter()
  667. {
  668. int i, c;
  669. i = 0;
  670. while (c = word[i]) {
  671. if (c < 0x20 || c > 0x7e || // Require ASCII-only
  672. i >= 14) { // of up to 14 characters long
  673. word = 0; return;
  674. }
  675. if (c >= 'a' && c <= 'z') // Convert to uppercase
  676. word[i] &= 0xDF;
  677. i++;
  678. }
  679. word[7] = 0; // Truncate at 7 characters
  680. }
  681. [List.External:Filter_Alnumspace]
  682. void filter()
  683. {
  684. int i, c;
  685. i = 0;
  686. while (c = word[i++])
  687. if (c != ' ' && (((c < '0' || c > '9') &&
  688. ((c &= 0xDF) < 'A' || c > 'Z'))) || i > 13) {
  689. word = 0; return;
  690. }
  691. }
  692. [List.External:Filter_Alnum]
  693. void filter()
  694. {
  695. int i, c;
  696. i = 0;
  697. while (c = word[i++])
  698. if (((c < '0' || c > '9') && ((c &= 0xDF) < 'A' || c > 'Z')) ||
  699. i > 13) {
  700. word = 0; return;
  701. }
  702. }
  703. [List.External:Filter_Alpha]
  704. void filter()
  705. {
  706. int i, c;
  707. i = 0;
  708. while (c = word[i++])
  709. if ((c &= 0xDF) < 'A' || c > 'Z' || i > 13) {
  710. word = 0; return;
  711. }
  712. }
  713. [List.External:Filter_LowerNum]
  714. void filter()
  715. {
  716. int i, c;
  717. i = 0;
  718. while (c = word[i++])
  719. if (((c < 'a' || c > 'z') && (c < '0' || c > '9')) || i > 13) {
  720. word = 0; return;
  721. }
  722. }
  723. [List.External:Filter_UpperNum]
  724. void filter()
  725. {
  726. int i, c;
  727. i = 0;
  728. while (c = word[i++])
  729. if (((c < 'A' || c > 'Z') && (c < '0' || c > '9')) || i > 13) {
  730. word = 0; return;
  731. }
  732. }
  733. [List.External:Filter_LowerSpace]
  734. void filter()
  735. {
  736. int i, c;
  737. i = 0;
  738. while (c = word[i++])
  739. if (((c < 'a' || c > 'z') && c != ' ') || i > 13) {
  740. word = 0; return;
  741. }
  742. }
  743. [List.External:Filter_Lower]
  744. void filter()
  745. {
  746. int i, c;
  747. i = 0;
  748. while (c = word[i++])
  749. if (c < 'a' || c > 'z' || i > 13) {
  750. word = 0; return;
  751. }
  752. }
  753. [List.External:Filter_Upper]
  754. void filter()
  755. {
  756. int i, c;
  757. i = 0;
  758. while (c = word[i++])
  759. if (c < 'A' || c > 'Z' || i > 13) {
  760. word = 0; return;
  761. }
  762. }
  763. [List.External:Filter_Digits]
  764. void filter()
  765. {
  766. int i, c;
  767. i = 0;
  768. while (c = word[i++])
  769. if (c < '0' || c > '9' || i > 20) {
  770. word = 0; return;
  771. }
  772. }
  773. [List.External:Filter_No_Cap_or_Symbols]
  774. void filter()
  775. {
  776. int i, c;
  777. i = 0;
  778. while (c = word[i++])
  779. if ((c < 'a' || c > 'z') && (c < '0' || c > '9')) {
  780. return;
  781. }
  782. word = 0; return;
  783. }
  784. # Reject words that are illegal UTF-8
  785. # We obviously let pure ASCII through too
  786. [List.External:Filter_UTF8]
  787. void filter()
  788. {
  789. int s, a, p;
  790. p = 0;
  791. while (s = word[p++] & 0xff) {
  792. if (s > 0x7f) {
  793. if (s < 0xc2 || s > 0xf7) { // illegal single-byte
  794. word = 0; return;
  795. }
  796. // two-byte c2..df
  797. a = word[p++] & 0xff;
  798. if (a < 0x80 || a > 0xbf) {
  799. word = 0; return;
  800. }
  801. if (s > 0xdf) { // three-byte e0..ef
  802. if (s == 0xe0 && a < 0xa0) {
  803. word = 0; return;
  804. }
  805. if (s == 0xed && a > 0x9f) {
  806. word = 0; return;
  807. }
  808. if (s == 0xf0 && a < 0x90) {
  809. word = 0; return;
  810. }
  811. if (s == 0xf4 && a > 0x8f) {
  812. word = 0; return;
  813. }
  814. a = word[p++] & 0xff;
  815. if (a < 0x80 || a > 0xbf) {
  816. word = 0; return;
  817. }
  818. if (s > 0xef) { // four-byte f0..f7
  819. a = word[p++] & 0xff;
  820. if (a < 0x80 || a > 0xbf) {
  821. word = 0; return;
  822. }
  823. }
  824. }
  825. }
  826. }
  827. }
  828. # Reject words that are LEGAL UTF-8 (also rejects pure ASCII)
  829. [List.External:Filter_non-UTF8]
  830. void filter()
  831. {
  832. int s, a, p;
  833. p = 0;
  834. while (s = word[p++] & 0xff) {
  835. if (s > 0x7f) {
  836. if (s < 0xc2 || s > 0xf7) { // illegal single-byte
  837. return;
  838. }
  839. // two-byte c2..df
  840. a = word[p++] & 0xff;
  841. if (a < 0x80 || a > 0xbf) {
  842. return;
  843. }
  844. if (s > 0xdf) { // three-byte e0..ef
  845. if (s == 0xe0 && a < 0xa0) {
  846. return;
  847. }
  848. if (s == 0xed && a > 0x9f) {
  849. return;
  850. }
  851. if (s == 0xf0 && a < 0x90) {
  852. return;
  853. }
  854. if (s == 0xf4 && a > 0x8f) {
  855. return;
  856. }
  857. a = word[p++] & 0xff;
  858. if (a < 0x80 || a > 0xbf) {
  859. return;
  860. }
  861. if (s > 0xef) { // four-byte f0..f7
  862. a = word[p++] & 0xff;
  863. if (a < 0x80 || a > 0xbf) {
  864. return;
  865. }
  866. }
  867. }
  868. }
  869. }
  870. word = 0;
  871. }
  872. # A simple cracker for LM hashes
  873. [List.External:LanMan]
  874. int length; // Current length
  875. int maxlength;
  876. void init()
  877. {
  878. if (req_minlen)
  879. length = req_minlen;
  880. else
  881. length = 1;
  882. if (req_maxlen)
  883. maxlength = req_maxlen;
  884. else // the format's limit
  885. maxlength = cipher_limit;
  886. word[0] = 'A' - 1; // Start with "A"
  887. word[length] = 0;
  888. }
  889. void generate()
  890. {
  891. int i;
  892. i = length - 1; // Start from the last character
  893. while (++word[i] > 'Z') // Try to increase it
  894. if (i) // Overflow here, any more positions?
  895. word[i--] = 'A'; // Yes, move to the left, and repeat
  896. else // No
  897. if (length < maxlength) {
  898. word[i = ++length] = 0; // Switch to the next length
  899. while (i--)
  900. word[i] = 'A';
  901. return;
  902. } else {
  903. word = 0; return; // We're done
  904. }
  905. }
  906. void restore()
  907. {
  908. length = 0; // Calculate the length
  909. while (word[length]) length++;
  910. }
  911. # Simple and well-commented, yet useful external mode example
  912. # NOTE, this has now been 'split' up into a base extern, 'base', and then
  913. # multiple External:double functions. It still has same code as original
  914. # double, but now can be easily expanded.
  915. [List.External_base:Double]
  916. /*
  917. * This cracking mode tries all the possible duplicated lowercase alphabetic
  918. * "words" of up to 8 characters long. Since word halves are the same, it
  919. * only has to try about 500,000 words.
  920. */
  921. /* Global variables: current length and word */
  922. /* make this 'long' enough for other externs that include this one */
  923. /* (up to 125 bytes long) */
  924. int length, current[126], max;
  925. /* this new 'type' variable, is used to tell double what character set to
  926. * use. It can use the original (alpha). If type is 0 (i.e. unset), then
  927. * a-z (alpha) character set is used. If type is '0' (a zero ascii byte)
  928. * then alnum charset is used, a-z0-9. If type is a space char, then all
  929. * charset is used [space - tilde] or [ -~]. This required setting the
  930. * type var in the init() of alnum or all doubles (it can be left unset
  931. * in the alpha versions). It also requires some if logic in generate.
  932. * other than that, it works the same, with almost no performance hit */
  933. int type;
  934. /* Generates a new word */
  935. void generate()
  936. {
  937. int i;
  938. /* Export last generated word, duplicating it at the same time; here "word"
  939. * is a pre-defined external variable. */
  940. word[(i = length) << 1] = 0;
  941. while (i--) word[length + i] = word[i] = current[i];
  942. /* Generate a new word */
  943. i = length - 1; // Start from the last character
  944. if (type == 0) {
  945. /* alpha */
  946. while (++current[i] > 'z') // Try to increase it
  947. if (i) // Overflow here, any more positions?
  948. current[i--] = 'a'; // Yes, move to the left, and repeat
  949. else { // No
  950. current = 0; // Request a length switch
  951. break; // Break out of the loop
  952. }
  953. } else if (type == '0') {
  954. /* alnum */
  955. if (current[i] == 'z') current[i] = '0'-1;
  956. while (++current[i] == '9') { // Try to increase it
  957. if (i) // Overflow here, any more positions?
  958. current[i--] = 'a'; // Yes, move to the left, and repeat
  959. else { // No
  960. current = 0; // Request a length switch
  961. break; // Break out of the loop
  962. }
  963. if (current[i] == 'z') current[i] = '0'-1;
  964. }
  965. } else if (type == ' ') {
  966. /* all */
  967. while (++current[i] > '~') { // Try to increase it
  968. if (i) // Overflow here, any more positions?
  969. current[i--] = ' '; // Yes, move to the left, and repeat
  970. else { // No
  971. current = 0; // Request a length switch
  972. break; // Break out of the loop
  973. }
  974. }
  975. }
  976. /* else ????? wtf?? */
  977. /* Switch to the next length, unless we were generating 8 character long
  978. * words already. */
  979. if (!current && length < max) {
  980. i = ++length;
  981. if (type == 0 || type == '0')
  982. while (i--) current[i] = 'a';
  983. else if (type == ' ')
  984. while (i--) current[i] = ' ';
  985. }
  986. }
  987. /* Called when restoring an interrupted session */
  988. void restore()
  989. {
  990. int i;
  991. /* Import the word back */
  992. i = 0;
  993. while (current[i] = word[i]) i++;
  994. /* ...and calculate the half-word length */
  995. length = i >> 1;
  996. }
  997. [List.External:Double]
  998. .include [List.External_base:Double]
  999. /* Called at startup to initialize the global variables */
  1000. void init()
  1001. {
  1002. int i;
  1003. if (req_minlen)
  1004. i = length = (req_minlen + 1) / 2;
  1005. else
  1006. i = length = 2; // Start with 4 character long words
  1007. while (i--) current[i] = 'a'; // Set our half-word to "aa"
  1008. if (req_maxlen)
  1009. max = (req_maxlen + 1) / 2;
  1010. else if (length > 4)
  1011. max = length;
  1012. else
  1013. max = 4;
  1014. }
  1015. [List.External:Double_alnum]
  1016. .include [List.External_base:Double]
  1017. /* Called at startup to initialize the global variables */
  1018. void init()
  1019. {
  1020. int i;
  1021. if (req_minlen)
  1022. i = length = (req_minlen + 1) / 2;
  1023. else
  1024. i = length = 2; // Start with 4 character long words
  1025. while (i--) current[i] = 'a'; // Set our half-word to "aa"
  1026. if (req_maxlen)
  1027. max = (req_maxlen + 1) / 2;
  1028. else if (length > 4)
  1029. max = length;
  1030. else
  1031. max = 4;
  1032. type = '0';
  1033. }
  1034. [List.External:Double_all]
  1035. .include [List.External_base:Double]
  1036. void init()
  1037. {
  1038. int i;
  1039. if (req_minlen)
  1040. i = length = (req_minlen + 1) / 2;
  1041. else
  1042. i = length = 2; // Start with 4 character long words
  1043. while (i--) current[i] = ' '; // Set our half-word to " "
  1044. if (req_maxlen)
  1045. max = (req_maxlen + 1) / 2;
  1046. else if (length > 4)
  1047. max = length;
  1048. else
  1049. max = 4;
  1050. type = ' ';
  1051. }
  1052. # Strip 0.5 ("Secure Tool for Recalling Important Passwords") cracker,
  1053. # based on analysis done by Thomas Roessler and Ian Goldberg. This will
  1054. # crack passwords you may have generated with Strip; other uses of Strip
  1055. # are unaffected.
  1056. [List.External:Strip]
  1057. int minlength, maxlength, mintype, maxtype;
  1058. int crack_seed, length, type;
  1059. int count, charset[128];
  1060. void init()
  1061. {
  1062. int c;
  1063. /* Password lengths to try; Strip can generate passwords of 4 to 16
  1064. * characters, but traditional crypt(3) hashes are limited to 8. */
  1065. minlength = req_minlen;
  1066. if (minlength < 4)
  1067. minlength = 4;
  1068. if (req_maxlen)
  1069. maxlength = req_maxlen;
  1070. else // the format's limit
  1071. maxlength = cipher_limit;
  1072. if (maxlength >16) maxlength = 16;
  1073. /* Password types to try (Numeric, Alpha-Num, Alpha-Num w/ Meta). */
  1074. mintype = 0; // 0
  1075. maxtype = 2; // 2
  1076. crack_seed = 0x10000;
  1077. length = minlength - 1;
  1078. type = mintype;
  1079. count = 0;
  1080. c = '0'; while (c <= '9') charset[count++] = c++;
  1081. }
  1082. void generate()
  1083. {
  1084. int seed, random;
  1085. int i, c;
  1086. if (crack_seed > 0xffff) {
  1087. crack_seed = 0;
  1088. if (++length > maxlength) {
  1089. length = minlength;
  1090. if (++type > maxtype) {
  1091. word[0] = 0;
  1092. return;
  1093. }
  1094. }
  1095. count = 10;
  1096. if (type >= 1) {
  1097. c = 'a'; while (c <= 'f') charset[count++] = c++;
  1098. c = 'h'; while (c <= 'z') charset[count++] = c++;
  1099. c = 'A'; while (c <= 'Z') charset[count++] = c++;
  1100. }
  1101. if (type == 2) {
  1102. charset[count++] = '!';
  1103. c = '#'; while (c <= '&') charset[count++] = c++;
  1104. c = '('; while (c <= '/') charset[count++] = c++;
  1105. c = '<'; while (c <= '>') charset[count++] = c++;
  1106. charset[count++] = '?'; charset[count++] = '@';
  1107. charset[count++] = '['; charset[count++] = ']';
  1108. charset[count++] = '^'; charset[count++] = '_';
  1109. c = '{'; while (c <= '~') charset[count++] = c++;
  1110. }
  1111. }
  1112. seed = (crack_seed++ << 16 >> 16) * 22695477 + 1;
  1113. i = 0;
  1114. while (i < length) {
  1115. random = ((seed = seed * 22695477 + 1) >> 16) & 0x7fff;
  1116. word[i++] = charset[random % count];
  1117. }
  1118. word[i] = 0;
  1119. }
  1120. # A variation of KnownForce configured to try all the 385641000 possible
  1121. # auto-generated passwords of DokuWiki versions up to at least 2013-05-10.
  1122. [List.External:DokuWiki]
  1123. int last; // Last character position, zero-based
  1124. int lastofs; // Last character position offset into charset[]
  1125. int lastid; // Current character index in the last position
  1126. int id[0x7f]; // Current character indices for other positions
  1127. int charset[0x7f00]; // Character sets, 0x100 elements for each position
  1128. void init()
  1129. {
  1130. int A[26], C[26], V[26];
  1131. int length;
  1132. int pos, ofs, i, c;
  1133. i = 0; while (i < 26) { A[i] = C[i] = 1; V[i++] = 0; }
  1134. i = 'a' - 'a'; C[i] = 0; V[i] = 1;
  1135. i = 'e' - 'a'; C[i] = 0; V[i] = 1;
  1136. i = 'i' - 'a'; C[i] = 0; V[i] = 1;
  1137. i = 'o' - 'a'; C[i] = 0; V[i] = 1;
  1138. i = 'u' - 'a'; C[i] = 0; V[i] = 1;
  1139. i = 'q' - 'a'; A[i] = C[i] = 0;
  1140. i = 'x' - 'a'; A[i] = C[i] = 0;
  1141. i = 'y' - 'a'; A[i] = C[i] = 0;
  1142. length = 8;
  1143. /* This defines the character sets for different character positions */
  1144. pos = 0;
  1145. while (pos < 6) {
  1146. ofs = pos++ << 8;
  1147. i = 0;
  1148. c = 'a' - 1;
  1149. while (++c <= 'z')
  1150. if (C[c - 'a'])
  1151. charset[ofs + i++] = c;
  1152. charset[ofs + i] = 0;
  1153. ofs = pos++ << 8;
  1154. i = 0;
  1155. c = 'a' - 1;
  1156. while (++c <= 'z')
  1157. if (V[c - 'a'])
  1158. charset[ofs + i++] = c;
  1159. charset[ofs + i] = 0;
  1160. ofs = pos++ << 8;
  1161. i = 0;
  1162. c = 'a' - 1;
  1163. while (++c <= 'z')
  1164. if (A[c - 'a'])
  1165. charset[ofs + i++] = c;
  1166. charset[ofs + i] = 0;
  1167. }
  1168. c = '1';
  1169. while (pos < length) {
  1170. ofs = pos++ << 8;
  1171. i = 0;
  1172. while (c <= '9')
  1173. charset[ofs + i++] = c++;
  1174. charset[ofs + i] = 0;
  1175. c = '0';
  1176. }
  1177. last = length - 1;
  1178. pos = -1;
  1179. while (++pos <= last)
  1180. word[pos] = charset[id[pos] = pos << 8];
  1181. lastid = (lastofs = last << 8) - 1;
  1182. word[pos] = 0;
  1183. }
  1184. void generate()
  1185. {
  1186. int pos;
  1187. /* Handle the typical case specially */
  1188. if (word[last] = charset[++lastid]) return;
  1189. word[pos = last] = charset[lastid = lastofs];
  1190. while (pos--) { // Have a preceding position?
  1191. if (word[pos] = charset[++id[pos]]) return;
  1192. word[pos] = charset[id[pos] = pos << 8];
  1193. }
  1194. word = 0; // We're done
  1195. }
  1196. void restore()
  1197. {
  1198. int i, c;
  1199. /* Calculate the current length and infer the character indices */
  1200. last = 0;
  1201. while (c = word[last]) {
  1202. i = lastofs = last << 8;
  1203. while (charset[i] != c && charset[i]) i++;
  1204. if (!charset[i]) i = lastofs; // Not found
  1205. id[last++] = i;
  1206. }
  1207. lastid = id[--last];
  1208. }
  1209. /*
  1210. * This takes advantage of CVE-2013-2120 to find seeds that KDE Paste applet
  1211. * uses to generate passwords.
  1212. *
  1213. * This software is Copyright (c) Michael Samuel <mik@miknet.net>,
  1214. * and it is hereby released to the general public under the following terms:
  1215. * Redistribution and use in source and binary forms, with or without
  1216. * modification, are permitted.
  1217. */
  1218. [List.External:KDEPaste]
  1219. int charset[95];
  1220. int charset_length, password_length, endTime, startTime, msec;
  1221. void init()
  1222. {
  1223. password_length = 8; /* Change this to match config */
  1224. endTime = session_start_time;
  1225. startTime = 1343743200; /* Aug 1 2012 - Change this as necessary */
  1226. msec = 1; /* msec is never 0 - it would crash the applet */
  1227. charset_length = 0;
  1228. int c;
  1229. /* Comment out classes that you don't need, but keep the order the same */
  1230. /* Lowers */
  1231. c = 'a'; while (c <= 'z') charset[charset_length++] = c++;
  1232. /* Uppers */
  1233. c = 'A'; while (c <= 'Z') charset[charset_length++] = c++;
  1234. /* Numbers */
  1235. c = '0'; while (c <= '9') charset[charset_length++] = c++;
  1236. charset[charset_length++] = '0'; /* Yep, it's there twice */
  1237. /* Symbols */
  1238. c = '!'; while (c <= '/') charset[charset_length++] = c++;
  1239. c = ':'; while (c <= '@') charset[charset_length++] = c++;
  1240. c = '['; while (c <= '`') charset[charset_length++] = c++;
  1241. c = '{'; while (c <= '~') charset[charset_length++] = c++;
  1242. }
  1243. void generate()
  1244. {
  1245. int i, rand_seed, rand_result;
  1246. /* Terminate once we've generated for all *
  1247. * of the time range (Plus a bit more...) */
  1248. if (endTime + 1000 < startTime) {
  1249. word = 0;
  1250. return;
  1251. }
  1252. /* Skip msecs that would generate dupes */
  1253. while (endTime % msec != 0) {
  1254. if (++msec > 999) {
  1255. endTime--;
  1256. msec = 1;
  1257. }
  1258. }
  1259. rand_seed = endTime / msec;
  1260. i = 0;
  1261. while (i < password_length) {
  1262. /* this works like rand_r() from eglibc */
  1263. rand_seed = rand_seed * 1103515245 + 12345;
  1264. rand_result = (rand_seed >> 16) & 2047;
  1265. rand_seed = rand_seed * 1103515245 + 12345;
  1266. rand_result <<= 10;
  1267. rand_result ^= (rand_seed >> 16) & 1023;
  1268. rand_seed = rand_seed * 1103515245 + 12345;
  1269. rand_result <<= 10;
  1270. rand_result ^= (rand_seed >> 16) & 1023;
  1271. word[i++] = charset[rand_result % charset_length];
  1272. }
  1273. word[i] = 0;
  1274. if (++msec > 999) {
  1275. endTime--;
  1276. msec = 1;
  1277. }
  1278. }
  1279. void restore()
  1280. {
  1281. int i, rand_seed, rand_result;
  1282. i = 0;
  1283. /* Very crude restore, just dry-run until we hit last word */
  1284. while (i != password_length) {
  1285. while (endTime % msec != 0) {
  1286. if (++msec > 999) {
  1287. endTime--;
  1288. msec = 1;
  1289. }
  1290. }
  1291. rand_seed = endTime / msec;
  1292. i = 0;
  1293. while (i < password_length) {
  1294. /* this works like rand_r() from eglibc */
  1295. rand_seed = rand_seed * 1103515245 + 12345;
  1296. rand_result = (rand_seed >> 16) & 2047;
  1297. rand_seed = rand_seed * 1103515245 + 12345;
  1298. rand_result <<= 10;
  1299. rand_result ^= (rand_seed >> 16) & 1023;
  1300. rand_seed = rand_seed * 1103515245 + 12345;
  1301. rand_result <<= 10;
  1302. rand_result ^= (rand_seed >> 16) & 1023;
  1303. if (charset[rand_result % charset_length] != word[i++])
  1304. break;
  1305. }
  1306. if (++msec > 999) {
  1307. endTime--;
  1308. msec = 1;
  1309. }
  1310. }
  1311. }
  1312. /* Awesome Password Generator RNG replay
  1313. * Written by Michael Samuel <mik@miknet.net>
  1314. * Public Domain.
  1315. *
  1316. * This takes advantage of a subtle bug, where a crypto RNG is used to
  1317. * seed the C# System.Random() class, which takes a 32-bit input, but
  1318. * converts negative numbers into non-negative numbers, resulting in
  1319. * only 31 bits of security.
  1320. *
  1321. * This only implements "easy to type" being *unticked*, and numbers,
  1322. * lowers, uppers and symbols being ticked, in random password mode.
  1323. * Changing the password length is easy, anything else is left as an
  1324. * exercise to the reader.
  1325. *
  1326. * Running Awesome Password Generator (1.3.2 or lower) in Mono is still
  1327. * vulnerable, but uses a different RNG, so this mode isn't compatible.
  1328. */
  1329. /* Awesome Password Generator 1.3.2 does a two-pass run, selecting which
  1330. * charset each position will have, then picking the character. This
  1331. * leads to heavy bias, and is fixed in 1.4.0 (along with many other
  1332. * fixes). If you have been using Awesome Password Generator, you should
  1333. * upgrade immediately and change your passwords.
  1334. */
  1335. [List.External:AwesomePasswordGenerator]
  1336. int numbers[10];
  1337. int lowers[26];
  1338. int uppers[26];
  1339. int symbols[32];
  1340. /* Since we don't have a double datatype, I simply pre-calculated the
  1341. * transition numbers calculating the scale formula:
  1342. * (double)randNum * 4.656612873077393e-10 * {4/10/26/32}
  1343. */
  1344. int boundaries_charclass[4];
  1345. int boundaries_numbers[10];
  1346. int boundaries_letters[26];
  1347. int boundaries_symbols[32];
  1348. /* This is the bug we're exploiting - the seed for the RNG is 32 bits
  1349. * from the crypto rng. The non-crypto RNG converts negative numbers
  1350. * into non-negative numbers, so there's only 2^31 possible seeds.
  1351. */
  1352. int seed;
  1353. int password_length;
  1354. void init()
  1355. {
  1356. password_length = 16; /* Change this to match config */
  1357. int c, i;
  1358. c = '0'; i = 0; while (c <= '9') numbers[i++] = c++;
  1359. c = 'a'; i = 0; while (c <= 'z') lowers[i++] = c++;
  1360. c = 'A'; i = 0; while (c <= 'Z') uppers[i++] = c++;
  1361. /* Symbols */
  1362. i = 0;
  1363. symbols[i++] = '!'; symbols[i++] = '@'; symbols[i++] = '#'; symbols[i++] = '$';
  1364. symbols[i++] = '%'; symbols[i++] = '^'; symbols[i++] = '&'; symbols[i++] = '*';
  1365. symbols[i++] = '('; symbols[i++] = ')'; symbols[i++] = '~'; symbols[i++] = '-';
  1366. symbols[i++] = '_'; symbols[i++] = '='; symbols[i++] = '+'; symbols[i++] = '\\';
  1367. symbols[i++] = '|'; symbols[i++] = '/'; symbols[i++] = '['; symbols[i++] = ']';
  1368. symbols[i++] = '{'; symbols[i++] = '}'; symbols[i++] = ';'; symbols[i++] = ':';
  1369. symbols[i++] = '`'; symbols[i++] = '\''; symbols[i++] = '"'; symbols[i++] = ',';
  1370. symbols[i++] = '.'; symbols[i++] = '<'; symbols[i++] = '>'; symbols[i++] = '?';
  1371. i = 0;
  1372. boundaries_charclass[i++] = 536870912; boundaries_charclass[i++] = 1073741824;
  1373. boundaries_charclass[i++] = 1610612736; boundaries_charclass[i++] = 2147483647;
  1374. i = 0;
  1375. boundaries_numbers[i++] = 214748365; boundaries_numbers[i++] = 429496730;
  1376. boundaries_numbers[i++] = 644245095; boundaries_numbers[i++] = 858993460;
  1377. boundaries_numbers[i++] = 1073741824; boundaries_numbers[i++] = 1288490189;
  1378. boundaries_numbers[i++] = 1503238554; boundaries_numbers[i++] = 1717986919;
  1379. boundaries_numbers[i++] = 1932735284; boundaries_numbers[i++] = 2147483647;
  1380. i = 0;
  1381. boundaries_letters[i++] = 82595525; boundaries_letters[i++] = 165191050;
  1382. boundaries_letters[i++] = 247786575; boundaries_letters[i++] = 330382100;
  1383. boundaries_letters[i++] = 412977625; boundaries_letters[i++] = 495573150;
  1384. boundaries_letters[i++] = 578168675; boundaries_letters[i++] = 660764200;
  1385. boundaries_letters[i++] = 743359725; boundaries_letters[i++] = 825955250;
  1386. boundaries_letters[i++] = 908550775; boundaries_letters[i++] = 991146300;
  1387. boundaries_letters[i++] = 1073741824; boundaries_letters[i++] = 1156337349;
  1388. boundaries_letters[i++] = 1238932874; boundaries_letters[i++] = 1321528399;
  1389. boundaries_letters[i++] = 1404123924; boundaries_letters[i++] = 1486719449;
  1390. boundaries_letters[i++] = 1569314974; boundaries_letters[i++] = 1651910499;
  1391. boundaries_letters[i++] = 1734506024; boundaries_letters[i++] = 1817101549;
  1392. boundaries_letters[i++] = 1899697074; boundaries_letters[i++] = 1982292599;
  1393. boundaries_letters[i++] = 2064888124; boundaries_letters[i++] = 2147483647;
  1394. i = 0;
  1395. boundaries_symbols[i++] = 67108864; boundaries_symbols[i++] = 134217728;
  1396. boundaries_symbols[i++] = 201326592; boundaries_symbols[i++] = 268435456;
  1397. boundaries_symbols[i++] = 335544320; boundaries_symbols[i++] = 402653184;
  1398. boundaries_symbols[i++] = 469762048; boundaries_symbols[i++] = 536870912;
  1399. boundaries_symbols[i++] = 603979776; boundaries_symbols[i++] = 671088640;
  1400. boundaries_symbols[i++] = 738197504; boundaries_symbols[i++] = 805306368;
  1401. boundaries_symbols[i++] = 872415232; boundaries_symbols[i++] = 939524096;
  1402. boundaries_symbols[i++] = 1006632960; boundaries_symbols[i++] = 1073741824;
  1403. boundaries_symbols[i++] = 1140850688; boundaries_symbols[i++] = 1207959552;
  1404. boundaries_symbols[i++] = 1275068416; boundaries_symbols[i++] = 1342177280;
  1405. boundaries_symbols[i++] = 1409286144; boundaries_symbols[i++] = 1476395008;
  1406. boundaries_symbols[i++] = 1543503872; boundaries_symbols[i++] = 1610612736;
  1407. boundaries_symbols[i++] = 1677721600; boundaries_symbols[i++] = 1744830464;
  1408. boundaries_symbols[i++] = 1811939328; boundaries_symbols[i++] = 1879048192;
  1409. boundaries_symbols[i++] = 1946157056; boundaries_symbols[i++] = 2013265920;
  1410. boundaries_symbols[i++] = 2080374784; boundaries_symbols[i++] = 2147483647;
  1411. seed = 0;
  1412. }
  1413. void generate()
  1414. {
  1415. int i, j, s, next, nextp, val, bucket, randnum, used_charsets;
  1416. int seedarray[56];
  1417. /* BEGIN System.Random(seed) */
  1418. if(seed < 0) {
  1419. /* Only bother with non-negative integers */
  1420. word = 0;
  1421. return;
  1422. }
  1423. s = 161803398 - seed++;
  1424. seedarray[55] = s;
  1425. i = val = 1;
  1426. while(i < 55) {
  1427. bucket = 21 * i % 55;
  1428. seedarray[bucket] = val;
  1429. val = s - val;
  1430. if(val < 0) val += 2147483647;
  1431. s = seedarray[bucket];
  1432. i++;
  1433. }
  1434. i = 1;
  1435. while(i < 5) {
  1436. j = 1;
  1437. while(j < 56) {
  1438. seedarray[j] -= seedarray[1 + (j + 30) % 55];
  1439. if(seedarray[j] < 0) seedarray[j] += 2147483647;
  1440. j++;
  1441. }
  1442. i++;
  1443. }
  1444. next = 0;
  1445. nextp = 21;
  1446. /* END System.Random(seed) */
  1447. used_charsets = 0;
  1448. while(used_charsets != 15) {
  1449. i = 0;
  1450. while(i < password_length) {
  1451. /* BEGIN Random.Sample() */
  1452. if (++next >= 56) next = 1;
  1453. if (++nextp >= 56) nextp = 1;
  1454. randnum = seedarray[next] - seedarray[nextp];
  1455. if (randnum == 2147483647) randnum--;
  1456. if (randnum < 0) randnum += 2147483647;
  1457. seedarray[next] = randnum;
  1458. /* END Random.Sample() */
  1459. j = 0;
  1460. while(boundaries_charclass[j] < randnum) j++;
  1461. word[i] = j; /* Temporarily store in word[] */
  1462. used_charsets |= (1 << j);
  1463. i++;
  1464. }
  1465. }
  1466. i = 0;
  1467. while(i < password_length) {
  1468. /* BEGIN Random.Sample() */
  1469. if (++next >= 56) next = 1;
  1470. if (++nextp >= 56) nextp = 1;
  1471. randnum = seedarray[next] - seedarray[nextp];
  1472. if (randnum == 2147483647) randnum--;
  1473. if (randnum < 0) randnum += 2147483647;
  1474. seedarray[next] = randnum;
  1475. /* END Random.Sample() */
  1476. j = 0;
  1477. if(word[i] == 0) {
  1478. while(boundaries_letters[j] < randnum) j++;
  1479. word[i++] = lowers[j];
  1480. } else if (word[i] == 1) {
  1481. while(boundaries_letters[j] < randnum) j++;
  1482. word[i++] = uppers[j];
  1483. } else if (word[i] == 2) {
  1484. while(boundaries_numbers[j] < randnum) j++;
  1485. word[i++] = numbers[j];
  1486. } else { /* if (word[i] == 3) */
  1487. while(boundaries_symbols[j] < randnum) j++;
  1488. word[i++] = symbols[j];
  1489. }
  1490. }
  1491. word[i] = 0;
  1492. }
  1493. void restore()
  1494. {
  1495. int i, j, s, next, nextp, val, bucket, randnum, used_charsets;
  1496. int seedarray[56];
  1497. int candidate[32]; /* This needs to be at-least as big as password-length */
  1498. seed = 0;
  1499. while(seed > 0) {
  1500. /* BEGIN System.Random(seed) */
  1501. s = 161803398 - seed++;
  1502. seedarray[55] = s;
  1503. i = val = 1;
  1504. while(i < 55) {
  1505. bucket = 21 * i % 55;
  1506. seedarray[bucket] = val;
  1507. val = s - val;
  1508. if(val < 0) val += 2147483647;
  1509. s = seedarray[bucket];
  1510. i++;
  1511. }
  1512. i = 1;
  1513. while(i < 5) {
  1514. j = 1;
  1515. while(j < 56) {
  1516. seedarray[j] -= seedarray[1 + (j + 30) % 55];
  1517. if(seedarray[j] < 0) seedarray[j] += 2147483647;
  1518. j++;
  1519. }
  1520. i++;
  1521. }
  1522. next = 0;
  1523. nextp = 21;
  1524. /* END System.Random(seed) */
  1525. used_charsets = 0;
  1526. while(used_charsets != 15) {
  1527. i = 0;
  1528. while(i < password_length) {
  1529. /* BEGIN Random.Sample() */
  1530. if (++next >= 56) next = 1;
  1531. if (++nextp >= 56) nextp = 1;
  1532. randnum = seedarray[next] - seedarray[nextp];
  1533. if (randnum == 2147483647) randnum--;
  1534. if (randnum < 0) randnum += 2147483647;
  1535. seedarray[next] = randnum;
  1536. /* END Random.Sample() */
  1537. j = 0;
  1538. while(boundaries_charclass[j] < randnum) j++;
  1539. candidate[i] = j;
  1540. used_charsets |= (1 << j);
  1541. i++;
  1542. }
  1543. }
  1544. i = 0;
  1545. while(i < password_length) {
  1546. /* BEGIN Random.Sample() */
  1547. if (++next >= 56) next = 1;
  1548. if (++nextp >= 56) nextp = 1;
  1549. randnum = seedarray[next] - seedarray[nextp];
  1550. if (randnum == 2147483647) randnum--;
  1551. if (randnum < 0) randnum += 2147483647;
  1552. seedarray[next] = randnum;
  1553. /* END Random.Sample() */
  1554. j = 0;
  1555. if(candidate[i] == 0) {
  1556. while(boundaries_letters[j] < randnum) j++;
  1557. if(lowers[j] != word[i++]) break;
  1558. } else if (candidate[i] == 1) {
  1559. while(boundaries_letters[j] < randnum) j++;
  1560. if(uppers[j] != word[i++]) break;
  1561. } else if (candidate[i] == 2) {
  1562. while(boundaries_numbers[j] < randnum) j++;
  1563. if(numbers[j] != word[i++]) break;
  1564. } else { /* if (word[i] == 3) */
  1565. while(boundaries_symbols[j] < randnum) j++;
  1566. if(symbols[j] != word[i++]) break;
  1567. }
  1568. }
  1569. if(i == password_length) return;
  1570. }
  1571. }
  1572. # Try sequences of adjacent keys on a keyboard as candidate passwords
  1573. [List.External:Keyboard]
  1574. int maxlength, length; // Maximum password length to try, current length
  1575. int fuzz; // The desired "fuzz factor", either 0 or 1
  1576. int id[15]; // Current character indices for each position
  1577. int m[0x800]; // The keys matrix
  1578. int mc[0x100]; // Counts of adjacent keys
  1579. int f[0x40], fc; // Characters for the first position, their count
  1580. void init()
  1581. {
  1582. int minlength;
  1583. int i, j, c, p;
  1584. int k[0x40];
  1585. // Initial password length to try
  1586. if (req_minlen)
  1587. minlength = req_minlen;
  1588. else
  1589. minlength = 1;
  1590. if (req_maxlen)
  1591. maxlength = req_maxlen;
  1592. else
  1593. maxlength = cipher_limit; // the format's limit
  1594. fuzz = 1; // "Fuzz factor", set to 0 for much quicker runs
  1595. /*
  1596. * This defines the keyboard layout, by default for a QWERTY keyboard.
  1597. */
  1598. i = 0; while (i < 0x40) k[i++] = 0;
  1599. k[0] = '`';
  1600. i = 0; while (++i <= 9) k[i] = '0' + i;
  1601. k[10] = '0'; k[11] = '-'; k[12] = '=';
  1602. k[0x11] = 'q'; k[0x12] = 'w'; k[0x13] = 'e'; k[0x14] = 'r';
  1603. k[0x15] = 't'; k[0x16] = 'y'; k[0x17] = 'u'; k[0x18] = 'i';
  1604. k[0x19] = 'o'; k[0x1a] = 'p'; k[0x1b] = '['; k[0x1c] = ']';
  1605. k[0x1d] = '\\';
  1606. k[0x21] = 'a'; k[0x22] = 's'; k[0x23] = 'd'; k[0x24] = 'f';
  1607. k[0x25] = 'g'; k[0x26] = 'h'; k[0x27] = 'j'; k[0x28] = 'k';
  1608. k[0x29] = 'l'; k[0x2a] = ';'; k[0x2b] = '\'';
  1609. k[0x31] = 'z'; k[0x32] = 'x'; k[0x33] = 'c'; k[0x34] = 'v';
  1610. k[0x35] = 'b'; k[0x36] = 'n'; k[0x37] = 'm'; k[0x38] = ',';
  1611. k[0x39] = '.'; k[0x3a] = '/';
  1612. i = 0; while (i < 0x100) mc[i++] = 0;
  1613. fc = 0;
  1614. /* rows */
  1615. c = 0;
  1616. i = 0;
  1617. while (i < 0x40) {
  1618. p = c;
  1619. c = k[i++] & 0xff;
  1620. if (!c) continue;
  1621. f[fc++] = c;
  1622. if (!p) continue;
  1623. m[(c << 3) + mc[c]++] = p;
  1624. m[(p << 3) + mc[p]++] = c;
  1625. }
  1626. f[fc] = 0;
  1627. /* columns */
  1628. i = 0;
  1629. while (i < 0x30) {
  1630. p = k[i++] & 0xff;
  1631. if (!p) continue;
  1632. j = 1 - fuzz;
  1633. while (j <= 1 + fuzz) {
  1634. c = k[i + 0x10 - j++] & 0xff;
  1635. if (!c) continue;
  1636. m[(c << 3) + mc[c]++] = p;
  1637. m[(p << 3) + mc[p]++] = c;
  1638. }
  1639. }
  1640. length = 0;
  1641. while (length < minlength)
  1642. id[length++] = 0;
  1643. }
  1644. void generate()
  1645. {
  1646. int i, p, maxcount;
  1647. word[i = 0] = p = f[id[0]];
  1648. while (++i < length)
  1649. word[i] = p = m[(p << 3) + id[i]];
  1650. word[i--] = 0;
  1651. if (i) maxcount = mc[word[i - 1]]; else maxcount = fc;
  1652. while (++id[i] >= maxcount) {
  1653. if (!i) {
  1654. if (length < maxlength) {
  1655. id[0] = 0;
  1656. id[length++] = 0;
  1657. }
  1658. return;
  1659. }
  1660. id[i--] = 0;
  1661. if (i) maxcount = mc[word[i - 1]]; else maxcount = fc;
  1662. }
  1663. }
  1664. void restore()
  1665. {
  1666. int i;
  1667. /* Calculate the length */
  1668. length = 0;
  1669. while (word[length])
  1670. id[length++] = 0;
  1671. /* Infer the first character index */
  1672. i = -1;
  1673. while (++i < fc) {
  1674. if (f[i] == word[0]) {
  1675. id[0] = i;
  1676. break;
  1677. }
  1678. }
  1679. /* This sample can be enhanced to infer the rest of the indices here */
  1680. }
  1681. # Simplest (fastest?) possible dumb exhaustive search, demonstrating a
  1682. # mode that does not need any special restore() handling.
  1683. # Defaults to printable ASCII.
  1684. [List.External:DumbDumb]
  1685. void init()
  1686. {
  1687. word[0] = ' ' - 1;
  1688. word[1] = 0;
  1689. }
  1690. void generate()
  1691. {
  1692. int i;
  1693. if (++word < 0x7f)
  1694. return;
  1695. i = 0;
  1696. while (word[i] > 0x7e) {
  1697. word[i++] = ' ';
  1698. if (!word[i]) {
  1699. word[i] = ' ';
  1700. word[i + 1] = 0;
  1701. } else
  1702. word[i]++;
  1703. }
  1704. if (i > cipher_limit)
  1705. word = 0;
  1706. }
  1707. /*
  1708. * This mode will resume correctly without any restore handing.
  1709. * The empty function just confirms to John that everything is in order.
  1710. */
  1711. void restore()
  1712. {
  1713. }
  1714. # Generic implementation of "dumb" exhaustive search, given a range of lengths
  1715. # and an arbitrary charset. This is pre-configured to try 8-bit characters
  1716. # against LM hashes, which is only reasonable to do for very short password
  1717. # half lengths.
  1718. [List.External:DumbForce]
  1719. int maxlength; // Maximum password length to try
  1720. int last; // Last character position, zero-based
  1721. int lastid; // Character index in the last position
  1722. int id[0x7f]; // Current character indices for other positions
  1723. int charset[0x100], c0; // Character set
  1724. void init()
  1725. {
  1726. int minlength;
  1727. int i, c;
  1728. // Initial password length to try, must be at least 1
  1729. if (req_minlen)
  1730. minlength = req_minlen;
  1731. else
  1732. minlength = 1;
  1733. if (req_maxlen)
  1734. maxlength = req_maxlen;
  1735. else
  1736. maxlength = cipher_limit; // the format's limit
  1737. /*
  1738. * This defines the character set.
  1739. *
  1740. * Let's say, we want to try TAB, all non-control ASCII characters, and all
  1741. * 8-bit characters, including the 8-bit terminal controls range (as these are
  1742. * used as regular national characters with some 8-bit encodings), but except
  1743. * for known terminal controls (risky for the terminal we may be running on).
  1744. *
  1745. * Also, let's say our hashes are case-insensitive, so skip lowercase letters
  1746. * (this is right for LM hashes).
  1747. */
  1748. i = 0;
  1749. charset[i++] = 9; // Add horizontal TAB (ASCII 9), then
  1750. c = ' '; // start with space (ASCII 32) and
  1751. while (c < 'a') // proceed till lowercase 'a'
  1752. charset[i++] = c++;
  1753. c = 'z' + 1; // Skip lowercase letters and
  1754. while (c <= 0x7e) // proceed for all printable ASCII
  1755. charset[i++] = c++;
  1756. c++; // Skip DEL (ASCII 127) and
  1757. while (c < 0x84) // proceed over 8-bit codes till IND
  1758. charset[i++] = c++;
  1759. charset[i++] = 0x86; // Skip IND (84 hex) and NEL (85 hex)
  1760. charset[i++] = 0x87;
  1761. c = 0x89; // Skip HTS (88 hex)
  1762. while (c < 0x8d) // Proceed till RI (8D hex)
  1763. charset[i++] = c++;
  1764. c = 0x91; // Skip RI, SS2, SS3, DCS
  1765. while (c < 0x96) // Proceed till SPA (96 hex)
  1766. charset[i++] = c++;
  1767. charset[i++] = 0x99; // Skip SPA, EPA, SOS
  1768. c = 0xa0; // Skip DECID, CSI, ST, OSC, PM, APC
  1769. while (c <= 0xff) // Proceed with the rest of 8-bit codes
  1770. charset[i++] = c++;
  1771. /* Zero-terminate it, and cache the first character */
  1772. charset[i] = 0;
  1773. c0 = charset[0];
  1774. last = minlength - 1;
  1775. i = 0;
  1776. while (i <= last) {
  1777. id[i] = 0;
  1778. word[i++] = c0;
  1779. }
  1780. lastid = -1;
  1781. word[i] = 0;
  1782. }
  1783. void generate()
  1784. {
  1785. int i;
  1786. /* Handle the typical case specially */
  1787. if (word[last] = charset[++lastid]) return;
  1788. lastid = 0;
  1789. word[i = last] = c0;
  1790. while (i--) { // Have a preceding position?
  1791. if (word[i] = charset[++id[i]]) return;
  1792. id[i] = 0;
  1793. word[i] = c0;
  1794. }
  1795. if (++last < maxlength) { // Next length?
  1796. id[last] = lastid = 0;
  1797. word[last] = c0;
  1798. word[last + 1] = 0;
  1799. } else // We're done
  1800. word = 0;
  1801. }
  1802. void restore()
  1803. {
  1804. int i, c;
  1805. /* Calculate the current length and infer the character indices */
  1806. last = 0;
  1807. while (c = word[last]) {
  1808. i = 0; while (charset[i] != c && charset[i]) i++;
  1809. if (!charset[i]) i = 0; // Not found
  1810. id[last++] = i;
  1811. }
  1812. lastid = id[--last];
  1813. }
  1814. # Generic implementation of exhaustive search for a partially-known password.
  1815. # This is pre-configured for length 8, lowercase and uppercase letters in the
  1816. # first 4 positions (52 different characters), and digits in the remaining 4
  1817. # positions - however, the corresponding part of init() may be modified to use
  1818. # arbitrary character sets or even fixed characters for each position.
  1819. [List.External:KnownForce]
  1820. int last; // Last character position, zero-based
  1821. int lastofs; // Last character position offset into charset[]
  1822. int lastid; // Current character index in the last position
  1823. int id[0x7f]; // Current character indices for other positions
  1824. int charset[0x7f00]; // Character sets, 0x100 elements for each position
  1825. void init()
  1826. {
  1827. int length, maxlength;
  1828. int pos, ofs, i, c;
  1829. if (req_minlen)
  1830. length = req_minlen;
  1831. else
  1832. length = 8; // Password length to try (NOTE: other [eg. shorter]
  1833. // lengths will not be tried!)
  1834. if (req_maxlen)
  1835. maxlength = req_maxlen;
  1836. else
  1837. maxlength = cipher_limit; // the format's limit
  1838. /* This defines the character sets for different character positions */
  1839. if (length > maxlength)
  1840. length = maxlength;
  1841. pos = 0;
  1842. while (pos < 4) {
  1843. ofs = pos++ << 8;
  1844. i = 0;
  1845. c = 'a';
  1846. while (c <= 'z')
  1847. charset[ofs + i++] = c++;
  1848. c = 'A';
  1849. while (c <= 'Z')
  1850. charset[ofs + i++] = c++;
  1851. charset[ofs + i] = 0;
  1852. }
  1853. while (pos < length) {
  1854. ofs = pos++ << 8;
  1855. i = 0;
  1856. c = '0';
  1857. while (c <= '9')
  1858. charset[ofs + i++] = c++;
  1859. charset[ofs + i] = 0;
  1860. }
  1861. last = length - 1;
  1862. pos = -1;
  1863. while (++pos <= last)
  1864. word[pos] = charset[id[pos] = pos << 8];
  1865. lastid = (lastofs = last << 8) - 1;
  1866. word[pos] = 0;
  1867. }
  1868. void generate()
  1869. {
  1870. int pos;
  1871. /* Handle the typical case specially */
  1872. if (word[last] = charset[++lastid]) return;
  1873. word[pos = last] = charset[lastid = lastofs];
  1874. while (pos--) { // Have a preceding position?
  1875. if (word[pos] = charset[++id[pos]]) return;
  1876. word[pos] = charset[id[pos] = pos << 8];
  1877. }
  1878. word = 0; // We're done
  1879. }
  1880. void restore()
  1881. {
  1882. int i, c;
  1883. /* Calculate the current length and infer the character indices */
  1884. last = 0;
  1885. while (c = word[last]) {
  1886. i = lastofs = last << 8;
  1887. while (charset[i] != c && charset[i]) i++;
  1888. if (!charset[i]) i = lastofs; // Not found
  1889. id[last++] = i;
  1890. }
  1891. lastid = id[--last];
  1892. }
  1893. # A variation of KnownForce configured to try likely date and time strings.
  1894. [List.External:DateTime]
  1895. int last; // Last character position, zero-based
  1896. int lastofs; // Last character position offset into charset[]
  1897. int lastid; // Current character index in the last position
  1898. int id[0x7f]; // Current character indices for other positions
  1899. int charset[0x7f00]; // Character sets, 0x100 elements for each position
  1900. void init()
  1901. {
  1902. int length;
  1903. int pos, ofs, i, c;
  1904. length = 8; // Must be one of: 4, 5, 7, 8
  1905. /* This defines the character sets for different character positions */
  1906. pos = 0;
  1907. while (pos < length - 6) {
  1908. ofs = pos++ << 8;
  1909. i = 0;
  1910. c = '0';
  1911. while (c <= '9')
  1912. charset[ofs + i++] = c++;
  1913. charset[ofs + i] = 0;
  1914. }
  1915. if (pos) {
  1916. ofs = pos++ << 8;
  1917. charset[ofs] = '/';
  1918. charset[ofs + 1] = '.';
  1919. charset[ofs + 2] = ':';
  1920. charset[ofs + 3] = 0;
  1921. }
  1922. while (pos < length - 3) {
  1923. ofs = pos++ << 8;
  1924. i = 0;
  1925. c = '0';
  1926. while (c <= '9')
  1927. charset[ofs + i++] = c++;
  1928. charset[ofs + i] = 0;
  1929. }
  1930. ofs = pos++ << 8;
  1931. charset[ofs] = '/';
  1932. charset[ofs + 1] = '.';
  1933. charset[ofs + 2] = ':';
  1934. charset[ofs + 3] = 0;
  1935. while (pos < length) {
  1936. ofs = pos++ << 8;
  1937. i = 0;
  1938. c = '0';
  1939. while (c <= '9')
  1940. charset[ofs + i++] = c++;
  1941. charset[ofs + i] = 0;
  1942. }
  1943. last = length - 1;
  1944. pos = -1;
  1945. while (++pos <= last)
  1946. word[pos] = charset[id[pos] = pos << 8];
  1947. lastid = (lastofs = last << 8) - 1;
  1948. word[pos] = 0;
  1949. }
  1950. void generate()
  1951. {
  1952. int pos;
  1953. /* Handle the typical case specially */
  1954. if (word[last] = charset[++lastid]) return;
  1955. word[pos = last] = charset[lastid = lastofs];
  1956. while (pos--) { // Have a preceding position?
  1957. if (word[pos] = charset[++id[pos]]) return;
  1958. word[pos] = charset[id[pos] = pos << 8];
  1959. }
  1960. word = 0; // We're done
  1961. }
  1962. void restore()
  1963. {
  1964. int i, c;
  1965. /* Calculate the current length and infer the character indices */
  1966. last = 0;
  1967. while (c = word[last]) {
  1968. i = lastofs = last << 8;
  1969. while (charset[i] != c && charset[i]) i++;
  1970. if (!charset[i]) i = lastofs; // Not found
  1971. id[last++] = i;
  1972. }
  1973. lastid = id[--last];
  1974. }
  1975. # Try strings of repeated characters.
  1976. #
  1977. # This is the code which is common for all [List.External:Repeats*]
  1978. # sections which include this External_base section.
  1979. # The generate() function will limit the maximum length of generated
  1980. # candidates to either the format's limit (maximum password length)
  1981. # or to the limit specified with --stdout=LENGTH (Default: 125),
  1982. # thus avoiding duplicate candidates for formats with limited maximum
  1983. # passwortd length.
  1984. # The comparison of the current length and the limit is only done
  1985. # after switching to a new length.
  1986. # So, if the minimum length specified already exceeds this limit,
  1987. # then all the candidates for the minimum length will be generated
  1988. # nevertheless.
  1989. [List.External_base:Repeats]
  1990. int minlength, maxlength, minc, maxc, length, c;
  1991. void generate()
  1992. {
  1993. int i;
  1994. i = 0;
  1995. while (i < length)
  1996. word[i++] = c;
  1997. word[i] = 0;
  1998. if (c++ < maxc)
  1999. return;
  2000. c = minc;
  2001. if (++length > maxlength)
  2002. c = 0; // Will NUL out the next "word" and thus terminate
  2003. }
  2004. # Try strings of repeated characters (range: space - 0xff).
  2005. [List.External:Repeats]
  2006. .include [List.External_base:Repeats]
  2007. void init()
  2008. {
  2009. if (req_minlen)
  2010. minlength = req_minlen;
  2011. else
  2012. minlength = 1;
  2013. if (req_maxlen)
  2014. maxlength = req_maxlen;
  2015. else
  2016. maxlength = cipher_limit; // the format's limit
  2017. minc = 0x20;
  2018. maxc = 0xff;
  2019. length = minlength; c = minc;
  2020. }
  2021. # Try strings of repeated digits (range: '0' - '9').
  2022. [List.External:Repeats_digits]
  2023. .include [List.External_base:Repeats]
  2024. void init()
  2025. {
  2026. if (req_minlen)
  2027. minlength = req_minlen;
  2028. else
  2029. minlength = 1;
  2030. if (req_maxlen)
  2031. maxlength = req_maxlen;
  2032. else
  2033. maxlength = cipher_limit; // the format's limit
  2034. minc = '0';
  2035. maxc = '9';
  2036. length = minlength; c = minc;
  2037. }
  2038. # Try strings of repeated lowercase letters (range: 'a' - 'z').
  2039. [List.External:Repeats_lowercase]
  2040. .include [List.External_base:Repeats]
  2041. void init()
  2042. {
  2043. if (req_minlen)
  2044. minlength = req_minlen;
  2045. else
  2046. minlength = 1;
  2047. if (req_maxlen)
  2048. maxlength = req_maxlen;
  2049. else
  2050. maxlength = cipher_limit; // the format's limit
  2051. minc = 'a';
  2052. maxc = 'z';
  2053. length = minlength; c = minc;
  2054. }
  2055. # Try strings of repeated printable ASCII characters
  2056. # (range: ' ' - '~').
  2057. [List.External:Repeats_printable_ASCII]
  2058. .include [List.External_base:Repeats]
  2059. void init()
  2060. {
  2061. if (req_minlen)
  2062. minlength = req_minlen;
  2063. else
  2064. minlength = 1;
  2065. if (req_maxlen)
  2066. maxlength = req_maxlen;
  2067. else
  2068. maxlength = cipher_limit; // the format's limit
  2069. minc = ' ';
  2070. maxc = '~';
  2071. length = minlength; c = minc;
  2072. }
  2073. # Try character sequences ("0123456", "acegikmoqs", "ZYXWVU", etc.).
  2074. #
  2075. # The generate() function will limit the maximum length of generated
  2076. # candidates to either the format's limit (maximum password length)
  2077. # or to the limit specified with --stdout=LENGTH (Default: 125),
  2078. # thus avoiding duplicate candidates for formats with limited maximum
  2079. # passwortd length.
  2080. # The comparison of the current length and the limit is only done
  2081. # after switching to a new length.
  2082. # So, if the minimum length specified already exceeds this limit,
  2083. # then all the candidates for the minimum length will be generated
  2084. # nevertheless.
  2085. # External modes reusing this External_base mode should only need to
  2086. # adjust the init() function.
  2087. # In the init() function, a minimum length which is > 1 should be
  2088. # specified.
  2089. # Otherwise, the generated candidates will not depend on the increment
  2090. # specified.
  2091. # For length = 1, the candidates will be the same as for external mode
  2092. # Repeats with length 1.
  2093. # Actually, Repeats is a special case of Sequence, using increment = 0.
  2094. # External modes reusing this External_base mode should also make sure
  2095. # that the number of different characters (specified as a range from "from"
  2096. # to "to") is not smaller than the minimum length ("minlength"),
  2097. # if the start increment "inc" is 1.
  2098. # For a start increment > 1, the number of different characters in the
  2099. # range "from" - "to" must be greater than or equal to
  2100. # (1 + ("minlength" - 1) * "inc").
  2101. # Otherwise you might get unexpected results.
  2102. # The range of characters to be used for the sequences needs to be
  2103. # specified by adjusting the "from" and "to" variables.
  2104. # To generate sequences which decrement characters ("987654"),
  2105. # "from" must be > "to".
  2106. # Otherwise, the generated sequences will increment characters ("abcdef").
  2107. #
  2108. # Variables to be used and the generate() function are common
  2109. # for all sections which include this External_base section.
  2110. [List.External_base:Sequence]
  2111. /*
  2112. * See the [List.External:Sequence_0-9] section to learn more about
  2113. * the meaning of these variables which can be adjusted to define
  2114. * new external modes based on an existing one:
  2115. */
  2116. int minlength, from, to, maxlength, inc, direction;
  2117. /*
  2118. * The value of these variables shouldn't be changed when copying
  2119. * an existing external mode:
  2120. */
  2121. int length, first;
  2122. void generate()
  2123. {
  2124. int i;
  2125. i = 0;
  2126. while (i < length) {
  2127. word[i] = first + (i * inc * direction);
  2128. ++i;
  2129. }
  2130. word[i] = 0;
  2131. // start the next sequence of the same length
  2132. // with the next character
  2133. first = first + direction;
  2134. // But check that a sequence of the current length
  2135. // is still possible (without leaving the range of
  2136. // characters allowed
  2137. if ((direction > 0 && first + (length - 1) * inc > to) ||
  2138. (direction < 0 && first - (length - 1) * inc < to)) {
  2139. // No more sequence is possible. Reset start character
  2140. first = from;
  2141. // Now try the next length.
  2142. // But just in case an individual External mode reusing
  2143. // this External_base mode did specify a maxlength
  2144. // which is larger than the one supported by the format
  2145. // or by --stdout=LENGTH, make sure no more candidates
  2146. // are generated.
  2147. // Checking this just once per length per increment
  2148. // doen't really hurt performance.
  2149. if (maxlength > cipher_limit)
  2150. maxlength = cipher_limit;
  2151. // For a similar reason, the maximum length of a
  2152. // sequence is limited by the number of different
  2153. // characters and by the increment.
  2154. // The larger the increment, the smaller
  2155. // the maximum possible length for a given
  2156. // character range.
  2157. while (inc * (maxlength - 1) > direction * (to - from))
  2158. --maxlength;
  2159. if (++length > maxlength) {
  2160. // The maximum length for this increment has been reached.
  2161. // Restart at minimum length with the next possible
  2162. // increment
  2163. ++inc;
  2164. // Unfortunately, we have to check again
  2165. // if the maximum length needs to be reduced
  2166. // for the new increment
  2167. while (inc * (maxlength - 1) > direction * (to - from))
  2168. --maxlength;
  2169. length = minlength;
  2170. }
  2171. if (maxlength < minlength)
  2172. // With the current increment, we can't even generate
  2173. // sequences of the minimum required length.
  2174. // So we need to stop here.
  2175. // This will make sure that no more candidiates
  2176. // will be generated:
  2177. first = 0;
  2178. }
  2179. }
  2180. # Try sequences of digits (range: '0' - '9').
  2181. #
  2182. # Aditional comments can be found in the
  2183. # section [List.External_base:Sequence]
  2184. #
  2185. # This external mode is thoroughly commented,
  2186. # to make it easier to copy and adjust it as needed.
  2187. [List.External:Sequence_0-9]
  2188. .include [List.External_base:Sequence]
  2189. void init()
  2190. {
  2191. // Adjust the following 4 variables if you want to define
  2192. // a different external mode.
  2193. // This is the start character for the generated sequence
  2194. // if "from" is smaller than "to", the increment from
  2195. // first to second character ... will be positive ("0123456789").
  2196. // Otherwise, it will be negative ("987654321").
  2197. from = '0';
  2198. to = '9';
  2199. // minimum length of the sequence
  2200. // make sure it is not larger than the number of different characters
  2201. // in the range between "from" and "to" specified above
  2202. minlength = 2;
  2203. // start increment for generating the sequence, usually 1
  2204. // if it is larger than 1, you need even more characters
  2205. // in the range between "from" and "to"
  2206. // Don't specify a negative value here.
  2207. // If you want to generate sequences like "zyxwvu" or "86420",
  2208. // adjust "from" and "to" so that "from" is larger than "to".
  2209. // (A start increment of 0 is also possible, in that case the first
  2210. // sequences will be candidates which just repeat the same character.)
  2211. inc = 1;
  2212. // For copied external modes, no further changes should be required
  2213. // in the statements following this comment
  2214. length = minlength;
  2215. first = from;
  2216. if (from <= to) {
  2217. maxlength = to - from + 1;
  2218. direction = 1;
  2219. } else {
  2220. // We have to create sequences which decrement the previous character
  2221. maxlength = from - to + 1;
  2222. direction = -1;
  2223. }
  2224. }
  2225. # Try sequence of lower case letters (range: 'a' - 'z').
  2226. # This external mode is not very well documented.
  2227. # Refer to [List.External:Sequence_0-9] for more detailed information.
  2228. [List.External:Sequence_a-z]
  2229. .include [List.External_base:Sequence]
  2230. void init()
  2231. {
  2232. from = 'a';
  2233. to = 'z';
  2234. minlength = 2;
  2235. inc = 1;
  2236. length = minlength;
  2237. first = from;
  2238. if (from <= to) {
  2239. maxlength = to - from + 1;
  2240. direction = 1;
  2241. } else {
  2242. maxlength = from - to + 1;
  2243. direction = -1;
  2244. }
  2245. }
  2246. # Try sequence of lower case letters (range: 'a' - 'z'), but reversed
  2247. # ("zxywvu").
  2248. # This external mode is not very well documented.
  2249. # Refer to [List.External:Sequence_0-9] for more detailed information.
  2250. [List.External:Sequence_z-a]
  2251. .include [List.External_base:Sequence]
  2252. void init()
  2253. {
  2254. from = 'z';
  2255. to = 'a';
  2256. minlength = 2;
  2257. inc = 1;
  2258. length = minlength;
  2259. first = from;
  2260. if (from <= to) {
  2261. maxlength = to - from + 1;
  2262. direction = 1;
  2263. } else {
  2264. maxlength = from - to + 1;
  2265. direction = -1;
  2266. }
  2267. }
  2268. # Try sequence of printable ASCII characters (range: ' ' - '~').
  2269. # This external mode is not very well documented.
  2270. # Refer to [List.External:Sequence_0-9] for more detailed information.
  2271. [List.External:Sequence_printable_ascii]
  2272. .include [List.External_base:Sequence]
  2273. void init()
  2274. {
  2275. from = ' ';
  2276. to = '~';
  2277. minlength = 2;
  2278. inc = 1;
  2279. length = minlength;
  2280. first = from;
  2281. if (from <= to) {
  2282. maxlength = to - from + 1;
  2283. direction = 1;
  2284. } else {
  2285. maxlength = from - to + 1;
  2286. direction = -1;
  2287. }
  2288. }
  2289. # Try sequence of printable ASCII characters (range: ' ' - '~'),
  2290. # but decrementing characters ("fedcba") instead of incrementing.
  2291. # This external mode is not very well documented.
  2292. # Refer to [List.External:Sequence_0-9] for more detailed information.
  2293. [List.External:Sequence_reversed_ascii]
  2294. .include [List.External_base:Sequence]
  2295. void init()
  2296. {
  2297. from = '~';
  2298. to = ' ';
  2299. minlength = 2;
  2300. inc = 1;
  2301. length = minlength;
  2302. first = from;
  2303. if (from <= to) {
  2304. maxlength = to - from + 1;
  2305. direction = 1;
  2306. } else {
  2307. maxlength = from - to + 1;
  2308. direction = -1;
  2309. }
  2310. }
  2311. # Try sequence of characters (range: space - 0xff).
  2312. # This external mode is not very well documented.
  2313. # Refer to [List.External:Sequence_0-9] for more detailed information.
  2314. [List.External:Sequence]
  2315. .include [List.External_base:Sequence]
  2316. void init()
  2317. {
  2318. from = ' ';
  2319. to = 0xff;
  2320. minlength = 2;
  2321. inc = 1;
  2322. length = minlength;
  2323. first = from;
  2324. if (from <= to) {
  2325. maxlength = to - from + 1;
  2326. direction = 1;
  2327. } else {
  2328. maxlength = from - to + 1;
  2329. direction = -1;
  2330. }
  2331. }
  2332. # Generate candidate passwords from many small subsets of characters from a
  2333. # much larger full character set. This will test for passwords containing too
  2334. # few different characters. As currently implemented, this code will produce
  2335. # some duplicates, although their number is relatively small when the maximum
  2336. # number of different characters (the maxdiff setting) is significantly lower
  2337. # than the maximum length (the maxlength setting). Nevertheless, you may want
  2338. # to pass the resulting candidate passwords through "unique" if you intend to
  2339. # test them against hashes that are salted and/or of a slow to compute type.
  2340. [List.External:Subsets]
  2341. int minlength; // Minimum password length to try
  2342. int maxlength; // Maximum password length to try
  2343. int startdiff; // Initial number of characters in a subset to try
  2344. int maxdiff; // Maximum number of characters in a subset to try
  2345. int last; // Last character position, zero-based
  2346. int lastid; // Character index in the last position
  2347. int id[0x7f]; // Current character indices for other positions
  2348. int subset[0x100], c0; // Current subset
  2349. int subcount; // Number of characters in the current subset
  2350. int subid[0x100]; // Indices into charset[] of characters in subset[]
  2351. int charset[0x100]; // Full character set
  2352. int charcount; // Number of characters in the full charset
  2353. void init()
  2354. {
  2355. int i, c;
  2356. // Minimum password length to try, must be at least 1
  2357. if (req_minlen)
  2358. minlength = req_minlen;
  2359. else
  2360. minlength = 1;
  2361. // Maximum password length to try, must be at least same as minlength
  2362. // This external mode's default maximum length can be adjusted
  2363. // using --max-length= on the command line
  2364. if (req_maxlen)
  2365. maxlength = req_maxlen;
  2366. else
  2367. maxlength = 8;
  2368. // "cipher_limit" is the variable which contains the format's
  2369. // maximum password length
  2370. if (maxlength > cipher_limit)
  2371. maxlength = cipher_limit;
  2372. startdiff = 1; // Initial number of different characters to try
  2373. maxdiff = 3; // Maximum number of different characters to try
  2374. /* This defines the character set */
  2375. i = 0;
  2376. c = 0x20;
  2377. while (c <= 0x7e)
  2378. charset[i++] = c++;
  2379. if (maxdiff > (charcount = i))
  2380. maxdiff = i;
  2381. if (maxdiff > maxlength)
  2382. maxdiff = maxlength;
  2383. /*
  2384. * Initialize the variables such that generate() gets to its "next subset"
  2385. * code, which will initialize everything for real.
  2386. */
  2387. subcount = (i = startdiff) - 1;
  2388. while (i--)
  2389. subid[i] = charcount;
  2390. subset[0] = c0 = 0;
  2391. last = maxlength - 1;
  2392. lastid = -1;
  2393. }
  2394. void generate()
  2395. {
  2396. int i;
  2397. /* Handle the typical case specially */
  2398. if (word[last] = subset[++lastid]) return;
  2399. lastid = 0;
  2400. word[i = last] = c0;
  2401. while (i--) { // Have a preceding position?
  2402. if (word[i] = subset[++id[i]]) return;
  2403. id[i] = 0;
  2404. word[i] = c0;
  2405. }
  2406. if (++last < maxlength) { // Next length?
  2407. id[last] = lastid = 0;
  2408. word[last] = c0;
  2409. word[last + 1] = 0;
  2410. return;
  2411. }
  2412. /* Next subset */
  2413. if (subcount) {
  2414. int j;
  2415. i = subcount - 1;
  2416. j = charcount;
  2417. while (++subid[i] >= j) {
  2418. if (i--) {
  2419. j--;
  2420. continue;
  2421. }
  2422. subid[i = 0] = 0;
  2423. subset[++subcount] = 0;
  2424. break;
  2425. }
  2426. } else {
  2427. subid[i = 0] = 0;
  2428. subset[++subcount] = 0;
  2429. }
  2430. subset[i] = charset[subid[i]];
  2431. while (++i < subcount)
  2432. subset[i] = charset[subid[i] = subid[i - 1] + 1];
  2433. if (subcount > maxdiff) {
  2434. word = 0; // Done
  2435. return;
  2436. }
  2437. /*
  2438. * We won't be able to fully use the subset if the length is smaller than the
  2439. * character count. We assume that we've tried all smaller subsets before, so
  2440. * we don't bother with such short lengths.
  2441. */
  2442. if (minlength < subcount)
  2443. last = subcount - 1;
  2444. else
  2445. last = minlength - 1;
  2446. c0 = subset[0];
  2447. i = 0;
  2448. while (i <= last) {
  2449. id[i] = 0;
  2450. word[i++] = c0;
  2451. }
  2452. lastid = 0;
  2453. word[i] = 0;
  2454. }
  2455. # Simple password policy matching: require at least one digit.
  2456. [List.External:AtLeast1-Simple]
  2457. void filter()
  2458. {
  2459. int i, c;
  2460. i = 0;
  2461. while (c = word[i++])
  2462. if (c >= '0' && c <= '9')
  2463. return; // Found at least one suitable character, good
  2464. word = 0; // No suitable characters found, skip this "word"
  2465. }
  2466. # The same password policy implemented in a more efficient and more generic
  2467. # fashion (easy to expand to include other "sufficient" characters as well).
  2468. [List.External:AtLeast1-Generic]
  2469. int mask[0x100];
  2470. void init()
  2471. {
  2472. int c;
  2473. mask[0] = 0; // Terminate the loop in filter() on NUL
  2474. c = 1;
  2475. while (c < 0x100)
  2476. mask[c++] = 1; // Continue looping in filter() on most chars
  2477. c = '0';
  2478. while (c <= '9')
  2479. mask[c++] = 0; // Terminate the loop in filter() on digits
  2480. }
  2481. void filter()
  2482. {
  2483. int i;
  2484. i = -1;
  2485. while (mask[word[++i]])
  2486. continue;
  2487. if (word[i])
  2488. return; // Found at least one suitable character, good
  2489. word = 0; // No suitable characters found, skip this "word"
  2490. }
  2491. # An efficient and fairly generic password policy matcher. The policy to match
  2492. # is specified in the check at the end of filter() and in mask[]. For example,
  2493. # lowercase and uppercase letters may be treated the same by initializing the
  2494. # corresponding mask[] elements to the same value, then adjusting the value to
  2495. # check "seen" for accordingly.
  2496. [List.External:Policy]
  2497. int mask[0x100];
  2498. void init()
  2499. {
  2500. int c;
  2501. mask[0] = 0x100;
  2502. c = 1;
  2503. while (c < 0x100)
  2504. mask[c++] = 0x200;
  2505. c = 'a';
  2506. while (c <= 'z')
  2507. mask[c++] = 1;
  2508. c = 'A';
  2509. while (c <= 'Z')
  2510. mask[c++] = 2;
  2511. c = '0';
  2512. while (c <= '9')
  2513. mask[c++] = 4;
  2514. }
  2515. void filter()
  2516. {
  2517. int i, seen;
  2518. /*
  2519. * This loop ends when we see NUL (sets 0x100) or a disallowed character
  2520. * (sets 0x200).
  2521. */
  2522. i = -1; seen = 0;
  2523. while ((seen |= mask[word[++i]]) < 0x100)
  2524. continue;
  2525. /*
  2526. * We should have seen at least one character of each type (which "add up"
  2527. * to 7) and then a NUL (adds 0x100), but not any other characters (would
  2528. * add 0x200). The length must be 8.
  2529. */
  2530. if (seen != 0x107 || i != 8)
  2531. word = 0; // Does not conform to policy
  2532. }
  2533. # Append the Luhn algorithm digit to arbitrary all-digit strings. Optimized
  2534. # for speed, not for size nor simplicity. The primary optimization trick is to
  2535. # compute the length and four sums in parallel (in two SIMD'ish variables).
  2536. # Then whether the length is even or odd determines which two of the four sums
  2537. # are actually used. Checks for non-digits and for NUL are packed into the
  2538. # SIMD'ish bitmasks as well.
  2539. [List.External:AppendLuhn]
  2540. int map1[0x100], map2[0x1fff];
  2541. void init()
  2542. {
  2543. int i;
  2544. map1[0] = ~0x7fffffff;
  2545. i = 1;
  2546. while (i < 0x100)
  2547. map1[i++] = ~0x7effffff;
  2548. i = -1;
  2549. while (++i < 10)
  2550. map1['0' + i] = i + ((i * 2 % 10 + i / 5) << 12);
  2551. i = -1;
  2552. while (++i < 0x1fff) {
  2553. if (i % 10)
  2554. map2[i] = '9' + 1 - i % 10;
  2555. else
  2556. map2[i] = '0';
  2557. }
  2558. }
  2559. void filter()
  2560. {
  2561. int i, o, e;
  2562. i = o = e = 0;
  2563. while ((o += map1[word[i++]]) >= 0) {
  2564. if ((e += map1[word[i++]]) >= 0)
  2565. continue;
  2566. if (e & 0x01000000)
  2567. return; // Not all-digit, leave unmodified
  2568. word[i--] = 0;
  2569. word[i] = map2[(e & 0xfff) + (o >> 12)];
  2570. return;
  2571. }
  2572. if (o & 0x01000000)
  2573. return; // Not all-digit, leave unmodified
  2574. word[i--] = 0;
  2575. word[i] = map2[(o & 0xfff) + (e >> 12)];
  2576. }
  2577. # Trivial Rotate function, which rotates letters in a word
  2578. # by a given number of places (like 13 in case of ROT13).
  2579. # Words which don't contain any letters (and thus wouldn't be changed
  2580. # by this filter) are skipped, because these unchanged words probably
  2581. # should have been tried before trying a mangled version.
  2582. [List.External_base:Filter_Rotate]
  2583. int rot; // The number of places to rotate each letter in a word
  2584. void filter()
  2585. {
  2586. int i, j, c;
  2587. i = 0;
  2588. j = 0; // j counts the number of changed characters
  2589. while (c = word[i]) {
  2590. if (c >= 'a' && c <= 'z') {
  2591. c = c - 26 + rot;
  2592. if (c < 'a') c += 26;
  2593. word[i] = c;
  2594. j++;
  2595. } else if (c >= 'A' && c <= 'Z' ) {
  2596. c = c - 26 + rot;
  2597. if (c < 'A') c += 26;
  2598. word[i] = c;
  2599. j++;
  2600. }
  2601. i++;
  2602. }
  2603. if (j == 0)
  2604. // Noting changed. Reject this word.
  2605. word = 0;
  2606. }
  2607. # ROT13 Example
  2608. [List.External:Filter_ROT13]
  2609. .include [List.External_base:Filter_Rotate]
  2610. void init()
  2611. {
  2612. // Just in case someone wants to "rotate" by other values,
  2613. // adjust the value of the rot variable
  2614. // (may be in a copied external mode):
  2615. // 13: "abcABCxyzXYZ" -> "nopNOPklmKLM"
  2616. // 1: "abcABCxyzXYZ" -> "bcdBCDyzaYZA"
  2617. // 25: "abcABCxyzXYZ" -> "zabZABwxyWXY"
  2618. // -1: "abcABCxyzXYZ" -> "zabZABwxyWXY"
  2619. // and so on
  2620. // Allowed range: -25 <= rot <= -1, or 1 <= rot <= 25
  2621. rot = 13;
  2622. // Don't change the following statement.
  2623. // It is supposed to "sanitize" the value to be in the
  2624. // range
  2625. rot = (rot + 26) % 26;
  2626. }
  2627. # Trivial parallel processing example (obsoleted by the "--node" option)
  2628. [List.External:Parallel]
  2629. /*
  2630. * This word filter makes John process some of the words only, for running
  2631. * multiple instances on different CPUs. It can be used with any cracking
  2632. * mode except for "single crack". Note: this is not a good solution, but
  2633. * is just an example of what can be done with word filters.
  2634. */
  2635. int node, total; // This node's number, and node count
  2636. int number; // Current word number
  2637. void init()
  2638. {
  2639. node = 1; total = 2; // Node 1 of 2, change as appropriate
  2640. number = node - 1; // Speedup the filter a bit
  2641. }
  2642. void filter()
  2643. {
  2644. if (number++ % total) // Word for a different node?
  2645. word = 0; // Yes, skip it
  2646. }
  2647. # Interrupt the cracking session after "max" words tried
  2648. [List.External:AutoAbort]
  2649. int max; // Maximum number of words to try
  2650. int number; // Current word number
  2651. void init()
  2652. {
  2653. max = 1000;
  2654. number = 0;
  2655. }
  2656. void filter()
  2657. {
  2658. if (++number > max)
  2659. abort = 1; // Interrupt the cracking session
  2660. }
  2661. # Print the status line after every "interval" words tried
  2662. [List.External:AutoStatus]
  2663. int interval; // How often to print the status
  2664. int number; // Current word number
  2665. void init()
  2666. {
  2667. interval = 1000;
  2668. number = 0;
  2669. }
  2670. void filter()
  2671. {
  2672. if (number++ % interval)
  2673. return;
  2674. status = 1; // Print the status line
  2675. }
  2676. # dumb-force UTF-16, in an external file
  2677. .include "$JOHN/dumb16.conf"
  2678. # dumb-force UTF-32, in an external file
  2679. .include "$JOHN/dumb32.conf"
  2680. # repeats UTF-16, in an external file
  2681. .include "$JOHN/repeats16.conf"
  2682. # repeats UTF-32, in an external file
  2683. .include "$JOHN/repeats32.conf"
  2684. # Dynamic ($dynamic_n$) scripting code, in an external file
  2685. # also shows/tests that .include <file> works the same as .include "$JOHN/file"
  2686. .include <dynamic.conf>
  2687. # Regex alphabets
  2688. .include <regex_alphabets.conf>
  2689. # include john.local.conf (defaults to being empty, but never overwritten)
  2690. .include "$JOHN/john.local.conf"
  2691. # End of john.conf file.
  2692. # Keep this comment, and blank line above it, to make sure a john.local.conf
  2693. # that does not end with \n is properly loaded.