示例#1
0
def getFile(filename, commentPrefix='#', lowercase=False, unique=False):

    retVal = list() if not unique else OrderedDict()

    if filename:
        filename = filename.strip('"\'')

    checkFile(filename)

    try:
        with open(filename, 'r') as f:
            for l in f:
                if commentPrefix:
                    if l.find(commentPrefix) != -1:
                        l = l[:l.find(commentPrefix)]

                line = line.strip()

                if line:
                    if lowercase:
                        line = line.lower()

                    if unique and line in retVal:
                        continue

                    if unique:
                        retVal[line] = True
                    else:
                        retVal.append(line)
    except (IOError, OSError, MemoryError) as ex:
        errMsg = "something went wrong while trying "
        errMsg += "to read the content of file '%s' ('%s')" % (filename, (ex))
        raise warnings(errMsg)

    return retVal if not unique else list(retVal.keys())
示例#2
0
class LRUDict(object):
    def __init__(self, capacity):
        self.capacity = capacity
        self.cache = OrderedDict()

    def __len__(self):
        return len(self.cache)

    def __contains__(self, key):
        return key in self.cache

    def __getitem__(self, key):
        value = self.cache.pop(key)
        self.cache[key] = value
        return value

    def get(self, key):
        return self.__getitem__(key)

    def __setitem__(self, key, value):
        try:
            self.cache.pop(key)
        except KeyError:
            if len(self.cache) >= self.capacity:
                self.cache.popitem(last=False)
        self.cache[key] = value

    def set(self, key, value):
        self.__setitem__(key, value)

    def keys(self):
        return self.cache.keys()
示例#3
0
def getFileItems(filename,
                 commentPrefix='#',
                 unicode_=True,
                 lowercase=False,
                 unique=False):
    """
    @function returns newline delimited items contained inside file
    """

    retVal = list() if not unique else OrderedDict()

    checkFile(filename)

    try:
        with open(filename, 'r') as f:
            for line in (f.readlines() if unicode_ else f.xreadlines()):
                # xreadlines doesn't return unicode strings when codecs.open() is used
                if commentPrefix and line.find(commentPrefix) != -1:
                    line = line[:line.find(commentPrefix)]

                line = line.strip()

                if not unicode_:
                    try:
                        line = str.encode(line)
                    except UnicodeDecodeError:
                        continue

                if line:
                    if lowercase:
                        line = line.lower()

                    if unique and line in retVal:
                        continue

                    if unique:
                        retVal[line] = True

                    else:
                        retVal.append(line)

    except (IOError, OSError, MemoryError) as ex:
        errMsg = "something went wrong while trying "
        errMsg += "to read the content of file '%s' ('%s')" % (filename, ex)
        raise ToolkitSystemException(errMsg)

    return retVal if not unique else retVal.keys()
示例#4
0
文件: use.py 项目: wellr00t3d/sqlmap
                    def unionThread():
                        threadData = getCurrentThreadData()

                        while kb.threadContinue:
                            with kb.locks.limit:
                                try:
                                    valueStart = time.time()
                                    threadData.shared.counter += 1
                                    num = threadData.shared.limits.next()
                                except StopIteration:
                                    break

                            if Backend.getIdentifiedDbms() in (DBMS.MSSQL,
                                                               DBMS.SYBASE):
                                field = expressionFieldsList[0]
                            elif Backend.isDbms(DBMS.ORACLE):
                                field = expressionFieldsList
                            else:
                                field = None

                            limitedExpr = agent.limitQuery(
                                num, expression, field)
                            output = _oneShotUnionUse(limitedExpr, unpack,
                                                      True)

                            if not kb.threadContinue:
                                break

                            if output:
                                with kb.locks.value:
                                    if all(_ in output
                                           for _ in (kb.chars.start,
                                                     kb.chars.stop)):
                                        items = parseUnionPage(output)

                                        if threadData.shared.showEta:
                                            threadData.shared.progress.progress(
                                                threadData.shared.counter)
                                        if isListLike(items):
                                            # in case that we requested N columns and we get M!=N then we have to filter a bit
                                            if len(items) > 1 and len(
                                                    expressionFieldsList) > 1:
                                                items = [
                                                    item for item in items
                                                    if isListLike(item)
                                                    and len(item) == len(
                                                        expressionFieldsList)
                                                ]
                                            items = [
                                                _ for _ in flattenValue(items)
                                            ]
                                            if len(items) > len(
                                                    expressionFieldsList):
                                                filtered = OrderedDict()
                                                for item in items:
                                                    key = re.sub(
                                                        r"[^A-Za-z0-9]", "",
                                                        item).lower()
                                                    if key not in filtered or re.search(
                                                            r"[^A-Za-z0-9]",
                                                            item):
                                                        filtered[key] = item
                                                items = filtered.values()
                                            items = [items]
                                        index = None
                                        for index in xrange(1 + len(
                                                threadData.shared.buffered)):
                                            if index < len(
                                                    threadData.shared.buffered
                                            ) and threadData.shared.buffered[
                                                    index][0] >= num:
                                                break
                                        threadData.shared.buffered.insert(
                                            index or 0, (num, items))
                                    else:
                                        index = None
                                        if threadData.shared.showEta:
                                            threadData.shared.progress.progress(
                                                threadData.shared.counter)
                                        for index in xrange(1 + len(
                                                threadData.shared.buffered)):
                                            if index < len(
                                                    threadData.shared.buffered
                                            ) and threadData.shared.buffered[
                                                    index][0] >= num:
                                                break
                                        threadData.shared.buffered.insert(
                                            index or 0, (num, None))

                                        items = output.replace(
                                            kb.chars.start, "").replace(
                                                kb.chars.stop,
                                                "").split(kb.chars.delimiter)

                                    while threadData.shared.buffered and (
                                            threadData.shared.lastFlushed + 1
                                            >= threadData.shared.buffered[0][0]
                                            or
                                            len(threadData.shared.buffered) >
                                            MAX_BUFFERED_PARTIAL_UNION_LENGTH):
                                        threadData.shared.lastFlushed, _ = threadData.shared.buffered[
                                            0]
                                        if not isNoneValue(_):
                                            threadData.shared.value.extend(
                                                arrayizeValue(_))
                                        del threadData.shared.buffered[0]

                                if conf.verbose == 1 and not (
                                        threadData.resumed
                                        and kb.suppressResumeInfo
                                ) and not threadData.shared.showEta:
                                    _ = ','.join(
                                        "\"%s\"" % _ for _ in
                                        flattenValue(arrayizeValue(
                                            items))) if not isinstance(
                                                items, basestring) else items
                                    status = "[%s] [INFO] %s: %s" % (
                                        time.strftime("%X"), "resumed"
                                        if threadData.resumed else "retrieved",
                                        _ if kb.safeCharEncode else
                                        safecharencode(_))

                                    if len(status) > width:
                                        status = "%s..." % status[:width - 3]

                                    dataToStdout("%s\n" % status)
