示例#1
0
    def endElement(self, name):
        if name == "signature":
            for version in (self.__version, self.__versionAlt):
                regObj = getCompiledRegex(" %s[\.\ ]+" % version)
                if version and regObj.search(self.__banner):
                    self.__feedInfo("dbmsRelease", self.__release)
                    self.__feedInfo("dbmsVersion", self.__version)
                    self.__feedInfo("dbmsServicePack", self.__servicePack)
                    break

            self.__version     = ""
            self.__versionAlt  = None
            self.__servicePack = ""

        elif name == "version":
            self.__inVersion = False
            self.__version = self.__version.replace(" ", "")

            regObj = getCompiledRegex(r"\A(?P<major>\d+)\.00\.(?P<build>\d+)\Z")
            match = regObj.search(self.__version)
            self.__versionAlt = "%s.0.%s.0" % (match.group('major'), match.group('build')) if match else None

        elif name == "servicepack":
            self.__inServicePack = False
            self.__servicePack = self.__servicePack.replace(" ", "")
示例#2
0
    def endElement(self, name):
        if name == "signature":
            for version in (self.__version, self.__versionAlt):
                regObj = getCompiledRegex(" %s[\.\ ]+" % version)
                if version and regObj.search(self.__banner):
                    self.__feedInfo("dbmsRelease", self.__release)
                    self.__feedInfo("dbmsVersion", self.__version)
                    self.__feedInfo("dbmsServicePack", self.__servicePack)
                    break

            self.__version     = ""
            self.__versionAlt  = None
            self.__servicePack = ""

        elif name == "version":
            self.__inVersion = False
            self.__version = self.__version.replace(" ", "")

            regObj = getCompiledRegex(r"\A(?P<major>\d+)\.00\.(?P<build>\d+)\Z")
            match = regObj.search(self.__version)
            self.__versionAlt = "%s.0.%s.0" % (match.group('major'), match.group('build')) if match else None

        elif name == "servicepack":
            self.__inServicePack = False
            self.__servicePack = self.__servicePack.replace(" ", "")
示例#3
0
def parseResponse(page, headers):
    """
    @param page: the page to parse to feed the knowledge base htmlFp
    (back-end DBMS fingerprint based upon DBMS error messages return
    through the web application) list and absFilePaths (absolute file
    paths) set.
    """

    if headers:
        headersParser(headers)

    if page:
        htmlParser(page)

        # Detect injectable page absolute system path
        # NOTE: this regular expression works if the remote web
        # application is written in PHP and debug/error messages are
        # enabled
        for regex in ( r" in <b>(?P<result>.*?)</b> on line",  r"(?:>|\s)(?P<result>[A-Za-z]:[\\/][\w.\\/]*)", r"(?:>|\s)(?P<result>/\w[/\w.]+)" ):
            regObj = getCompiledRegex(regex)

            for match in regObj.finditer(page):
                absFilePath = match.group("result").strip()
                page = page.replace(absFilePath, "")

                if isWindowsDriveLetterPath(absFilePath):
                    absFilePath = posixToNtSlashes(absFilePath)

                if absFilePath not in kb.absFilePaths:
                    kb.absFilePaths.add(absFilePath)
示例#4
0
def checkPayload(payload):
    """
    This method checks if the generated payload is detectable by the
    PHPIDS filter rules
    """

    if not payload:
        return

    global rules

    detected = False
    payload = urldecode(payload)

    if not rules:
        xmlrules = readXmlFile(paths.PHPIDS_RULES_XML)
        rules = []

        for xmlrule in xmlrules.getElementsByTagName("filter"):
            rule = "(?i)%s" % xmlrule.getElementsByTagName('rule')[0].childNodes[0].nodeValue
            desc = __adjustGrammar(xmlrule.getElementsByTagName('description')[0].childNodes[0].nodeValue)
            rules.append((rule, desc))

    if payload:
        for rule, desc in rules:
            regObj = getCompiledRegex(rule)

            if regObj.search(payload):
                detected = True
                logger.warn("highly probable IDS/IPS detection: '%s: %s'" % (desc, payload))

    if not detected:
        logger.warn("payload '%s' possibly gone undetected" % payload)
示例#5
0
def replaceVars(item, vars_):
    retVal = item
    if item and vars_:
        for var in re.findall(getCompiledRegex("\$\{([^}]+)\}"), item):
            if var in vars_:
                retVal = retVal.replace("${%s}" % var, vars_[var])
    return retVal
示例#6
0
def checkPayload(payload):
    """
    This method checks if the generated payload is detectable by the
    PHPIDS filter rules
    """

    global rules

    detected = False
    payload = urldecode(payload)

    if not rules:
        xmlrules = readXmlFile(paths.PHPIDS_RULES_XML)
        rules = []

        for xmlrule in xmlrules.getElementsByTagName("filter"):
            rule = "(?i)%s" % xmlrule.getElementsByTagName(
                'rule')[0].childNodes[0].nodeValue
            desc = __adjustGrammar(
                xmlrule.getElementsByTagName('description')
                [0].childNodes[0].nodeValue)
            rules.append((rule, desc))

    if payload:
        for rule, desc in rules:
            regObj = getCompiledRegex(rule)

            if regObj.search(payload):
                detected = True
                logger.warn("highly probable IDS/IPS detection: '%s: %s'" %
                            (desc, payload))

    if not detected:
        logger.warn("payload '%s' possibly gone undetected" % payload)
