diff --git a/lib/core/option.py b/lib/core/option.py index cf694dd01..5c1b6e353 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -1541,7 +1541,7 @@ def __setKnowledgeBaseAttributes(flushAll=True): kb.testedParams = set() kb.userAgents = None kb.vainRun = True - kb.wordlist = None + kb.wordlists = None def __useWizardInterface(): """ diff --git a/lib/core/wordlist.py b/lib/core/wordlist.py index 1880d52e6..488488515 100644 --- a/lib/core/wordlist.py +++ b/lib/core/wordlist.py @@ -5,21 +5,21 @@ Copyright (c) 2006-2012 sqlmap developers (http://sqlmap.org/) See the file 'doc/COPYING' for copying permission """ -from lib.core.common import singleTimeLogMessage - class Wordlist: """ Iterator for looping over a large dictionaries """ - def __init__(self, filenames): + def __init__(self, filenames, proc_id=None, proc_count=None, custom=None): self.filenames = filenames self.fp = None self.index = 0 + self.counter = -1 self.iter = None - self.custom = [] + self.custom = custom or [] + self.proc_id = proc_id + self.proc_count = proc_count self.adjust() - self.lock = None def __iter__(self): return self @@ -29,22 +29,17 @@ class Wordlist: if self.index > len(self.filenames): raise StopIteration elif self.index == len(self.filenames): - if self.custom: + if not self.proc_id: self.iter = iter(self.custom) else: raise StopIteration else: current = self.filenames[self.index] - infoMsg = "loading dictionary from '%s'" % current - singleTimeLogMessage(infoMsg) self.fp = open(current, "r") self.iter = iter(self.fp) self.index += 1 - def append(self, value): - self.custom.append(value) - def closeFP(self): if self.fp: self.fp.close() @@ -52,16 +47,17 @@ class Wordlist: def next(self): retVal = None - if self.lock: - self.lock.acquire() - try: - retVal = self.iter.next().rstrip() - except StopIteration: - self.adjust() - retVal = self.iter.next().rstrip() - finally: - if self.lock: - self.lock.release() + while True: + try: + retVal = self.iter.next().rstrip() + except StopIteration: + self.adjust() + retVal = self.iter.next().rstrip() + if not self.proc_count: + break + self.counter += 1 + if self.counter % self.proc_count == self.proc_id: + break return retVal def rewind(self): diff --git a/lib/utils/hash.py b/lib/utils/hash.py index 3d1742fb5..e4ed43c9e 100644 --- a/lib/utils/hash.py +++ b/lib/utils/hash.py @@ -410,11 +410,13 @@ def hashRecognition(value): return retVal -def __bruteProcessVariantA(attack_info, hash_regex, wordlist, suffix, retVal, proc_id, proc_count): +def __bruteProcessVariantA(attack_info, hash_regex, suffix, retVal, proc_id, proc_count, wordlists, custom_wordlist): count = 0 rotator = 0 hashes = set([item[0][1] for item in attack_info]) + wordlist = Wordlist(wordlists, proc_id, getattr(proc_count, "value", 0), custom_wordlist) + try: for word in wordlist: if not attack_info: @@ -451,7 +453,7 @@ def __bruteProcessVariantA(attack_info, hash_regex, wordlist, suffix, retVal, pr attack_info.remove(item) - elif (proc_id == 0 or getattr(proc_count, 'value', 0) == 1) and count % HASH_MOD_ITEM_DISPLAY == 0 or hash_regex == HASH.ORACLE_OLD or hash_regex == HASH.CRYPT_GENERIC and IS_WIN: + elif (proc_id == 0 or getattr(proc_count, "value", 0) == 1) and count % HASH_MOD_ITEM_DISPLAY == 0 or hash_regex == HASH.ORACLE_OLD or hash_regex == HASH.CRYPT_GENERIC and IS_WIN: rotator += 1 if rotator >= len(ROTATING_CHARS): rotator = 0 @@ -477,10 +479,12 @@ def __bruteProcessVariantA(attack_info, hash_regex, wordlist, suffix, retVal, pr if hasattr(proc_count, 'value'): proc_count.value -= 1 -def __bruteProcessVariantB(user, hash_, kwargs, hash_regex, wordlist, suffix, retVal, found, proc_id, proc_count): +def __bruteProcessVariantB(user, hash_, kwargs, hash_regex, suffix, retVal, found, proc_id, proc_count, wordlists, custom_wordlist): count = 0 rotator = 0 + wordlist = Wordlist(wordlists, proc_id, getattr(proc_count, "value", 0), custom_wordlist) + try: for word in wordlist: if found.value: @@ -515,7 +519,7 @@ def __bruteProcessVariantB(user, hash_, kwargs, hash_regex, wordlist, suffix, re found.value = True - elif (proc_id == 0 or getattr(proc_count, 'value', 0) == 1) and count % HASH_MOD_ITEM_DISPLAY == 0 or hash_regex == HASH.ORACLE_OLD or hash_regex == HASH.CRYPT_GENERIC and IS_WIN: + elif (proc_id == 0 or getattr(proc_count, "value", 0) == 1) and count % HASH_MOD_ITEM_DISPLAY == 0 or hash_regex == HASH.ORACLE_OLD or hash_regex == HASH.CRYPT_GENERIC and IS_WIN: rotator += 1 if rotator >= len(ROTATING_CHARS): rotator = 0 @@ -545,6 +549,7 @@ def __bruteProcessVariantB(user, hash_, kwargs, hash_regex, wordlist, suffix, re def dictionaryAttack(attack_dict): suffix_list = [""] + custom_wordlist = [] hash_regexes = [] results = [] resumes = [] @@ -610,8 +615,8 @@ def dictionaryAttack(attack_dict): if not attack_info: continue - if not kb.wordlist: - while not kb.wordlist: + if not kb.wordlists: + while not kb.wordlists: # the slowest of all methods hence smaller default dict if hash_regex in (HASH.ORACLE_OLD, HASH.WORDPRESS): @@ -644,10 +649,7 @@ def dictionaryAttack(attack_dict): for dictPath in dictPaths: checkFile(dictPath) - kb.wordlist = Wordlist(dictPaths) - - if _multiprocessing: - kb.wordlist.lock = _multiprocessing.Lock() + kb.wordlists = dictPaths except sqlmapFilePathException, msg: warnMsg = "there was a problem while loading dictionaries" @@ -665,9 +667,8 @@ def dictionaryAttack(attack_dict): for item in attack_info: ((user, _), _) = item - if user and not user.startswith(DUMMY_USER_PREFIX): - kb.wordlist.append(normalizeUnicode(user)) + custom_wordlist.append(normalizeUnicode(user)) if hash_regex in (HASH.MYSQL, HASH.MYSQL_OLD, HASH.MD5_GENERIC, HASH.SHA1_GENERIC): for suffix in suffix_list: @@ -679,13 +680,11 @@ def dictionaryAttack(attack_dict): infoMsg = "using suffix '%s'" % suffix logger.info(infoMsg) - kb.wordlist.rewind() - retVal = None processes = [] try: - if _multiprocessing and not IS_WIN: + if _multiprocessing: if _multiprocessing.cpu_count() > 1: infoMsg = "starting %d processes " % _multiprocessing.cpu_count() singleTimeLogMessage(infoMsg) @@ -694,7 +693,7 @@ def dictionaryAttack(attack_dict): count = _multiprocessing.Value('i', _multiprocessing.cpu_count()) for i in xrange(_multiprocessing.cpu_count()): - p = _multiprocessing.Process(target=__bruteProcessVariantA, args=(attack_info, hash_regex, kb.wordlist, suffix, retVal, i, count)) + p = _multiprocessing.Process(target=__bruteProcessVariantA, args=(attack_info, hash_regex, suffix, retVal, i, count, kb.wordlists, custom_wordlist)) processes.append(p) for p in processes: @@ -709,7 +708,7 @@ def dictionaryAttack(attack_dict): singleTimeWarnMessage(warnMsg) retVal = Queue() - __bruteProcessVariantA(attack_info, hash_regex, kb.wordlist, suffix, retVal, 0, 1) + __bruteProcessVariantA(attack_info, hash_regex, suffix, retVal, 0, 1, kb.wordlists, custom_wordlist) except KeyboardInterrupt: print @@ -751,13 +750,11 @@ def dictionaryAttack(attack_dict): infoMsg = "using suffix '%s'" % suffix logger.info(infoMsg) - kb.wordlist.rewind() - retVal = None processes = [] try: - if _multiprocessing and not IS_WIN: + if _multiprocessing: if _multiprocessing.cpu_count() > 1: infoMsg = "starting %d processes " % _multiprocessing.cpu_count() singleTimeLogMessage(infoMsg) @@ -767,7 +764,7 @@ def dictionaryAttack(attack_dict): count = _multiprocessing.Value('i', _multiprocessing.cpu_count()) for i in xrange(_multiprocessing.cpu_count()): - p = _multiprocessing.Process(target=__bruteProcessVariantB, args=(user, hash_, kwargs, hash_regex, kb.wordlist, suffix, retVal, found_, i, count)) + p = _multiprocessing.Process(target=__bruteProcessVariantB, args=(user, hash_, kwargs, hash_regex, suffix, retVal, found_, i, count, kb.wordlists, custom_wordlist)) processes.append(p) for p in processes: @@ -790,7 +787,7 @@ def dictionaryAttack(attack_dict): found_ = Value() found_.value = False - __bruteProcessVariantB(user, hash_, kwargs, hash_regex, kb.wordlist, suffix, retVal, found_, 0, 1) + __bruteProcessVariantB(user, hash_, kwargs, hash_regex, suffix, retVal, found_, 0, 1, kb.wordlists, custom_wordlist) found = found_.value