示例#5
0
def _setRequestParams():
    """
    Check and set the parameters and perform checks on 'data' option for
    HTTP method POST.
    """

    if conf.direct:
        conf.parameters[None] = "direct connection"
        return

    testableParameters = False

    # Perform checks on GET parameters
    if conf.parameters.get(PLACE.GET):
        parameters = conf.parameters[PLACE.GET]
        paramDict = paramToDict(PLACE.GET, parameters)

        if paramDict:
            conf.paramDict[PLACE.GET] = paramDict
            testableParameters = True

    # Perform checks on POST parameters
    if conf.method == HTTPMETHOD.POST and conf.data is None:
        errMsg = "HTTP POST method depends on HTTP data value to be posted"
        raise SqlmapSyntaxException(errMsg)

    if conf.data is not None:
        conf.method = HTTPMETHOD.POST if not conf.method or conf.method == HTTPMETHOD.GET else conf.method

        def process(match, repl):
            retVal = match.group(0)

            if not (conf.testParameter
                    and match.group("name") not in conf.testParameter):
                retVal = repl
                while True:
                    _ = re.search(r"\\g<([^>]+)>", retVal)
                    if _:
                        retVal = retVal.replace(
                            _.group(0),
                            match.group(
                                int(_.group(1)) if _.group(1).isdigit() else _.
                                group(1)))
                    else:
                        break

            return retVal

        if kb.processUserMarks is None and CUSTOM_INJECTION_MARK_CHAR in conf.data:
            message = "custom injection marking character ('%s') found in option " % CUSTOM_INJECTION_MARK_CHAR
            message += "'--data'. Do you want to process it? [Y/n/q] "
            test = readInput(message, default="Y")
            if test and test[0] in ("q", "Q"):
                raise SqlmapUserQuitException
            else:
                kb.processUserMarks = not test or test[0] not in ("n", "N")

        if not (kb.processUserMarks
                and CUSTOM_INJECTION_MARK_CHAR in conf.data):
            if re.search(JSON_RECOGNITION_REGEX, conf.data):
                message = "JSON data found in %s data. " % conf.method
                message += "Do you want to process it? [Y/n/q] "
                test = readInput(message, default="Y")
                if test and test[0] in ("q", "Q"):
                    raise SqlmapUserQuitException
                elif test[0] not in ("n", "N"):
                    conf.data = conf.data.replace(CUSTOM_INJECTION_MARK_CHAR,
                                                  ASTERISK_MARKER)
                    conf.data = re.sub(
                        r'("(?P<name>[^"]+)"\s*:\s*"[^"]+)"',
                        functools.partial(process,
                                          repl=r'\g<1>%s"' %
                                          CUSTOM_INJECTION_MARK_CHAR),
                        conf.data)
                    conf.data = re.sub(
                        r'("(?P<name>[^"]+)"\s*:\s*)(-?\d[\d\.]*\b)',
                        functools.partial(process,
                                          repl=r'\g<0>%s' %
                                          CUSTOM_INJECTION_MARK_CHAR),
                        conf.data)
                    kb.postHint = POST_HINT.JSON

            elif re.search(JSON_LIKE_RECOGNITION_REGEX, conf.data):
                message = "JSON-like data found in %s data. " % conf.method
                message += "Do you want to process it? [Y/n/q] "
                test = readInput(message, default="Y")
                if test and test[0] in ("q", "Q"):
                    raise SqlmapUserQuitException
                elif test[0] not in ("n", "N"):
                    conf.data = conf.data.replace(CUSTOM_INJECTION_MARK_CHAR,
                                                  ASTERISK_MARKER)
                    conf.data = re.sub(
                        r"('(?P<name>[^']+)'\s*:\s*'[^']+)'",
                        functools.partial(process,
                                          repl=r"\g<1>%s'" %
                                          CUSTOM_INJECTION_MARK_CHAR),
                        conf.data)
                    conf.data = re.sub(
                        r"('(?P<name>[^']+)'\s*:\s*)(-?\d[\d\.]*\b)",
                        functools.partial(process,
                                          repl=r"\g<0>%s" %
                                          CUSTOM_INJECTION_MARK_CHAR),
                        conf.data)
                    kb.postHint = POST_HINT.JSON_LIKE

            elif re.search(SOAP_RECOGNITION_REGEX, conf.data):
                message = "SOAP/XML data found in %s data. " % conf.method
                message += "Do you want to process it? [Y/n/q] "
                test = readInput(message, default="Y")
                if test and test[0] in ("q", "Q"):
                    raise SqlmapUserQuitException
                elif test[0] not in ("n", "N"):
                    conf.data = conf.data.replace(CUSTOM_INJECTION_MARK_CHAR,
                                                  ASTERISK_MARKER)
                    conf.data = re.sub(
                        r"(<(?P<name>[^>]+)( [^<]*)?>)([^<]+)(</\2)",
                        functools.partial(process,
                                          repl=r"\g<1>\g<4>%s\g<5>" %
                                          CUSTOM_INJECTION_MARK_CHAR),
                        conf.data)
                    kb.postHint = POST_HINT.SOAP if "soap" in conf.data.lower(
                    ) else POST_HINT.XML

            elif re.search(MULTIPART_RECOGNITION_REGEX, conf.data):
                message = "Multipart like data found in %s data. " % conf.method
                message += "Do you want to process it? [Y/n/q] "
                test = readInput(message, default="Y")
                if test and test[0] in ("q", "Q"):
                    raise SqlmapUserQuitException
                elif test[0] not in ("n", "N"):
                    conf.data = conf.data.replace(CUSTOM_INJECTION_MARK_CHAR,
                                                  ASTERISK_MARKER)
                    conf.data = re.sub(
                        r"(?si)((Content-Disposition[^\n]+?name\s*=\s*[\"'](?P<name>[^\n]+?)[\"']).+?)(((\r)?\n)+--)",
                        functools.partial(process,
                                          repl=r"\g<1>%s\g<4>" %
                                          CUSTOM_INJECTION_MARK_CHAR),
                        conf.data)
                    kb.postHint = POST_HINT.MULTIPART

        if not kb.postHint:
            if CUSTOM_INJECTION_MARK_CHAR in conf.data:  # later processed
                pass
            else:
                place = PLACE.POST

                conf.parameters[place] = conf.data
                paramDict = paramToDict(place, conf.data)

                if paramDict:
                    conf.paramDict[place] = paramDict
                    testableParameters = True
        else:
            if CUSTOM_INJECTION_MARK_CHAR not in conf.data:  # in case that no usable parameter values has been found
                conf.parameters[PLACE.POST] = conf.data

    kb.processUserMarks = True if (kb.postHint and CUSTOM_INJECTION_MARK_CHAR
                                   in conf.data) else kb.processUserMarks

    if re.search(URI_INJECTABLE_REGEX, conf.url, re.I) and not any(
            place in conf.parameters for place in (PLACE.GET, PLACE.POST)
    ) and not kb.postHint and not CUSTOM_INJECTION_MARK_CHAR in (conf.data
                                                                 or ""):
        warnMsg = "you've provided target URL without any GET "
        warnMsg += "parameters (e.g. www.site.com/article.php?id=1) "
        warnMsg += "and without providing any POST parameters "
        warnMsg += "through --data option"
        logger.warn(warnMsg)

        message = "do you want to try URI injections "
        message += "in the target URL itself? [Y/n/q] "
        test = readInput(message, default="Y")

        if not test or test[0] not in ("n", "N"):
            conf.url = "%s%s" % (conf.url, CUSTOM_INJECTION_MARK_CHAR)
            kb.processUserMarks = True
        elif test[0] in ("q", "Q"):
            raise SqlmapUserQuitException

    for place, value in ((PLACE.URI, conf.url), (PLACE.CUSTOM_POST, conf.data),
                         (PLACE.CUSTOM_HEADER, str(conf.httpHeaders))):
        _ = re.sub(PROBLEMATIC_CUSTOM_INJECTION_PATTERNS, "", value
                   or "") if place == PLACE.CUSTOM_HEADER else value or ""
        if CUSTOM_INJECTION_MARK_CHAR in _:
            if kb.processUserMarks is None:
                lut = {
                    PLACE.URI:
                    '-u',
                    PLACE.CUSTOM_POST:
                    '--data',
                    PLACE.CUSTOM_HEADER:
                    '--headers/--user-agent/--referer/--cookie'
                }
                message = "custom injection marking character ('%s') found in option " % CUSTOM_INJECTION_MARK_CHAR
                message += "'%s'. Do you want to process it? [Y/n/q] " % lut[
                    place]
                test = readInput(message, default="Y")
                if test and test[0] in ("q", "Q"):
                    raise SqlmapUserQuitException
                else:
                    kb.processUserMarks = not test or test[0] not in ("n", "N")

            if not kb.processUserMarks:
                if place == PLACE.URI:
                    query = urlparse.urlsplit(value).query
                    if query:
                        parameters = conf.parameters[PLACE.GET] = query
                        paramDict = paramToDict(PLACE.GET, parameters)

                        if paramDict:
                            conf.url = conf.url.split('?')[0]
                            conf.paramDict[PLACE.GET] = paramDict
                            testableParameters = True
                elif place == PLACE.CUSTOM_POST:
                    conf.parameters[PLACE.POST] = conf.data
                    paramDict = paramToDict(PLACE.POST, conf.data)

                    if paramDict:
                        conf.paramDict[PLACE.POST] = paramDict
                        testableParameters = True

            else:
                conf.parameters[place] = value
                conf.paramDict[place] = OrderedDict()

                if place == PLACE.CUSTOM_HEADER:
                    for index in xrange(len(conf.httpHeaders)):
                        header, value = conf.httpHeaders[index]
                        if CUSTOM_INJECTION_MARK_CHAR in re.sub(
                                PROBLEMATIC_CUSTOM_INJECTION_PATTERNS, "",
                                value):
                            parts = value.split(CUSTOM_INJECTION_MARK_CHAR)
                            for i in xrange(len(parts) - 1):
                                conf.paramDict[place][
                                    "%s #%d%s" %
                                    (header, i + 1, CUSTOM_INJECTION_MARK_CHAR
                                     )] = "%s,%s" % (header, "".join(
                                         "%s%s" %
                                         (parts[j], CUSTOM_INJECTION_MARK_CHAR
                                          if i == j else "")
                                         for j in xrange(len(parts))))
                            conf.httpHeaders[index] = (
                                header,
                                value.replace(CUSTOM_INJECTION_MARK_CHAR, ""))
                else:
                    parts = value.split(CUSTOM_INJECTION_MARK_CHAR)

                    for i in xrange(len(parts) - 1):
                        conf.paramDict[place]["%s#%d%s" % (
                            ("%s " % kb.postHint) if kb.postHint else "",
                            i + 1, CUSTOM_INJECTION_MARK_CHAR)] = "".join(
                                "%s%s" %
                                (parts[j],
                                 CUSTOM_INJECTION_MARK_CHAR if i == j else "")
                                for j in xrange(len(parts)))

                    if place == PLACE.URI and PLACE.GET in conf.paramDict:
                        del conf.paramDict[PLACE.GET]
                    elif place == PLACE.CUSTOM_POST and PLACE.POST in conf.paramDict:
                        del conf.paramDict[PLACE.POST]

                testableParameters = True

    if kb.processUserMarks:
        for item in ("url", "data", "agent", "referer", "cookie"):
            if conf.get(item):
                conf[item] = conf[item].replace(CUSTOM_INJECTION_MARK_CHAR, "")

    # Perform checks on Cookie parameters
    if conf.cookie:
        conf.parameters[PLACE.COOKIE] = conf.cookie
        paramDict = paramToDict(PLACE.COOKIE, conf.cookie)

        if paramDict:
            conf.paramDict[PLACE.COOKIE] = paramDict
            testableParameters = True

    # Perform checks on header values
    if conf.httpHeaders:
        for httpHeader, headerValue in conf.httpHeaders:
            # Url encoding of the header values should be avoided
            # Reference: http://stackoverflow.com/questions/5085904/is-ok-to-urlencode-the-value-in-headerlocation-value

            httpHeader = httpHeader.title()

            if httpHeader == HTTP_HEADER.USER_AGENT:
                conf.parameters[PLACE.USER_AGENT] = urldecode(headerValue)

                condition = any((not conf.testParameter,
                                 intersect(conf.testParameter,
                                           USER_AGENT_ALIASES)))

                if condition:
                    conf.paramDict[PLACE.USER_AGENT] = {
                        PLACE.USER_AGENT: headerValue
                    }
                    testableParameters = True

            elif httpHeader == HTTP_HEADER.REFERER:
                conf.parameters[PLACE.REFERER] = urldecode(headerValue)

                condition = any((not conf.testParameter,
                                 intersect(conf.testParameter,
                                           REFERER_ALIASES)))

                if condition:
                    conf.paramDict[PLACE.REFERER] = {
                        PLACE.REFERER: headerValue
                    }
                    testableParameters = True

            elif httpHeader == HTTP_HEADER.HOST:
                conf.parameters[PLACE.HOST] = urldecode(headerValue)

                condition = any((not conf.testParameter,
                                 intersect(conf.testParameter, HOST_ALIASES)))

                if condition:
                    conf.paramDict[PLACE.HOST] = {PLACE.HOST: headerValue}
                    testableParameters = True

    if not conf.parameters:
        errMsg = "you did not provide any GET, POST and Cookie "
        errMsg += "parameter, neither an User-Agent, Referer or Host header value"
        raise SqlmapGenericException(errMsg)

    elif not testableParameters:
        errMsg = "all testable parameters you provided are not present "
        errMsg += "within the given request data"
        raise SqlmapGenericException(errMsg)