示例#7
0
def replaceVars(item, vars_):
    retVal = item
    if item and vars_:
        for var in re.findall(getCompiledRegex("\$\{([^}]+)\}"), item):
            if var in vars_:
                retVal = retVal.replace("${%s}" % var, vars_[var])
    return retVal
示例#8
0
文件: hash.py 项目: Marquand/Script
def hashRecognition(value):
    retVal = None

    if isinstance(value, basestring):
        for name, regex in getPublicTypeMembers(HASH):
            # Hashes for Oracle and old MySQL look the same hence these checks
            if Backend.getIdentifiedDbms() == DBMS.ORACLE and regex == HASH.MYSQL_OLD:
                continue
            elif Backend.getIdentifiedDbms() == DBMS.MYSQL and regex == HASH.ORACLE_OLD:
                continue
            elif regex == HASH.CRYPT_GENERIC and getCompiledRegex(GENERAL_IP_ADDRESS_REGEX).match(value):
                continue
            elif getCompiledRegex(regex).match(value):
                retVal = regex
                break

    return retVal
示例#9
0
文件: agent.py 项目: zhiwenuil/sqlmap
    def getFields(self, query):
        """
        Take in input a query string and return its fields (columns) and
        more details.

        Example:

        Input:  SELECT user, password FROM mysql.user
        Output: user,password

        @param query: query to be processed
        @type query: C{str}

        @return: query fields (columns) and more details
        @rtype: C{str}
        """

        prefixRegex = "(?:\s+(?:FIRST|SKIP)\s+\d+)*"
        fieldsSelectTop = getCompiledRegex("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", re.I).search(query)
        fieldsSelectDistinct = getCompiledRegex("\ASELECT%s\s+DISTINCT\((.+?)\)\s+FROM" % prefixRegex, re.I).search(query)
        fieldsSelectCase = getCompiledRegex("\ASELECT%s\s+(\(CASE WHEN\s+.+\s+END\))" % prefixRegex, re.I).search(query)
        fieldsSelectFrom = getCompiledRegex("\ASELECT%s\s+(.+?)\s+FROM\s+" % prefixRegex, re.I).search(query)
        fieldsExists = getCompiledRegex("EXISTS(.*)", re.I).search(query)
        fieldsSelect = getCompiledRegex("\ASELECT%s\s+(.*)" % prefixRegex, re.I).search(query)
        fieldsSubstr = getCompiledRegex("\A(SUBSTR|MID\()", re.I).search(query)
        fieldsMinMaxstr = getCompiledRegex("(?:MIN|MAX)\(([^\(\)]+)\)", re.I).search(query)
        fieldsNoSelect = query

        if fieldsSubstr:
            fieldsToCastStr = query
        elif fieldsMinMaxstr:
            fieldsToCastStr = fieldsMinMaxstr.groups()[0]
        elif fieldsExists:
            fieldsToCastStr = fieldsSelect.groups()[0]
        elif fieldsSelectTop:
            fieldsToCastStr = fieldsSelectTop.groups()[0]
        elif fieldsSelectDistinct:
            fieldsToCastStr = fieldsSelectDistinct.groups()[0]
        elif fieldsSelectCase:
            fieldsToCastStr = fieldsSelectCase.groups()[0]
        elif fieldsSelectFrom:
            fieldsToCastStr = fieldsSelectFrom.groups()[0]
        elif fieldsSelect:
            fieldsToCastStr = fieldsSelect.groups()[0]
        elif fieldsNoSelect:
            fieldsToCastStr = fieldsNoSelect

        # Function
        if re.search("\A\w+\(.*\)", fieldsToCastStr, re.I) or (fieldsSelectCase and "WHEN use" not in query) or fieldsSubstr:
            fieldsToCastList = [fieldsToCastStr]
        else:
            fieldsToCastList = fieldsToCastStr.replace(", ", ",")
            fieldsToCastList = fieldsToCastList.split(",")

        return fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, fieldsToCastList, fieldsToCastStr, fieldsExists
示例#10
0
def hashRecognition(value):
    retVal = None

    if isinstance(value, basestring):
        for name, regex in getPublicTypeMembers(HASH):
            # Hashes for Oracle and old MySQL look the same hence these checks
            if Backend.getIdentifiedDbms(
            ) == DBMS.ORACLE and regex == HASH.MYSQL_OLD:
                continue
            elif Backend.getIdentifiedDbms(
            ) == DBMS.MYSQL and regex == HASH.ORACLE_OLD:
                continue
            elif regex == HASH.CRYPT_GENERIC and getCompiledRegex(
                    GENERAL_IP_ADDRESS_REGEX).match(value):
                continue
            elif getCompiledRegex(regex).match(value):
                retVal = regex
                break

    return retVal
