Using PACK - Interesting Results
#1
New to using PACK so maybe using it incorrectly.. here's what I'm seeing:

Code:
python policygen.py --minlength=9 --maxlength=9 --mindigit=1 --maxdigit=3 --minspecial=1 --maxspecial=2 --minupper=1 --maxupper=2 --minlower=1 --maxlower=6
                      _
    PolicyGen 0.0.2  | |
     _ __   __ _  ___| | _
    | '_ \ / _` |/ __| |/ /
    | |_) | (_| | (__|   <
    | .__/ \__,_|\___|_|\_\
    | |                    
    |_| iphelix@thesprawl.org


[*]Using 1,000,000,000 keys/sec for calculations.
[*]Password policy:
   Pass Lengths: min:9 max:9
   Min strength: l:1 u:1 d:1 s:1
   Max strength: l:6 u:2 d:None s:2
[*]Generating [compliant] masks.
[*]Generating 9 character password masks.
[*]Total Masks:  262144 Time: >1 year
[*]Policy Masks: 63000 Time: >1 year

Even though I specify maxdigit=3, in the Max Strength section above, it still says d:None

If I do the following:
Code:
python policygen.py --minlength=9 --maxlength=9 --mindigit=1 --maxdigit=8 --minlower=1
                      _
    PolicyGen 0.0.2  | |
     _ __   __ _  ___| | _
    | '_ \ / _` |/ __| |/ /
    | |_) | (_| | (__|   <
    | .__/ \__,_|\___|_|\_\
    | |                    
    |_| iphelix@thesprawl.org


[*]Using 1,000,000,000 keys/sec for calculations.
[*]Password policy:
   Pass Lengths: min:9 max:9
   Min strength: l:1 u:None d:1 s:None
   Max strength: l:None u:None d:None s:None
[*]Generating [compliant] masks.
[*]Generating 9 character password masks.
[*]Total Masks:  262144 Time: >1 year
[*]Policy Masks: 223290 Time: >1 year

No matter what I do with maxdigit, it doesn't get recognized... I was thinking it was cosmetic so I ran the same command but output it to a file, and sure enough there were extra ?d in the mask lists.

Am I using this incorrectly?  I'm trying to create a mask file that has:
exactly 9 length
min 1 special
max 2 special
min 1 upper
max 2 upper
min 1 digit
max 3 digit
min 1 lower
max 6 lower (since 1 upper 1 special 1 digit is min - that would make 9)
#2
This problem was already reported several months ago (see https://github.com/iphelix/pack/issues/1), but it wasn't merged yet.

I think there are some forked versions that integrate the fix, like the python 3 version of @hydraze https://github.com/Hydraze/pack

You could just make the slight change recommended in the issue and everything should work fine or try to use a newer fork (but I'm not sure what other changes they made to the project etc... I only know that the one from hydraze should be run with python3, which shouldn't be a problem at all).
#3
That worked.  Thanks philsmd.
#4
Now I've got myself thoroughly confused.. I ran the following (using the fix that philsmd pointed me to):
Code:
[*]Using 12,000,000,000 keys/sec for calculations.
[*]Password policy:
   Pass Lengths: min:9 max:9
   Min strength: l:1 u:0 d:0 s:0
   Max strength: l:9 u:1 d:4 s:2
[*]Generating [compliant] masks.
[*]Generating 9 character password masks.
[*]Total Masks:  262144 Time: >1 year
[*]Policy Masks: 28246 Time: 23 days, 19:34:47

Notice it was 9 for min/max length
Lower 1/9
Upper 0/1
Digit 0/4
Special 0/2
Created 28246 policy masks

Then I ran the following:
Code:
[*]Using 12,000,000,000 keys/sec for calculations.
[*]Password policy:
   Pass Lengths: min:9 max:9
   Min strength: l:1 u:2 d:0 s:0
   Max strength: l:7 u:2 d:4 s:2
[*]Generating [compliant] masks.
[*]Generating 9 character password masks.
[*]Total Masks:  262144 Time: >1 year
[*]Policy Masks: 41364 Time: 45 days, 22:01:53

Everything same as first run EXCEPT in this case I'm using Min/Max 2 for UPPER (I've also changed the max for lower to be 7 since min upper is 2).  This created 41364 policy masks.

As a quick "logic-check", I ran the following next:
Code:
[*]Using 12,000,000,000 keys/sec for calculations.
[*]Password policy:
   Pass Lengths: min:9 max:9
   Min strength: l:1 u:0 d:0 s:0
   Max strength: l:9 u:2 d:4 s:2
[*]Generating [compliant] masks.
[*]Generating 9 character password masks.
[*]Total Masks:  262144 Time: >1 year
[*]Policy Masks: 69610 Time: 69 days, 17:36:40

This one is basically the "combination" of the two examples above - it has same MIN/MAX for digit and special.  But for upper it has 0/2 min/max.  All three example using 9 for mask length.

Notice that number of policy masks from example 1 and 2 add up to the number of policy masks in example 3.  So at quick glance I thought my logic was solid.... but then I started thinking about it more and..

I can't figure out why the second example created more policy masks than the first example.  In the first example, it was trying 0 or 1 UPPER.  In the second example, it was trying EXACTLY 2 UPPER (which in my mind means less policy masks).

EDIT:after thinking about this more, I'm guessing the reason for this is that with 2 UPPER's, they have 9 different places they could go in the mask - is this right?