Cleaned up source code spacing and added mask output to maskgen.py

This commit is contained in:
iphelix 2013-07-17 19:46:52 -07:00
parent 7cfa4ab6a2
commit 4f84adc320
3 changed files with 361 additions and 340 deletions

View File

@ -29,6 +29,7 @@
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import csv, string import csv, string
import datetime
from operator import itemgetter from operator import itemgetter
from optparse import OptionParser from optparse import OptionParser
@ -47,11 +48,26 @@ allmasks = dict()
def complexity(mask): def complexity(mask):
count = 1 count = 1
for char in mask[1:].split("?"): for char in mask[1:].split("?"):
if char == "l": count *= 26
elif char == "u": count *= 26 # Loweralpha
elif char == "d": count *= 10 if char == "l":
elif char == "s": count *= 33 count *= 26
else: "[!] Error, unknown mask ?%s" % char
# Upperalpha
elif char == "u":
count *= 26
# Numeric
elif char == "d":
count *= 10
# Special
elif char == "s":
count *= 33
# Unknown mask
else:
print "[!] Error, unknown mask ?%s in a mask %s" % (char,mask)
return count return count
@ -59,18 +75,11 @@ def complexity(mask):
## Calculate complexity of a complex mask ## Calculate complexity of a complex mask
################################################################### ###################################################################
def maskcomplexity(mask): def maskcomplexity(mask):
complexity = 1 combined_complexity = 1
for submask in mask.split(" "): for submask in mask.split():
permutations = 0 combined_complexity *= complexity(submask)
for char in submask[1:].split("?"):
if char == "l": permutations += 26
elif char == "u": permutations += 26
elif char == "d": permutations += 10
elif char == "s": permutations += 33
else: "[!] Error, unknown mask ?%s" % char
if permutations: complexity *= permutations
return complexity return combined_complexity
################################################################### ###################################################################
## Check if complex mask matches a sample mask ## Check if complex mask matches a sample mask
@ -100,20 +109,15 @@ def genmask(mask):
global mastermasks global mastermasks
length = len(mask)/2 length = len(mask)/2
try: if not length in mastermasks:
lengthmask = mastermasks[length]
except:
mastermasks[length] = dict() mastermasks[length] = dict()
lengthmask = mastermasks[length]
for i,v in enumerate(mask[1:].split("?")): for i,v in enumerate(mask[1:].split("?")):
try:
positionmask = lengthmask[i]
except:
lengthmask[i] = set()
positionmask = lengthmask[i]
positionmask.add("?%s" % v) if not i in mastermasks[length]:
mastermasks[length][i] = set()
mastermasks[length][i].add("?%s" % v)
################################################################### ###################################################################
## Store all masks in based on length and count ## Store all masks in based on length and count
@ -122,14 +126,10 @@ def storemask(mask,occurrence):
global allmasks global allmasks
length = len(mask)/2 length = len(mask)/2
#print "Storing mask %s" % mask if not length in allmasks:
try:
lengthmask = allmasks[length]
except:
allmasks[length] = dict() allmasks[length] = dict()
lengthmask = allmasks[length]
lengthmask[mask] = int(occurrence) allmasks[length][mask] = int(occurrence)
def main(): def main():
# Constants # Constants
@ -160,6 +160,8 @@ def main():
parser.add_option("--checkmask", dest="checkmask",help="check mask coverage", metavar="?u?l ?l ?l ?l ?l ?d") parser.add_option("--checkmask", dest="checkmask",help="check mask coverage", metavar="?u?l ?l ?l ?l ?l ?d")
parser.add_option("--showmasks", dest="showmasks",help="Show matching masks", action="store_true", default=False) parser.add_option("--showmasks", dest="showmasks",help="Show matching masks", action="store_true", default=False)
parser.add_option("--pps", dest="pps",help="Passwords per Second", type="int", default=pps, metavar="1000000000") parser.add_option("--pps", dest="pps",help="Passwords per Second", type="int", default=pps, metavar="1000000000")
parser.add_option("-o", "--masksoutput", dest="masks_output",help="Save masks to a file", metavar="masks.hcmask")
parser.add_option("-q", "--quiet", action="store_true", dest="quiet", default=False, help="Don't show headers.") parser.add_option("-q", "--quiet", action="store_true", dest="quiet", default=False, help="Don't show headers.")
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
@ -181,12 +183,12 @@ def main():
# Prepare master mask list for analysis # Prepare master mask list for analysis
mastermasks[length] = dict() mastermasks[length] = dict()
lengthmask = mastermasks[length]
for i, submask in enumerate(options.checkmask.split(" ")): for i, submask in enumerate(options.checkmask.split(" ")):
lengthmask[i] = set()
positionmask = lengthmask[i] mastermasks[length][i] = set()
for char in submask[1:].split("?"): for char in submask[1:].split("?"):
positionmask.add("?%s" % char) mastermasks[length][i].add("?%s" % char)
for (mask,occurrence) in maskReader: for (mask,occurrence) in maskReader:
total_occurrence += int(occurrence) total_occurrence += int(occurrence)
@ -213,24 +215,43 @@ def main():
#################################################################################### ####################################################################################
## Analysis ## Analysis
#################################################################################### ####################################################################################
if options.masks_output:
f = open(options.masks_output,'w+')
for length,lengthmask in sorted(mastermasks.iteritems()): for length,lengthmask in sorted(mastermasks.iteritems()):
maskstring = "" maskstring = ""
for position,maskset in lengthmask.iteritems(): maskstring += "%s " % string.join(maskset,"") for position,maskset in lengthmask.iteritems():
maskstring += "%s " % string.join(maskset,"")
mask_time = maskcomplexity(maskstring)/options.pps
sample_time += mask_time
length_occurrence = 0 length_occurrence = 0
combined_mask_time = 0
# Calculate occurrence and time complexity of component masks
# for each password length.
for mask, occurrence in allmasks[length].iteritems(): for mask, occurrence in allmasks[length].iteritems():
length_occurrence += int(occurrence) length_occurrence += int(occurrence)
print "[*] [%d] [%d/%d] [%.02f] [%dd|%dh|%dm|%ds] %s" % (length, length_occurrence, total_occurrence, length_occurrence*100/total_occurrence, mask_time/60/60/24, mask_time/60/60, mask_time/60, mask_time,maskstring) combined_mask_time += complexity(mask)/options.pps
sample_time += combined_mask_time
time_string = "Don't bother."
if not combined_mask_time > 3784320000:
time_string = str(datetime.timedelta(seconds=combined_mask_time))
print "[*] [%d] [%d/%d] [%.02f] [%s]" % (length, length_occurrence, total_occurrence, length_occurrence*100/total_occurrence, time_string)
if options.showmasks: if options.showmasks:
for mask,mask_occurrence in sorted(allmasks[length].iteritems(),key=itemgetter(1),reverse=True): for mask,mask_occurrence in sorted(allmasks[length].iteritems(),key=itemgetter(1),reverse=True):
mask_time = complexity(mask)/options.pps mask_time = complexity(mask)/options.pps
print " [%d] [%d/%d] [%.02f] [%.02f] [%dd|%dh|%dm|%ds] %s" % (length, mask_occurrence, length_occurrence, mask_occurrence*100/length_occurrence, mask_occurrence*100/total_occurrence,mask_time/60/60/24, mask_time/60/60, mask_time/60, mask_time,mask) print " [%d] [%d/%d] [%.02f] [%.02f] [%dd|%dh|%dm|%ds] %s" % (length, mask_occurrence, length_occurrence, mask_occurrence*100/length_occurrence, mask_occurrence*100/total_occurrence,mask_time/60/60/24, mask_time/60/60, mask_time/60, mask_time,mask)
if options.masks_output:
for mask,mask_occurrence in sorted(allmasks[length].iteritems(),key=itemgetter(1),reverse=True):
f.write("%s\n" % mask)
print "[*] Coverage is %%%d (%d/%d)" % (sample_occurrence*100/total_occurrence,sample_occurrence,total_occurrence) print "[*] Coverage is %%%d (%d/%d)" % (sample_occurrence*100/total_occurrence,sample_occurrence,total_occurrence)
print "[*] Total time [%dd|%dh|%dm|%ds]" % (sample_time/60/60/24,sample_time/60/60,sample_time/60,sample_time) print "[*] Total time [%dd|%dh|%dm|%ds]" % (sample_time/60/60/24,sample_time/60/60,sample_time/60,sample_time)

View File

@ -122,7 +122,7 @@ def main():
parser.add_option("-l", "--length", dest="length_filter",help="Password length filter.",metavar="8") parser.add_option("-l", "--length", dest="length_filter",help="Password length filter.",metavar="8")
parser.add_option("-c", "--charset", dest="char_filter", help="Password charset filter.", metavar="loweralpha") parser.add_option("-c", "--charset", dest="char_filter", help="Password charset filter.", metavar="loweralpha")
parser.add_option("-m", "--mask", dest="mask_filter",help="Password mask filter", metavar="stringdigit") parser.add_option("-m", "--mask", dest="mask_filter",help="Password mask filter", metavar="stringdigit")
parser.add_option("-o", "--maskoutput", dest="mask_output",help="Save masks to a file", metavar="masks.csv") parser.add_option("-o", "--masksoutput", dest="mask_output",help="Generate and save masks db to a file", metavar="masks.csv")
parser.add_option("-q", "--quiet", action="store_true", dest="quiet", default=False, help="Don't show headers.") parser.add_option("-q", "--quiet", action="store_true", dest="quiet", default=False, help="Don't show headers.")
(options, args) = parser.parse_args() (options, args) = parser.parse_args()