示例#11
0
文件: hash.py 项目: zhiwenuil/sqlmap
def hashRecognition(value):
    retVal = None

    isOracle, isMySQL = Backend.isDbms(DBMS.ORACLE), Backend.isDbms(DBMS.MYSQL)

    if isinstance(value, basestring):
        for name, regex in getPublicTypeMembers(HASH):
            # Hashes for Oracle and old MySQL look the same hence these checks
            if isOracle and regex == HASH.MYSQL_OLD:
                continue
            elif isMySQL and regex == HASH.ORACLE_OLD:
                continue
            elif regex == HASH.CRYPT_GENERIC:
                if any([getCompiledRegex(GENERAL_IP_ADDRESS_REGEX).match(value), value.lower() == value, value.upper() == value, value.isdigit()]):
                    continue
            elif getCompiledRegex(regex).match(value):
                retVal = regex
                break

    return retVal
示例#12
0
文件: agent.py 项目: zhiwenuil/sqlmap
    def replacePayload(self, inpStr, payload):
        """
        Replaces payload inside the input string with a given payload
        """
        retVal = inpStr

        if inpStr:
            regObj = getCompiledRegex("(%s.*?%s)" % (PAYLOAD_DELIMITER, PAYLOAD_DELIMITER))
            retVal = regObj.sub("%s%s%s" % (PAYLOAD_DELIMITER, payload, PAYLOAD_DELIMITER), inpStr)

        return retVal
示例#13
0
    def getRemoteTempPath(self):
        if not conf.tmpPath:
            if kb.os == "Windows":
                conf.tmpPath = "C:/WINDOWS/Temp"
            else:
                conf.tmpPath = "/tmp"

        if getCompiledRegex("(?i)\A[\w]:[\/\\\\]+").search(conf.tmpPath):
            kb.os = "Windows"

        conf.tmpPath = normalizePath(conf.tmpPath)
        conf.tmpPath = ntToPosixSlashes(conf.tmpPath)

        setRemoteTempPath()
示例#14
0
文件: misc.py 项目: zhiwenuil/sqlmap
    def getRemoteTempPath(self):
        if not conf.tmpPath:
            if Backend.isOs(OS.WINDOWS):
                conf.tmpPath = "C:/WINDOWS/Temp"
            else:
                conf.tmpPath = "/tmp"

        if getCompiledRegex("(?i)\A[\w]:[\/\\\\]+").search(conf.tmpPath):
            Backend.setOs(OS.WINDOWS)

        conf.tmpPath = normalizePath(conf.tmpPath)
        conf.tmpPath = ntToPosixSlashes(conf.tmpPath)

        setRemoteTempPath()
示例#15
0
文件: agent.py 项目: zhiwenuil/sqlmap
    def extractPayload(self, inpStr):
        """
        Extracts payload from inside of the input string
        """
        retVal = None

        if inpStr:
            regObj = getCompiledRegex("%s(?P<result>.*?)%s" % (PAYLOAD_DELIMITER, PAYLOAD_DELIMITER))
            match = regObj.search(inpStr)

            if match:
                retVal = match.group("result")

        return retVal
示例#16
0
    def getRemoteTempPath(self):
        if not conf.tmpPath:
            if kb.os == "Windows":
                conf.tmpPath = "C:/WINDOWS/Temp"
            else:
                conf.tmpPath = "/tmp"

        if getCompiledRegex("(?i)\A[\w]:[\/\\\\]+").search(conf.tmpPath):
            kb.os = "Windows"

        conf.tmpPath = normalizePath(conf.tmpPath)
        conf.tmpPath = ntToPosixSlashes(conf.tmpPath)

        setRemoteTempPath()
示例#17
0
    def removePayloadDelimiters(self, inpStr, urlencode_=True):
        """
        Removes payload delimiters from inside the input string
        """
        retVal = inpStr

        if inpStr:
            if urlencode_:
                regObj = getCompiledRegex("(?P<result>%s.*?%s)" % (PAYLOAD_DELIMITER, PAYLOAD_DELIMITER))

                for match in regObj.finditer(inpStr):
                    retVal = retVal.replace(match.group("result"), urlencode(match.group("result").strip(PAYLOAD_DELIMITER), convall=True))
            else:
                retVal = retVal.replace(PAYLOAD_DELIMITER, '')

        return retVal
