예제 #1
0
    def __init__(self):

        super(RawReportProcessor, self).__init__()
        from faraday import setupPlugins
        setupPlugins()

        self.pending_actions = Queue()

        try:
            plugin_manager = PluginManager(
                os.path.join(CONF.getConfigPath(), "plugins"))
        except AttributeError:
            get_logger().warning(
                "Upload reports in WEB-UI not configurated, run Faraday client and try again..."
            )
            self._stop = True
            return

        mappers_manager = MapperManager()

        self.model_controller = ModelController(mappers_manager,
                                                self.pending_actions)
        self.model_controller.start()
        self.end_event = Event()

        plugin_controller = PluginController('PluginController',
                                             plugin_manager, mappers_manager,
                                             self.pending_actions,
                                             self.end_event)

        self.processor = ReportProcessor(plugin_controller, None)
        self._stop = False
예제 #2
0
 def __load_ssl_certs(self):
     certs = (server.config.ssl.keyfile, server.config.ssl.certificate)
     if not all(certs):
         logger.get_logger(__name__).critical(
             "HTTPS request but SSL certificates are not configured")
         exit(1)  # Abort web-server startup
     return ssl.DefaultOpenSSLContextFactory(*certs)
예제 #3
0
def list_interfaces(workspace=None):
    validate_workspace(workspace)
    get_logger(__name__).debug("Request parameters: {!r}"\
        .format(flask.request.args))

    dao = InterfaceDAO(workspace)
    result = dao.list(interface_filter=flask.request.args)

    return flask.jsonify(result)
예제 #4
0
def list_services(workspace=None):
    validate_workspace(workspace)
    get_logger(__name__).debug("Request parameters: {!r}"\
        .format(flask.request.args))

    services_dao = ServiceDAO(workspace)

    services = services_dao.list(service_filter=flask.request.args)

    return flask.jsonify(services)
예제 #5
0
def count_notes(workspace=None):
    validate_workspace(workspace)
    get_logger(__name__).debug("Request parameters: {!r}"\
        .format(request.args))

    services_dao = NoteDAO(workspace)
    result = services_dao.count()
    if result is None:
        abort(400)

    return jsonify(result)
예제 #6
0
def list_notes(workspace=None):

    validate_workspace(workspace)
    get_logger(__name__).debug("Request parameters: {!r}".format(request.args))

    note_filter = filter_request_args()

    dao = NoteDAO(workspace)

    result = dao.list(note_filter=note_filter)

    return jsonify(result)
예제 #7
0
def list_commands(workspace=None):
    validate_workspace(workspace)
    get_logger(__name__).debug(
        "Request parameters: {!r}".format(flask.request.args))

    commands_filter = filter_request_args()

    dao = CommandDAO(workspace)

    result = dao.list(command_filter=commands_filter)

    return flask.jsonify(result)
예제 #8
0
def get_exploits(cveid):
    """
    Use Vulns API to get all exploits available for a specific CVE-ID
    """

    get_logger(__name__).debug("Request parameters: {!r}".format(
        flask.request.args))

    headers = {
        "Content-Type": "application/json",
        "Accept": "application/json"
    }

    response = requests.get(
        "https://vulners.com/api/v3/search/id/?references=True&id=" + cveid,
        headers=headers,
        timeout=3)

    try:

        json_response = {"metasploit": [], "exploitdb": [], "cveid": cveid}

        if response.status_code == 200:

            obj_response = response.json()

            if obj_response["data"]["references"] is not {}:

                metasploit_modules = obj_response["data"]["references"][
                    cveid].get("metasploit", [])
                exploitdb_modules = obj_response["data"]["references"][
                    cveid].get("exploitdb", [])

                for module in metasploit_modules:
                    obj_module = {}
                    obj_module.update({"title": module["title"]})
                    obj_module.update({"id": module["id"]})
                    obj_module.update({"href": module["href"]})
                    json_response["metasploit"].append(obj_module)

                for module in exploitdb_modules:
                    obj_module = {}
                    obj_module.update({"title": module["title"]})
                    obj_module.update({"id": module["id"]})
                    obj_module.update({"href": module["href"]})
                    json_response["exploitdb"].append(obj_module)

    except KeyError as ex:
        abort(
            make_response(
                jsonify(message='Could not find {0}'.format(ex.message)), 400))

    return flask.jsonify(json_response)
