10 KiB
maskgen (part of the sprawl's password analysis and cracking toolkit)
Notes
MaskGen allows you to craft pattern-based mask attacks for input into Hashcat family of password crackers. The tool uses output produced by statsgen above with the '-o' flag in order to produce the most optimal mask attack sorted by mask complexity, mask occurrence or ratio of the two (optimal index).
Help Text
Usage: maskgen [options] masksfile.csv
Options:
--version show program's version number and exit
-h, --help show this help message and exit
--minlength=8 Minimum password length
--maxlength=8 Maximum password length
--mintime=MINTIME Minimum time to crack
--maxtime=MAXTIME Maximum time to crack
--complexity=COMPLEXITY
maximum password complexity
--occurence=OCCURENCE
minimum times mask was used
--checkmask=?u?l ?l ?l ?l ?l ?d
check mask coverage
--showmasks Show matching masks
--pps=1000000000 Passwords per Second
Example Usage
Let's run MaskGen with only StatGen's output as an argument:
$ python maskgen.py rockyou.masks
_
MaskGen #.#.# | |
_ __ __ _ ___| | _
| '_ \ / _` |/ __| |/ /
| |_) | (_| | (__| <
| .__/ \__,_|\___|_|\_\
| |
|_| iphelix@thesprawl.org
[*] Analyzing masks in [rockyou.masks]
[*] Using 1,000,000,000 keys/sec for calculations.
[*] Sorting masks by their [optindex].
[*] Finished generating masks:
Masks generated: 146578
Masks coverage: 100% (14344390/14344390)
Masks runtime: >1 year
There are several pieces of information that you should observe:
Default cracking speed used for calculations is 1,000,000,000 keys/sec Default sorting mode is [optindex] equivalent to --optindex flag. 146,578 unique masks were generated which have 100% coverage Total runtime of all generated masks is more than 1 year. Specifying target time
Since you are usually limited in time to perform and craft attacks, maskgen allows you to specify how much time you have to perform mask attacks and will generate the most optimal collection of masks based on the sorting mode. Let's play a bit with different sorting modes and target times:
$ python maskgen.py rockyou.masks --targettime 600 --optindex -q
[*] Analyzing masks in [rockyou.masks]
[*] Using 1,000,000,000 keys/sec for calculations.
[*] Sorting masks by their [optindex].
[!] Target time exceeded.
[*] Finished generating masks:
Masks generated: 779
Masks coverage: 56% (8116195/14344390)
Masks runtime: 0:11:36
$ python maskgen.py rockyou.masks --targettime 600 --complexity -q
[*] Analyzing masks in [rockyou.masks]
[*] Using 1,000,000,000 keys/sec for calculations.
[*] Sorting masks by their [complexity].
[!] Target time exceeded.
[*] Finished generating masks:
Masks generated: 5163
Masks coverage: 31% (4572346/14344390)
Masks runtime: 0:10:01
$ python maskgen.py rockyou.masks --targettime 600 --occurrence -q
[*] Analyzing masks in [rockyou.masks]
[*] Using 1,000,000,000 keys/sec for calculations.
[*] Sorting masks by their [occurrence].
[!] Target time exceeded.
[*] Finished generating masks:
Masks generated: 4
Masks coverage: 16% (2390986/14344390)
Masks runtime: 1:34:05
All of the above runs have target time of 600 seconds (or 10 minutes) with different sorting modes. Based on our experiments, masks generated using OptIndex sorting mode can crack 56% of RockYou passwords in about 10 minutes. At the same time masks generated using Occurrence sorting mode not only have pretty weak coverage of only 16%, but also exceeded specified target time by more than an hour.
NOTE: Masks sorted by complexity can be very effective when attacking policy based lists.
Let's see some of the masks generated by maskgen in optindex mode using the --showmasks flag:
$ python maskgen.py rockyou.masks --targettime 43200 --optindex -q --showmasks
[*] Analyzing masks in [rockyou.masks]
[*] Using 1,000,000,000 keys/sec for calculations.
[*] Sorting masks by their [optindex].
[L:] Mask: [ Occ: ] [ Time: ]
...
[ 7] ?l?d?s?l?l?d?d [6 ] [ 0:00:00]
[ 8] ?s?l?l?l?l?l?l?s [3480 ] [ 0:05:36]
[ 9] ?l?l?l?l?d?d?d?d?s [1553 ] [ 0:02:30]
[ 8] ?d?l?d?d?d?l?l?l [47 ] [ 0:00:04]
[ 8] ?d?l?l?d?l?d?d?l [47 ] [ 0:00:04]
[ 8] ?d?l?l?d?d?l?d?l [47 ] [ 0:00:04]
[ 8] ?d?l?d?l?d?d?l?l [47 ] [ 0:00:04]
[ 8] ?d?d?l?l?d?l?d?l [47 ] [ 0:00:04]
[ 8] ?d?l?d?d?l?l?l?l [122 ] [ 0:00:11]
[ 8] ?u?u?d?u?d?d?d?d [18 ] [ 0:00:01]
[ 6] ?d?s?s?s?s?s [4 ] [ 0:00:00]
[10] ?l?l?l?l?l?l?l?l?d?d [213109 ] [ 5:48:02]
[!] Target time exceeded.
[*] Finished generating masks:
Masks generated: 3970
Masks coverage: 74% (10620959/14344390)
Masks runtime: 16:10:38
Displayed masks follow a pretty intuitive format:
[ 9] ?l?l?l?l?d?d?d?d?s [1553 ] [ 0:02:30]
\ \ \ \
\ \_ generated mask \ \_ mask runtime
\ \
\_ mask length \_ mask occurrence
In the above sample you can see some of the logic that goes into mask generation. For example, while '?s?l?l?l?l?l?l?s' mask has one of the longest runtimes in the sample (5 minutes), it still has higher priority because of its relatively higher occurrence to '?l?l?l?l?d?d?d?d?s'. At the same time, while '?l?d?s?l?l?d?d' has pretty low coverage it still gets a higher priority than other masks because as only a six character mask it executes very quickly.
Specifying mask filters
You can further optimize your generated mask attacks by using filters. For example, you may have sufficiently powerful hardware where you can simple bruteforce all of the passwords up to 8 characters. In this case, you can generate masks only greater than 8 characters using the --minlength flag as follows:
$ python maskgen.py rockyou.masks --targettime 43200 --optindex -q --minlength 8
[*] Analyzing masks in [rockyou.masks]
[*] Using 1,000,000,000 keys/sec for calculations.
[*] Sorting masks by their [optindex].
[!] Target time exceeded.
[*] Finished generating masks:
Masks generated: 585
Masks coverage: 41% (5905182/14344390)
Masks runtime: 15:50:36
Naturally the generated mask coverage was reduced, but these filters become useful when preparing a collection of masks when attacking password lists other than the one used to generate them.
The list below shows additional filters you can use:
Individual Mask Filter Options:
--minlength=8 Minimum password length
--maxlength=8 Maximum password length
--mintime=3600 Minimum mask runtime (seconds)
--maxtime=3600 Maximum mask runtime (seconds)
--mincomplexity=1 Minimum complexity
--maxcomplexity=100
Maximum complexity
--minoccurrence=1 Minimum occurrence
--maxoccurrence=100
Maximum occurrence
Occurrence and complexity flags can be particularly powerful to fine-tune generated masks using different sorting modes.
Saving generated masks
Once you are satisfied with the above generated masks, you can save them using the -o flag:
$ python maskgen.py rockyou.masks --targettime 43200 --optindex -q -o rockyou.hcmask
[*] Analyzing masks in [rockyou.masks]
[*] Saving generated masks to [rockyou.hcmask]
[*] Using 1,000,000,000 keys/sec for calculations.
[*] Sorting masks by their [optindex].
[!] Target time exceeded.
[*] Finished generating masks:
Masks generated: 3970
Masks coverage: 74% (10620959/14344390)
Masks runtime: 16:10:38
This will produce 'rockyou.hcmask' file which can be directly used by Hashcat suite of tools or as part of a custom script that loops through them.
Checking mask coverage
It is often useful to see how well generated masks perform against already cracked lists. Maskgen can compare a collection of masks against others to see how well they would perform if masks from one password list would be attempted against another. Let's compare how well masks generated from RockYou list will perform against another compromised list such as Gawker:
$ python statsgen.py ../PACK-0.0.3/archive/gawker.dic -o gawker.masks
$ python maskgen.py gawker.masks --checkmasksfile rockyou.hcmask -q
[*] Analyzing masks in [gawker.masks]
[*] Using 1,000,000,000 keys/sec for calculations.
[*] Checking coverage of masks in [rockyou.hcmask]
[*] Finished matching masks:
Masks matched: 1775
Masks coverage: 96% (1048889/1084394)
Masks runtime: 16:25:44
Using the '--checkmasksfile' parameter we attempted to run masks inside 'rockyou.hcmask' file generated earlier against masks from a sample leaked list 'gawker.masks'. This results in a good 96% coverage where 1775 of the 3970 total generated RockYou-based masks matched masks in Gawker list.
It is also possible to see the coverage of one or more masks by specifying them directly on the command-line as follows:
$ python maskgen.py gawker.masks --checkmasks="?u?l?l?l?l?l?d,?l?l?l?l?l?d?d" -q
[*] Analyzing masks in [gawker.masks]
[*] Using 1,000,000,000 keys/sec for calculations.
[*] Checking coverage of the these masks [?u?l?l?l?l?l?d, ?l?l?l?l?l?d?d]
[*] Finished matching masks:
Masks matched: 2
Masks coverage: 1% (18144/1084394)
Masks runtime: 0:00:04
Both of the specified masks matched with only 1% coverage.
Specifying speed
Depending on your exact hardware specs and target hash you may want to increase or decrease keys/sec speed used during calculations using the '--pps' parameter:
$ python maskgen.py rockyou.masks --targettime 43200 --pps 50000000 -q
[*] Analyzing masks in [rockyou.masks]
[*] Using 50,000,000 keys/sec for calculations.
[*] Sorting masks by their [optindex].
[!] Target time exceeded.
[*] Finished generating masks:
Masks generated: 1192
Masks coverage: 61% (8754548/14344390)
Masks runtime: 12:17:31
Using the '--pps' parameter to match you actual performance makes target time more meaningful.