示例#18
0
def dictionaryAttack(attack_dict):
    suffix_list = [""]
    hash_regexes = []
    results = []

    for (_, hashes) in attack_dict.items():
        for hash_ in hashes:
            if not hash_:
                continue

            hash_ = hash_.split()[0]
            regex = hashRecognition(hash_)

            if regex and regex not in hash_regexes:
                hash_regexes.append(regex)
                infoMsg = "using hash method: '%s'" % __functions__[
                    regex].func_name
                logger.info(infoMsg)

    for hash_regex in hash_regexes:
        attack_info = []

        for (user, hashes) in attack_dict.items():
            for hash_ in hashes:
                if not hash_:
                    continue

                hash_ = hash_.split()[0]

                if getCompiledRegex(hash_regex).match(hash_):
                    hash_ = hash_.lower()

                    if hash_regex in (HASH.MYSQL, HASH.MYSQL_OLD,
                                      HASH.MD5_GENERIC, HASH.SHA1_GENERIC):
                        attack_info.append([(user, hash_), {}])

                    elif hash_regex in (HASH.ORACLE_OLD, HASH.POSTGRES):
                        attack_info.append([(user, hash_), {'username': user}])

                    elif hash_regex in (HASH.ORACLE):
                        attack_info.append([(user, hash_), {
                            'salt': hash_[-20:]
                        }])

                    elif hash_regex in (HASH.MSSQL, HASH.MSSQL_OLD):
                        attack_info.append([(user, hash_), {
                            'salt': hash_[6:14]
                        }])

                    elif hash_regex in (HASH.CRYPT_GENERIC):
                        attack_info.append([(user, hash_), {
                            'salt': hash_[0:2]
                        }])

        if not attack_info:
            continue

        if not kb.wordlist:
            if hash_regex == HASH.ORACLE_OLD:  #it's the slowest of all methods hence smaller default dict
                message = "what's the dictionary's location? [%s]" % paths.ORACLE_DEFAULT_PASSWD
                dictpath = readInput(message,
                                     default=paths.ORACLE_DEFAULT_PASSWD)

            else:
                message = "what's the dictionary's location? [%s]" % paths.WORDLIST
                dictpath = readInput(message, default=paths.WORDLIST)

            checkFile(dictpath)

            infoMsg = "loading dictionary from: '%s'" % dictpath
            logger.info(infoMsg)
            kb.wordlist = getFileItems(dictpath, None, False)

            message = "do you want to use common password suffixes? (slow!) [y/N] "
            test = readInput(message, default="N")

            if test[0] in ("y", "Y"):
                suffix_list += COMMON_PASSWORD_SUFFIXES

        infoMsg = "starting dictionary attack (%s)" % __functions__[
            hash_regex].func_name
        logger.info(infoMsg)

        for item in attack_info:
            ((user, _), _) = item
            kb.wordlist.append(normalizeUnicode(user))

        length = len(kb.wordlist) * len(suffix_list)

        if hash_regex in (HASH.MYSQL, HASH.MYSQL_OLD, HASH.MD5_GENERIC,
                          HASH.SHA1_GENERIC):
            count = 0

            for suffix in suffix_list:
                if not attack_info:
                    break

                for word in kb.wordlist:
                    if not attack_info:
                        break

                    count += 1

                    if suffix:
                        word = word + suffix

                    try:
                        current = __functions__[hash_regex](password=word,
                                                            uppercase=False)

                        for item in attack_info:
                            ((user, hash_), _) = item

                            if hash_ == current:
                                results.append((user, hash_, word))
                                clearConsoleLine()

                                infoMsg = "[%s] [INFO] found: '%s'" % (
                                    time.strftime("%X"), word)

                                if user and not user.startswith(
                                        DUMMY_USER_PREFIX):
                                    infoMsg += " for user: '******'\n" % user
                                else:
                                    infoMsg += " for hash: '%s'\n" % hash_

                                dataToStdout(infoMsg, True)

                                attack_info.remove(item)

                            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:
                                status = '%d/%d words (%d%s)' % (
                                    count, length, round(
                                        100.0 * count / length), '%')
                                dataToStdout("\r[%s] [INFO] %s" %
                                             (time.strftime("%X"), status))

                    except KeyboardInterrupt:
                        print
                        warnMsg = "user aborted during dictionary attack phase"
                        logger.warn(warnMsg)
                        return results

                    except:
                        warnMsg = "there was a problem while hashing entry: %s. " % repr(
                            word)
                        warnMsg += "Please report by e-mail to %s." % ML
                        logger.critical(warnMsg)

            clearConsoleLine()

        else:
            for ((user, hash_), kwargs) in attack_info:
                count = 0
                found = False

                for suffix in suffix_list:
                    if found:
                        break

                    for word in kb.wordlist:
                        current = __functions__[hash_regex](password=word,
                                                            uppercase=False,
                                                            **kwargs)
                        count += 1

                        if suffix:
                            word = word + suffix

                        try:
                            if hash_ == current:
                                if regex == HASH.ORACLE_OLD:  #only for cosmetic purposes
                                    word = word.upper()
                                results.append((user, hash_, word))
                                clearConsoleLine()

                                infoMsg = "[%s] [INFO] found: '%s'" % (
                                    time.strftime("%X"), word)

                                if user and not user.startswith(
                                        DUMMY_USER_PREFIX):
                                    infoMsg += " for user: '******'\n" % user
                                else:
                                    infoMsg += " for hash: '%s'\n" % hash_

                                dataToStdout(infoMsg, True)

                                found = True
                                break
                            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:
                                status = '%d/%d words (%d%s)' % (
                                    count, length, round(
                                        100.0 * count / length), '%')
                                if not user.startswith(DUMMY_USER_PREFIX):
                                    status += ' (user: %s)' % user
                                dataToStdout("\r[%s] [INFO] %s" %
                                             (time.strftime("%X"), status))

                        except KeyboardInterrupt:
                            print
                            warnMsg = "user aborted during dictionary attack phase"
                            logger.warn(warnMsg)
                            return results

                        except:
                            warnMsg = "there was a problem while hashing entry: %s. " % repr(
                                word)
                            warnMsg += "Please report by e-mail to %s." % ML
                            logger.critical(warnMsg)

                clearConsoleLine()

    if len(hash_regexes) == 0:
        warnMsg = "unknown hash Format. "
        warnMsg += "Please report by e-mail to %s." % ML
        logger.warn(warnMsg)

    if len(results) == 0:
        warnMsg = "no clear password(s) found"
        logger.warn(warnMsg)

    return results
