PageRenderTime 63ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/run/john.conf

https://bitbucket.org/lcirvin/cse465-project
Config | 1616 lines | 1413 code | 203 blank | 0 comment | 0 complexity | 0f77383dad849a2c49bf89205fe7ff43 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. #
  2. # This file is part of John the Ripper password cracker,
  3. # Copyright (c) 1996-2006,2008-2012 by Solar Designer
  4. #
  5. # ...with changes in the jumbo patch, by various authors
  6. #
  7. # The [Options] section is for general options only.
  8. # Note that MPI specific options have been moved
  9. # to [Options.MPI]
  10. # There is also a new section [Options.OpenCL]
  11. # for OpenCL specific options
  12. # Default settings for Markov mode have been moved
  13. # to [Markov.Default], but you can define other
  14. # Markov modes as well, see ../doc/MARKOV
  15. [Options]
  16. # Wordlist file name, to be used in batch mode
  17. Wordlist = $JOHN/password.lst
  18. # Use idle cycles only
  19. Idle = Y
  20. # Crash recovery file saving delay in seconds
  21. Save = 600
  22. # Beep when a password is found (who needs this anyway?)
  23. Beep = N
  24. # Time formatting string used in status ETA.
  25. # %c means 'local' specific canonical form, such as:
  26. # 05/06/11 18:10:34
  27. #
  28. # Other examples
  29. # %d/%m/%y %H:%M (day/mon/year hour:min)
  30. # %m/%d/%y %H:%M (mon/day/year hour:min)
  31. # %Y-%m-%d %H:%M (ISO 8601 style, 2011-05-06 18:10)
  32. TimeFormat = %c
  33. # Threshold for showing ETA, in percent. ETA will not be
  34. # shown if progress is less than this. If too low, early
  35. # reported figures will be less accurate (default 0.05%)
  36. ETAthreshold = 0.05%
  37. # Emit a status line whenever a password is cracked (this is the same as
  38. # passing the --crack-status option flag to john). NOTE: if this is set
  39. # to true here, --crack-status will toggle it back to false.
  40. CrackStatus = N
  41. # When printing status, show number of candidates tried (eg. 1/43210 for one
  42. # guess out of 43 thousand candidates). Note that the number is not equal to
  43. # "words tried" but rather "words x hash" combinations so if you are attacking
  44. # 1000 hashes, "43210" means you have tried about 43 words from your wordlist.
  45. StatusShowCandidates = N
  46. # Always report (to screen and log) cracked passwords as UTF-8, regardless of
  47. # input encoding. This is recommended if you have your terminal set for UTF-8.
  48. AlwaysReportUTF8 = N
  49. # Always store Unicode (UTF-16) passwords as UTF-8 in john.pot, regardless
  50. # of input encoding. This prevents john.pot from being filled with mixed
  51. # and eventually unknown encodings. This is recommended if you have your
  52. # terminal set for UTF-8.
  53. UnicodeStoreUTF8 = N
  54. # Always report/store non-Unicode formats as UTF-8, regardless of input
  55. # encoding. This is NOT recommended unless you REALLY understand the
  56. # implications. The actual codepage that was used is not stored anywhere
  57. # except in the log file.
  58. CPstoreUTF8 = N
  59. # Write cracked passwords to the log file (default is just the user name)
  60. LogCrackedPasswords = N
  61. [Options:MPI]
  62. # Automagically disable OMP if MPI is used (set to N if
  63. # you want to run one MPI process per multi-core host)
  64. MPIOMPmutex = Y
  65. # Print a notice if disabling OMP (when MPIOMPmutex = Y)
  66. # or when running OMP and MPI at the same time
  67. MPIOMPverbose = Y
  68. [Options:OpenCL]
  69. # Set default OpenCL platform and/or device. Command line options will
  70. # override these. If neither is set, we will search for a GPU or fall-back
  71. # to platform 0, device 0.
  72. #Platform = 0
  73. #Device = 0
  74. # Format-specific settings for Local Work Size and Global Work Size call.
  75. # An LWS or GWS of zero will initiate auto enumeration. The environment
  76. # variables LWS and/or GWS will override these figures.
  77. #ssha_LWS = 512
  78. #ssha_GWS = 8192
  79. # For RAR format. MaxDuration (seconds) can be used to limit run time in case
  80. # there is a watch-dog time-out.
  81. #rar_LWS = 128
  82. #rar_GWS = 8192
  83. rar_MaxDuration = 5
  84. # For crypt SHA-512.
  85. #sha512crypt_LWS = 64
  86. #sha512crypt_GWS = 8192
  87. # Markov modes, see ../doc/MARKOV for more information
  88. [Markov:Default]
  89. # Default Markov mode settings
  90. #
  91. # Statsfile cannot be specified on the command line, so
  92. # specifying it here is mandatory
  93. Statsfile = $JOHN/stats
  94. # MkvLvl and MkvMaxLen should also be specified here, as a fallback for
  95. # --markov usage without specifying LEVEL and/or LENGTH on the command line
  96. MkvLvl = 200
  97. MkvMaxLen = 12
  98. # MkvMinLvl and MkvMinLen should not be specified at all in [Markov:Default],
  99. # or they should be equal to 0 (which is the default if not specified.
  100. # MkvMinLvl and MkvMinLen can be used in other Markov mode sections
  101. # except [Markov:Default]
  102. ; MkvMinLvl = 0
  103. ; MkvMinLen = 0
  104. # A user defined character class is named with a single digit, ie. 0..9. After
  105. # the equal-sign, just list all characters that this class should match. You
  106. # can specify ranges within brackets, much like pre-processor ranges in rules.
  107. # BEWARE of encoding if using non-ASCII characters. If you put UTF-8 characters
  108. # here, it will *not* work! You must use a singlebyte encoding and it should
  109. # be the same here as you intend to use for your dictionary.
  110. # You can however put characters here in \xA3 format (for codepoint 0xA3 - in
  111. # many iso-8859-x codepages that would mean a pound sign). This works in ranges
  112. # too but NOTE that this syntax does NOT work in any other section of john.conf
  113. #
  114. # This is a couple of example classes:
  115. # ?0 matches (one version of) base64 characters
  116. # ?1 matches hex digits
  117. # ?2 matches the TAB character (never try to use \x00!)
  118. [UserClasses]
  119. 0 = [a-zA-Z0-9/.]
  120. 1 = [0-9a-fA-F]
  121. 2 = \x09
  122. # "Single crack" mode rules
  123. [List.Rules:Single]
  124. # Simple rules come first...
  125. :
  126. -s x**
  127. -c (?a c Q
  128. -c l Q
  129. -s-c x** /?u l
  130. # These were not included in crackers I've seen, but are pretty efficient,
  131. # so I include them near the beginning
  132. >6 '6
  133. >7 '7 l
  134. -c >6 '6 /?u l
  135. >5 '5
  136. # Weird order, eh? Can't do anything about it, the order is based on the
  137. # number of successful cracks...
  138. <* d
  139. r c
  140. -c <* (?a d c
  141. -c >5 '5 /?u l
  142. -c u Q
  143. -c )?a r l
  144. -[:c] <* !?A \p1[lc] p
  145. -c <* c Q d
  146. -c >7 '7 /?u
  147. >4 '4 l
  148. -c <+ (?l c r
  149. -c <+ )?l l Tm
  150. >3 '3
  151. -c >4 '4 /?u
  152. -c >3 '3 /?u l
  153. -c u Q r
  154. <* d M 'l f Q
  155. -c <* l Q d M 'l f Q
  156. # About 50% of single-mode-crackable passwords get cracked by now...
  157. # >2 x12 ... >8 x18
  158. >[2-8] x1\1
  159. >9 \[
  160. # >3 x22 ... >9 x28
  161. >[3-9] x2\p[2-8]
  162. # >4 x32 ... >9 x37
  163. >[4-9] x3\p[2-7]
  164. # >2 x12 /?u l ... >8 x18 /?u l
  165. -c >[2-8] x1\1 /?u l
  166. -c >9 \[ /?u l
  167. # >3 x22 /?u l ... >9 x28 /?u l
  168. -c >[3-9] x2\p[2-8] /?u l
  169. # >4 x32 /?u l ... >9 x37 /?u l
  170. -c >[4-9] x3\p[2-7] /?u l
  171. # Now to the suffix stuff...
  172. <* l $[1-9!0a-rt-z"-/:-@\[-`{-~]
  173. -c <* (?a c $[1-9!0a-rt-z"-/:-@\[-`{-~]
  174. -[:c] <* !?A (?\p1[za] \p1[lc] $s M 'l p Q X0z0 'l $s
  175. -[:c] <* /?A (?\p1[za] \p1[lc] $s
  176. <* l r $[1-9!]
  177. -c <* /?a u $[1-9!]
  178. -[:c] <- (?\p1[za] \p1[lc] Az"'s"
  179. -[:c] <- (?\p1[za] \p1[lc] Az"!!"
  180. -[:c] (?\p1[za] \p1[lc] $! <- Az"!!"
  181. # Removing vowels...
  182. -[:c] /?v @?v >2 (?\p1[za] \p1[lc]
  183. /?v @?v >2 <* d
  184. # crack -> cracked, crack -> cracking
  185. <* l [PI]
  186. -c <* l [PI] (?a c
  187. # mary -> marie
  188. -[:c] <* (?\p1[za] \p1[lc] )y omi $e
  189. # marie -> mary
  190. -[:c] <* (?\p1[za] \p1[lc] )e \] )i val1 oay
  191. # The following are some 3l33t rules
  192. -[:c] l /[aelos] s\0\p[4310$] (?\p1[za] \p1[:c]
  193. -[:c] l /a /[elos] sa4 s\0\p[310$] (?\p1[za] \p1[:c]
  194. -[:c] l /e /[los] se3 s\0\p[10$] (?\p1[za] \p1[:c]
  195. -[:c] l /l /[os] sl1 s\0\p[0$] (?\p1[za] \p1[:c]
  196. -[:c] l /o /s so0 ss$ (?\p1[za] \p1[:c]
  197. -[:c] l /a /e /[los] sa4 se3 s\0\p[10$] (?\p1[za] \p1[:c]
  198. -[:c] l /a /l /[os] sa4 sl1 s\0\p[0$] (?\p1[za] \p1[:c]
  199. -[:c] l /a /o /s sa4 so0 ss$ (?\p1[za] \p1[:c]
  200. -[:c] l /e /l /[os] se3 sl1 s\0\p[0$] (?\p1[za] \p1[:c]
  201. -[:c] l /[el] /o /s s\0\p[31] so0 ss$ (?\p1[za] \p1[:c]
  202. -[:c] l /a /e /l /[os] sa4 se3 sl1 s\0\p[0$] (?\p1[za] \p1[:c]
  203. -[:c] l /a /[el] /o /s sa4 s\0\p[31] so0 ss$ (?\p1[za] \p1[:c]
  204. -[:c] l /e /l /o /s se3 sl1 so0 ss$ (?\p1[za] \p1[:c]
  205. -[:c] l /a /e /l /o /s sa4 se3 sl1 so0 ss$ (?\p1[za] \p1[:c]
  206. # Now to the prefix stuff...
  207. l ^[1a-z2-90]
  208. -c l Q ^[A-Z]
  209. ^[A-Z]
  210. l ^["-/:-@\[-`{-~]
  211. -[:c] <9 (?a \p1[lc] A0"[tT]he"
  212. -[:c] <9 (?a \p1[lc] A0"[aA]my"
  213. -[:c] <9 (?a \p1[lc] A0"[mdMD]r"
  214. -[:c] <9 (?a \p1[lc] A0"[mdMD]r."
  215. -[:c] <9 (?a \p1[lc] A0"__"
  216. <- !?A l p ^[240-9]
  217. # Some word pair rules...
  218. # johnsmith -> JohnSmith, johnSmith
  219. -p-c (?a 2 (?a c 1 [cl]
  220. # JohnSmith -> john smith, john_smith, john-smith
  221. -p 1 <- $[ _\-] + l
  222. # JohnSmith -> John smith, John_smith, John-smith
  223. -p-c 1 <- (?a c $[ _\-] 2 l
  224. # JohnSmith -> john Smith, john_Smith, john-Smith
  225. -p-c 1 <- l $[ _\-] 2 (?a c
  226. # johnsmith -> John Smith, John_Smith, John-Smith
  227. -p-c 1 <- (?a c $[ _\-] 2 (?a c
  228. # Applying different simple rules to each of the two words
  229. -p-[c:] 1 \p1[ur] 2 l
  230. -p-c 2 (?a c 1 [ur]
  231. -p-[c:] 1 l 2 \p1[ur]
  232. -p-c 1 (?a c 2 [ur]
  233. # jsmith -> smithj, etc...
  234. -[:c] (?a \p1[lc] [{}]
  235. -[:c] (?a \p1[lc] [{}] \0
  236. # Toggle case...
  237. -c <+ )?u l Tm
  238. -c T0 Q M c Q l Q u Q C Q X0z0 'l
  239. -c T[1-9A-E] Q M l Tm Q C Q u Q l Q c Q X0z0 'l
  240. -c l Q T[1-9A-E] Q M T\0 Q l Tm Q C Q u Q X0z0 'l
  241. -c >2 <G %2?a [lu] T0 M T2 T4 T6 T8 TA TC TE Q M l Tm Q X0z0 'l
  242. -c >2 /?l /?u t Q M c Q C Q l Tm Q X0z0 'l
  243. # Deleting chars...
  244. >[2-8] D\p[1-7]
  245. >[8-9A-E] D\1
  246. -c /?u >[2-8] D\p[1-7] l
  247. -c /?u >[8-9A-E] D\1 l
  248. =1?a \[ M c Q
  249. -c (?a >[1-9A-E] D\1 c
  250. # Inserting a dot...
  251. -[:c] >3 (?a \p1[lc] i[12].
  252. # More suffix stuff...
  253. <- l Az"[190][0-9]"
  254. -c <- (?a c Az"[190][0-9]"
  255. <- l Az"[782][0-9]"
  256. -c <- (?a c Az"[782][0-9]"
  257. <* l $[A-Z]
  258. -c <* (?a c $[A-Z]
  259. # cracking -> CRACKiNG
  260. -c u /I sIi
  261. # Crack96 -> cRACK96
  262. %2?a C Q
  263. # Crack96 -> cRACK(^
  264. /?A S Q
  265. # Crack96 -> CRaCK96
  266. -c /?v V Q
  267. # Really weird charset conversions, like "england" -> "rmh;smf"
  268. :[RL] Q
  269. l Q [RL]
  270. -c (?a c Q [RL]
  271. :[RL] \0 Q
  272. # Both prefixing and suffixing...
  273. <- l ^[1!@#$%^&*\-=_+.?|:'"] $\1
  274. <- l ^[({[<] $\p[)}\]>]
  275. # The rest of two-digit suffix stuff, less common numbers...
  276. <- l Az"[63-5][0-9]"
  277. -c <- (?a c Az"[63-5][0-9]"
  278. # Some multi-digit numbers...
  279. -[:c] (?a \p1[lc] Az"007" <+
  280. -[:c] (?a \p1[lc] Az"123" <+
  281. -[:c] (?a \p1[lc] Az"[0-9]\0\0" <+
  282. -[:c] (?a \p1[lc] Az"1234" <+
  283. -[:c] (?a \p1[lc] Az"[0-9]\0\0\0" <+
  284. -[:c] (?a \p1[lc] Az"12345" <+
  285. -[:c] (?a \p1[lc] Az"[0-9]\0\0\0\0" <+
  286. -[:c] (?a \p1[lc] Az"123456" <+
  287. -[:c] (?a \p1[lc] Az"[0-9]\0\0\0\0\0" <+
  288. # Some [birth] years...
  289. l Az"19[7-96-0]" <+ >-
  290. l Az"20[01]" <+ >-
  291. l Az"19[7-9][0-9]" <+
  292. l Az"20[01][0-9]" <+
  293. l Az"19[6-0][9-0]" <+
  294. [List.Rules:Extra]
  295. # Insert/overstrike some characters...
  296. !?A >[1-6] l i\0[a-z]
  297. !?A l o0[a-z]
  298. !?A >[1-7] l o\0[a-z]
  299. # Toggle case everywhere (up to length 8), assuming that certain case
  300. # combinations were already tried.
  301. -c T1 Q M T0 Q
  302. -c T2 Q M T[z0] T[z1] Q
  303. -c T3 Q M T[z0] T[z1] T[z2] Q
  304. -c T4 Q M T[z0] T[z1] T[z2] T[z3] Q
  305. -c T5 Q M T[z0] T[z1] T[z2] T[z3] T[z4] Q
  306. -c T6 Q M T[z0] T[z1] T[z2] T[z3] T[z4] T[z5] Q
  307. -c T7 Q M T[z0] T[z1] T[z2] T[z3] T[z4] T[z5] T[z6] Q
  308. # Very slow stuff...
  309. l Az"[1-90][0-9][0-9]" <+
  310. -c (?a c Az"[1-90][0-9][0-9]" <+
  311. <[\-9] l A\p[z0]"[a-z][a-z]"
  312. <- l ^[a-z] $[a-z]
  313. # Wordlist mode rules
  314. [List.Rules:Wordlist]
  315. # Try words as they are
  316. :
  317. # Lowercase every pure alphanumeric word
  318. -c >3 !?X l Q
  319. # Capitalize every pure alphanumeric word
  320. -c (?a >2 !?X c Q
  321. # Lowercase and pluralize pure alphabetic words
  322. <* >2 !?A l p
  323. # Lowercase pure alphabetic words and append '1'
  324. <* >2 !?A l $1
  325. # Capitalize pure alphabetic words and append '1'
  326. -c <* >2 !?A c $1
  327. # Duplicate reasonably short pure alphabetic words (fred -> fredfred)
  328. <7 >1 !?A l d
  329. # Lowercase and reverse pure alphabetic words
  330. >3 !?A l M r Q
  331. # Prefix pure alphabetic words with '1'
  332. >2 !?A l ^1
  333. # Uppercase pure alphanumeric words
  334. -c >2 !?X u Q M c Q u
  335. # Lowercase pure alphabetic words and append a digit or simple punctuation
  336. <* >2 !?A l $[2!37954860.?]
  337. # Words containing punctuation, which is then squeezed out, lowercase
  338. /?p @?p >3 l
  339. # Words with vowels removed, lowercase
  340. /?v @?v >3 l
  341. # Words containing whitespace, which is then squeezed out, lowercase
  342. /?w @?w >3 l
  343. # Capitalize and duplicate short pure alphabetic words (fred -> FredFred)
  344. -c <7 >1 !?A c d
  345. # Capitalize and reverse pure alphabetic words (fred -> derF)
  346. -c <+ >2 !?A c r
  347. # Reverse and capitalize pure alphabetic words (fred -> Derf)
  348. -c >2 !?A l M r Q c
  349. # Lowercase and reflect pure alphabetic words (fred -> fredderf)
  350. <7 >1 !?A l d M 'l f Q
  351. # Uppercase the last letter of pure alphabetic words (fred -> freD)
  352. -c <+ >2 !?A l M r Q c r
  353. # Prefix pure alphabetic words with '2' or '4'
  354. >2 !?A l ^[24]
  355. # Capitalize pure alphabetic words and append a digit or simple punctuation
  356. -c <* >2 !?A c $[2!3957468.?0]
  357. # Prefix pure alphabetic words with digits
  358. >2 !?A l ^[379568]
  359. # Capitalize and pluralize pure alphabetic words of reasonable length
  360. -c <* >2 !?A c p
  361. # Lowercase/capitalize pure alphabetic words of reasonable length and convert:
  362. # crack -> cracked, crack -> cracking
  363. -[:c] <* >2 !?A \p1[lc] M [PI] Q
  364. # Try the second half of split passwords
  365. -s x**
  366. -s-c x** M l Q
  367. # Case toggler for cracking MD4-based NTLM hashes (with the contributed patch)
  368. # given already cracked DES-based LM hashes.
  369. # Rename this section to [List.Rules:Wordlist] to activate it.
  370. [List.Rules:NT]
  371. :
  372. -c T0Q
  373. -c T1QT[z0]
  374. -c T2QT[z0]T[z1]
  375. -c T3QT[z0]T[z1]T[z2]
  376. -c T4QT[z0]T[z1]T[z2]T[z3]
  377. -c T5QT[z0]T[z1]T[z2]T[z3]T[z4]
  378. -c T6QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]
  379. -c T7QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]
  380. -c T8QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]
  381. -c T9QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]
  382. -c TAQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]
  383. -c TBQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]T[zA]
  384. -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]
  385. -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]
  386. # For Single Mode against fast hashes
  387. [List.Rules:Single-Extra]
  388. .include [List.Rules:Single]
  389. .include [List.Rules:Extra]
  390. # For Wordlist mode and very fast hashes
  391. [List.Rules:Jumbo]
  392. .include [List.Rules:Wordlist]
  393. .include [List.Rules:Single]
  394. .include [List.Rules:Extra]
  395. .include [List.Rules:NT]
  396. # Incremental modes
  397. [Incremental:All]
  398. File = $JOHN/all.chr
  399. MinLen = 0
  400. MaxLen = 8
  401. CharCount = 95
  402. [Incremental:All15]
  403. .include [Incremental:All]
  404. MaxLen = 5
  405. [Incremental:All6]
  406. .include [Incremental:All]
  407. MaxLen = 6
  408. MinLen = 6
  409. [Incremental:All7]
  410. .include [Incremental:All]
  411. MinLen = 7
  412. MaxLen = 7
  413. [Incremental:All8]
  414. .include [Incremental:All]
  415. MinLen = 8
  416. [Incremental:Alpha]
  417. File = $JOHN/alpha.chr
  418. MinLen = 1
  419. MaxLen = 8
  420. CharCount = 26
  421. [Incremental:Digits]
  422. File = $JOHN/digits.chr
  423. MinLen = 1
  424. MaxLen = 8
  425. CharCount = 10
  426. [Incremental:Digits8]
  427. File = $JOHN/digits.chr
  428. MinLen = 8
  429. MaxLen = 8
  430. CharCount = 10
  431. [Incremental:Alnum]
  432. File = $JOHN/alnum.chr
  433. MinLen = 1
  434. MaxLen = 8
  435. CharCount = 36
  436. [Incremental:LanMan]
  437. File = $JOHN/lanman.chr
  438. MinLen = 0
  439. MaxLen = 7
  440. CharCount = 69
  441. # Some pre-defined word filters
  442. [List.External:Filter_Alpha]
  443. void filter()
  444. {
  445. int i, c;
  446. i = 0;
  447. while (c = word[i++])
  448. if (c < 'a' || c > 'z') {
  449. word = 0; return;
  450. }
  451. }
  452. [List.External:Filter_Digits]
  453. void filter()
  454. {
  455. int i, c;
  456. i = 0;
  457. while (c = word[i++])
  458. if (c < '0' || c > '9') {
  459. word = 0; return;
  460. }
  461. }
  462. [List.External:Filter_Alnum]
  463. void filter()
  464. {
  465. int i, c;
  466. i = 0;
  467. while (c = word[i++])
  468. if ((c < 'a' || c > 'z') && (c < '0' || c > '9')) {
  469. word = 0; return;
  470. }
  471. }
  472. [List.External:Filter_No_Cap_or_Symbols]
  473. void filter()
  474. {
  475. int i, c;
  476. i = 0;
  477. while (c = word[i++])
  478. if ((c < 'a' || c > 'z') && (c < '0' || c > '9')) {
  479. return;
  480. }
  481. word = 0; return;
  482. }
  483. [List.External:Filter_LanMan]
  484. void filter()
  485. {
  486. int i, c;
  487. word[7] = 0; // Truncate at 7 characters
  488. i = 0; // Convert to uppercase
  489. while (c = word[i]) {
  490. if (c >= 'a' && c <= 'z') word[i] &= 0xDF;
  491. i++;
  492. }
  493. }
  494. # A simple cracker for LM hashes
  495. [List.External:LanMan]
  496. int length; // Current length
  497. void init()
  498. {
  499. word[0] = 'A' - 1; // Start with "A"
  500. word[length = 1] = 0;
  501. }
  502. void generate()
  503. {
  504. int i;
  505. i = length - 1; // Start from the last character
  506. while (++word[i] > 'Z') // Try to increase it
  507. if (i) // Overflow here, any more positions?
  508. word[i--] = 'A'; // Yes, move to the left, and repeat
  509. else // No
  510. if (length < 7) {
  511. word[i = ++length] = 0; // Switch to the next length
  512. while (i--)
  513. word[i] = 'A';
  514. return;
  515. } else {
  516. word = 0; return; // We're done
  517. }
  518. }
  519. void restore()
  520. {
  521. length = 0; // Calculate the length
  522. while (word[length]) length++;
  523. }
  524. # Simple and well-commented, yet useful external mode example
  525. # NOTE, this has now been 'split' up into a base extern, 'base', and then
  526. # multiple External:double functions. It still has same code as original
  527. # double, but now can be easily expanded.
  528. [List.External_base:Double]
  529. /*
  530. * This cracking mode tries all the possible duplicated lowercase alphabetic
  531. * "words" of up to 8 characters long. Since word halves are the same, it
  532. * only has to try about 500,000 words.
  533. */
  534. /* Global variables: current length and word */
  535. /* make this 'long' enough for other externs that include this one */
  536. /* (up to 14 bytes long) We currently have double and double10 defined, */
  537. /* but could add more, up to double14 */
  538. int length, current[15], max;
  539. /* this new 'type' variable, is used to tell double what character set to
  540. * use. It can use the original (alpha). If type is 0 (i.e. unset), then
  541. * a-z (alpha) character set is used. If type is '0' (a zero ascii byte)
  542. * then alnum charset is used, a-z0-9. If type is a space char, then all
  543. * charset is used [space - tilde] or [ -~]. This required setting the
  544. * type var in the init() of alnum or all doubles (it can be left unset
  545. * in the alpha versions). It also requires some if logic in generate.
  546. * other than that, it works the same, with almost no performance hit */
  547. int type;
  548. /* Generates a new word */
  549. void generate()
  550. {
  551. int i;
  552. /* Export last generated word, duplicating it at the same time; here "word"
  553. * is a pre-defined external variable. */
  554. word[(i = length) << 1] = 0;
  555. while (i--) word[length + i] = word[i] = current[i];
  556. /* Generate a new word */
  557. i = length - 1; // Start from the last character
  558. if (type == 0) {
  559. /* alpha */
  560. while (++current[i] > 'z') // Try to increase it
  561. if (i) // Overflow here, any more positions?
  562. current[i--] = 'a'; // Yes, move to the left, and repeat
  563. else { // No
  564. current = 0; // Request a length switch
  565. break; // Break out of the loop
  566. }
  567. } else if (type == '0') {
  568. /* alnum */
  569. if (current[i] == 'z') current[i] = '0'-1;
  570. while (++current[i] == '9') { // Try to increase it
  571. if (i) // Overflow here, any more positions?
  572. current[i--] = 'a'; // Yes, move to the left, and repeat
  573. else { // No
  574. current = 0; // Request a length switch
  575. break; // Break out of the loop
  576. }
  577. if (current[i] == 'z') current[i] = '0'-1;
  578. }
  579. } else if (type == ' ') {
  580. /* all */
  581. while (++current[i] > '~') { // Try to increase it
  582. if (i) // Overflow here, any more positions?
  583. current[i--] = ' '; // Yes, move to the left, and repeat
  584. else { // No
  585. current = 0; // Request a length switch
  586. break; // Break out of the loop
  587. }
  588. }
  589. }
  590. /* else ????? wtf?? */
  591. /* Switch to the next length, unless we were generating 8 character long
  592. * words already. */
  593. if (!current && length < max) {
  594. i = ++length;
  595. if (type == 0 || type == '0')
  596. while (i--) current[i] = 'a';
  597. else if (type == ' ')
  598. while (i--) current[i] = ' ';
  599. }
  600. }
  601. /* Called when restoring an interrupted session */
  602. void restore()
  603. {
  604. int i;
  605. /* Import the word back */
  606. i = 0;
  607. while (current[i] = word[i]) i++;
  608. /* ...and calculate the half-word length */
  609. length = i >> 1;
  610. }
  611. [List.External:Double]
  612. .include [List.External_base:Double]
  613. /* Called at startup to initialize the global variables */
  614. void init()
  615. {
  616. int i;
  617. i = length = 2; // Start with 4 character long words
  618. while (i--) current[i] = 'a'; // Set our half-word to "aa"
  619. max = 4;
  620. }
  621. [List.External:Double_alnum]
  622. .include [List.External_base:Double]
  623. /* Called at startup to initialize the global variables */
  624. void init()
  625. {
  626. int i;
  627. i = length = 2; // Start with 4 character long words
  628. while (i--) current[i] = 'a'; // Set our half-word to "aa"
  629. max = 4;
  630. type = '0';
  631. }
  632. [List.External:Double_all]
  633. .include [List.External_base:Double]
  634. void init()
  635. {
  636. int i;
  637. i = length = 2; // Start with 4 character long words
  638. while (i--) current[i] = ' '; // Set our half-word to " "
  639. max = 4;
  640. type = ' ';
  641. }
  642. [List.External:Double10]
  643. .include [List.External_base:Double]
  644. /* Called at startup to initialize the global variables */
  645. void init()
  646. {
  647. int i;
  648. i = length = 5; // Start with 10 character long words (we assume double has already been run)
  649. while (i--) current[i] = 'a'; // Set our half-word to "aaaaa"
  650. max = 5;
  651. }
  652. [List.External:Double10_alnum]
  653. .include [List.External_base:Double]
  654. void init()
  655. {
  656. int i;
  657. i = length = 5; // Start with 4 character long words
  658. while (i--) current[i] = 'a'; // Set our half-word to "aaaaa"
  659. max = 5;
  660. type = '0';
  661. }
  662. # Strip 0.5 ("Secure Tool for Recalling Important Passwords") cracker,
  663. # based on analysis done by Thomas Roessler and Ian Goldberg. This will
  664. # crack passwords you may have generated with Strip; other uses of Strip
  665. # are unaffected.
  666. [List.External:Strip]
  667. int minlength, maxlength, mintype, maxtype;
  668. int crack_seed, length, type;
  669. int count, charset[128];
  670. void init()
  671. {
  672. int c;
  673. /* Password lengths to try; Strip can generate passwords of 4 to 16
  674. * characters, but traditional crypt(3) hashes are limited to 8. */
  675. minlength = 4; // 4
  676. maxlength = 8; // 16
  677. /* Password types to try (Numeric, Alpha-Num, Alpha-Num w/ Meta). */
  678. mintype = 0; // 0
  679. maxtype = 2; // 2
  680. crack_seed = 0x10000;
  681. length = minlength - 1;
  682. type = mintype;
  683. count = 0;
  684. c = '0'; while (c <= '9') charset[count++] = c++;
  685. }
  686. void generate()
  687. {
  688. int seed, random;
  689. int i, c;
  690. if (crack_seed > 0xffff) {
  691. crack_seed = 0;
  692. if (++length > maxlength) {
  693. length = minlength;
  694. if (++type > maxtype) {
  695. word[0] = 0;
  696. return;
  697. }
  698. }
  699. count = 10;
  700. if (type >= 1) {
  701. c = 'a'; while (c <= 'f') charset[count++] = c++;
  702. c = 'h'; while (c <= 'z') charset[count++] = c++;
  703. c = 'A'; while (c <= 'Z') charset[count++] = c++;
  704. }
  705. if (type == 2) {
  706. charset[count++] = '!';
  707. c = '#'; while (c <= '&') charset[count++] = c++;
  708. c = '('; while (c <= '/') charset[count++] = c++;
  709. c = '<'; while (c <= '>') charset[count++] = c++;
  710. charset[count++] = '?'; charset[count++] = '@';
  711. charset[count++] = '['; charset[count++] = ']';
  712. charset[count++] = '^'; charset[count++] = '_';
  713. c = '{'; while (c <= '~') charset[count++] = c++;
  714. }
  715. }
  716. seed = (crack_seed++ << 16 >> 16) * 22695477 + 1;
  717. i = 0;
  718. while (i < length) {
  719. random = ((seed = seed * 22695477 + 1) >> 16) & 0x7fff;
  720. word[i++] = charset[random % count];
  721. }
  722. word[i] = 0;
  723. }
  724. # Try sequences of adjacent keys on a keyboard as candidate passwords
  725. [List.External:Keyboard]
  726. int maxlength, length; // Maximum password length to try, current length
  727. int fuzz; // The desired "fuzz factor", either 0 or 1
  728. int id[15]; // Current character indices for each position
  729. int m[0x800], mc[0x100];// The keys matrix, counts of adjacent keys
  730. int f[0x40], fc; // Characters for the first position, their count
  731. void init()
  732. {
  733. int minlength;
  734. int i, j, c, p;
  735. int k[0x40];
  736. minlength = 1; // Initial password length to try
  737. maxlength = 15; // Maximum password length to try, up to 15
  738. fuzz = 1; // "Fuzz factor", set to 0 for much quicker runs
  739. /*
  740. * This defines the keyboard layout, by default for a QWERTY keyboard.
  741. */
  742. i = 0; while (i < 0x40) k[i++] = 0;
  743. k[0] = '`';
  744. i = 0; while (++i <= 9) k[i] = '0' + i;
  745. k[10] = '0'; k[11] = '-'; k[12] = '=';
  746. k[0x11] = 'q'; k[0x12] = 'w'; k[0x13] = 'e'; k[0x14] = 'r';
  747. k[0x15] = 't'; k[0x16] = 'y'; k[0x17] = 'u'; k[0x18] = 'i';
  748. k[0x19] = 'o'; k[0x1a] = 'p'; k[0x1b] = '['; k[0x1c] = ']';
  749. k[0x1d] = '\\';
  750. k[0x21] = 'a'; k[0x22] = 's'; k[0x23] = 'd'; k[0x24] = 'f';
  751. k[0x25] = 'g'; k[0x26] = 'h'; k[0x27] = 'j'; k[0x28] = 'k';
  752. k[0x29] = 'l'; k[0x2a] = ';'; k[0x2b] = '\'';
  753. k[0x31] = 'z'; k[0x32] = 'x'; k[0x33] = 'c'; k[0x34] = 'v';
  754. k[0x35] = 'b'; k[0x36] = 'n'; k[0x37] = 'm'; k[0x38] = ',';
  755. k[0x39] = '.'; k[0x3a] = '/';
  756. i = 0; while (i < 0x100) mc[i++] = 0;
  757. fc = 0;
  758. /* rows */
  759. c = 0;
  760. i = 0;
  761. while (i < 0x40) {
  762. p = c;
  763. c = k[i++] & 0xff;
  764. if (!c) continue;
  765. f[fc++] = c;
  766. if (!p) continue;
  767. m[(c << 3) + mc[c]++] = p;
  768. m[(p << 3) + mc[p]++] = c;
  769. }
  770. f[fc] = 0;
  771. /* columns */
  772. i = 0;
  773. while (i < 0x30) {
  774. p = k[i++] & 0xff;
  775. if (!p) continue;
  776. j = 1 - fuzz;
  777. while (j <= 1 + fuzz) {
  778. c = k[i + 0x10 - j++] & 0xff;
  779. if (!c) continue;
  780. m[(c << 3) + mc[c]++] = p;
  781. m[(p << 3) + mc[p]++] = c;
  782. }
  783. }
  784. length = 0;
  785. while (length < minlength)
  786. id[length++] = 0;
  787. }
  788. void generate()
  789. {
  790. int i, p, maxcount;
  791. word[i = 0] = p = f[id[0]];
  792. while (++i < length)
  793. word[i] = p = m[(p << 3) + id[i]];
  794. word[i--] = 0;
  795. if (i) maxcount = mc[word[i - 1]]; else maxcount = fc;
  796. while (++id[i] >= maxcount) {
  797. if (!i) {
  798. if (length < maxlength) {
  799. id[0] = 0;
  800. id[length++] = 0;
  801. }
  802. return;
  803. }
  804. id[i--] = 0;
  805. if (i) maxcount = mc[word[i - 1]]; else maxcount = fc;
  806. }
  807. }
  808. void restore()
  809. {
  810. int i;
  811. /* Calculate the length */
  812. length = 0;
  813. while (word[length])
  814. id[length++] = 0;
  815. /* Infer the first character index */
  816. i = -1;
  817. while (++i < fc) {
  818. if (f[i] == word[0]) {
  819. id[0] = i;
  820. break;
  821. }
  822. }
  823. /* This sample can be enhanced to infer the rest of the indices here */
  824. }
  825. # Generic implementation of "dumb" exhaustive search, given a range of lengths
  826. # and an arbitrary charset. This is pre-configured to try 8-bit characters
  827. # against LM hashes, which is only reasonable to do for very short password
  828. # half lengths.
  829. [List.External:DumbForce]
  830. int maxlength; // Maximum password length to try
  831. int last; // Last character position, zero-based
  832. int lastid; // Character index in the last position
  833. int id[0x7f]; // Current character indices for other positions
  834. int charset[0x100], c0; // Character set
  835. void init()
  836. {
  837. int minlength;
  838. int i, c;
  839. minlength = 1; // Initial password length to try, must be at least 1
  840. maxlength = 7; // Must be at least same as minlength
  841. /*
  842. * This defines the character set.
  843. *
  844. * Let's say, we want to try TAB, all non-control ASCII characters, and all
  845. * 8-bit characters, including the 8-bit terminal controls range (as these are
  846. * used as regular national characters with some 8-bit encodings), but except
  847. * for known terminal controls (risky for the terminal we may be running on).
  848. *
  849. * Also, let's say our hashes are case-insensitive, so skip lowercase letters
  850. * (this is right for LM hashes).
  851. */
  852. i = 0;
  853. charset[i++] = 9; // Add horizontal TAB (ASCII 9), then
  854. c = ' '; // start with space (ASCII 32) and
  855. while (c < 'a') // proceed till lowercase 'a'
  856. charset[i++] = c++;
  857. c = 'z' + 1; // Skip lowercase letters and
  858. while (c <= 0x7e) // proceed for all printable ASCII
  859. charset[i++] = c++;
  860. c++; // Skip DEL (ASCII 127) and
  861. while (c < 0x84) // proceed over 8-bit codes till IND
  862. charset[i++] = c++;
  863. charset[i++] = 0x86; // Skip IND (84 hex) and NEL (85 hex)
  864. charset[i++] = 0x87;
  865. c = 0x89; // Skip HTS (88 hex)
  866. while (c < 0x8d) // Proceed till RI (8D hex)
  867. charset[i++] = c++;
  868. c = 0x91; // Skip RI, SS2, SS3, DCS
  869. while (c < 0x96) // Proceed till SPA (96 hex)
  870. charset[i++] = c++;
  871. charset[i++] = 0x99; // Skip SPA, EPA, SOS
  872. c = 0xa0; // Skip DECID, CSI, ST, OSC, PM, APC
  873. while (c <= 0xff) // Proceed with the rest of 8-bit codes
  874. charset[i++] = c++;
  875. /* Zero-terminate it, and cache the first character */
  876. charset[i] = 0;
  877. c0 = charset[0];
  878. last = minlength - 1;
  879. i = 0;
  880. while (i <= last) {
  881. id[i] = 0;
  882. word[i++] = c0;
  883. }
  884. lastid = -1;
  885. word[i] = 0;
  886. }
  887. void generate()
  888. {
  889. int i;
  890. /* Handle the typical case specially */
  891. if (word[last] = charset[++lastid]) return;
  892. lastid = 0;
  893. word[i = last] = c0;
  894. while (i--) { // Have a preceding position?
  895. if (word[i] = charset[++id[i]]) return;
  896. id[i] = 0;
  897. word[i] = c0;
  898. }
  899. if (++last < maxlength) { // Next length?
  900. id[last] = lastid = 0;
  901. word[last] = c0;
  902. word[last + 1] = 0;
  903. } else // We're done
  904. word = 0;
  905. }
  906. void restore()
  907. {
  908. int i, c;
  909. /* Calculate the current length and infer the character indices */
  910. last = 0;
  911. while (c = word[last]) {
  912. i = 0; while (charset[i] != c && charset[i]) i++;
  913. if (!charset[i]) i = 0; // Not found
  914. id[last++] = i;
  915. }
  916. lastid = id[--last];
  917. }
  918. # Generic implementation of exhaustive search for a partially-known password.
  919. # This is pre-configured for length 8, lowercase and uppercase letters in the
  920. # first 4 positions (52 different characters), and digits in the remaining 4
  921. # positions - however, the corresponding part of init() may be modified to use
  922. # arbitrary character sets or even fixed characters for each position.
  923. [List.External:KnownForce]
  924. int last; // Last character position, zero-based
  925. int lastofs; // Last character position offset into charset[]
  926. int lastid; // Current character index in the last position
  927. int id[0x7f]; // Current character indices for other positions
  928. int charset[0x7f00]; // Character sets, 0x100 elements for each position
  929. void init()
  930. {
  931. int length;
  932. int pos, ofs, i, c;
  933. length = 8; // Password length to try
  934. /* This defines the character sets for different character positions */
  935. pos = 0;
  936. while (pos < 4) {
  937. ofs = pos++ << 8;
  938. i = 0;
  939. c = 'a';
  940. while (c <= 'z')
  941. charset[ofs + i++] = c++;
  942. c = 'A';
  943. while (c <= 'Z')
  944. charset[ofs + i++] = c++;
  945. charset[ofs + i] = 0;
  946. }
  947. while (pos < length) {
  948. ofs = pos++ << 8;
  949. i = 0;
  950. c = '0';
  951. while (c <= '9')
  952. charset[ofs + i++] = c++;
  953. charset[ofs + i] = 0;
  954. }
  955. last = length - 1;
  956. pos = -1;
  957. while (++pos <= last)
  958. word[pos] = charset[id[pos] = pos << 8];
  959. lastid = (lastofs = last << 8) - 1;
  960. word[pos] = 0;
  961. }
  962. void generate()
  963. {
  964. int pos;
  965. /* Handle the typical case specially */
  966. if (word[last] = charset[++lastid]) return;
  967. word[pos = last] = charset[lastid = lastofs];
  968. while (pos--) { // Have a preceding position?
  969. if (word[pos] = charset[++id[pos]]) return;
  970. word[pos] = charset[id[pos] = pos << 8];
  971. }
  972. word = 0; // We're done
  973. }
  974. void restore()
  975. {
  976. int i, c;
  977. /* Calculate the current length and infer the character indices */
  978. last = 0;
  979. while (c = word[last]) {
  980. i = lastofs = last << 8;
  981. while (charset[i] != c && charset[i]) i++;
  982. if (!charset[i]) i = lastofs; // Not found
  983. id[last++] = i;
  984. }
  985. lastid = id[--last];
  986. }
  987. # A variation of KnownForce configured to try likely date and time strings.
  988. [List.External:DateTime]
  989. int last; // Last character position, zero-based
  990. int lastofs; // Last character position offset into charset[]
  991. int lastid; // Current character index in the last position
  992. int id[0x7f]; // Current character indices for other positions
  993. int charset[0x7f00]; // Character sets, 0x100 elements for each position
  994. void init()
  995. {
  996. int length;
  997. int pos, ofs, i, c;
  998. length = 8; // Must be one of: 4, 5, 7, 8
  999. /* This defines the character sets for different character positions */
  1000. pos = 0;
  1001. while (pos < length - 6) {
  1002. ofs = pos++ << 8;
  1003. i = 0;
  1004. c = '0';
  1005. while (c <= '9')
  1006. charset[ofs + i++] = c++;
  1007. charset[ofs + i] = 0;
  1008. }
  1009. if (pos) {
  1010. ofs = pos++ << 8;
  1011. charset[ofs] = '/';
  1012. charset[ofs + 1] = '.';
  1013. charset[ofs + 2] = ':';
  1014. charset[ofs + 3] = 0;
  1015. }
  1016. while (pos < length - 3) {
  1017. ofs = pos++ << 8;
  1018. i = 0;
  1019. c = '0';
  1020. while (c <= '9')
  1021. charset[ofs + i++] = c++;
  1022. charset[ofs + i] = 0;
  1023. }
  1024. ofs = pos++ << 8;
  1025. charset[ofs] = '/';
  1026. charset[ofs + 1] = '.';
  1027. charset[ofs + 2] = ':';
  1028. charset[ofs + 3] = 0;
  1029. while (pos < length) {
  1030. ofs = pos++ << 8;
  1031. i = 0;
  1032. c = '0';
  1033. while (c <= '9')
  1034. charset[ofs + i++] = c++;
  1035. charset[ofs + i] = 0;
  1036. }
  1037. last = length - 1;
  1038. pos = -1;
  1039. while (++pos <= last)
  1040. word[pos] = charset[id[pos] = pos << 8];
  1041. lastid = (lastofs = last << 8) - 1;
  1042. word[pos] = 0;
  1043. }
  1044. void generate()
  1045. {
  1046. int pos;
  1047. /* Handle the typical case specially */
  1048. if (word[last] = charset[++lastid]) return;
  1049. word[pos = last] = charset[lastid = lastofs];
  1050. while (pos--) { // Have a preceding position?
  1051. if (word[pos] = charset[++id[pos]]) return;
  1052. word[pos] = charset[id[pos] = pos << 8];
  1053. }
  1054. word = 0; // We're done
  1055. }
  1056. void restore()
  1057. {
  1058. int i, c;
  1059. /* Calculate the current length and infer the character indices */
  1060. last = 0;
  1061. while (c = word[last]) {
  1062. i = lastofs = last << 8;
  1063. while (charset[i] != c && charset[i]) i++;
  1064. if (!charset[i]) i = lastofs; // Not found
  1065. id[last++] = i;
  1066. }
  1067. lastid = id[--last];
  1068. }
  1069. # Try strings of repeated characters.
  1070. [List.External:Repeats]
  1071. int minlength, maxlength, minc, maxc, length, c;
  1072. void init()
  1073. {
  1074. minlength = 1;
  1075. maxlength = 72;
  1076. minc = 0x20;
  1077. maxc = 0xff;
  1078. length = minlength; c = minc;
  1079. }
  1080. void generate()
  1081. {
  1082. int i;
  1083. i = 0;
  1084. while (i < length)
  1085. word[i++] = c;
  1086. word[i] = 0;
  1087. if (c++ < maxc)
  1088. return;
  1089. c = minc;
  1090. if (++length > maxlength)
  1091. c = 0; // Will NUL out the next "word" and thus terminate
  1092. }
  1093. # Generate candidate passwords from many small subsets of characters from a
  1094. # much larger full character set. This will test for passwords containing too
  1095. # few different characters. As currently implemented, this code will produce
  1096. # some duplicates, although their number is relatively small when the maximum
  1097. # number of different characters (the maxdiff setting) is significantly lower
  1098. # than the maximum length (the maxlength setting). Nevertheless, you may want
  1099. # to pass the resulting candidate passwords through "unique" if you intend to
  1100. # test them against hashes that are salted and/or of a slow to compute type.
  1101. [List.External:Subsets]
  1102. int minlength; // Minimum password length to try
  1103. int maxlength; // Maximum password length to try
  1104. int startdiff; // Initial number of characters in a subset to try
  1105. int maxdiff; // Maximum number of characters in a subset to try
  1106. int last; // Last character position, zero-based
  1107. int lastid; // Character index in the last position
  1108. int id[0x7f]; // Current character indices for other positions
  1109. int subset[0x100], c0; // Current subset
  1110. int subcount; // Number of characters in the current subset
  1111. int subid[0x100]; // Indices into charset[] of characters in subset[]
  1112. int charset[0x100]; // Full character set
  1113. int charcount; // Number of characters in the full charset
  1114. void init()
  1115. {
  1116. int i, c;
  1117. minlength = 1; // Minimum password length to try, must be at least 1
  1118. maxlength = 8; // Must be at least same as minlength
  1119. startdiff = 1; // Initial number of different characters to try
  1120. maxdiff = 3; // Maximum number of different characters to try
  1121. /* This defines the character set */
  1122. i = 0;
  1123. c = 0x20;
  1124. while (c <= 0x7e)
  1125. charset[i++] = c++;
  1126. if (maxdiff > (charcount = i))
  1127. maxdiff = i;
  1128. if (maxdiff > maxlength)
  1129. maxdiff = maxlength;
  1130. /*
  1131. * Initialize the variables such that generate() gets to its "next subset"
  1132. * code, which will initialize everything for real.
  1133. */
  1134. subcount = (i = startdiff) - 1;
  1135. while (i--)
  1136. subid[i] = charcount;
  1137. subset[0] = c0 = 0;
  1138. last = maxlength - 1;
  1139. lastid = -1;
  1140. }
  1141. void generate()
  1142. {
  1143. int i;
  1144. /* Handle the typical case specially */
  1145. if (word[last] = subset[++lastid]) return;
  1146. lastid = 0;
  1147. word[i = last] = c0;
  1148. while (i--) { // Have a preceding position?
  1149. if (word[i] = subset[++id[i]]) return;
  1150. id[i] = 0;
  1151. word[i] = c0;
  1152. }
  1153. if (++last < maxlength) { // Next length?
  1154. id[last] = lastid = 0;
  1155. word[last] = c0;
  1156. word[last + 1] = 0;
  1157. return;
  1158. }
  1159. /* Next subset */
  1160. if (subcount) {
  1161. int j;
  1162. i = subcount - 1;
  1163. j = charcount;
  1164. while (++subid[i] >= j) {
  1165. if (i--) {
  1166. j--;
  1167. continue;
  1168. }
  1169. subid[i = 0] = 0;
  1170. subset[++subcount] = 0;
  1171. break;
  1172. }
  1173. } else {
  1174. subid[i = 0] = 0;
  1175. subset[++subcount] = 0;
  1176. }
  1177. subset[i] = charset[subid[i]];
  1178. while (++i < subcount)
  1179. subset[i] = charset[subid[i] = subid[i - 1] + 1];
  1180. if (subcount > maxdiff) {
  1181. word = 0; // Done
  1182. return;
  1183. }
  1184. /*
  1185. * We won't be able to fully use the subset if the length is smaller than the
  1186. * character count. We assume that we've tried all smaller subsets before, so
  1187. * we don't bother with such short lengths.
  1188. */
  1189. if (minlength < subcount)
  1190. last = subcount - 1;
  1191. else
  1192. last = minlength - 1;
  1193. c0 = subset[0];
  1194. i = 0;
  1195. while (i <= last) {
  1196. id[i] = 0;
  1197. word[i++] = c0;
  1198. }
  1199. lastid = 0;
  1200. word[i] = 0;
  1201. }
  1202. # Simple password policy matching: require at least one digit.
  1203. [List.External:AtLeast1-Simple]
  1204. void filter()
  1205. {
  1206. int i, c;
  1207. i = 0;
  1208. while (c = word[i++])
  1209. if (c >= '0' && c <= '9')
  1210. return; // Found at least one suitable character, good
  1211. word = 0; // No suitable characters found, skip this "word"
  1212. }
  1213. # The same password policy implemented in a more efficient and more generic
  1214. # fashion (easy to expand to include other "sufficient" characters as well).
  1215. [List.External:AtLeast1-Generic]
  1216. int mask[0x100];
  1217. void init()
  1218. {
  1219. int c;
  1220. mask[0] = 0; // Terminate the loop in filter() on NUL
  1221. c = 1;
  1222. while (c < 0x100)
  1223. mask[c++] = 1; // Continue looping in filter() on most chars
  1224. c = '0';
  1225. while (c <= '9')
  1226. mask[c++] = 0; // Terminate the loop in filter() on digits
  1227. }
  1228. void filter()
  1229. {
  1230. int i;
  1231. i = -1;
  1232. while (mask[word[++i]])
  1233. continue;
  1234. if (word[i])
  1235. return; // Found at least one suitable character, good
  1236. word = 0; // No suitable characters found, skip this "word"
  1237. }
  1238. # An efficient and fairly generic password policy matcher. The policy to match
  1239. # is specified in the check at the end of filter() and in mask[]. For example,
  1240. # lowercase and uppercase letters may be treated the same by initializing the
  1241. # corresponding mask[] elements to the same value, then adjusting the value to
  1242. # check "seen" for accordingly.
  1243. [List.External:Policy]
  1244. int mask[0x100];
  1245. void init()
  1246. {
  1247. int c;
  1248. mask[0] = 0x100;
  1249. c = 1;
  1250. while (c < 0x100)
  1251. mask[c++] = 0x200;
  1252. c = 'a';
  1253. while (c <= 'z')
  1254. mask[c++] = 1;
  1255. c = 'A';
  1256. while (c <= 'Z')
  1257. mask[c++] = 2;
  1258. c = '0';
  1259. while (c <= '9')
  1260. mask[c++] = 4;
  1261. }
  1262. void filter()
  1263. {
  1264. int i, seen;
  1265. /*
  1266. * This loop ends when we see NUL (sets 0x100) or a disallowed character
  1267. * (sets 0x200).
  1268. */
  1269. i = -1; seen = 0;
  1270. while ((seen |= mask[word[++i]]) < 0x100)
  1271. continue;
  1272. /*
  1273. * We should have seen at least one character of each type (which "add up"
  1274. * to 7) and then a NUL (adds 0x100), but not any other characters (would
  1275. * add 0x200). The length must be 8.
  1276. */
  1277. if (seen != 0x107 || i != 8)
  1278. word = 0; // Does not conform to policy
  1279. }
  1280. # Append the Luhn algorithm digit to arbitrary all-digit strings. Optimized
  1281. # for speed, not for size nor simplicity. The primary optimization trick is to
  1282. # compute the length and four sums in parallel (in two SIMD'ish variables).
  1283. # Then whether the length is even or odd determines which two of the four sums
  1284. # are actually used. Checks for non-digits and for NUL are packed into the
  1285. # SIMD'ish bitmasks as well.
  1286. [List.External:AppendLuhn]
  1287. int map1[0x100], map2[0x1fff];
  1288. void init()
  1289. {
  1290. int i;
  1291. map1[0] = ~0x7fffffff;
  1292. i = 1;
  1293. while (i < 0x100)
  1294. map1[i++] = ~0x7effffff;
  1295. i = -1;
  1296. while (++i < 10)
  1297. map1['0' + i] = i + ((i * 2 % 10 + i / 5) << 12);
  1298. i = -1;
  1299. while (++i < 0x1fff) {
  1300. if (i % 10)
  1301. map2[i] = '9' + 1 - i % 10;
  1302. else
  1303. map2[i] = '0';
  1304. }
  1305. }
  1306. void filter()
  1307. {
  1308. int i, o, e;
  1309. i = o = e = 0;
  1310. while ((o += map1[word[i++]]) >= 0) {
  1311. if ((e += map1[word[i++]]) >= 0)
  1312. continue;
  1313. if (e & 0x01000000)
  1314. return; // Not all-digit, leave unmodified
  1315. word[i--] = 0;
  1316. word[i] = map2[(e & 0xfff) + (o >> 12)];
  1317. return;
  1318. }
  1319. if (o & 0x01000000)
  1320. return; // Not all-digit, leave unmodified
  1321. word[i--] = 0;
  1322. word[i] = map2[(o & 0xfff) + (e >> 12)];
  1323. }
  1324. # Trivial Rot13 Example
  1325. # Words which don't contain any letters (and thus wouldn't be changed
  1326. # by Rot13) are skipped, because these unchanged words probably should
  1327. # have been tried before trying a mangled version.
  1328. [List.External:Filter_Rot13]
  1329. void filter()
  1330. {
  1331. int i, j, c;
  1332. j = 0;
  1333. i = 0; // Convert to uppercase
  1334. while (c = word[i]) {
  1335. if ((c >= 'a' && c <= 'm') || c >= 'A' && c <= 'M' ) {
  1336. word[i] = c + 13;
  1337. j++;
  1338. } else if ((c >= 'n' && c <= 'z') || c >= 'N' && c <= 'Z' ) {
  1339. word[i] = c - 13;
  1340. j++;
  1341. }
  1342. i++;
  1343. }
  1344. if (j == 0)
  1345. word = 0;
  1346. }
  1347. # Trivial parallel processing example
  1348. [List.External_base:Parallel]
  1349. /*
  1350. * This word filter makes John process some of the words only, for running
  1351. * multiple instances on different CPUs. It can be used with any cracking
  1352. * mode except for "single crack". Note: this is not a good solution, but
  1353. * is just an example of what can be done with word filters.
  1354. */
  1355. int node, total; // This node's number, and node count
  1356. int number; // Current word number
  1357. void filter()
  1358. {
  1359. if (number++ % total) // Word for a different node?
  1360. word = 0; // Yes, skip it
  1361. }
  1362. [List.External:Parallel1_2]
  1363. .include [List.External_base:Parallel]
  1364. void init()
  1365. {
  1366. node = 1; total = 2; // Node 1 of 2
  1367. number = node - 1; // Speedup the filter a bit
  1368. }
  1369. [List.External:Parallel2_2]
  1370. .include [List.External_base:Parallel]
  1371. void init()
  1372. {
  1373. node = 2; total = 2; // Node 2 of 2
  1374. number = node - 1; // Speedup the filter a bit
  1375. }
  1376. # Interrupt the cracking session after "max" words tried
  1377. [List.External:AutoAbort]
  1378. int max; // Maximum number of words to try
  1379. int number; // Current word number
  1380. void init()
  1381. {
  1382. max = 1000;
  1383. number = 0;
  1384. }
  1385. void filter()
  1386. {
  1387. if (++number > max)
  1388. abort = 1; // Interrupt the cracking session
  1389. }
  1390. # Print the status line after every "interval" words tried
  1391. [List.External:AutoStatus]
  1392. int interval; // How often to print the status
  1393. int number; // Current word number
  1394. void init()
  1395. {
  1396. interval = 1000;
  1397. number = 0;
  1398. }
  1399. void filter()
  1400. {
  1401. if (number++ % interval)
  1402. return;
  1403. status = 1; // Print the status line
  1404. }
  1405. # dumb-force UTF-16, in an external file
  1406. .include "$JOHN/dumb16.conf"
  1407. # dumb-force UTF-32, in an external file
  1408. .include "$JOHN/dumb32.conf"
  1409. # Dynamic ($dynamic_n$) scripting code, in an external file
  1410. # also shows/tests that .include <file> works the same as .include "$JOHN/file"
  1411. .include <dynamic.conf>
  1412. # include john.local.conf (defaults to being empty, but never overwritten)
  1413. .include "$JOHN/john.local.conf"