示例#6
0
文件: connect.py 项目: z0r1nga/w3af
    def queryPage(value=None, place=None, content=False, getRatioValue=False, silent=False, method=None, timeBasedCompare=False, noteResponseTime=True, auxHeaders=None, response=False, raise404=None, removeReflection=True):
        """
        This method calls a function to get the target URL page content
        and returns its page MD5 hash or a boolean value in case of
        string match check ('--string' command line parameter)
        """

        if conf.direct:
            return direct(value, content)

        get = None
        post = None
        cookie = None
        ua = None
        referer = None
        host = None
        page = None
        pageLength = None
        uri = None
        code = None

        if not place:
            place = kb.injection.place or PLACE.GET

        if not auxHeaders:
            auxHeaders = {}

        raise404 = place != PLACE.URI if raise404 is None else raise404
        method = method or conf.method

        value = agent.adjustLateValues(value)
        payload = agent.extractPayload(value)
        threadData = getCurrentThreadData()

        if conf.httpHeaders:
            headers = OrderedDict(conf.httpHeaders)
            contentType = max(headers[_] if _.upper() == HTTP_HEADER.CONTENT_TYPE.upper() else None for _ in headers.keys())

            if (kb.postHint or conf.skipUrlEncode) and kb.postUrlEncode:
                kb.postUrlEncode = False
                conf.httpHeaders = [_ for _ in conf.httpHeaders if _[1] != contentType]
                contentType = POST_HINT_CONTENT_TYPES.get(kb.postHint, PLAIN_TEXT_CONTENT_TYPE)
                conf.httpHeaders.append((HTTP_HEADER.CONTENT_TYPE, contentType))

        if payload:
            if kb.tamperFunctions:
                for function in kb.tamperFunctions:
                    try:
                        payload = function(payload=payload, headers=auxHeaders)
                    except Exception, ex:
                        errMsg = "error occurred while running tamper "
                        errMsg += "function '%s' ('%s')" % (function.func_name, ex)
                        raise SqlmapGenericException(errMsg)

                    if not isinstance(payload, basestring):
                        errMsg = "tamper function '%s' returns " % function.func_name
                        errMsg += "invalid payload type ('%s')" % type(payload)
                        raise SqlmapValueException(errMsg)

                value = agent.replacePayload(value, payload)

            logger.log(CUSTOM_LOGGING.PAYLOAD, safecharencode(payload))

            if place == PLACE.CUSTOM_POST and kb.postHint:
                if kb.postHint in (POST_HINT.SOAP, POST_HINT.XML):
                    # payloads in SOAP/XML should have chars > and < replaced
                    # with their HTML encoded counterparts
                    payload = payload.replace('>', "&gt;").replace('<', "&lt;")
                elif kb.postHint == POST_HINT.JSON:
                    if payload.startswith('"') and payload.endswith('"'):
                        payload = json.dumps(payload[1:-1])
                    else:
                        payload = json.dumps(payload)[1:-1]
                elif kb.postHint == POST_HINT.JSON_LIKE:
                    payload = payload.replace("'", REPLACEMENT_MARKER).replace('"', "'").replace(REPLACEMENT_MARKER, '"')
                    if payload.startswith('"') and payload.endswith('"'):
                        payload = json.dumps(payload[1:-1])
                    else:
                        payload = json.dumps(payload)[1:-1]
                    payload = payload.replace("'", REPLACEMENT_MARKER).replace('"', "'").replace(REPLACEMENT_MARKER, '"')
                value = agent.replacePayload(value, payload)
            else:
                # GET, POST, URI and Cookie payload needs to be thoroughly URL encoded
                if place in (PLACE.GET, PLACE.URI, PLACE.COOKIE) and not conf.skipUrlEncode or place in (PLACE.POST, PLACE.CUSTOM_POST) and kb.postUrlEncode:
                    payload = urlencode(payload, '%', False, place != PLACE.URI)  # spaceplus is handled down below
                    value = agent.replacePayload(value, payload)

            if conf.hpp:
                if not any(conf.url.lower().endswith(_.lower()) for _ in (WEB_API.ASP, WEB_API.ASPX)):
                    warnMsg = "HTTP parameter pollution should work only against "
                    warnMsg += "ASP(.NET) targets"
                    singleTimeWarnMessage(warnMsg)
                if place in (PLACE.GET, PLACE.POST):
                    _ = re.escape(PAYLOAD_DELIMITER)
                    match = re.search("(?P<name>\w+)=%s(?P<value>.+?)%s" % (_, _), value)
                    if match:
                        payload = match.group("value")

                        for splitter in (urlencode(' '), ' '):
                            if splitter in payload:
                                prefix, suffix = ("*/", "/*") if splitter == ' ' else (urlencode(_) for _ in ("*/", "/*"))
                                parts = payload.split(splitter)
                                parts[0] = "%s%s" % (parts[0], suffix)
                                parts[-1] = "%s%s=%s%s" % (DEFAULT_GET_POST_DELIMITER, match.group("name"), prefix, parts[-1])
                                for i in xrange(1, len(parts) - 1):
                                    parts[i] = "%s%s=%s%s%s" % (DEFAULT_GET_POST_DELIMITER, match.group("name"), prefix, parts[i], suffix)
                                payload = "".join(parts)

                        for splitter in (urlencode(','), ','):
                            payload = payload.replace(splitter, "%s%s=" % (DEFAULT_GET_POST_DELIMITER, match.group("name")))

                        value = agent.replacePayload(value, payload)
                else:
                    warnMsg = "HTTP parameter pollution works only with regular "
                    warnMsg += "GET and POST parameters"
                    singleTimeWarnMessage(warnMsg)
