Codebase list pack / debian/0.0.2-1kali1
debian/0.0.2-1kali1

Tree @debian/0.0.2-1kali1 (Download .tar.gz)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
PACK (Password Analysis and Cracking Kit) by iphelix
====================================================

1.0 About
---------

PACK was developed in order to aid in a password cracking competition "Crack Me If You Can" that occurred during Defcon 2010. The goal of this toolkit is to aiding in preparation for the "better than bruteforce" password attacks by analyzing common ways that people create passwords. After the analysis stage, the statistical database can be used to generate attack masks for common tools such as Hashcat, oclHashcat, and others. 

NOTE: This tool itself can not crack passwords, but helps other tools crack more passwords faster.

2.0 Usage
---------

The following is a sample analysis and generation session that will illustrate the use of this kit. In all of the examples, a standard hashcat notation to represent different character sets is used:

?l - lowercase characters
?u - uppercase characters
?d - digits
?s - special characters

2.1 DictStat
------------

Before we can begin using the toolkit we must establish selection criteria for the sample input. Since we are looking to analyze the way people create their passwords, we must obtain as large of a list of leaked passwords as possible. One such excellent list is based on RockYou.com compromise. This list both provides large and diverse enough sample that it can be used as a good estimate for common passwords used by similar sites (e.g. social networking). The analysis obtained from this list may not work for organizations with specific password policies (e.g. 8 characters, minimum digit and special character requirements, etc.). As such, selecting sample input should be as close to your target as possible. In addition, try to avoid obtaining lists based on already cracked passwords as it will generate statistics skewed toward the type of passwords that could be cracked and not the overall sample.

In the example below, we will use rockyou.txt containing approximately 14 million passwords. Launch dictstat with the following command line:

$ python dictstat.py rockyou.txt

NOTE: It is highly recommended that you install psyco python module for larger lists.

Below is an output from the above command:

-------------------------------------------------------------------------------

[*] Analyzing dictionary: rockyou.txt
[+] Analyzing 100% (14344391/14344391) passwords
    NOTE: Statistics below is relative to the number of analyzed passwords, not total number of passwords

[*] Line Count Statistics...
[+]                         8: 20% (2966004)
[+]                         7: 17% (2506264)
[+]                         9: 15% (2191000)
[+]                        10: 14% (2013690)
[+]                         6: 13% (1947858)
[+]                        11: 06% (865973)
[+]                        12: 03% (555333)
[+]                        13: 02% (364169)
[+]                         5: 01% (259174)
[+]                        14: 01% (248514)
[+]                        15: 01% (161181)

[*] Mask statistics...
[+]               stringdigit: 37% (5339715)
[+]                 allstring: 28% (4115881)
[+]                  alldigit: 16% (2346842)
[+]                 othermask: 05% (731240)
[+]               digitstring: 04% (663975)
[+]         stringdigitstring: 03% (450753)
[+]       stringspecialstring: 01% (204494)
[+]        stringspecialdigit: 01% (167826)
[+]             stringspecial: 01% (147874)
[+]          digitstringdigit: 00% (130518)
[+]      specialstringspecial: 00% (25100)
[+]             specialstring: 00% (14410)
[+]                allspecial: 00% (5763)

[*] Charset statistics...
[+]             loweralphanum: 42% (6075055)
[+]                loweralpha: 25% (3726656)
[+]                   numeric: 16% (2346842)
[+]      loweralphaspecialnum: 03% (472673)
[+]             upperalphanum: 02% (407436)
[+]             mixedalphanum: 02% (382246)
[+]         loweralphaspecial: 02% (381095)
[+]                upperalpha: 01% (229893)
[+]                mixedalpha: 01% (159332)
[+]      mixedalphaspecialnum: 00% (53240)
[+]         mixedalphaspecial: 00% (49633)
[+]      upperalphaspecialnum: 00% (27732)
[+]         upperalphaspecial: 00% (26795)
[+]                   special: 00% (5763)