示例#19
0
def resume(expression, payload):
    """
    This function can be called to resume part or entire output of a
    SQL injection query output.
    """

    try:
        if "sqlmapfile" in expression or "sqlmapoutput" in expression or conf.freshQueries:
            return None

        condition = (
                      kb.resumedQueries and conf.url in kb.resumedQueries
                      and expression in kb.resumedQueries[conf.url]
                    )

        if not condition:
            return None

        resumedValue = kb.resumedQueries[conf.url][expression]

        if not resumedValue:
            return None

        resumedValue = restoreDumpMarkedChars(resumedValue, True)

        if resumedValue[-1] == "]":
            resumedValue = resumedValue[:-1]

            infoMsg = "read from file '%s': " % conf.sessionFile
            logValue = getCompiledRegex("%s(.*?)%s" % (DUMP_START_MARKER, DUMP_STOP_MARKER), re.S).findall(resumedValue)

            if logValue:
                if kb.technique == PAYLOAD.TECHNIQUE.UNION:
                    logValue = ", ".join([value.replace(DUMP_DEL_MARKER, ", ") for value in logValue])
                else:
                    return None
            else:
                logValue = resumedValue

            if "\n" in logValue:
                infoMsg += "%s..." % logValue.split("\n")[0]
            else:
                infoMsg += logValue

            if not kb.suppressResumeInfo:
                dataToStdout("[%s] [INFO] %s\n" % (time.strftime("%X"), infoMsg))

            return resumedValue

        # If we called this function without providing a payload it means
        # that we have called it from lib/request/inject __goInband() or
        # from __goError() function so we return to the calling function
        # so that the query output will be retrieved taking advantage
        # of either error-based or inband SQL injection vulnerability.
        if not payload:
            return None

        if not Backend.getIdentifiedDbms():
            return None

        substringQuery = queries[Backend.getIdentifiedDbms()].substring.query
        select = getCompiledRegex("\ASELECT ", re.I).search(expression)

        _, length, regExpr = queryOutputLength(expression, payload)

        if not length:
            return None

        if len(resumedValue) == int(length):
            infoMsg = "read from file '%s': " % conf.sessionFile
            infoMsg += "%s" % resumedValue.split("\n")[0]
            logger.info(infoMsg)

            dataToSessionFile("[%s][%s][%s][%s][%s]\n" % (conf.url, kb.injection.place, conf.parameters[kb.injection.place], expression, replaceNewlineTabs(resumedValue)))

            return resumedValue
        elif len(resumedValue) < int(length):
            infoMsg = "resumed from file '%s': " % conf.sessionFile
            infoMsg += "%s..." % resumedValue.split("\n")[0]
            logger.info(infoMsg)

            dataToSessionFile("[%s][%s][%s][%s][%s" % (conf.url, kb.injection.place, conf.parameters[kb.injection.place], expression, replaceNewlineTabs(resumedValue)))

            if select:
                newExpr = expression.replace(regExpr, safeStringFormat(substringQuery, (regExpr, len(resumedValue) + 1, int(length))), 1)
            else:
                newExpr = safeStringFormat(substringQuery, (expression, len(resumedValue) + 1, int(length)))

            missingCharsLength = int(length) - len(resumedValue)

            infoMsg = "retrieving pending %d query " % missingCharsLength
            infoMsg += "output characters"
            logger.info(infoMsg)

            start = time.time()
            count, finalValue = bisection(payload, newExpr, length=missingCharsLength)

            debugMsg = "performed %d queries in %d seconds" % (count, calculateDeltaSeconds(start))
            logger.debug(debugMsg)

            if len(finalValue) != ( int(length) - len(resumedValue) ):
                warnMsg = "the total length of the query is not "
                warnMsg += "right, sqlmap is going to retrieve the "
                warnMsg += "query value from the beginning now"
                logger.warn(warnMsg)

                return None

            return "%s%s" % (resumedValue, finalValue)

        return None
    except ValueError:
        errMsg = "invalid resume value for expression: '%s'" % expression
        logger.error(errMsg)
        return None