示例#7
0
def _setRequestParams():
    """
    Check and set the parameters and perform checks on 'data' option for
    HTTP method POST.
    """

    if conf.direct:
        conf.parameters[None] = "direct connection"
        return

    hintNames = []
    testableParameters = False

    # Perform checks on GET parameters
    if conf.parameters.get(PLACE.GET):
        parameters = conf.parameters[PLACE.GET]
        paramDict = paramToDict(PLACE.GET, parameters)

        if paramDict:
            conf.paramDict[PLACE.GET] = paramDict
            testableParameters = True

    # Perform checks on POST parameters
    if conf.method == HTTPMETHOD.POST and conf.data is None:
        logger.warn("detected empty POST body")
        conf.data = ""

    if conf.data is not None:
        conf.method = HTTPMETHOD.POST if not conf.method or conf.method == HTTPMETHOD.GET else conf.method

        def process(match, repl):
            retVal = match.group(0)

            if not (conf.testParameter
                    and match.group("name") not in conf.testParameter):
                retVal = repl
                while True:
                    _ = re.search(r"\\g<([^>]+)>", retVal)
                    if _:
                        retVal = retVal.replace(
                            _.group(0),
                            match.group(
                                int(_.group(1)) if _.group(1).isdigit() else _.
                                group(1)))
                    else:
                        break
                if kb.customInjectionMark in retVal:
                    hintNames.append((retVal.split(kb.customInjectionMark)[0],
                                      match.group("name")))
            return retVal

        if kb.processUserMarks is None and kb.customInjectionMark in conf.data:
            message = "custom injection marker ('%s') found in option " % kb.customInjectionMark
            message += "'--data'. Do you want to process it? [Y/n/q] "
            choice = readInput(message, default='Y').upper()

            if choice == 'Q':
                raise SqlmapUserQuitException
            else:
                kb.processUserMarks = choice == 'Y'

                if kb.processUserMarks:
                    kb.testOnlyCustom = True

        if re.search(JSON_RECOGNITION_REGEX, conf.data):
            message = "JSON data found in %s data. " % conf.method
            message += "Do you want to process it? [Y/n/q] "
            choice = readInput(message, default='Y').upper()

            if choice == 'Q':
                raise SqlmapUserQuitException
            elif choice == 'Y':
                if not (kb.processUserMarks
                        and kb.customInjectionMark in conf.data):
                    conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE,
                                        conf.data)
                    conf.data = conf.data.replace(kb.customInjectionMark,
                                                  ASTERISK_MARKER)
                    conf.data = re.sub(
                        r'("(?P<name>[^"]+)"\s*:\s*".+?)"(?<!\\")',
                        functools.partial(process,
                                          repl=r'\g<1>%s"' %
                                          kb.customInjectionMark), conf.data)
                    conf.data = re.sub(
                        r'("(?P<name>[^"]+)"\s*:\s*)(-?\d[\d\.]*)\b',
                        functools.partial(process,
                                          repl=r'\g<1>\g<3>%s' %
                                          kb.customInjectionMark), conf.data)
                    conf.data = re.sub(
                        r'("(?P<name>[^"]+)"\s*:\s*)((true|false|null))\b',
                        functools.partial(process,
                                          repl=r'\g<1>\g<3>%s' %
                                          kb.customInjectionMark), conf.data)
                    match = re.search(r'(?P<name>[^"]+)"\s*:\s*\[([^\]]+)\]',
                                      conf.data)
                    if match and not (conf.testParameter
                                      and match.group("name")
                                      not in conf.testParameter):
                        _ = match.group(2)
                        _ = re.sub(r'("[^"]+)"',
                                   r'\g<1>%s"' % kb.customInjectionMark, _)
                        _ = re.sub(r'(\A|,|\s+)(-?\d[\d\.]*\b)',
                                   r'\g<0>%s' % kb.customInjectionMark, _)
                        conf.data = conf.data.replace(
                            match.group(0),
                            match.group(0).replace(match.group(2), _))

                kb.postHint = POST_HINT.JSON

        elif re.search(JSON_LIKE_RECOGNITION_REGEX, conf.data):
            message = "JSON-like data found in %s data. " % conf.method
            message += "Do you want to process it? [Y/n/q] "
            choice = readInput(message, default='Y').upper()

            if choice == 'Q':
                raise SqlmapUserQuitException
            elif choice == 'Y':
                if not (kb.processUserMarks
                        and kb.customInjectionMark in conf.data):
                    conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE,
                                        conf.data)
                    conf.data = conf.data.replace(kb.customInjectionMark,
                                                  ASTERISK_MARKER)
                    conf.data = re.sub(
                        r"('(?P<name>[^']+)'\s*:\s*'[^']+)'",
                        functools.partial(process,
                                          repl=r"\g<1>%s'" %
                                          kb.customInjectionMark), conf.data)
                    conf.data = re.sub(
                        r"('(?P<name>[^']+)'\s*:\s*)(-?\d[\d\.]*\b)",
                        functools.partial(process,
                                          repl=r"\g<0>%s" %
                                          kb.customInjectionMark), conf.data)

                kb.postHint = POST_HINT.JSON_LIKE

        elif re.search(ARRAY_LIKE_RECOGNITION_REGEX, conf.data):
            message = "Array-like data found in %s data. " % conf.method
            message += "Do you want to process it? [Y/n/q] "
            choice = readInput(message, default='Y').upper()

            if choice == 'Q':
                raise SqlmapUserQuitException
            elif choice == 'Y':
                if not (kb.processUserMarks
                        and kb.customInjectionMark in conf.data):
                    conf.data = conf.data.replace(kb.customInjectionMark,
                                                  ASTERISK_MARKER)
                    conf.data = re.sub(
                        r"(=[^%s]+)" % DEFAULT_GET_POST_DELIMITER,
                        r"\g<1>%s" % kb.customInjectionMark, conf.data)

                kb.postHint = POST_HINT.ARRAY_LIKE

        elif re.search(XML_RECOGNITION_REGEX, conf.data):
            message = "SOAP/XML data found in %s data. " % conf.method
            message += "Do you want to process it? [Y/n/q] "
            choice = readInput(message, default='Y').upper()

            if choice == 'Q':
                raise SqlmapUserQuitException
            elif choice == 'Y':
                if not (kb.processUserMarks
                        and kb.customInjectionMark in conf.data):
                    conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE,
                                        conf.data)
                    conf.data = conf.data.replace(kb.customInjectionMark,
                                                  ASTERISK_MARKER)
                    conf.data = re.sub(
                        r"(<(?P<name>[^>]+)( [^<]*)?>)([^<]+)(</\2)",
                        functools.partial(process,
                                          repl=r"\g<1>\g<4>%s\g<5>" %
                                          kb.customInjectionMark), conf.data)

                kb.postHint = POST_HINT.SOAP if "soap" in conf.data.lower(
                ) else POST_HINT.XML

        elif re.search(MULTIPART_RECOGNITION_REGEX, conf.data):
            message = "Multipart-like data found in %s data. " % conf.method
            message += "Do you want to process it? [Y/n/q] "
            choice = readInput(message, default='Y').upper()

            if choice == 'Q':
                raise SqlmapUserQuitException
            elif choice == 'Y':
                if not (kb.processUserMarks
                        and kb.customInjectionMark in conf.data):
                    conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE,
                                        conf.data)
                    conf.data = conf.data.replace(kb.customInjectionMark,
                                                  ASTERISK_MARKER)
                    conf.data = re.sub(
                        r"(?si)((Content-Disposition[^\n]+?name\s*=\s*[\"']?(?P<name>[^\"'\r\n]+)[\"']?).+?)(((\r)?\n)+--)",
                        functools.partial(process,
                                          repl=r"\g<1>%s\g<4>" %
                                          kb.customInjectionMark), conf.data)

                kb.postHint = POST_HINT.MULTIPART

        if not kb.postHint:
            if kb.customInjectionMark in conf.data:  # later processed
                pass
            else:
                place = PLACE.POST

                conf.parameters[place] = conf.data
                paramDict = paramToDict(place, conf.data)

                if paramDict:
                    conf.paramDict[place] = paramDict
                    testableParameters = True
        else:
            if kb.customInjectionMark not in conf.data:  # in case that no usable parameter values has been found
                conf.parameters[PLACE.POST] = conf.data

    kb.processUserMarks = True if (kb.postHint and kb.customInjectionMark in (
        conf.data or "")) else kb.processUserMarks

    if re.search(URI_INJECTABLE_REGEX, conf.url, re.I) and not any(
            place in conf.parameters for place in
        (PLACE.GET,
         PLACE.POST)) and not kb.postHint and kb.customInjectionMark not in (
             conf.data or "") and conf.url.startswith("http"):
        warnMsg = "you've provided target URL without any GET "
        warnMsg += "parameters (e.g. 'http://www.site.com/article.php?id=1') "
        warnMsg += "and without providing any POST parameters "
        warnMsg += "through option '--data'"
        logger.warn(warnMsg)

        message = "do you want to try URI injections "
        message += "in the target URL itself? [Y/n/q] "
        choice = readInput(message, default='Y').upper()

        if choice == 'Q':
            raise SqlmapUserQuitException
        elif choice == 'Y':
            conf.url = "%s%s" % (conf.url, kb.customInjectionMark)
            kb.processUserMarks = True

    for place, value in ((PLACE.URI, conf.url), (PLACE.CUSTOM_POST, conf.data),
                         (PLACE.CUSTOM_HEADER, str(conf.httpHeaders))):
        _ = re.sub(PROBLEMATIC_CUSTOM_INJECTION_PATTERNS, "", value
                   or "") if place == PLACE.CUSTOM_HEADER else value or ""
        if kb.customInjectionMark in _:
            if kb.processUserMarks is None:
                lut = {
                    PLACE.URI:
                    '-u',
                    PLACE.CUSTOM_POST:
                    '--data',
                    PLACE.CUSTOM_HEADER:
                    '--headers/--user-agent/--referer/--cookie'
                }
                message = "custom injection marker ('%s') found in option " % kb.customInjectionMark
                message += "'%s'. Do you want to process it? [Y/n/q] " % lut[
                    place]
                choice = readInput(message, default='Y').upper()

                if choice == 'Q':
                    raise SqlmapUserQuitException
                else:
                    kb.processUserMarks = choice == 'Y'

                    if kb.processUserMarks:
                        kb.testOnlyCustom = True

                        if "=%s" % kb.customInjectionMark in _:
                            warnMsg = "it seems that you've provided empty parameter value(s) "
                            warnMsg += "for testing. Please, always use only valid parameter values "
                            warnMsg += "so sqlmap could be able to run properly"
                            logger.warn(warnMsg)

            if not kb.processUserMarks:
                if place == PLACE.URI:
                    query = urlparse.urlsplit(value).query
                    if query:
                        parameters = conf.parameters[PLACE.GET] = query
                        paramDict = paramToDict(PLACE.GET, parameters)

                        if paramDict:
                            conf.url = conf.url.split('?')[0]
                            conf.paramDict[PLACE.GET] = paramDict
                            testableParameters = True
                elif place == PLACE.CUSTOM_POST:
                    conf.parameters[PLACE.POST] = conf.data
                    paramDict = paramToDict(PLACE.POST, conf.data)

                    if paramDict:
                        conf.paramDict[PLACE.POST] = paramDict
                        testableParameters = True

            else:
                conf.parameters[place] = value
                conf.paramDict[place] = OrderedDict()

                if place == PLACE.CUSTOM_HEADER:
                    for index in xrange(len(conf.httpHeaders)):
                        header, value = conf.httpHeaders[index]
                        if kb.customInjectionMark in re.sub(
                                PROBLEMATIC_CUSTOM_INJECTION_PATTERNS, "",
                                value):
                            parts = value.split(kb.customInjectionMark)
                            for i in xrange(len(parts) - 1):
                                conf.paramDict[place]["%s #%d%s" % (
                                    header, i + 1, kb.customInjectionMark
                                )] = "%s,%s" % (header, "".join(
                                    "%s%s" %
                                    (parts[j],
                                     kb.customInjectionMark if i == j else "")
                                    for j in xrange(len(parts))))
                            conf.httpHeaders[index] = (
                                header,
                                value.replace(kb.customInjectionMark, ""))
                else:
                    parts = value.split(kb.customInjectionMark)

                    for i in xrange(len(parts) - 1):
                        name = None
                        if kb.postHint:
                            for ending, _ in hintNames:
                                if parts[i].endswith(ending):
                                    name = "%s %s" % (kb.postHint, _)
                                    break
                        if name is None:
                            name = "%s#%s%s" % (
                                ("%s " % kb.postHint) if kb.postHint else "",
                                i + 1, kb.customInjectionMark)
                        conf.paramDict[place][name] = "".join(
                            "%s%s" % (parts[j],
                                      kb.customInjectionMark if i == j else "")
                            for j in xrange(len(parts)))

                    if place == PLACE.URI and PLACE.GET in conf.paramDict:
                        del conf.paramDict[PLACE.GET]
                    elif place == PLACE.CUSTOM_POST and PLACE.POST in conf.paramDict:
                        del conf.paramDict[PLACE.POST]

                testableParameters = True

    if kb.processUserMarks:
        for item in ("url", "data", "agent", "referer", "cookie"):
            if conf.get(item):
                conf[item] = conf[item].replace(kb.customInjectionMark, "")

    # Perform checks on Cookie parameters
    if conf.cookie:
        conf.parameters[PLACE.COOKIE] = conf.cookie
        paramDict = paramToDict(PLACE.COOKIE, conf.cookie)

        if paramDict:
            conf.paramDict[PLACE.COOKIE] = paramDict
            testableParameters = True

    # Perform checks on header values
    if conf.httpHeaders:
        for httpHeader, headerValue in list(conf.httpHeaders):
            # Url encoding of the header values should be avoided
            # Reference: http://stackoverflow.com/questions/5085904/is-ok-to-urlencode-the-value-in-headerlocation-value

            if httpHeader.title() == HTTP_HEADER.USER_AGENT:
                conf.parameters[PLACE.USER_AGENT] = urldecode(headerValue)

                condition = any((not conf.testParameter,
                                 intersect(conf.testParameter,
                                           USER_AGENT_ALIASES, True)))

                if condition:
                    conf.paramDict[PLACE.USER_AGENT] = {
                        PLACE.USER_AGENT: headerValue
                    }
                    testableParameters = True

            elif httpHeader.title() == HTTP_HEADER.REFERER:
                conf.parameters[PLACE.REFERER] = urldecode(headerValue)

                condition = any((not conf.testParameter,
                                 intersect(conf.testParameter, REFERER_ALIASES,
                                           True)))

                if condition:
                    conf.paramDict[PLACE.REFERER] = {
                        PLACE.REFERER: headerValue
                    }
                    testableParameters = True

            elif httpHeader.title() == HTTP_HEADER.HOST:
                conf.parameters[PLACE.HOST] = urldecode(headerValue)

                condition = any((not conf.testParameter,
                                 intersect(conf.testParameter, HOST_ALIASES,
                                           True)))

                if condition:
                    conf.paramDict[PLACE.HOST] = {PLACE.HOST: headerValue}
                    testableParameters = True

            else:
                condition = intersect(conf.testParameter, [httpHeader], True)

                if condition:
                    conf.parameters[PLACE.CUSTOM_HEADER] = str(
                        conf.httpHeaders)
                    conf.paramDict[PLACE.CUSTOM_HEADER] = {
                        httpHeader:
                        "%s,%s%s" %
                        (httpHeader, headerValue, kb.customInjectionMark)
                    }
                    conf.httpHeaders = [
                        (_[0], _[1].replace(kb.customInjectionMark, ""))
                        for _ in conf.httpHeaders
                    ]
                    testableParameters = True

    if not conf.parameters:
        errMsg = "you did not provide any GET, POST and Cookie "
        errMsg += "parameter, neither an User-Agent, Referer or Host header value"
        raise SqlmapGenericException(errMsg)

    elif not testableParameters:
        errMsg = "all testable parameters you provided are not present "
        errMsg += "within the given request data"
        raise SqlmapGenericException(errMsg)

    if conf.csrfToken:
        if not any(conf.csrfToken in _ for _ in
                   (conf.paramDict.get(PLACE.GET, {}),
                    conf.paramDict.get(PLACE.POST, {}))) and not re.search(
                        r"\b%s\b" % re.escape(conf.csrfToken), conf.data
                        or "") and conf.csrfToken not in set(
                            _[0].lower() for _ in conf.httpHeaders
                        ) and conf.csrfToken not in conf.paramDict.get(
                            PLACE.COOKIE, {}):
            errMsg = "anti-CSRF token parameter '%s' not " % conf.csrfToken
            errMsg += "found in provided GET, POST, Cookie or header values"
            raise SqlmapGenericException(errMsg)
    else:
        for place in (PLACE.GET, PLACE.POST, PLACE.COOKIE):
            if conf.csrfToken:
                break

            for parameter in conf.paramDict.get(place, {}):
                if any(parameter.lower().count(_)
                       for _ in CSRF_TOKEN_PARAMETER_INFIXES):
                    message = "%s parameter '%s' appears to hold anti-CSRF token. " % (
                        place, parameter)
                    message += "Do you want sqlmap to automatically update it in further requests? [y/N] "

                    if readInput(message, default='N', boolean=True):
                        conf.csrfToken = getUnicode(parameter)
                        break