[*] Advanced Mask statistics...
[+]          ?l?l?l?l?l?l?l?l: 04% (688053)
[+]              ?l?l?l?l?l?l: 04% (601257)
[+]            ?l?l?l?l?l?l?l: 04% (585093)
[+]        ?l?l?l?l?l?l?l?l?l: 03% (516862)
[+]            ?d?d?d?d?d?d?d: 03% (487437)
[+]      ?d?d?d?d?d?d?d?d?d?d: 03% (478224)
[+]          ?d?d?d?d?d?d?d?d: 02% (428306)
[+]          ?l?l?l?l?l?l?d?d: 02% (420326)
[+]      ?l?l?l?l?l?l?l?l?l?l: 02% (416961)
[+]              ?d?d?d?d?d?d: 02% (390546)
[+]        ?d?d?d?d?d?d?d?d?d: 02% (307540)
[+]            ?l?l?l?l?l?d?d: 02% (292318)
[+]        ?l?l?l?l?l?l?l?d?d: 01% (273640)
[+]    ?l?l?l?l?l?l?l?l?l?l?l: 01% (267742)
[+]          ?l?l?l?l?d?d?d?d: 01% (235364)
[+]              ?l?l?l?l?d?d: 01% (215079)
[+]      ?l?l?l?l?l?l?l?l?d?d: 01% (213117)
[+]            ?l?l?l?l?l?l?d: 01% (193110)
[+]          ?l?l?l?l?l?l?l?d: 01% (189855)
[+]  ?l?l?l?l?l?l?l?l?l?l?l?l: 01% (189360)
[+]            ?l?l?l?d?d?d?d: 01% (178308)
[+]        ?l?l?l?l?l?d?d?d?d: 01% (173560)
[+]      ?l?l?l?l?l?l?d?d?d?d: 01% (160596)
[+]        ?l?l?l?l?l?l?l?l?d: 01% (160061)
[+]          ?l?l?l?l?l?d?d?d: 01% (152406)

-------------------------------------------------------------------------------

Here is what we can immediately learn from the list above:
1) The majority of passwords are 6-10 characters
2) The majority of passwords follow masks of the form "string followed by digits", "all string", and "all digits".
3) The majority of passwords use lower alphanumeric and lower alpha character sets.

In the last section "Advanced Mask Statistics", you can look at actual masks matching the most frequent passwords. Masks are generated by attempting to find the minimum matching set of regular expressions that would match that string.

You can interpret individual symbols as follows:
?l - a single lowercase character
?u - a single uppercase character
?d - a single digit
?s - a single special character

So, if we will take the first entry as an example, "?l?l?l?l?l?l?l?l" mask will match all of the lowercase alpha passwords. Given the sample size you will be able to crack approximately 4% of passwords.

While the standard output yields a lot of data, you may be interested in using filters to narrow down on password data and may be gain additional insight into the way people generate passwords.

Let's see how people tend to select their passwords which follow the mask string followed by digits:

$ python dictstat.py -m stringdigit rockyou.txt

[*] Analyzing dictionary: rockyou.txt
[+] Analyzing 37% (5339715/14344391) passwords
    NOTE: Statistics below is relative to the number of analyzed passwords, not total number of passwords

[*] Line Count Statistics...
[+]                         8: 23% (1267292)
[+]                         7: 18% (981472)
[+]                         9: 17% (940000)
[+]                        10: 14% (750966)
[+]                         6: 11% (619001)
[+]                        11: 05% (294874)
[+]                        12: 03% (175879)
[+]                        13: 01% (103048)
[+]                        14: 01% (65959)

[*] Mask statistics...
[+]               stringdigit: 100% (5339715)

[*] Charset statistics...
[+]             loweralphanum: 88% (4720336)
[+]             upperalphanum: 06% (325943)
[+]             mixedalphanum: 05% (293436)