示例#20
0
文件: hash.py 项目: Marquand/Script
def dictionaryAttack(attack_dict):
    suffix_list = [""]
    hash_regexes = []
    results = []

    for (_, hashes) in attack_dict.items():
        for hash_ in hashes:
            if not hash_:
                continue

            hash_ = hash_.split()[0]
            regex = hashRecognition(hash_)

            if regex and regex not in hash_regexes:
                hash_regexes.append(regex)
                infoMsg = "using hash method: '%s'" % __functions__[regex].func_name
                logger.info(infoMsg)

    for hash_regex in hash_regexes:
        attack_info = []

        for (user, hashes) in attack_dict.items():
            for hash_ in hashes:
                if not hash_:
                    continue

                hash_ = hash_.split()[0]

                if getCompiledRegex(hash_regex).match(hash_):
                    hash_ = hash_.lower()

                    if hash_regex in (HASH.MYSQL, HASH.MYSQL_OLD, HASH.MD5_GENERIC, HASH.SHA1_GENERIC):
                        attack_info.append([(user, hash_), {}])

                    elif hash_regex in (HASH.ORACLE_OLD, HASH.POSTGRES):
                        attack_info.append([(user, hash_), {'username': user}])

                    elif hash_regex in (HASH.ORACLE):
                        attack_info.append([(user, hash_), {'salt': hash_[-20:]}])

                    elif hash_regex in (HASH.MSSQL, HASH.MSSQL_OLD):
                        attack_info.append([(user, hash_), {'salt': hash_[6:14]}])

                    elif hash_regex in (HASH.CRYPT_GENERIC):
                        attack_info.append([(user, hash_), {'salt': hash_[0:2]}])

        if not attack_info:
            continue

        if not kb.wordlist:
            if hash_regex == HASH.ORACLE_OLD: #it's the slowest of all methods hence smaller default dict
                message = "what's the dictionary's location? [%s]" % paths.ORACLE_DEFAULT_PASSWD
                dictpath = readInput(message, default=paths.ORACLE_DEFAULT_PASSWD)

            else:
                message = "what's the dictionary's location? [%s]" % paths.WORDLIST
                dictpath = readInput(message, default=paths.WORDLIST)

            checkFile(dictpath)

            infoMsg = "loading dictionary from: '%s'" % dictpath
            logger.info(infoMsg)
            kb.wordlist = getFileItems(dictpath, None, False)

            message = "do you want to use common password suffixes? (slow!) [y/N] "
            test = readInput(message, default="N")

            if test[0] in ("y", "Y"):
                suffix_list += COMMON_PASSWORD_SUFFIXES

        infoMsg = "starting dictionary attack (%s)" % __functions__[hash_regex].func_name
        logger.info(infoMsg)

        for item in attack_info:
            ((user, _), _) = item
            kb.wordlist.append(normalizeUnicode(user))

        length = len(kb.wordlist) * len(suffix_list)

        if hash_regex in (HASH.MYSQL, HASH.MYSQL_OLD, HASH.MD5_GENERIC, HASH.SHA1_GENERIC):
            count = 0

            for suffix in suffix_list:
                if not attack_info:
                    break

                for word in kb.wordlist:
                    if not attack_info:
                        break

                    count += 1

                    if suffix:
                        word = word + suffix

                    try:
                        current = __functions__[hash_regex](password = word, uppercase = False)

                        for item in attack_info:
                            ((user, hash_), _) = item

                            if hash_ == current:
                                results.append((user, hash_, word))
                                clearConsoleLine()

                                infoMsg = "[%s] [INFO] found: '%s'" % (time.strftime("%X"), word)

                                if user and not user.startswith(DUMMY_USER_PREFIX):
                                    infoMsg += " for user: '******'\n" % user
                                else:
                                    infoMsg += " for hash: '%s'\n" % hash_

                                dataToStdout(infoMsg, True)

                                attack_info.remove(item)

                            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:
                                status = '%d/%d words (%d%s)' % (count, length, round(100.0*count/length), '%')
                                dataToStdout("\r[%s] [INFO] %s" % (time.strftime("%X"), status))

                    except KeyboardInterrupt:
                        print
                        warnMsg = "user aborted during dictionary attack phase"
                        logger.warn(warnMsg)
                        return results

                    except:
                        warnMsg = "there was a problem while hashing entry: %s. " % repr(word)
                        warnMsg += "Please report by e-mail to %s." % ML
                        logger.critical(warnMsg)

            clearConsoleLine()

        else:
            for ((user, hash_), kwargs) in attack_info:
                count = 0
                found = False

                for suffix in suffix_list:
                    if found:
                        break

                    for word in kb.wordlist:
                        current = __functions__[hash_regex](password = word, uppercase = False, **kwargs)
                        count += 1

                        if suffix:
                            word = word + suffix

                        try:
                            if hash_ == current:
                                if regex == HASH.ORACLE_OLD: #only for cosmetic purposes
                                    word = word.upper()
                                results.append((user, hash_, word))
                                clearConsoleLine()

                                infoMsg = "[%s] [INFO] found: '%s'" % (time.strftime("%X"), word)

                                if user and not user.startswith(DUMMY_USER_PREFIX):
                                    infoMsg += " for user: '******'\n" % user
                                else:
                                    infoMsg += " for hash: '%s'\n" % hash_

                                dataToStdout(infoMsg, True)

                                found = True
                                break
                            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:
                                status = '%d/%d words (%d%s)' % (count, length, round(100.0*count/length), '%')
                                if not user.startswith(DUMMY_USER_PREFIX):
                                    status += ' (user: %s)' % user
                                dataToStdout("\r[%s] [INFO] %s" % (time.strftime("%X"), status))

                        except KeyboardInterrupt:
                            print
                            warnMsg = "user aborted during dictionary attack phase"
                            logger.warn(warnMsg)
                            return results

                        except:
                            warnMsg = "there was a problem while hashing entry: %s. " % repr(word)
                            warnMsg += "Please report by e-mail to %s." % ML
                            logger.critical(warnMsg)

                clearConsoleLine()

    if len(hash_regexes) == 0:
        warnMsg  = "unknown hash Format. "
        warnMsg += "Please report by e-mail to %s." % ML
        logger.warn(warnMsg)

    if len(results) == 0:
        warnMsg  = "no clear password(s) found"
        logger.warn(warnMsg)

    return results