示例#8
0
def forgeHeaders(items=None, base=None):
    """
    Prepare HTTP Cookie, HTTP User-Agent and HTTP Referer headers to use when performing
    the HTTP requests
    """

    items = items or {}

    for _ in items.keys():
        if items[_] is None:
            del items[_]

    headers = OrderedDict(conf.httpHeaders if base is None else base)
    headers.update(items.items())

    class _str(str):
        def capitalize(self):
            return _str(self)

        def title(self):
            return _str(self)

    _ = headers
    headers = OrderedDict()
    for key, value in _.items():
        success = False

        for _ in headers:
            if _.upper() == key.upper():
                del headers[_]
                break

        if key.upper() not in (_.upper() for _ in getPublicTypeMembers(HTTP_HEADER, True)):
            try:
                headers[_str(key)] = value  # dirty hack for http://bugs.python.org/issue12455
            except UnicodeEncodeError:      # don't do the hack on non-ASCII header names (they have to be properly encoded later on)
                pass
            else:
                success = True
        if not success:
            key = '-'.join(_.capitalize() for _ in key.split('-'))
            headers[key] = value

    if conf.cj:
        if HTTP_HEADER.COOKIE in headers:
            for cookie in conf.cj:
                if cookie.domain_specified and not (conf.hostname or "").endswith(cookie.domain):
                    continue

                if ("%s=" % getUnicode(cookie.name)) in getUnicode(headers[HTTP_HEADER.COOKIE]):
                    if conf.loadCookies:
                        conf.httpHeaders = filter(None, ((item if item[0] != HTTP_HEADER.COOKIE else None) for item in conf.httpHeaders))
                    elif kb.mergeCookies is None:
                        message = "you provided a HTTP %s header value. " % HTTP_HEADER.COOKIE
                        message += "The target URL provided its own cookies within "
                        message += "the HTTP %s header which intersect with yours. " % HTTP_HEADER.SET_COOKIE
                        message += "Do you want to merge them in further requests? [Y/n] "

                        kb.mergeCookies = readInput(message, default='Y', boolean=True)

                    if kb.mergeCookies and kb.injection.place != PLACE.COOKIE:
                        def _(value):
                            return re.sub(r"(?i)\b%s=[^%s]+" % (re.escape(getUnicode(cookie.name)), conf.cookieDel or DEFAULT_COOKIE_DELIMITER), ("%s=%s" % (getUnicode(cookie.name), getUnicode(cookie.value))).replace('\\', r'\\'), value)

                        headers[HTTP_HEADER.COOKIE] = _(headers[HTTP_HEADER.COOKIE])

                        if PLACE.COOKIE in conf.parameters:
                            conf.parameters[PLACE.COOKIE] = _(conf.parameters[PLACE.COOKIE])

                        conf.httpHeaders = [(item[0], item[1] if item[0] != HTTP_HEADER.COOKIE else _(item[1])) for item in conf.httpHeaders]

                elif not kb.testMode:
                    headers[HTTP_HEADER.COOKIE] += "%s %s=%s" % (conf.cookieDel or DEFAULT_COOKIE_DELIMITER, getUnicode(cookie.name), getUnicode(cookie.value))

        if kb.testMode and not any((conf.csrfToken, conf.safeUrl)):
            resetCookieJar(conf.cj)

    return headers
示例#9
0
文件: basic.py 项目: 0xDigs/sqlmap
def forgeHeaders(items=None):
    """
    Prepare HTTP Cookie, HTTP User-Agent and HTTP Referer headers to use when performing
    the HTTP requests
    """

    items = items or {}

    for _ in items.keys():
        if items[_] is None:
            del items[_]

    headers = OrderedDict(conf.httpHeaders)
    headers.update(items.items())

    class _str(str):
        def capitalize(self):
            return _str(self)

        def title(self):
            return _str(self)

    _ = headers
    headers = OrderedDict()
    for key, value in _.items():
        success = False

        for _ in headers:
            if _.upper() == key.upper():
                del headers[_]
                break

        if key.upper() not in (_.upper() for _ in getPublicTypeMembers(HTTP_HEADER, True)):
            try:
                headers[_str(key)] = value  # dirty hack for http://bugs.python.org/issue12455
            except UnicodeEncodeError:      # don't do the hack on non-ASCII header names (they have to be properly encoded later on)
                pass
            else:
                success = True
        if not success:
            key = '-'.join(_.capitalize() for _ in key.split('-'))
            headers[key] = value

    if conf.cj:
        if HTTP_HEADER.COOKIE in headers:
            for cookie in conf.cj:
                if cookie.domain_specified and not conf.hostname.endswith(cookie.domain):
                    continue

                if ("%s=" % cookie.name) in headers[HTTP_HEADER.COOKIE]:
                    if conf.loadCookies:
                        conf.httpHeaders = filter(None, ((item if item[0] != HTTP_HEADER.COOKIE else None) for item in conf.httpHeaders))
                    elif kb.mergeCookies is None:
                        message = "you provided a HTTP %s header value. " % HTTP_HEADER.COOKIE
                        message += "The target URL provided its own cookies within "
                        message += "the HTTP %s header which intersect with yours. " % HTTP_HEADER.SET_COOKIE
                        message += "Do you want to merge them in futher requests? [Y/n] "
                        _ = readInput(message, default="Y")
                        kb.mergeCookies = not _ or _[0] in ("y", "Y")

                    if kb.mergeCookies and kb.injection.place != PLACE.COOKIE:
                        _ = lambda x: re.sub(r"(?i)\b%s=[^%s]+" % (re.escape(cookie.name), conf.cookieDel or DEFAULT_COOKIE_DELIMITER), "%s=%s" % (cookie.name, getUnicode(cookie.value)), x)
                        headers[HTTP_HEADER.COOKIE] = _(headers[HTTP_HEADER.COOKIE])

                        if PLACE.COOKIE in conf.parameters:
                            conf.parameters[PLACE.COOKIE] = _(conf.parameters[PLACE.COOKIE])

                        conf.httpHeaders = [(item[0], item[1] if item[0] != HTTP_HEADER.COOKIE else _(item[1])) for item in conf.httpHeaders]

                elif not kb.testMode:
                    headers[HTTP_HEADER.COOKIE] += "%s %s=%s" % (conf.cookieDel or DEFAULT_COOKIE_DELIMITER, cookie.name, getUnicode(cookie.value))

        if kb.testMode and not conf.csrfToken:
            resetCookieJar(conf.cj)

    return headers
示例#10
0
文件: use.py 项目: cxh852456/sqlmap
                    def unionThread():
                        threadData = getCurrentThreadData()

                        while kb.threadContinue:
                            with kb.locks.limit:
                                try:
                                    valueStart = time.time()
                                    threadData.shared.counter += 1
                                    num = threadData.shared.limits.next()
                                except StopIteration:
                                    break

                            if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
                                field = expressionFieldsList[0]
                            elif Backend.isDbms(DBMS.ORACLE):
                                field = expressionFieldsList
                            else:
                                field = None

                            limitedExpr = agent.limitQuery(num, expression, field)
                            output = _oneShotUnionUse(limitedExpr, unpack, True)

                            if not kb.threadContinue:
                                break

                            if output:
                                with kb.locks.value:
                                    if all(_ in output for _ in (kb.chars.start, kb.chars.stop)):
                                        items = parseUnionPage(output)

                                        if threadData.shared.showEta:
                                            threadData.shared.progress.progress(time.time() - valueStart, threadData.shared.counter)
                                        if isListLike(items):
                                            # in case that we requested N columns and we get M!=N then we have to filter a bit
                                            if len(items) > 1 and len(expressionFieldsList) > 1:
                                                items = [item for item in items if isListLike(item) and len(item) == len(expressionFieldsList)]
                                            items = [_ for _ in flattenValue(items)]
                                            if len(items) > len(expressionFieldsList):
                                                filtered = OrderedDict()
                                                for item in items:
                                                    key = re.sub(r"[^A-Za-z0-9]", "", item).lower()
                                                    if key not in filtered or re.search(r"[^A-Za-z0-9]", item):
                                                        filtered[key] = item
                                                items = filtered.values()
                                            items = [items]
                                        index = None
                                        for index in xrange(1 + len(threadData.shared.buffered)):
                                            if index < len(threadData.shared.buffered) and threadData.shared.buffered[index][0] >= num:
                                                break
                                        threadData.shared.buffered.insert(index or 0, (num, items))
                                    else:
                                        index = None
                                        if threadData.shared.showEta:
                                            threadData.shared.progress.progress(time.time() - valueStart, threadData.shared.counter)
                                        for index in xrange(1 + len(threadData.shared.buffered)):
                                            if index < len(threadData.shared.buffered) and threadData.shared.buffered[index][0] >= num:
                                                break
                                        threadData.shared.buffered.insert(index or 0, (num, None))

                                        items = output.replace(kb.chars.start, "").replace(kb.chars.stop, "").split(kb.chars.delimiter)

                                    while threadData.shared.buffered and (threadData.shared.lastFlushed + 1 >= threadData.shared.buffered[0][0] or len(threadData.shared.buffered) > MAX_BUFFERED_PARTIAL_UNION_LENGTH):
                                        threadData.shared.lastFlushed, _ = threadData.shared.buffered[0]
                                        if not isNoneValue(_):
                                            threadData.shared.value.extend(arrayizeValue(_))
                                        del threadData.shared.buffered[0]

                                if conf.verbose == 1 and not (threadData.resumed and kb.suppressResumeInfo) and not threadData.shared.showEta:
                                    _ = ','.join("\"%s\"" % _ for _ in flattenValue(arrayizeValue(items))) if not isinstance(items, basestring) else items
                                    status = "[%s] [INFO] %s: %s" % (time.strftime("%X"), "resumed" if threadData.resumed else "retrieved", _ if kb.safeCharEncode else safecharencode(_))

                                    if len(status) > width:
                                        status = "%s..." % status[:width - 3]

                                    dataToStdout("%s\n" % status)