[*] Advanced Mask statistics...
[+]          ?l?l?l?l?l?l?d?d: 07% (420326)
[+]            ?l?l?l?l?l?d?d: 05% (292318)
[+]        ?l?l?l?l?l?l?l?d?d: 05% (273640)
[+]          ?l?l?l?l?d?d?d?d: 04% (235364)
[+]              ?l?l?l?l?d?d: 04% (215079)
[+]      ?l?l?l?l?l?l?l?l?d?d: 03% (213117)
[+]            ?l?l?l?l?l?l?d: 03% (193110)
[+]          ?l?l?l?l?l?l?l?d: 03% (189855)
[+]            ?l?l?l?d?d?d?d: 03% (178308)
[+]        ?l?l?l?l?l?d?d?d?d: 03% (173560)
[+]      ?l?l?l?l?l?l?d?d?d?d: 03% (160596)
[+]        ?l?l?l?l?l?l?l?l?d: 02% (160061)
[+]          ?l?l?l?l?l?d?d?d: 02% (152406)
[+]        ?l?l?l?l?l?l?d?d?d: 02% (132220)
[+]      ?l?l?l?l?l?l?l?l?l?d: 02% (129833)
[+]              ?l?l?l?l?l?d: 02% (114739)
[+]            ?l?l?l?l?d?d?d: 02% (111221)
[+]              ?l?l?d?d?d?d: 01% (98305)
[+]              ?l?l?l?d?d?d: 01% (98189)
[+]      ?l?l?l?l?l?l?l?d?d?d: 01% (87613)
[+]    ?l?l?l?l?l?l?l?l?l?d?d: 01% (82655)
[+]    ?l?l?l?l?l?l?l?d?d?d?d: 01% (70915)
[+]            ?l?d?d?d?d?d?d: 01% (54888)


As we look at the above output, you will immediately notice that "Mask statistics" only has one entry: "stringdigit". This is because of our specified filter. Let's analyze the data. On the very top of the output, you can see that only 37% passwords were analyzed. You can estimate that by cracking only passwords match this mask you can at most crack about 37% of the total set.

Next, it appears that only 11% of this password type use anything other than lowercase. So it would be smart to concentrate on only lowercase strings matching this mask. At last, in the "Advanced Mask Statistics" section you can see that the majority of "stringdigit" passwords consist of a string with two or four digits following it.

With the information gained from the above, you can begin creating a mental image of you target's password generation patterns.

There are other filters available for password length, mask, and character sets:

Length: -l [integer]

Mask: -m [numeric, loweralpha, upperalpha, mixedalpha, loweralphanum, upperalphanum, mixedaphanum, special, loweralphaspecial, upperalphaspecial, mixedalphaspecial, loweraphaspecialnum, upperalphaspecialnum, mixedalphaspecialnum]

Character sets: -c [alldigit, allstring, stringdigit, digitstring, digitstringdigit, stringdigitstring, allspecial, stringspecial, specialstring, stringspecialstring, stringspecialdigit, specialstringspecial]

DEVELOPERS: You can edit respective lists on the very top of the sourcefiles and add regular expressions for whatever mask or character set you can imagine.

While the "Advanced Mask Section" only displays patterns matching greater than 1% of all passwords, you can obtain and save a full list of passwords masks matching a given dictionary by using the following command:

$ python dictstat.py -o rockyou.csv rockyou.txt

The above command will save all of the password masks and their frequencies into a CSV file 'rockyou.csv'. Naturally, you can provide filters to only generate masks file matching your parameters. The output file can be used as an input to MaskGen tool covered in the next section.

2.2 MaskGen
-----------

While analyzing passwords using DictGen can be both revealing and exciting, it is simply not feasible for larger data sets. MaskGen will analyze the masks output file produced by DictGen and help you generate custom password mask input files for you applications.

Let's run MaskGen with minimum parameters and observe it's output:

$ python maskgen.py rockyou.csv

