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
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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()
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))
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)
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)
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
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)
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)
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)
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
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
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
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
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
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()
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)
def start_server(): get_logger(__name__).info('Running as a daemon') WORKDIR = server.config.FARADAY_BASE createDaemon()
def render(self, request): logger.get_logger(__name__).debug("-> CouchDB: {} {}".format( request.method, request.uri)) return proxy.ReverseProxyResource.render(self, request)