示例#11
0
 def __init__(self, capacity):
     self.capacity = capacity
     self.cache = OrderedDict()
示例#12
0
    def queryPage(value=None, place=None, content=False, getRatioValue=False, silent=False, method=None, timeBasedCompare=False, noteResponseTime=True, auxHeaders=None, response=False, raise404=None, removeReflection=True):
        """
        This method calls a function to get the target URL page content
        and returns its page MD5 hash or a boolean value in case of
        string match check ('--string' command line parameter)
        """

        if conf.direct:
            return direct(value, content)

        get = None
        post = None
        cookie = None
        ua = None
        referer = None
        host = None
        page = None
        pageLength = None
        uri = None
        code = None

        if not place:
            place = kb.injection.place or PLACE.GET

        if not auxHeaders:
            auxHeaders = {}

        raise404 = place != PLACE.URI if raise404 is None else raise404

        value = agent.adjustLateValues(value)
        payload = agent.extractPayload(value)
        threadData = getCurrentThreadData()

        if conf.httpHeaders:
            headers = OrderedDict(conf.httpHeaders)
            contentType = max(headers[_] if _.upper() == HTTP_HEADER.CONTENT_TYPE.upper() else None for _ in headers.keys())

            if (kb.postHint or conf.skipUrlEncode) and kb.postUrlEncode:
                kb.postUrlEncode = False
                conf.httpHeaders = [_ for _ in conf.httpHeaders if _[1] != contentType]
                contentType = POST_HINT_CONTENT_TYPES.get(kb.postHint, PLAIN_TEXT_CONTENT_TYPE)
                conf.httpHeaders.append((HTTP_HEADER.CONTENT_TYPE, contentType))

        if payload:
            if kb.tamperFunctions:
                for function in kb.tamperFunctions:
                    payload = function(payload=payload, headers=auxHeaders)
                    if not isinstance(payload, basestring):
                        errMsg = "tamper function '%s' returns " % function.func_name
                        errMsg += "invalid payload type ('%s')" % type(payload)
                        raise SqlmapValueException(errMsg)

                value = agent.replacePayload(value, payload)

            logger.log(CUSTOM_LOGGING.PAYLOAD, safecharencode(payload))

            if place == PLACE.CUSTOM_POST and kb.postHint:
                if kb.postHint in (POST_HINT.SOAP, POST_HINT.XML):
                    # payloads in SOAP/XML should have chars > and < replaced
                    # with their HTML encoded counterparts
                    payload = payload.replace('>', "&gt;").replace('<', "&lt;")
                elif kb.postHint == POST_HINT.JSON:
                    if payload.startswith('"') and payload.endswith('"'):
                        payload = json.dumps(payload[1:-1])
                    else:
                        payload = json.dumps(payload)[1:-1]
                elif kb.postHint == POST_HINT.JSON_LIKE:
                    payload = payload.replace("'", REPLACEMENT_MARKER).replace('"', "'").replace(REPLACEMENT_MARKER, '"')
                    if payload.startswith('"') and payload.endswith('"'):
                        payload = json.dumps(payload[1:-1])
                    else:
                        payload = json.dumps(payload)[1:-1]
                    payload = payload.replace("'", REPLACEMENT_MARKER).replace('"', "'").replace(REPLACEMENT_MARKER, '"')
                value = agent.replacePayload(value, payload)
            else:
                # GET, POST, URI and Cookie payload needs to be throughly URL encoded
                if place in (PLACE.GET, PLACE.URI, PLACE.COOKIE) and not conf.skipUrlEncode or place in (PLACE.POST, PLACE.CUSTOM_POST) and kb.postUrlEncode:
                    payload = urlencode(payload, '%', False, place != PLACE.URI)  # spaceplus is handled down below
                    value = agent.replacePayload(value, payload)

            if conf.hpp:
                if not any(conf.url.lower().endswith(_.lower()) for _ in (WEB_API.ASP, WEB_API.ASPX)):
                    warnMsg = "HTTP parameter pollution should work only against "
                    warnMsg += "ASP(.NET) targets"
                    singleTimeWarnMessage(warnMsg)
                if place in (PLACE.GET, PLACE.POST):
                    _ = re.escape(PAYLOAD_DELIMITER)
                    match = re.search("(?P<name>\w+)=%s(?P<value>.+?)%s" % (_, _), value)
                    if match:
                        payload = match.group("value")

                        for splitter in (urlencode(' '), ' '):
                            if splitter in payload:
                                prefix, suffix = ("*/", "/*") if splitter == ' ' else (urlencode(_) for _ in ("*/", "/*"))
                                parts = payload.split(splitter)
                                parts[0] = "%s%s" % (parts[0], suffix)
                                parts[-1] = "%s%s=%s%s" % (DEFAULT_GET_POST_DELIMITER, match.group("name"), prefix, parts[-1])
                                for i in xrange(1, len(parts) - 1):
                                    parts[i] = "%s%s=%s%s%s" % (DEFAULT_GET_POST_DELIMITER, match.group("name"), prefix, parts[i], suffix)
                                payload = "".join(parts)

                        for splitter in (urlencode(','), ','):
                            payload = payload.replace(splitter, "%s%s=" % (DEFAULT_GET_POST_DELIMITER, match.group("name")))

                        value = agent.replacePayload(value, payload)
                else:
                    warnMsg = "HTTP parameter pollution works only with regular "
                    warnMsg += "GET and POST parameters"
                    singleTimeWarnMessage(warnMsg)

        if place:
            value = agent.removePayloadDelimiters(value)

        if PLACE.GET in conf.parameters:
            get = conf.parameters[PLACE.GET] if place != PLACE.GET or not value else value

        if PLACE.POST in conf.parameters:
            post = conf.parameters[PLACE.POST] if place != PLACE.POST or not value else value

        if PLACE.CUSTOM_POST in conf.parameters:
            post = conf.parameters[PLACE.CUSTOM_POST].replace(CUSTOM_INJECTION_MARK_CHAR, "") if place != PLACE.CUSTOM_POST or not value else value
            post = post.replace(ASTERISK_MARKER, '*') if post else post

        if PLACE.COOKIE in conf.parameters:
            cookie = conf.parameters[PLACE.COOKIE] if place != PLACE.COOKIE or not value else value

        if PLACE.USER_AGENT in conf.parameters:
            ua = conf.parameters[PLACE.USER_AGENT] if place != PLACE.USER_AGENT or not value else value

        if PLACE.REFERER in conf.parameters:
            referer = conf.parameters[PLACE.REFERER] if place != PLACE.REFERER or not value else value

        if PLACE.HOST in conf.parameters:
            host = conf.parameters[PLACE.HOST] if place != PLACE.HOST or not value else value

        if PLACE.URI in conf.parameters:
            uri = conf.url if place != PLACE.URI or not value else value
        else:
            uri = conf.url

        if value and place == PLACE.CUSTOM_HEADER:
            auxHeaders[value.split(',')[0]] = value.split(',', 1)[1]

        if conf.rParam:
            def _randomizeParameter(paramString, randomParameter):
                retVal = paramString
                match = re.search("%s=(?P<value>[^&;]+)" % randomParameter, paramString)
                if match:
                    origValue = match.group("value")
                    retVal = re.sub("%s=[^&;]+" % randomParameter, "%s=%s" % (randomParameter, randomizeParameterValue(origValue)), paramString)
                return retVal

            for randomParameter in conf.rParam:
                for item in (PLACE.GET, PLACE.POST, PLACE.COOKIE):
                    if item in conf.parameters:
                        if item == PLACE.GET and get:
                            get = _randomizeParameter(get, randomParameter)
                        elif item == PLACE.POST and post:
                            post = _randomizeParameter(post, randomParameter)
                        elif item == PLACE.COOKIE and cookie:
                            cookie = _randomizeParameter(cookie, randomParameter)

        if conf.evalCode:
            delimiter = conf.paramDel or DEFAULT_GET_POST_DELIMITER
            variables = {"uri": uri}
            originals = {}

            for item in filter(None, (get, post if not kb.postHint else None)):
                for part in item.split(delimiter):
                    if '=' in part:
                        name, value = part.split('=', 1)
                        value = urldecode(value, convall=True, plusspace=(item==post and kb.postSpaceToPlus))
                        evaluateCode("%s=%s" % (name.strip(), repr(value)), variables)

            if cookie:
                for part in cookie.split(conf.cookieDel or DEFAULT_COOKIE_DELIMITER):
                    if '=' in part:
                        name, value = part.split('=', 1)
                        value = urldecode(value, convall=True)
                        evaluateCode("%s=%s" % (name.strip(), repr(value)), variables)

            originals.update(variables)
            evaluateCode(conf.evalCode, variables)
            uri = variables["uri"]

            for name, value in variables.items():
                if name != "__builtins__" and originals.get(name, "") != value:
                    if isinstance(value, (basestring, int)):
                        found = False
                        value = unicode(value)

                        regex = r"((\A|%s)%s=).+?(%s|\Z)" % (re.escape(delimiter), name, re.escape(delimiter))
                        if re.search(regex, (get or "")):
                            found = True
                            get = re.sub(regex, "\g<1>%s\g<3>" % value, get)

                        if re.search(regex, (post or "")):
                            found = True
                            post = re.sub(regex, "\g<1>%s\g<3>" % value, post)

                        regex = r"((\A|%s)%s=).+?(%s|\Z)" % (re.escape(conf.cookieDel or DEFAULT_COOKIE_DELIMITER), name, re.escape(conf.cookieDel or DEFAULT_COOKIE_DELIMITER))
                        if re.search(regex, (cookie or "")):
                            found = True
                            cookie = re.sub(regex, "\g<1>%s\g<3>" % value, cookie)

                        if not found:
                            if post is not None:
                                post += "%s%s=%s" % (delimiter, name, value)
                            elif get is not None:
                                get += "%s%s=%s" % (delimiter, name, value)
                            elif cookie is not None:
                                cookie += "%s%s=%s" % (conf.cookieDel or DEFAULT_COOKIE_DELIMITER, name, value)

        if not conf.skipUrlEncode:
            get = urlencode(get, limit=True)

        if post is not None:
            if place not in (PLACE.POST, PLACE.CUSTOM_POST) and hasattr(post, UNENCODED_ORIGINAL_VALUE):
                post = getattr(post, UNENCODED_ORIGINAL_VALUE)
            elif kb.postUrlEncode:
                post = urlencode(post, spaceplus=kb.postSpaceToPlus)

        if timeBasedCompare:
            if len(kb.responseTimes) < MIN_TIME_RESPONSES:
                clearConsoleLine()

                if conf.tor:
                    warnMsg = "it's highly recommended to avoid usage of switch '--tor' for "
                    warnMsg += "time-based injections because of its high latency time"
                    singleTimeWarnMessage(warnMsg)

                warnMsg = "[%s] [WARNING] time-based comparison requires " % time.strftime("%X")
                warnMsg += "larger statistical model, please wait"
                dataToStdout(warnMsg)

                while len(kb.responseTimes) < MIN_TIME_RESPONSES:
                    Connect.queryPage(content=True)
                    dataToStdout('.')

                dataToStdout("\n")

            elif not kb.testMode:
                warnMsg = "it is very important not to stress the network adapter "
                warnMsg += "during usage of time-based payloads to prevent potential "
                warnMsg += "errors "
                singleTimeWarnMessage(warnMsg)

            if not kb.laggingChecked:
                kb.laggingChecked = True

                deviation = stdev(kb.responseTimes)

                if deviation > WARN_TIME_STDEV:
                    kb.adjustTimeDelay = ADJUST_TIME_DELAY.DISABLE

                    warnMsg = "considerable lagging has been detected "
                    warnMsg += "in connection response(s). Please use as high "
                    warnMsg += "value for option '--time-sec' as possible (e.g. "
                    warnMsg += "10 or more)"
                    logger.critical(warnMsg)


        if conf.safUrl and conf.saFreq > 0:
            kb.queryCounter += 1
            if kb.queryCounter % conf.saFreq == 0:
                Connect.getPage(url=conf.safUrl, cookie=cookie, direct=True, silent=True, ua=ua, referer=referer, host=host)

        start = time.time()

        if kb.nullConnection and not content and not response and not timeBasedCompare:
            noteResponseTime = False

            pushValue(kb.pageCompress)
            kb.pageCompress = False

            if kb.nullConnection == NULLCONNECTION.HEAD:
                method = HTTPMETHOD.HEAD
            elif kb.nullConnection == NULLCONNECTION.RANGE:
                auxHeaders[HTTP_HEADER.RANGE] = "bytes=-1"

            _, headers, code = Connect.getPage(url=uri, get=get, post=post, cookie=cookie, ua=ua, referer=referer, host=host, silent=silent, method=method, auxHeaders=auxHeaders, raise404=raise404, skipRead=(kb.nullConnection == NULLCONNECTION.SKIP_READ))

            if headers:
                if kb.nullConnection in (NULLCONNECTION.HEAD, NULLCONNECTION.SKIP_READ) and HTTP_HEADER.CONTENT_LENGTH in headers:
                    pageLength = int(headers[HTTP_HEADER.CONTENT_LENGTH])
                elif kb.nullConnection == NULLCONNECTION.RANGE and HTTP_HEADER.CONTENT_RANGE in headers:
                    pageLength = int(headers[HTTP_HEADER.CONTENT_RANGE][headers[HTTP_HEADER.CONTENT_RANGE].find('/') + 1:])

            kb.pageCompress = popValue()

        if not pageLength:
            try:
                page, headers, code = Connect.getPage(url=uri, get=get, post=post, cookie=cookie, ua=ua, referer=referer, host=host, silent=silent, method=method, auxHeaders=auxHeaders, response=response, raise404=raise404, ignoreTimeout=timeBasedCompare)
            except MemoryError:
                page, headers, code = None, None, None
                warnMsg = "site returned insanely large response"
                if kb.testMode:
                    warnMsg += " in testing phase. This is a common "
                    warnMsg += "behavior in custom WAF/IDS/IPS solutions"
                singleTimeWarnMessage(warnMsg)

        if conf.secondOrder:
            page, headers, code = Connect.getPage(url=conf.secondOrder, cookie=cookie, ua=ua, silent=silent, auxHeaders=auxHeaders, response=response, raise404=False, ignoreTimeout=timeBasedCompare, refreshing=True)

        threadData.lastQueryDuration = calculateDeltaSeconds(start)

        kb.originalCode = kb.originalCode or code

        if kb.testMode:
            kb.testQueryCount += 1

        if timeBasedCompare:
            return wasLastResponseDelayed()
        elif noteResponseTime:
            kb.responseTimes.append(threadData.lastQueryDuration)

        if not response and removeReflection:
            page = removeReflectiveValues(page, payload)

        kb.maxConnectionsFlag = re.search(MAX_CONNECTIONS_REGEX, page or "", re.I) is not None
        kb.permissionFlag = re.search(PERMISSION_DENIED_REGEX, page or "", re.I) is not None

        if content or response:
            return page, headers

        if getRatioValue:
            return comparison(page, headers, code, getRatioValue=False, pageLength=pageLength), comparison(page, headers, code, getRatioValue=True, pageLength=pageLength)
        else:
            return comparison(page, headers, code, getRatioValue, pageLength)