[*] [0] [11/14344391] [0.00] [0d|0h|0m|0s] ? 
[*] [1] [49/14344391] [0.00] [0d|0h|0m|0s] ?s?u?l?d 
[*] [2] [340/14344391] [0.00] [0d|0h|0m|0s] ?s?u?l?d ?s?u?l?d 
[*] [3] [2479/14344391] [0.00] [0d|0h|0m|0s] ?s?u?l?d ?s?u?l?d ?s?u?l?d 
[*] [4] [18015/14344391] [0.00] [0d|0h|0m|0s] ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d 
[*] [5] [259174/14344391] [1.00] [0d|0h|0m|7s] ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d 
[*] [6] [1947858/14344391] [13.00] [0d|0h|12m|735s] ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d 
[*] [7] [2506264/14344391] [17.00] [0d|19h|1163m|69833s] ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d 
[*] [8] [2966004/14344391] [20.00] [76d|1842h|110570m|6634204s] ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d 
[*] [9] [2191000/14344391] [15.00] [7294d|175069h|10504156m|630249409s] ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d

...
[*] Coverage is %100 (14344391/14344391)
[*] Total time 1754409989919144353064355175042468812368733249495616893327070104
8211232752070650397369740269713581215815201614225211442387866496572012147724920
4649812938136306665865356654151858255534645195728557246448055491199506753532407
0837796021192337530275757511267739149674126051965467434111830202528596251368154
7242960405598417380173912831468583249522597950717975278703858956758951666222598
6032208513767643382460723235228659294580495141287225869341138204996227078055906
67374828225147228141265693827036d|421058397580594644735445242010192514968495979
8789480543984968251570695860496956095368737664731259491795648387414050746173087
9591772829154539809115955105152713599807685596996445981328314846974853739147533
3178878816208477777001071045086161007266181802704257395921790252471712184186839
2486068631003283571338310497343620171241739079552459979885423508172314066888926
1496221483998934236647730043304234411790573576454878230699318833908934208641873
1691990944987334176016995877403533475390376651848886h|2526350385483567868412671
4520611550898109758792736883263909809509424175162981736572212425988387556950773
8903244843044770385277550636974927238854695730630916281598846113581978675887969
8890818491224348851999073272897250866662006426270516966043597090816225544375530
7415148302731051210354916411786019701428029862984061721027450434477314759879312
5410490338844013335568977328903993605419886380259825406470743441458729269384195
91300345360525185123901519456699240050561019752644212008523422599110933198m|151
5810231290140721047602871236693053886585527564212995834588570565450509778904194
3327455593032534170464334194690582686223116653038218495634331281743837854976895


Ignore the crazy long last line for a minute and let's take a look at line with prefix of [5]:

[*] [5] [259174/14344391] [1.00] [0d:0h:0m:7s] ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d 
 \          \             \          \           \
  \          \             \          \           \ matching mask
   \          \             \          \
    \          \             \          \ time to crack
     \          \             \ 
      \          \             \ percent coverage from sample
       \          \
        \          \ total number of matching passwords
         \
          \ password length
          
NOTE: day, hour, minute, and seconds parameters are independent of each other. [0d|0h|1m|60s] means the total runtime is 60 seconds and not 1 minute 60 seconds. You will find it useful when doing calculations and converting back and forth.
                   
The information contained in the above file will present you with an ordered list of masks together with how long it will take to crack all passwords matching this mask (default speed is 1000000000 keys/sec), the percentage coverage of the total sample, total count of matching passwords.

In our example "?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d ?s?u?l?d" mask shows that every single character in every position has the mask of "?s?u?l?d" or every single character. This line is suggesting that in order to crack every single password of length 5, you must attempt to crack every single character set for each position (or complete bruteforce) and it will take you about 7 seconds to do that.

