def checkConnection(suppressOutput=False): if not any([conf.proxy, conf.tor]): try: socket.getaddrinfo(conf.hostname, None) except socket.gaierror: errMsg = "host '%s' does not exist" % conf.hostname raise sqlmapConnectionException, errMsg if not suppressOutput: infoMsg = "testing connection to the target url" logger.info(infoMsg) try: page, _ = Request.queryPage(content=True, noteResponseTime=False) kb.originalPage = kb.pageTemplate = page kb.errorIsNone = False if not kb.originalPage and wasLastRequestHTTPError(): errMsg = "unable to retrieve page content" raise sqlmapConnectionException, errMsg elif wasLastRequestDBMSError(): warnMsg = "there is a DBMS error found in the HTTP response body" warnMsg += "which could interfere with the results of the tests" logger.warn(warnMsg) elif wasLastRequestHTTPError(): warnMsg = "the web server responded with an HTTP error code (%d) " % getLastRequestHTTPError( ) warnMsg += "which could interfere with the results of the tests" logger.warn(warnMsg) else: kb.errorIsNone = True except sqlmapConnectionException, errMsg: errMsg = getUnicode(errMsg) logger.critical(errMsg) if conf.ipv6: warnMsg = "check connection to a provided " warnMsg += "IPv6 address with a tool like ping6 " warnMsg += "(e.g. 'ping6 %s') " % conf.hostname warnMsg += "prior to running sqlmap to avoid " warnMsg += "any addressing issues" singleTimeWarnMessage(warnMsg) if any(code in kb.httpErrorCodes for code in (httplib.NOT_FOUND, )): if conf.multipleTargets: return False msg = "it is not recommended to continue in this kind of cases. Do you want to quit and make sure that everything is set up properly? [Y/n] " if readInput(msg, default="Y") not in ("n", "N"): raise sqlmapSilentQuitException else: kb.ignoreNotFound = True else: raise
def checkConnection(suppressOutput=False): if not any([conf.proxy, conf.tor]): try: socket.getaddrinfo(conf.hostname, None) except socket.gaierror: errMsg = "host '%s' does not exist" % conf.hostname raise SqlmapConnectionException, errMsg if not suppressOutput: infoMsg = "testing connection to the target url" logger.info(infoMsg) try: page, _ = Request.queryPage(content=True, noteResponseTime=False) kb.originalPage = kb.pageTemplate = page kb.errorIsNone = False if not kb.originalPage and wasLastRequestHTTPError(): errMsg = "unable to retrieve page content" raise SqlmapConnectionException, errMsg elif wasLastRequestDBMSError(): warnMsg = "there is a DBMS error found in the HTTP response body " warnMsg += "which could interfere with the results of the tests" logger.warn(warnMsg) elif wasLastRequestHTTPError(): warnMsg = "the web server responded with an HTTP error code (%d) " % getLastRequestHTTPError() warnMsg += "which could interfere with the results of the tests" logger.warn(warnMsg) else: kb.errorIsNone = True except SqlmapConnectionException, errMsg: errMsg = getUnicode(errMsg) logger.critical(errMsg) if conf.ipv6: warnMsg = "check connection to a provided " warnMsg += "IPv6 address with a tool like ping6 " warnMsg += "(e.g. 'ping6 %s') " % conf.hostname warnMsg += "prior to running sqlmap to avoid " warnMsg += "any addressing issues" singleTimeWarnMessage(warnMsg) if any(code in kb.httpErrorCodes for code in (httplib.NOT_FOUND, )): if conf.multipleTargets: return False msg = "it is not recommended to continue in this kind of cases. Do you want to quit and make sure that everything is set up properly? [Y/n] " if readInput(msg, default="Y") not in ("n", "N"): raise SqlmapSilentQuitException else: kb.ignoreNotFound = True else: raise
def _comparison(page, headers, code, getRatioValue, pageLength): threadData = getCurrentThreadData() if kb.testMode: threadData.lastComparisonHeaders = listToStrValue( _ for _ in headers.headers if not _.startswith("%s:" % URI_HTTP_HEADER)) if headers else "" threadData.lastComparisonPage = page threadData.lastComparisonCode = code if page is None and pageLength is None: return None if any((conf.string, conf.notString, conf.regexp)): rawResponse = "%s%s" % (listToStrValue( _ for _ in headers.headers if not _.startswith("%s:" % URI_HTTP_HEADER)) if headers else "", page) # String to match in page when the query is True if conf.string: return conf.string in rawResponse # String to match in page when the query is False if conf.notString: if conf.notString in rawResponse: return False else: if kb.errorIsNone and (wasLastResponseDBMSError() or wasLastResponseHTTPError()): return None else: return True # Regular expression to match in page when the query is True and/or valid if conf.regexp: return re.search(conf.regexp, rawResponse, re.I | re.M) is not None # HTTP code to match when the query is valid if conf.code: return conf.code == code seqMatcher = threadData.seqMatcher seqMatcher.set_seq1(kb.pageTemplate) if page: # In case of an DBMS error page return None if kb.errorIsNone and ( wasLastResponseDBMSError() or wasLastResponseHTTPError()) and not kb.negativeLogic: if not (wasLastResponseHTTPError() and getLastRequestHTTPError() in (conf.ignoreCode or [])): return None # Dynamic content lines to be excluded before comparison if not kb.nullConnection: page = removeDynamicContent(page) seqMatcher.set_seq1(removeDynamicContent(kb.pageTemplate)) if not pageLength: pageLength = len(page) if kb.nullConnection and pageLength: if not seqMatcher.a: errMsg = "problem occurred while retrieving original page content " errMsg += "which prevents sqlmap from continuation. Please rerun, " errMsg += "and if the problem persists turn off any optimization switches" raise SqlmapNoneDataException(errMsg) ratio = 1. * pageLength / len(seqMatcher.a) if ratio > 1.: ratio = 1. / ratio else: # Preventing "Unicode equal comparison failed to convert both arguments to Unicode" # (e.g. if one page is PDF and the other is HTML) if isinstance(seqMatcher.a, six.binary_type) and isinstance( page, six.text_type): page = getBytes(page, kb.pageEncoding or DEFAULT_PAGE_ENCODING, "ignore") elif isinstance(seqMatcher.a, six.text_type) and isinstance( page, six.binary_type): seqMatcher.a = getBytes(seqMatcher.a, kb.pageEncoding or DEFAULT_PAGE_ENCODING, "ignore") if any(_ is None for _ in (page, seqMatcher.a)): return None elif seqMatcher.a and page and seqMatcher.a == page: ratio = 1. elif kb.skipSeqMatcher or seqMatcher.a and page and any( len(_) > MAX_DIFFLIB_SEQUENCE_LENGTH for _ in (seqMatcher.a, page)): if not page or not seqMatcher.a: return float(seqMatcher.a == page) else: ratio = 1. * len(seqMatcher.a) / len(page) if ratio > 1: ratio = 1. / ratio else: seq1, seq2 = None, None if conf.titles: seq1 = extractRegexResult(HTML_TITLE_REGEX, seqMatcher.a) seq2 = extractRegexResult(HTML_TITLE_REGEX, page) else: seq1 = getFilteredPageContent( seqMatcher.a, True) if conf.textOnly else seqMatcher.a seq2 = getFilteredPageContent(page, True) if conf.textOnly else page if seq1 is None or seq2 is None: return None seq1 = seq1.replace(REFLECTED_VALUE_MARKER, "") seq2 = seq2.replace(REFLECTED_VALUE_MARKER, "") if kb.heavilyDynamic: seq1 = seq1.split("\n") seq2 = seq2.split("\n") key = None else: key = (hash(seq1), hash(seq2)) seqMatcher.set_seq1(seq1) seqMatcher.set_seq2(seq2) if key in kb.cache.comparison: ratio = kb.cache.comparison[key] else: ratio = round( seqMatcher.quick_ratio() if not kb.heavilyDynamic else seqMatcher.ratio(), 3) if key: kb.cache.comparison[key] = ratio # If the url is stable and we did not set yet the match ratio and the # current injected value changes the url page content if kb.matchRatio is None: if ratio >= LOWER_RATIO_BOUND and ratio <= UPPER_RATIO_BOUND: kb.matchRatio = ratio logger.debug("setting match ratio for current parameter to %.3f" % kb.matchRatio) if kb.testMode: threadData.lastComparisonRatio = ratio # If it has been requested to return the ratio and not a comparison # response if getRatioValue: return ratio elif ratio > UPPER_RATIO_BOUND: return True elif ratio < LOWER_RATIO_BOUND: return False elif kb.matchRatio is None: return None else: return (ratio - kb.matchRatio) > DIFF_TOLERANCE