示例#13
0
def __setRequestParams():
    """
    Check and set the parameters and perform checks on 'data' option for
    HTTP method POST.
    """

    if conf.direct:
        conf.parameters[None] = "direct connection"
        return

    testableParameters = False

    # Perform checks on GET parameters
    if conf.parameters.get(PLACE.GET):
        parameters = conf.parameters[PLACE.GET]
        paramDict = paramToDict(PLACE.GET, parameters)

        if paramDict:
            conf.paramDict[PLACE.GET] = paramDict
            testableParameters = True

    # Perform checks on POST parameters
    if conf.method == HTTPMETHOD.POST and not conf.data:
        errMsg = "HTTP POST method depends on HTTP data value to be posted"
        raise sqlmapSyntaxException, errMsg

    if conf.data:
        conf.method = HTTPMETHOD.POST

        if CUSTOM_INJECTION_MARK_CHAR in conf.data:  # later processed
            pass

        elif re.search(JSON_RECOGNITION_REGEX, conf.data):
            message = "JSON like data found in POST data. "
            message += "Do you want to process it? [Y/n/q] "
            test = readInput(message, default="Y")
            if test and test[0] in ("q", "Q"):
                raise sqlmapUserQuitException
            elif test[0] not in ("n", "N"):
                conf.data = re.sub(r'("[^"]+"\s*:\s*"[^"]+)"',
                                   r'\g<1>%s"' % CUSTOM_INJECTION_MARK_CHAR,
                                   conf.data)
                conf.data = re.sub(r'("[^"]+"\s*:\s*)(-?\d[\d\.]*\b)',
                                   r'\g<0>%s' % CUSTOM_INJECTION_MARK_CHAR,
                                   conf.data)
                kb.processUserMarks = True
                kb.postHint = POST_HINT.JSON

        elif re.search(SOAP_RECOGNITION_REGEX, conf.data):
            message = "SOAP/XML like data found in POST data. "
            message += "Do you want to process it? [Y/n/q] "
            test = readInput(message, default="Y")
            if test and test[0] in ("q", "Q"):
                raise sqlmapUserQuitException
            elif test[0] not in ("n", "N"):
                conf.data = re.sub(r"(<([^>]+)( [^<]*)?>)([^<]+)(</\2)",
                                   r"\g<1>\g<4>*\g<5>", conf.data)
                kb.processUserMarks = True
                kb.postHint = POST_HINT.SOAP if "soap" in conf.data.lower(
                ) else POST_HINT.XML

        else:
            place = PLACE.POST

            conf.parameters[place] = conf.data
            paramDict = paramToDict(place, conf.data)

            if paramDict:
                conf.paramDict[place] = paramDict
                testableParameters = True

    if re.search(URI_INJECTABLE_REGEX, conf.url, re.I) and not any(
            map(lambda place: place in conf.parameters,
                [PLACE.GET, PLACE.POST])):
        warnMsg = "you've provided target url without any GET "
        warnMsg += "parameters (e.g. www.site.com/article.php?id=1) "
        warnMsg += "and without providing any POST parameters "
        warnMsg += "through --data option"
        logger.warn(warnMsg)

        message = "do you want to try URI injections "
        message += "in the target url itself? [Y/n/q] "
        test = readInput(message, default="Y")

        if not test or test[0] not in ("n", "N"):
            conf.url = "%s%s" % (conf.url, CUSTOM_INJECTION_MARK_CHAR)
            kb.processUserMarks = True
        elif test[0] in ("q", "Q"):
            raise sqlmapUserQuitException

    for place, value in ((PLACE.URI, conf.url), (PLACE.CUSTOM_POST,
                                                 conf.data)):
        if CUSTOM_INJECTION_MARK_CHAR in (value or ""):
            if kb.processUserMarks is None:
                _ = {PLACE.URI: '-u', PLACE.CUSTOM_POST: '--data'}
                message = "custom injection marking character ('%s') found in option " % CUSTOM_INJECTION_MARK_CHAR
                message += "'%s'. Do you want to process it? [Y/n/q] " % _[
                    place]
                test = readInput(message, default="Y")
                if test and test[0] in ("q", "Q"):
                    raise sqlmapUserQuitException
                else:
                    kb.processUserMarks = not test or test[0] not in ("n", "N")

            if not kb.processUserMarks:
                continue

            conf.parameters[place] = value
            conf.paramDict[place] = OrderedDict()
            parts = value.split(CUSTOM_INJECTION_MARK_CHAR)

            for i in xrange(len(parts) - 1):
                conf.paramDict[place]["%s#%d%s" % (
                    ("%s " % kb.postHint) if kb.postHint else "", i + 1,
                    CUSTOM_INJECTION_MARK_CHAR)] = "".join(
                        "%s%s" % (parts[j],
                                  CUSTOM_INJECTION_MARK_CHAR if i == j else "")
                        for j in xrange(len(parts)))

            if place == PLACE.URI and PLACE.GET in conf.paramDict:
                del conf.paramDict[PLACE.GET]
            elif place == PLACE.CUSTOM_POST and PLACE.POST in conf.paramDict:
                del conf.paramDict[PLACE.POST]

            testableParameters = True

    if kb.processUserMarks:
        conf.url = conf.url.replace(CUSTOM_INJECTION_MARK_CHAR, "")
        conf.data = conf.data.replace(CUSTOM_INJECTION_MARK_CHAR,
                                      "") if conf.data else conf.data

    # Perform checks on Cookie parameters
    if conf.cookie:
        conf.parameters[PLACE.COOKIE] = conf.cookie
        paramDict = paramToDict(PLACE.COOKIE, conf.cookie)

        if paramDict:
            conf.paramDict[PLACE.COOKIE] = paramDict
            testableParameters = True

    # Perform checks on header values
    if conf.httpHeaders:
        for httpHeader, headerValue in conf.httpHeaders:
            # Url encoding of the header values should be avoided
            # Reference: http://stackoverflow.com/questions/5085904/is-ok-to-urlencode-the-value-in-headerlocation-value

            httpHeader = httpHeader.title()

            if httpHeader == HTTPHEADER.USER_AGENT:
                conf.parameters[PLACE.USER_AGENT] = urldecode(headerValue)

                condition = any((not conf.testParameter,
                                 intersect(conf.testParameter,
                                           USER_AGENT_ALIASES)))

                if condition:
                    conf.paramDict[PLACE.USER_AGENT] = {
                        PLACE.USER_AGENT: headerValue
                    }
                    testableParameters = True

            elif httpHeader == HTTPHEADER.REFERER:
                conf.parameters[PLACE.REFERER] = urldecode(headerValue)

                condition = any((not conf.testParameter,
                                 intersect(conf.testParameter,
                                           REFERER_ALIASES)))

                if condition:
                    conf.paramDict[PLACE.REFERER] = {
                        PLACE.REFERER: headerValue
                    }
                    testableParameters = True

            elif httpHeader == HTTPHEADER.HOST:
                conf.parameters[PLACE.HOST] = urldecode(headerValue)

                condition = any((not conf.testParameter,
                                 intersect(conf.testParameter, HOST_ALIASES)))

                if condition:
                    conf.paramDict[PLACE.HOST] = {PLACE.HOST: headerValue}
                    testableParameters = True

    if not conf.parameters:
        errMsg = "you did not provide any GET, POST and Cookie "
        errMsg += "parameter, neither an User-Agent, Referer or Host header value"
        raise sqlmapGenericException, errMsg

    elif not testableParameters:
        errMsg = "all testable parameters you provided are not present "
        errMsg += "within the GET, POST and Cookie parameters"
        raise sqlmapGenericException, errMsg