NOTE: There is a bit of black magic going on in the background to generate masks for a specific password length. As you may have observed passwords become more complex by adding extra characters (exponential growth) as opposed to just increasing the character set in any given slot. As such, I have chosen to generate masks based on the length of passwords that they match. Combined masks are generated by looking at all masks of a given length and combining them together. For example masks ?l?l?l and ?l?l?d matching three character passwords will be combined to "?l ?l ?l?d" to match all passwords represented by both masks.

The last (really long) line tells you the total number of days/hours/minutes/seconds to crack every single password using every single mask in our database. The time is so huge, because we are performing a dumb bruteforcing attack. What we are going to try to do is to attempt to crack the maximum number of password in minimum time.

You should almost never run MaskGen with no parameters (except may be cases to remind yourself why dumb bruteforcing is bad). Let's use some of the data gained from DictStat to generate a set of masks that will give us 50% of passwords withing some reasonable time.      

We have already collected statistical data about how many time each of the masks occurs, so let's leave out all of the infrequently occuring masks:

$ python maskgen.py --occurence=10000 rockyou.csv 

[*] [5] [220730/14344391] [1.00] [0d|0h|0m|0s] ?u?l?d ?u?l?d ?u?l?d ?u?l?d ?u?l?d 
[*] [6] [1741132/14344391] [12.00] [0d|0h|1m|87s] ?u?l?d ?u?l?d ?u?l?d ?u?l?d ?u?l?d ?s?u?l?d 
[*] [7] [2228900/14344391] [15.00] [0d|1h|89m|5396s] ?u?l?d ?u?l?d ?u?l?d ?u?l?d ?u?l?d ?u?l?d ?s?u?l?d 
[*] [8] [2591942/14344391] [18.00] [5d|142h|8543m|512622s] ?u?l?d ?u?l?d ?u?l?d ?u?l?d ?u?l?d ?s?u?l?d ?u?l?d ?s?u?l?d 
[*] [9] [1857159/14344391] [12.00] [563d|13527h|811651m|48699101s] ?u?l?d ?u?l?d ?u?l?d ?u?l?d ?s?u?l?d ?u?l?d ?s?u?l?d ?u?l?d ?s?u?l?d 
[*] [10] [1623494/14344391] [11.00] [14884d|357228h|21433720m|1286023221s] ?u?d?l ?u?d?l ?u?d?l ?u?d?l ?u?d?l ?u?d?l ?u?d?l ?u?d?l ?u?d?l ?s?u?d?l 
[*] [11] [634442/14344391] [4.00] [602275d|14454600h|867276011m|52036560683s] ?u?l?d ?u?l?d ?u?l?d ?u?l?d ?u?l?d ?u?l?d ?u?l?d ?u?l?d ?u?l?d ?u?l?d ?u?l?d 
[*] [12] [362705/14344391] [2.00] [54842d|1316217h|78973022m|4738381338s] ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d 
[*] [13] [205833/14344391] [1.00] [1974325d|47383813h|2843028802m|170581728179s] ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d 
[*] [14] [133214/14344391] [0.00] [71075720d|1705817281h|102349036907m|6140942214464s] ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d 
[*] [15] [55398/14344391] [0.00] [19412723d|465905372h|27954322371m|1677259342285s] ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l 
[*] [16] [33484/14344391] [0.00] [504730820d|12113539694h|726812381657m|43608742899428s] ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l 
[*] [17] [13147/14344391] [0.00] [13123001335d|314952032051h|18897121923085m|1133827315385150s] ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l ?l 
[*] Coverage is %81 (11701580/14344391)
[*] Total time 13720867497d|329300819931h|19758049195865m|1185482951751954s 

Using above masks you will be able to achieve significantly better cracking times while still preserving more than 80% total password coverage. At the same time, you will avoid pure bruteforcing of every possible charter in every position. For example, for passwords greater than 15 characters you can use only lowercase alpha characters.

Let's take the above output to a much more reasonable time to satisfy our goal of cracking passwords in about a day with %50 coverage. For that, we will increase the frequency count as well as add maximum mask runtime paramter of one day or 8640 seconds:

