Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4513ef4

Browse files
committed
massive (like really massive) dictionary support
1 parent 43db6b0 commit 4513ef4

2 files changed

Lines changed: 78 additions & 13 deletions

File tree

lib/core/common.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,62 @@ def write(self, fp):
132132

133133
fp.write("\n")
134134

135+
class Wordlist:
136+
"""
137+
Iterator for looping over a large dictionaries
138+
"""
139+
140+
def __init__(self, filenames):
141+
self.filenames = filenames
142+
self.fp = None
143+
self.index = 0
144+
self.iter = None
145+
self.cursize = 0
146+
self.custom = []
147+
self.adjust()
148+
149+
def __iter__(self):
150+
return self
151+
152+
def adjust(self):
153+
self.closeFP()
154+
if self.index > len(self.filenames):
155+
raise StopIteration
156+
elif self.index == len(self.filenames):
157+
self.iter = iter(self.custom)
158+
else:
159+
current = self.filenames[self.index]
160+
infoMsg = "loading dictionary from: '%s'" % current
161+
singleTimeLogMessage(infoMsg)
162+
self.fp = open(current, "r")
163+
self.cursize = os.path.getsize(current)
164+
self.iter = self.fp.xreadlines()
165+
self.index += 1
166+
167+
def append(self, value):
168+
self.custom.append(value)
169+
170+
def closeFP(self):
171+
if self.fp:
172+
self.fp.close()
173+
174+
def next(self):
175+
try:
176+
return self.iter.next().rstrip()
177+
except StopIteration:
178+
self.adjust()
179+
return self.iter.next().rstrip()
180+
181+
def percentage(self):
182+
retVal = 0
183+
if self.fp:
184+
retVal = round(100.0 * self.fp.tell() / self.cursize)
185+
return retVal
186+
187+
def rewind(self):
188+
self.index = 0
189+
self.adjust()
190+
135191
class DynamicContentItem:
136192
"""
137193
Represents line in content page with dynamic properties (candidate

lib/utils/hash.py

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
except ImportError, _:
1414
from extra.fcrypt.fcrypt import crypt
1515

16+
import os
1617
import re
1718
import time
1819

@@ -33,6 +34,8 @@
3334
from lib.core.common import normalizeUnicode
3435
from lib.core.common import paths
3536
from lib.core.common import readInput
37+
from lib.core.common import singleTimeLogMessage
38+
from lib.core.common import Wordlist
3639
from lib.core.convert import hexdecode
3740
from lib.core.convert import hexencode
3841
from lib.core.convert import utf8encode
@@ -363,7 +366,6 @@ def dictionaryAttack(attack_dict):
363366
continue
364367

365368
if not kb.wordlist:
366-
367369
while not kb.wordlist:
368370
message = "what dictionary do you want to use?\n"
369371
message += "[1] Default (Press Enter)\n"
@@ -386,15 +388,10 @@ def dictionaryAttack(attack_dict):
386388
else:
387389
dictPaths = [paths.WORDLIST]
388390

389-
kb.wordlist = []
390-
391391
for dictPath in dictPaths:
392392
checkFile(dictPath)
393393

394-
infoMsg = "loading dictionary from: '%s'" % dictPath
395-
logger.info(infoMsg)
396-
397-
kb.wordlist.extend(getFileItems(dictPath, None, False))
394+
kb.wordlist = Wordlist(dictPaths)
398395

399396
except sqlmapFilePathException, msg:
400397
warnMsg = "there was a problem while loading dictionaries"
@@ -416,15 +413,20 @@ def dictionaryAttack(attack_dict):
416413
if user:
417414
kb.wordlist.append(normalizeUnicode(user))
418415

419-
length = len(kb.wordlist) * len(suffix_list)
420-
421416
if hash_regex in (HASH.MYSQL, HASH.MYSQL_OLD, HASH.MD5_GENERIC, HASH.SHA1_GENERIC):
422417
count = 0
423418

424419
for suffix in suffix_list:
425420
if not attack_info:
426421
break
427422

423+
if suffix:
424+
clearConsoleLine()
425+
infoMsg = "using suffix: '%s'" % suffix
426+
logger.info(infoMsg)
427+
428+
kb.wordlist.rewind()
429+
428430
for word in kb.wordlist:
429431
if not attack_info:
430432
break
@@ -458,8 +460,8 @@ def dictionaryAttack(attack_dict):
458460

459461
attack_info.remove(item)
460462

461-
elif count % HASH_MOD_ITEM_DISPLAY == 0 or count == length or hash_regex in (HASH.ORACLE_OLD) or hash_regex == HASH.CRYPT_GENERIC and IS_WIN:
462-
status = '%d/%d words (%d%s)' % (count, length, round(100.0*count/length), '%')
463+
elif count % HASH_MOD_ITEM_DISPLAY == 0 or hash_regex in (HASH.ORACLE_OLD) or hash_regex == HASH.CRYPT_GENERIC and IS_WIN:
464+
status = 'current status: %d%s (%s...)' % (kb.wordlist.percentage(), '%', word.ljust(5)[:5])
463465
dataToStdout("\r[%s] [INFO] %s" % (time.strftime("%X"), status))
464466

465467
except KeyboardInterrupt:
@@ -484,6 +486,13 @@ def dictionaryAttack(attack_dict):
484486
if found:
485487
break
486488

489+
if suffix:
490+
clearConsoleLine()
491+
infoMsg = "using suffix: '%s'" % suffix
492+
logger.info(infoMsg)
493+
494+
kb.wordlist.rewind()
495+
487496
for word in kb.wordlist:
488497
current = __functions__[hash_regex](password = word, uppercase = False, **kwargs)
489498
count += 1
@@ -512,8 +521,8 @@ def dictionaryAttack(attack_dict):
512521

513522
found = True
514523
break
515-
elif count % HASH_MOD_ITEM_DISPLAY == 0 or count == length or hash_regex in (HASH.ORACLE_OLD) or hash_regex == HASH.CRYPT_GENERIC and IS_WIN:
516-
status = '%d/%d words (%d%s)' % (count, length, round(100.0*count/length), '%')
524+
elif count % HASH_MOD_ITEM_DISPLAY == 0 or hash_regex in (HASH.ORACLE_OLD) or hash_regex == HASH.CRYPT_GENERIC and IS_WIN:
525+
status = 'current status: %d%s (%s...)' % (kb.wordlist.percentage(), '%', word.ljust(5)[:5])
517526
if not user.startswith(DUMMY_USER_PREFIX):
518527
status += ' (user: %s)' % user
519528
dataToStdout("\r[%s] [INFO] %s" % (time.strftime("%X"), status))

0 commit comments

Comments
 (0)