예제 #9
0
def file_upload(workspace=None):
    """
    Upload a report file to Server and process that report with Faraday client plugins.
    """
    get_logger(__name__).debug("Importing new plugin report in server...")

    # Authorization code copy-pasted from server/api/base.py
    ws = Workspace.query.filter_by(name=workspace).one()
    if not (ws.active):
        # Don't raise a 403 to prevent workspace name enumeration
        abort(404, "Workspace disabled: %s" % workspace)

    if 'file' not in request.files:
        abort(400)

    try:
        validate_csrf(request.form.get('csrf_token'))
    except ValidationError:
        abort(403)

    report_file = request.files['file']

    if report_file.filename == '':
        abort(400)

    if report_file:

        chars = string.ascii_uppercase + string.digits
        random_prefix = ''.join(random.choice(chars) for x in range(12))
        raw_report_filename = '{0}{1}'.format(
            random_prefix, secure_filename(report_file.filename))

        try:
            file_path = os.path.join(
                CONF.getConfigPath(),
                'uploaded_reports/{0}'.format(raw_report_filename))
        except AttributeError:
            get_logger().warning(
                "Upload reports in WEB-UI not configurated, run Faraday client and try again..."
            )
            abort(
                make_response(
                    jsonify(
                        message=
                        "Upload reports not configurated: Run faraday client and start Faraday server again"
                    ), 500))

        with open(file_path, 'w') as output:
            output.write(report_file.read())

    UPLOAD_REPORTS_QUEUE.put((workspace, file_path, request.cookies))
    return make_response(jsonify(message="ok"), 200)
예제 #10
0
def create_csv_from_vulns(workspace=None):

    validate_workspace(workspace)

    get_logger(__name__).debug("Request parameters: {!r}"\
        .format(flask.request.args))

    cred_filter = filter_request_args()

    dao = CredentialDAO(workspace)
    result = dao.list(cred_filter=cred_filter)

    return flask.jsonify(result)
예제 #11
0
def count_services(workspace=None):
    validate_workspace(workspace)
    get_logger(__name__).debug("Request parameters: {!r}"\
        .format(flask.request.args))

    field = flask.request.args.get('group_by')

    services_dao = ServiceDAO(workspace)
    result = services_dao.count(group_by=field)
    if result is None:
        flask.abort(400)

    return flask.jsonify(result)
예제 #12
0
def list_services(workspace=None):
    validate_workspace(workspace)
    get_logger(__name__).debug("Request parameters: {!r}"\
        .format(flask.request.args))

    port = get_integer_parameter('port', default=None)

    services_dao = ServiceDAO(workspace)
    services_by_host = services_dao.list(port)

    result = {'hosts': services_by_host}

    return flask.jsonify(result)
예제 #13
0
def setup_and_run_server(cli_arguments):
    import server.web
    import server.database

    server.database.setup()

    web_server = server.web.WebServer(enable_ssl=cli_arguments.ssl)
    get_logger().info('Faraday Server is ready')

    # Now that server is ready to go, run in background if requested
    if cli_arguments.start:
        daemonize.start_server()

    daemonize.create_pid_file()

    web_server.run()
예제 #14
0
def copy_default_config_to_local():
    if os.path.exists(LOCAL_CONFIG_FILE):
        return

    # Create directory if it doesn't exist
    try:
        os.makedirs(os.path.dirname(LOCAL_CONFIG_FILE))
    except OSError as e:
        if e.errno != errno.EEXIST:
            raise

    # Copy default config file into faraday local config
    shutil.copyfile(DEFAULT_CONFIG_FILE, LOCAL_CONFIG_FILE)

    from server.utils.logger import get_logger
    get_logger(__name__).info(u"Local faraday-server configuration created at {}".format(LOCAL_CONFIG_FILE))