$ python maskgen.py --occurence=100000 --maxtime=8640 rockyou.csv

[*] [5] [125816/14344391] [0.00] [0d|0h|0m|0s] ?l ?l ?l ?l ?l 
[*] [6] [1321621/14344391] [9.00] [0d|0h|0m|2s] ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d 
[*] [7] [1847487/14344391] [12.00] [0d|0h|1m|78s] ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d 
[*] [8] [2114310/14344391] [14.00] [0d|0h|47m|2821s] ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d 
[*] [9] [1563883/14344391] [10.00] [1d|28h|1692m|101559s] ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d 
[*] [10] [638820/14344391] [4.00] [0d|6h|362m|21767s] ?d?l ?d?l ?d?l ?d?l ?d?l ?d?l ?d ?d ?d ?d 
[*] [11] [107864/14344391] [0.00] [0d|0h|1m|100s] ?d ?d ?d ?d ?d ?d ?d ?d ?d ?d ?d 
[*] Coverage is %53 (7719801/14344391)
[*] Total time 1d|35h|2105m|126327s 

We have almost reached our, but we can fine tune it by adding maximum password complexity. Password complexity is determined based on the number of all possible passwords matching a mask. For example, mask "?l?d ?l?d" can have up to (26+10)^2 or 1296 passwords. In our example, we are going to relax the occurence flag, but include maximum password complexity of 2821109907456 which corresponds to an eight character loweralphanumeric password (26+10)^8. We are also going to include --showmasks flag to see the exact component masks and their respective counts and relative percentages.

$ maskgen.py --occurence=50000 --maxtime=8640 --complexity=2821109907456 --showmasks rockyou.csv

[*] [5] [125816/14344391] [0.00] [0d|0h|0m|0s] ?l ?l ?l ?l ?l 
    [5] [125816/125816] [100.00] [0.00] [0d|0h|0m|0s] ?l?l?l?l?l
[*] [6] [1569957/14344391] [10.00] [0d|0h|0m|56s] ?u?l?d ?u?l?d ?u?l?d ?u?l?d ?u?l?d ?u?l?d 
    [6] [601257/1569957] [38.00] [4.00] [0d|0h|0m|0s] ?l?l?l?l?l?l
    [6] [390546/1569957] [24.00] [2.00] [0d|0h|0m|0s] ?d?d?d?d?d?d
    [6] [215079/1569957] [13.00] [1.00] [0d|0h|0m|0s] ?l?l?l?l?d?d
    [6] [114739/1569957] [7.00] [0.00] [0d|0h|0m|0s] ?l?l?l?l?l?d
    [6] [98305/1569957] [6.00] [0.00] [0d|0h|0m|0s] ?l?l?d?d?d?d
    [6] [98189/1569957] [6.00] [0.00] [0d|0h|0m|0s] ?l?l?l?d?d?d
    [6] [51842/1569957] [3.00] [0.00] [0d|0h|0m|0s] ?u?u?u?u?u?u
[*] [7] [1902375/14344391] [13.00] [0d|0h|1m|78s] ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d 
    [7] [585093/1902375] [30.00] [4.00] [0d|0h|0m|8s] ?l?l?l?l?l?l?l
    [7] [487437/1902375] [25.00] [3.00] [0d|0h|0m|0s] ?d?d?d?d?d?d?d
    [7] [292318/1902375] [15.00] [2.00] [0d|0h|0m|1s] ?l?l?l?l?l?d?d
    [7] [193110/1902375] [10.00] [1.00] [0d|0h|0m|3s] ?l?l?l?l?l?l?d
    [7] [178308/1902375] [9.00] [1.00] [0d|0h|0m|0s] ?l?l?l?d?d?d?d
    [7] [111221/1902375] [5.00] [0.00] [0d|0h|0m|0s] ?l?l?l?l?d?d?d
    [7] [54888/1902375] [2.00] [0.00] [0d|0h|0m|0s] ?l?d?d?d?d?d?d