示例#14
0
    def queryPage(value=None, place=None, content=False, getRatioValue=False, silent=False, method=None, timeBasedCompare=False, noteResponseTime=True, auxHeaders=None, response=False, raise404=None, removeReflection=True):
        """
        This method calls a function to get the target URL page content
        and returns its page MD5 hash or a boolean value in case of
        string match check ('--string' command line parameter)
        """

        ###########  Connect the Database directly
        if conf.direct:
            return direct(value, content)

        get = None
        post = None
        cookie = None
        ua = None
        referer = None
        host = None
        page = None
        pageLength = None
        uri = None
        code = None

        # print "place -----",place
        if not place:
            #print kb.injection.place
            #print "place.get:",PLACE.GET
            place = kb.injection.place or PLACE.GET## kb.injection.place = none , place.get= 'get'

        if not auxHeaders:
            auxHeaders = {}

        raise404 = place != PLACE.URI if raise404 is None else raise404

        value = agent.adjustLateValues(value)
        """
        print "-------------------------  value ---------------------------"
        print value
        print "----------------------------------------------------------"
        """
        payload = agent.extractPayload(value)
        """
        payload_file = open("payload_file","a")
        print "------------------  Payload -------------------------"
        print >>payload_file, payload
        payload_file.close()
        """
        threadData = getCurrentThreadData()
        #print type(threadData)

        if conf.httpHeaders:
            headers = OrderedDict(conf.httpHeaders)
            contentType = max(headers[_] if _.upper() == HTTP_HEADER.CONTENT_TYPE.upper() else None for _ in headers.keys())

            if (kb.postHint or conf.skipUrlEncode) and kb.postUrlEncode:
                kb.postUrlEncode = False
                conf.httpHeaders = [_ for _ in conf.httpHeaders if _[1] != contentType]
                contentType = POST_HINT_CONTENT_TYPES.get(kb.postHint, PLAIN_TEXT_CONTENT_TYPE)
                conf.httpHeaders.append((HTTP_HEADER.CONTENT_TYPE, contentType))

        if payload:
            if kb.tamperFunctions:
                for function in kb.tamperFunctions:
                    try:
                        payload = function(payload=payload, headers=auxHeaders)
                    except Exception, ex:
                        errMsg = "error occurred while running tamper "
                        errMsg += "function '%s' ('%s')" % (function.func_name, ex)
                        raise SqlmapGenericException(errMsg)

                    if not isinstance(payload, basestring):
                        errMsg = "tamper function '%s' returns " % function.func_name
                        errMsg += "invalid payload type ('%s')" % type(payload)
                        raise SqlmapValueException(errMsg)

                value = agent.replacePayload(value, payload)

            logger.log(CUSTOM_LOGGING.PAYLOAD, safecharencode(payload))

            if place == PLACE.CUSTOM_POST and kb.postHint:
                if kb.postHint in (POST_HINT.SOAP, POST_HINT.XML):
                    # payloads in SOAP/XML should have chars > and < replaced
                    # with their HTML encoded counterparts
                    payload = payload.replace('>', "&gt;").replace('<', "&lt;")
                elif kb.postHint == POST_HINT.JSON:
                    if payload.startswith('"') and payload.endswith('"'):
                        payload = json.dumps(payload[1:-1])
                    else:
                        payload = json.dumps(payload)[1:-1]
                elif kb.postHint == POST_HINT.JSON_LIKE:
                    payload = payload.replace("'", REPLACEMENT_MARKER).replace('"', "'").replace(REPLACEMENT_MARKER, '"')
                    if payload.startswith('"') and payload.endswith('"'):
                        payload = json.dumps(payload[1:-1])
                    else:
                        payload = json.dumps(payload)[1:-1]
                    payload = payload.replace("'", REPLACEMENT_MARKER).replace('"', "'").replace(REPLACEMENT_MARKER, '"')
                value = agent.replacePayload(value, payload)
            else:
                # GET, POST, URI and Cookie payload needs to be throughly URL encoded
                if place in (PLACE.GET, PLACE.URI, PLACE.COOKIE) and not conf.skipUrlEncode or place in (PLACE.POST, PLACE.CUSTOM_POST) and kb.postUrlEncode:
                    payload = urlencode(payload, '%', False, place != PLACE.URI)  # spaceplus is handled down below
                    value = agent.replacePayload(value, payload)
示例#15
0
def forgeHeaders(items=None):
    """
    准备执行HTTP请求时要使用的HTTP Cookie,HTTP User-Agent和HTTP Referer头
    """

    items = items or {}

    for _ in items.keys():
        if items[_] is None:
            del items[_]

    headers = OrderedDict(conf.httpHeaders)
    headers.update(items.items())

    class _str(str):
        def capitalize(self):
            return _str(self)

        def title(self):
            return _str(self)

    _ = headers
    headers = OrderedDict()
    for key, value in _.items():
        success = False

        for _ in headers:
            if _.upper() == key.upper():
                del headers[_]
                break

        if key.upper() not in (
                _.upper() for _ in getPublicTypeMembers(HTTP_HEADER, True)):
            try:
                headers[_str(
                    key
                )] = value  # dirty hack for http://bugs.python.org/issue12455
            except UnicodeEncodeError:  # don't do the hack on non-ASCII header names (they have to be properly encoded later on)
                pass
            else:
                success = True
        if not success:
            key = '-'.join(_.capitalize() for _ in key.split('-'))
            headers[key] = value

    if conf.cj:
        if HTTP_HEADER.COOKIE in headers:
            for cookie in conf.cj:
                if cookie.domain_specified and not conf.hostname.endswith(
                        cookie.domain):
                    continue

                if ("%s=" % getUnicode(cookie.name)) in getUnicode(
                        headers[HTTP_HEADER.COOKIE]):
                    if conf.loadCookies:
                        conf.httpHeaders = filter(
                            None,
                            ((item if item[0] != HTTP_HEADER.COOKIE else None)
                             for item in conf.httpHeaders))
                    elif kb.mergeCookies is None:
                        message = u"您提供了HTTP header cookie值 %s, " % HTTP_HEADER.COOKIE
                        message += u"目标URL在与您的交叉点的"
                        message += u"HTTP header中提供了自己的cookie %s 。" % HTTP_HEADER.SET_COOKIE
                        message += u"是否要在进一步的请求中合并它们? [Y/n] "

                        kb.mergeCookies = readInput(message,
                                                    default='Y',
                                                    boolean=True)

                    if kb.mergeCookies and kb.injection.place != PLACE.COOKIE:
                        _ = lambda x: re.sub(
                            r"(?i)\b%s=[^%s]+" %
                            (re.escape(getUnicode(cookie.name)), conf.cookieDel
                             or DEFAULT_COOKIE_DELIMITER),
                            ("%s=%s" %
                             (getUnicode(cookie.name), getUnicode(cookie.value)
                              )).replace('\\', r'\\'), x)
                        headers[HTTP_HEADER.COOKIE] = _(
                            headers[HTTP_HEADER.COOKIE])

                        if PLACE.COOKIE in conf.parameters:
                            conf.parameters[PLACE.COOKIE] = _(
                                conf.parameters[PLACE.COOKIE])

                        conf.httpHeaders = [
                            (item[0], item[1]
                             if item[0] != HTTP_HEADER.COOKIE else _(item[1]))
                            for item in conf.httpHeaders
                        ]

                elif not kb.testMode:
                    headers[HTTP_HEADER.COOKIE] += "%s %s=%s" % (
                        conf.cookieDel or DEFAULT_COOKIE_DELIMITER,
                        getUnicode(cookie.name), getUnicode(cookie.value))

        if kb.testMode and not any((conf.csrfToken, conf.safeUrl)):
            resetCookieJar(conf.cj)

    return headers