예제 #15
0
def list_commands(workspace=None):
    validate_workspace(workspace)
    get_logger(__name__).debug("Request parameters: {!r}".format(
        flask.request.args))

    page = get_integer_parameter('page', default=0)
    page_size = get_integer_parameter('page_size', default=0)

    commands_filter = filter_request_args('page', 'page_size')

    dao = CommandDAO(workspace)

    result = dao.list(page=page,
                      page_size=page_size,
                      command_filter=commands_filter)

    return flask.jsonify(result)
예제 #16
0
def count_vulnerabilities(workspace=None):
    validate_workspace(workspace)
    get_logger(__name__).debug("Request parameters: {!r}"\
        .format(request.args))

    field = request.args.get('group_by')
    search = request.args.get('search')
    vuln_filter = filter_request_args('search', 'group_by')

    vuln_dao = VulnerabilityDAO(workspace)
    result = vuln_dao.count(group_by=field,
                            search=search,
                            vuln_filter=vuln_filter)
    if result is None:
        abort(400)

    return jsonify(result)
예제 #17
0
def ask_to_install(missing_packages):
    logger = get_logger(__name__)
    logger.warning("The following packages are not installed:")
    for package in missing_packages:
        logger.warning("%s" % package)
    res = query_yes_no("Do you want to install them?", default="no")
    if res:
        checker = DependencyChecker(server.config.REQUIREMENTS_FILE)
        checker.install_packages(missing_packages)
    return res
예제 #18
0
def list_hosts(workspace=None):
    validate_workspace(workspace)
    get_logger(__name__).debug("Request parameters: {!r}"\
        .format(flask.request.args))

    page = get_integer_parameter('page', default=0)
    page_size = get_integer_parameter('page_size', default=0)
    search = flask.request.args.get('search')
    order_by = flask.request.args.get('sort')
    order_dir = flask.request.args.get('sort_dir')

    host_filter = filter_request_args('page', 'page_size', 'search', 'sort',
                                      'sort_dir')

    dao = HostDAO(workspace)
    result = dao.list(search=search,
                      page=page,
                      page_size=page_size,
                      order_by=order_by,
                      order_dir=order_dir,
                      host_filter=host_filter)

    return flask.jsonify(result)
예제 #19
0
def get_vulnerabilities(workspace=None):
    validate_workspace(workspace)
    get_logger(__name__).debug("Request parameters: {!r}"\
        .format(request.args))

    page = get_integer_parameter('page', default=0)
    page_size = get_integer_parameter('page_size', default=0)
    search = request.args.get('search')
    order_by = request.args.get('sort')
    order_dir = request.args.get('sort_dir')

    vuln_filter = filter_request_args('page', 'page_size', 'search', 'sort',
                                      'sort_dir')

    vuln_dao = VulnerabilityDAO(workspace)

    result = vuln_dao.list(search=search,
                           page=page,
                           page_size=page_size,
                           order_by=order_by,
                           order_dir=order_dir,
                           vuln_filter=vuln_filter)

    return jsonify(result)
예제 #20
0
def process_run_commands(cli_arguments):
    logger = get_logger(__name__)

    if cli_arguments.stop:
        if not daemonize.stop_server():
            # Exists with an error if it couldn't close the server
            sys.exit(1)
        else:
            logger.info("Faraday Server stopped successfully")
            sys.exit(0)

    # Check if server is already running
    pid = daemonize.is_server_running()
    if pid is not None:
        logger.error("Faraday Server is already running. PID: {}".format(pid))
        sys.exit(1)
예제 #21
0
def stop_server():
    """Stops Faraday Server if it isn't running"""
    logger = get_logger(__name__)

    pid = is_server_running()
    if pid is None:
        logger.error('Faraday Server is not running')
        return False

    try:
        os.kill(pid, signal.SIGTERM)
    except OSError, err:
        if err.errno == errno.EPERM:
            logger.error("Couldn't stop Faraday Server. User doesn't"\
                "have enough permissions")
            return False
        else:
            raise err