[*] [8] [2114310/14344391] [14.00] [0d|0h|47m|2821s] ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d ?l?d 
    [8] [688053/2114310] [32.00] [4.00] [0d|0h|3m|208s] ?l?l?l?l?l?l?l?l
    [8] [428306/2114310] [20.00] [2.00] [0d|0h|0m|0s] ?d?d?d?d?d?d?d?d
    [8] [420326/2114310] [19.00] [2.00] [0d|0h|0m|30s] ?l?l?l?l?l?l?d?d
    [8] [235364/2114310] [11.00] [1.00] [0d|0h|0m|4s] ?l?l?l?l?d?d?d?d
    [8] [189855/2114310] [8.00] [1.00] [0d|0h|1m|80s] ?l?l?l?l?l?l?l?d
    [8] [152406/2114310] [7.00] [1.00] [0d|0h|0m|11s] ?l?l?l?l?l?d?d?d
[*] [9] [1047021/14344391] [7.00] [0d|7h|470m|28211s] ?d?l ?d?l ?d?l ?d?l ?d?l ?d?l ?d?l ?d?l ?d 
    [9] [307540/1047021] [29.00] [2.00] [0d|0h|0m|1s] ?d?d?d?d?d?d?d?d?d
    [9] [273640/1047021] [26.00] [1.00] [0d|0h|13m|803s] ?l?l?l?l?l?l?l?d?d
    [9] [173560/1047021] [16.00] [1.00] [0d|0h|1m|118s] ?l?l?l?l?l?d?d?d?d
    [9] [160061/1047021] [15.00] [1.00] [0d|0h|34m|2088s] ?l?l?l?l?l?l?l?l?d
    [9] [132220/1047021] [12.00] [0.00] [0d|0h|5m|308s] ?l?l?l?l?l?l?d?d?d
[*] [10] [478224/14344391] [3.00] [0d|0h|0m|10s] ?d ?d ?d ?d ?d ?d ?d ?d ?d ?d 
    [10] [478224/478224] [100.00] [3.00] [0d|0h|0m|10s] ?d?d?d?d?d?d?d?d?d?d
[*] [11] [107864/14344391] [0.00] [0d|0h|1m|100s] ?d ?d ?d ?d ?d ?d ?d ?d ?d ?d ?d 
    [11] [107864/107864] [100.00] [0.00] [0d|0h|1m|100s] ?d?d?d?d?d?d?d?d?d?d?d
[*] Coverage is %51 (7345567/14344391)
[*] Total time 0d|8h|521m|31276s 

Aha! By only losing a few cracked passwords, we have significantly reduced our cracking time. There is a wealth of information that you can analyze, but with enough practice you should be able to achieve that perfect mask combination representative of your target that can be used in your attacks.

There are a few additional parameters which I did not cover before, but that can be useful for generating masks:

--pps - You can specify exact passwords per second speed of your setup
--minlength and --maxlength - Defined minimum and maximum password lengths

--checkmask - Checks how many times a particular mask appears in the sample

For example, if you are interested in finding out how well "?l ?l ?l ?l ?l ?l ?l?d ?l?d" mask will perform in the sample, you can execute the following command:

$ python maskgen.py --checkmask="?l ?l ?l ?l ?l ?l ?l?d ?l?d" --showmasks rockyou.csv

[*] [8] [1305708/14344391] [9.00] [0d|0h|6m|400s] ?l ?l ?l ?l ?l ?l ?l?d ?l?d 
    [8] [688053/1305708] [52.00] [4.00] [0d|0h|3m|208s] ?l?l?l?l?l?l?l?l
    [8] [420326/1305708] [32.00] [2.00] [0d|0h|0m|30s] ?l?l?l?l?l?l?d?d
    [8] [189855/1305708] [14.00] [1.00] [0d|0h|1m|80s] ?l?l?l?l?l?l?l?d
    [8] [7474/1305708] [0.00] [0.00] [0d|0h|1m|80s] ?l?l?l?l?l?l?d?l