示例#21
0
文件: hash.py 项目: zhiwenuil/sqlmap
def dictionaryAttack(attack_dict):
    suffix_list = [""]
    hash_regexes = []
    results = []
    resumes = []
    processException = False

    for (_, hashes) in attack_dict.items():
        for hash_ in hashes:
            if not hash_:
                continue

            hash_ = hash_.split()[0]
            regex = hashRecognition(hash_)

            if regex and regex not in hash_regexes:
                hash_regexes.append(regex)
                infoMsg = "using hash method '%s'" % __functions__[regex].func_name
                logger.info(infoMsg)

    for hash_regex in hash_regexes:
        keys = set()
        attack_info = []

        for (user, hashes) in attack_dict.items():
            for hash_ in hashes:
                if not hash_:
                    continue

                hash_ = hash_.split()[0].lower()

                if getCompiledRegex(hash_regex).match(hash_):
                    item = None

                    if hash_regex in (HASH.MYSQL, HASH.MYSQL_OLD, HASH.MD5_GENERIC, HASH.SHA1_GENERIC):
                        item = [(user, hash_), {}]
                    elif hash_regex in (HASH.ORACLE_OLD, HASH.POSTGRES):
                        item = [(user, hash_), {'username': user}]
                    elif hash_regex in (HASH.ORACLE):
                        item = [(user, hash_), {'salt': hash_[-20:]}]
                    elif hash_regex in (HASH.MSSQL, HASH.MSSQL_OLD):
                        item = [(user, hash_), {'salt': hash_[6:14]}]
                    elif hash_regex in (HASH.CRYPT_GENERIC):
                        item = [(user, hash_), {'salt': hash_[0:2]}]

                    if item and hash_ not in keys:
                        resumed = conf.hashDB.retrieve(hash_)
                        if not resumed:
                            attack_info.append(item)
                        else:
                            infoMsg = "resuming password '%s' for hash '%s'" % (resumed, hash_)
                            if user and not user.startswith(DUMMY_USER_PREFIX):
                                infoMsg += " for user '%s'" % user
                            logger.info(infoMsg)
                            resumes.append((user, hash_, resumed))
                        keys.add(hash_)

        if not attack_info:
            continue

        if not kb.wordlist:
            while not kb.wordlist:
                message = "what dictionary do you want to use?\n"
                message += "[1] default dictionary file (press Enter)\n"
                message += "[2] custom dictionary file\n"
                message += "[3] file with list of dictionary files"
                choice = readInput(message, default="1")

                try:
                    if choice == "2":
                        message = "what's the custom dictionary's location?\n"
                        dictPaths = [readInput(message)]

                        logger.info("using custom dictionary")
                    elif choice == "3":
                        message = "what's the list file location?\n"
                        listPath = readInput(message)
                        checkFile(listPath)
                        dictPaths = getFileItems(listPath)

                        logger.info("using custom list of dictionaries")
                    else:
                        # It is the slowest of all methods hence smaller default dict
                        if hash_regex == HASH.ORACLE_OLD:
                            dictPaths = [paths.SMALL_DICT]
                        else:
                            dictPaths = [paths.WORDLIST]

                        logger.info("using default dictionary")

                    for dictPath in dictPaths:
                        checkFile(dictPath)

                    kb.wordlist = Wordlist(dictPaths)

                    if _multiprocessing:
                        kb.wordlist.lock = _multiprocessing.Lock()

                except sqlmapFilePathException, msg:
                    warnMsg = "there was a problem while loading dictionaries"
                    warnMsg += " ('%s')" % msg
                    logger.critical(warnMsg)

            message = "do you want to use common password suffixes? (slow!) [y/N] "
            test = readInput(message, default="N")

            if test[0] in ("y", "Y"):
                suffix_list += COMMON_PASSWORD_SUFFIXES

        infoMsg = "starting dictionary-based cracking (%s)" % __functions__[hash_regex].func_name
        logger.info(infoMsg)

        for item in attack_info:
            ((user, _), _) = item

            if user and not user.startswith(DUMMY_USER_PREFIX):
                kb.wordlist.append(normalizeUnicode(user))

        if hash_regex in (HASH.MYSQL, HASH.MYSQL_OLD, HASH.MD5_GENERIC, HASH.SHA1_GENERIC):
            for suffix in suffix_list:
                if len(attack_info) == len(results) or processException:
                    break

                if suffix:
                    clearConsoleLine()
                    infoMsg = "using suffix '%s'" % suffix
                    logger.info(infoMsg)

                kb.wordlist.rewind()

                retVal = None
                processes = []

                try:
                    if _multiprocessing and not IS_WIN:
                        if _multiprocessing.cpu_count() > 1:
                            infoMsg = "starting %d processes " % _multiprocessing.cpu_count()
                            singleTimeLogMessage(infoMsg)

                        retVal = _multiprocessing.Queue()
                        for i in xrange(_multiprocessing.cpu_count()):
                            p = _multiprocessing.Process(target=__bruteProcessVariantA, args=(attack_info, hash_regex, kb.wordlist, suffix, retVal, i, _multiprocessing.cpu_count()))
                            processes.append(p)

                        for p in processes:
                            p.start()

                        for p in processes:
                            p.join()

                    else:
                        warnMsg = "multiprocessing hash cracking is currently "
                        warnMsg += "not supported on this platform"
                        singleTimeWarnMessage(warnMsg)

                        retVal = Queue()
                        __bruteProcessVariantA(attack_info, hash_regex, kb.wordlist, suffix, retVal, 0, 1)

                except KeyboardInterrupt:
                    print
                    processException = True
                    warnMsg = "user aborted during dictionary-based attack phase (Ctrl+C was pressed)"
                    logger.warn(warnMsg)

                    for process in processes:
                        process.terminate()
                        process.join()

                finally:
                    if retVal:
                        conf.hashDB.beginTransaction()
                        while not retVal.empty():
                            _, hash_, word = item = retVal.get(block=False)
                            conf.hashDB.write(hash_, word)
                            results.append(item)
                        conf.hashDB.endTransaction()

            clearConsoleLine()

        else:
            for ((user, hash_), kwargs) in attack_info:
                if processException:
                    break

                count = 0
                found = False

                for suffix in suffix_list:
                    if found or processException:
                        break

                    if suffix:
                        clearConsoleLine()
                        infoMsg = "using suffix '%s'" % suffix
                        logger.info(infoMsg)

                    kb.wordlist.rewind()

                    retVal = None
                    processes = []

                    try:
                        if _multiprocessing and not IS_WIN:
                            if _multiprocessing.cpu_count() > 1:
                                infoMsg = "starting %d processes " % _multiprocessing.cpu_count()
                                singleTimeLogMessage(infoMsg)

                            retVal = _multiprocessing.Queue()
                            found_ = _multiprocessing.Value('i', False)

                            for i in xrange(_multiprocessing.cpu_count()):
                                p = _multiprocessing.Process(target=__bruteProcessVariantB, args=(user, hash_, kwargs, hash_regex, kb.wordlist, suffix, retVal, found_, i, _multiprocessing.cpu_count()))
                                processes.append(p)

                            for p in processes:
                                p.start()

                            for p in processes:
                                p.join()

                            found = found_.value != 0

                        else:
                            warnMsg = "multiprocessing hash cracking is currently "
                            warnMsg += "not supported on this platform"
                            singleTimeWarnMessage(warnMsg)

                            class Value():
                                pass

                            retVal = Queue()
                            found_ = Value()
                            found_.value = False

                            __bruteProcessVariantB(user, hash_, kwargs, hash_regex, kb.wordlist, suffix, retVal, found_, 0, 1)

                            found = found_.value

                    except KeyboardInterrupt:
                        print
                        processException = True
                        warnMsg = "user aborted during dictionary-based attack phase (Ctrl+C was pressed)"
                        logger.warn(warnMsg)

                        for process in processes:
                            process.terminate()
                            process.join()

                    finally:
                        if retVal:
                            conf.hashDB.beginTransaction()
                            while not retVal.empty():
                                _, hash_, word = item = retVal.get(block=False)
                                conf.hashDB.write(hash_, word)
                                results.append(item)
                            conf.hashDB.endTransaction()

                clearConsoleLine()