예제 #22
0
def get_server_pid():
    logger = get_logger(__name__)

    if not os.path.isfile(server.config.FARADAY_SERVER_PID_FILE):
        return None

    with open(server.config.FARADAY_SERVER_PID_FILE, 'r') as pid_file:
        # If PID file is badly written, delete it and
        # assume server is not running
        try:
            pid = int(pid_file.readline())
        except ValueError:
            logger.warning('PID file was found but is corrupted. '\
                'Assuming server is not running. Please check manually'\
                'if Faraday Server is effectively running')
            remove_pid_file()
            return None

    return pid
예제 #23
0
def is_server_running(port):
    """Returns server PID if it is running. Otherwise returns None"""
    logger = get_logger(__name__)
    pid = get_server_pid(port)
    if pid is None:
        return None

    try:
        os.kill(pid, 0)
    except OSError, err:
        if err.errno == errno.ESRCH:
            remove_pid_file(port)
            return None
        elif err.errno == errno.EPERM:
            logger.warning("Server is running BUT the current user"\
                "doesn't have enough access to operate with it")
            return pid
        else:
            raise
예제 #24
0
    def run(self):
        logger.info('Tool report processor started')
        while not self._stop:
            try:

                workspace, file_path, cookie = UPLOAD_REPORTS_QUEUE.get(
                    False, timeout=0.1)
                get_logger().info(
                    'Processing raw report {0}'.format(file_path))

                # Cookie of user, used to create objects in server with the right owner.
                server.FARADAY_UPLOAD_REPORTS_WEB_COOKIE = cookie
                server.FARADAY_UPLOAD_REPORTS_OVERWRITE_SERVER_URL = "http://{0}:{1}".format(
                    FaradayServerConfig.faraday_server.bind_address,
                    FaradayServerConfig.faraday_server.port)

                self.processor.ws_name = workspace

                command_id = self.processor.processReport(file_path)
                UPLOAD_REPORTS_CMD_QUEUE.put(command_id)
                if not command_id:
                    continue

                self.end_event.wait()
                get_logger().info(
                    'Report processing of report {0} finished'.format(
                        file_path))
                self.end_event.clear()

            except Empty:
                time.sleep(0.1)

            except KeyboardInterrupt as ex:
                get_logger().info(
                    'Keyboard interrupt, stopping report processing thread')
                self.stop()

            except Exception as ex:
                get_logger().exception(ex)
                continue
예제 #25
0
def stop_server(port):
    """Stops Faraday Server if it isn't running"""
    logger = get_logger(__name__)
    pid = is_server_running(port)
    if pid is None:
        logger.error('Faraday Server is not running')
        return False

    try:
        logger.info('Sending SIGTERM to pid {0}, in port {1}'.format(
            pid, port))
        os.kill(pid, signal.SIGTERM)
        logger.info("Faraday Server stopped successfully")
    except OSError, err:
        if err.errno == errno.EPERM:
            logger.error("Couldn't stop Faraday Server. User doesn't"\
                "have enough permissions")
            return False
        else:
            raise err
예제 #26
0
def setup_environment(cli_arguments):
    logger = get_logger(__name__)
    server.config.copy_default_config_to_local()

    if cli_arguments.debug:
        set_logging_level(server.config.DEBUG)

    missing_packages = check_dependencies()

    if len(missing_packages) > 0:
        answer = ask_to_install(missing_packages)
        if answer:
            logger.info(
                "Dependencies installed. Please launch Faraday Server again")
            sys.exit(0)
        else:
            logger.error("Dependencies not met")
            sys.exit(1)

    server.config.gen_web_config()
예제 #27
0
 def connectionLost(self, reason):
     if not reason.check(error.ConnectionClosed):
         logger.get_logger(__name__).error("Connection error: {}".format(
             reason.value))
     return proxy.ProxyClient.connectionLost(self, reason)
예제 #28
0
def start_server():
    get_logger(__name__).info('Running as a daemon')
    WORKDIR = server.config.FARADAY_BASE
    createDaemon()
예제 #29
0
 def render(self, request):
     logger.get_logger(__name__).debug("-> CouchDB: {} {}".format(
         request.method, request.uri))
     return proxy.ReverseProxyResource.render(self, request)