[*] Coverage is %9 (1305708/14344391)
[*] Total time 0d|0h|6m|400s 

The above output, will tell you that this mask matches only 9 percent of passwords and will take only 6 minutes of cracking time.

3.0 PolicyGen
--------------

A lot of the dictionary attacks will fail in the corporate environment with minimum password complexity rules. Instead of performing a pure bruteforcing attack, we can leverage known password complexity rules to avoid trying password candidates that are not compliant with the policy (e.g. ?l?l?l?l?l?l?l?l when at least one digit is required). Using PolicyGen, you will be able to generate a list of valid policy compliant (or intentionally non-compliant) rules that can be used to significantly decrease cracking time. Below is a sample session where we generate all valid password masks for the environment requiring at least one digit, one upper, and one special characters.

$ python policygen.py --output=masks.txt --mindigit=1 --minupper=1 --minspecial=1 --length 8 --pps=40000000000
[*] Password policy:
[+] Password length: 8
[+] Minimum strength: lower: 0, upper: 1, digits: 1, special: 1
[+] Maximum strength: lower: 8, upper: 8, digits: 8, special: 8
[*] Total Masks:  65536 Runtime: [1d|38h|2324m|139463s]
[*] Policy Masks: 46620 Runtime: [0d|18h|1097m|65828s]

As you can see from the output above, the total bruteforce runtime for an eight character password is 38 hours. However, when cracking passwords only matching a specific policy, we can reduce this time to only 18 hours!

Here is a snippet of the 'masks.txt' that we have generated above:

?l?l?l?l?l?u?d?s
?l?l?l?l?l?u?s?d
?l?l?l?l?l?d?u?s
?l?l?l?l?l?d?s?u
?l?l?l?l?l?s?u?d
?l?l?l?l?l?s?d?u
?l?l?l?l?u?l?d?s
?l?l?l?l?u?l?s?d
?l?l?l?l?u?u?d?s
?l?l?l?l?u?u?s?d
...

All of the above masks, will contain at least one digit, upper, and special characters.

You can also run PolicyGen in verbose mode to see the exact character and complexity statistics for each mask:

$ python policygen.py --output=masks.txt --mindigit=1 --minupper=1 --minspecial=1 --length 8 --pps=40000000000 --verbose | head
[*] Password policy:
[+] Password length: 8
[+] Minimum strength: lower: 0, upper: 1, digits: 1, special: 1
[+] Maximum strength: lower: 8, upper: 8, digits: 8, special: 8
[*] [0d|0h|0m|2s] ?l?l?l?l?l?u?d?s [l:5 u:1 d:1 s:1]
[*] [0d|0h|0m|2s] ?l?l?l?l?l?u?s?d [l:5 u:1 d:1 s:1]
[*] [0d|0h|0m|2s] ?l?l?l?l?l?d?u?s [l:5 u:1 d:1 s:1]
[*] [0d|0h|0m|2s] ?l?l?l?l?l?d?s?u [l:5 u:1 d:1 s:1]
[*] [0d|0h|0m|2s] ?l?l?l?l?l?s?u?d [l:5 u:1 d:1 s:1]
[*] [0d|0h|0m|2s] ?l?l?l?l?l?s?d?u [l:5 u:1 d:1 s:1]
...

NOTE: You can also use this program to test for compliance of existing passwords to the defined minimum password complexity policy. Simply reverse --mindigit to --maxdigit parameters in order to generate masks matching non-compliant passwords.

4.0 Conclusion
--------------

While this guide introduces a large number of methods to analyze passwords and generate masks, there is a number of tricks that you can discover to truly master the art of password cracking.

Feel free to contact me with bug reports, suggestions, as well as creative use of the tool here: iphelix@gmail.com.

Happy cracking!
	-iphelix