def post_attachment(self, workspace_name, vuln_id): try: validate_csrf(request.form.get('csrf_token')) except wtforms.ValidationError: flask.abort(403) vuln_workspace_check = db.session.query( VulnerabilityGeneric, Workspace.id).join(Workspace).filter( VulnerabilityGeneric.id == vuln_id, Workspace.name == workspace_name).first() if vuln_workspace_check: if 'file' not in request.files: flask.abort(400) faraday_file = FaradayUploadedFile(request.files['file'].read()) filename = request.files['file'].filename get_or_create(db.session, File, object_id=vuln_id, object_type='vulnerability', name=filename, filename=filename, content=faraday_file) db.session.commit() return flask.jsonify({'message': 'Evidence upload was successful'}) else: flask.abort(404, "Vulnerability not found")
def bulk_create(self, workspace_name): try: validate_csrf(flask.request.form.get('csrf_token')) except wtforms.ValidationError: flask.abort(403) def parse_hosts(list_string): items = re.findall(r"([.a-zA-Z0-9_-]+)", list_string) return items workspace = self._get_workspace(workspace_name) logger.info("Create hosts from CSV") if 'file' not in flask.request.files: abort(400, "Missing File in request") hosts_file = flask.request.files['file'] stream = StringIO(hosts_file.stream.read().decode("utf-8"), newline=None) FILE_HEADERS = {'description', 'hostnames', 'ip', 'os'} try: hosts_reader = csv.DictReader(stream) if set(hosts_reader.fieldnames) != FILE_HEADERS: logger.error("Missing Required headers in CSV (%s)", FILE_HEADERS) abort(400, "Missing Required headers in CSV (%s)" % FILE_HEADERS) hosts_created_count = 0 hosts_with_errors_count = 0 for host_dict in hosts_reader: try: hostnames = parse_hosts(host_dict.pop('hostnames')) other_fields = { 'owned': False, 'mac': u'00:00:00:00:00:00', 'default_gateway_ip': u'None' } host_dict.update(other_fields) host = super(HostsView, self)._perform_create(host_dict, workspace_name) host.workspace = workspace for name in hostnames: get_or_create(db.session, Hostname, name=name, host=host, workspace=host.workspace) db.session.commit() except Exception as e: logger.error("Error creating host (%s)", e) hosts_with_errors_count += 1 else: logger.debug("Host Created (%s)", host_dict) hosts_created_count += 1 return make_response( jsonify(hosts_created=hosts_created_count, hosts_with_errors=hosts_with_errors_count), 200) except Exception as e: logger.error("Error parsing hosts CSV (%s)", e) abort(400, "Error parsing hosts CSV (%s)" % e)
def _perform_create(self, data, **kwargs): hostnames = data.pop('hostnames', []) host = super()._perform_create(data, **kwargs) for name in hostnames: get_or_create(db.session, Hostname, name=name, host=host, workspace=host.workspace) db.session.commit() return host
def update_executors(agent, executors): incoming_executor_names = set() for raw_executor in executors: if 'executor_name' not in raw_executor or 'args' not in raw_executor: continue executor, _ = get_or_create( db.session, Executor, **{ 'name': raw_executor['executor_name'], 'agent': agent, } ) executor.parameters_metadata = raw_executor['args'] db.session.add(executor) db.session.commit() incoming_executor_names.add(raw_executor['executor_name']) current_executors = Executor.query.filter(Executor.agent == agent) for current_executor in current_executors: if current_executor.name not in incoming_executor_names: db.session.delete(current_executor) db.session.commit() return True
def _process_attachments(self, obj, attachments): old_attachments = db.session.query(File).filter_by( object_id=obj.id, object_type='vulnerability', ) for old_attachment in old_attachments: db.session.delete(old_attachment) for filename, attachment in attachments.items(): faraday_file = FaradayUploadedFile(b64decode(attachment['data'])) get_or_create( db.session, File, object_id=obj.id, object_type='vulnerability', name=os.path.splitext(os.path.basename(filename))[0], filename=os.path.basename(filename), content=faraday_file, )
def _process_attachments(self, obj, attachments): old_attachments = db.session.query(File).options( joinedload(File.creator), joinedload(File.update_user)).filter_by( object_id=obj.id, object_type='vulnerability', ) for old_attachment in old_attachments: db.session.delete(old_attachment) for filename, attachment in attachments.items(): faraday_file = FaradayUploadedFile(b64decode(attachment['data'])) get_or_create( db.session, File, object_id=obj.id, object_type='vulnerability', name=Path(filename).stem, filename=Path(filename).name, content=faraday_file, )
def add_custom_field_wizard(): print('This wizard will guide you to ADD custom field to the vulneraiblity model.') field_name = click.prompt('Field name') field_display_name = click.prompt('Display name') field_type = click.prompt('Field type (int, str, list)', type=click.Choice(['int', 'str', 'list'])) custom_fields = db.session.query(CustomFieldsSchema) #Checks the name of the fields wont be a duplicate for custom_field in custom_fields: if field_name == custom_field.field_name \ or field_display_name == custom_field.field_display_name: print('Custom field already exists, skipping') sys.exit(1) current_used_orders = set() if custom_fields.count(): print('Custom field current order') for custom_field in custom_fields: current_used_orders.add(custom_field.field_order) print(f'Field {custom_field.field_display_name}, order {custom_field.field_order}') field_order = click.prompt('Field order index') invalid_field_order = False try: int(field_order) except ValueError: invalid_field_order = True while invalid_field_order or int(field_order) in current_used_orders: print('Field order already used or invalid value, please choose another value') field_order = click.prompt('Field order index') try: int(field_order) except ValueError: invalid_field_order = True continue invalid_field_order = False confirmation = click.prompt('New CustomField will be added to vulnerability -> Order {order} ({0},{1},{2}) <-, confirm to continue (yes/no)'\ .format(field_name, field_display_name, field_type, order=field_order)) if not confirmation: sys.exit(1) custom_field_data, created = get_or_create( db.session, CustomFieldsSchema, table_name='vulnerability', field_name=field_name, field_order=field_order, ) if not created: print('Custom field already exists, skipping') sys.exit(1) custom_field_data.field_display_name = field_display_name custom_field_data.field_type = field_type db.session.commit()
def _get_create_command_object(self, object, object_type): cmd_object_relation, created = get_or_create( self.session, CommandObject, workspace_id=self.workspace.id, command_id=self.command_id, object_type=object_type, object_id=object.id, ) cmd_object_relation.created_persistent = False if created: self.session.add(cmd_object_relation) self.session.commit()
def update(self, new_config=None): saved_config, created = get_or_create(db.session, Configuration, key=self.settings_key) if created: saved_config.value = self.update_configuration(new_config) else: # SQLAlchemy doesn't detect in-place mutations to the structure of a JSON type. # Thus, we make a deepcopy of the JSON so SQLAlchemy can detect the changes. saved_config.value = self.update_configuration( new_config, saved_config.value) db.session.commit() self.__class__.value.fget.cache_clear() if self.must_restart_threads: os.kill(os.getpid(), signal.SIGUSR1)
def post_attachment(self, workspace_name, vuln_id): """ --- post: tags: ["Vulnerability", "File"] description: Creates a new attachment in the vuln responses: 201: description: Created tags: ["Vulnerability", "File"] responses: 200: description: Ok """ vuln_workspace_check = db.session.query( VulnerabilityGeneric, Workspace.id).join(Workspace).filter( VulnerabilityGeneric.id == vuln_id, Workspace.name == workspace_name).first() if vuln_workspace_check: if 'file' not in request.files: flask.abort(400) vuln = VulnerabilitySchema().dump(vuln_workspace_check[0]) filename = request.files['file'].filename _attachments = vuln['_attachments'] if filename in _attachments: message = 'Evidence already exists in vuln' return make_response( flask.jsonify(message=message, success=False, code=400), 400) else: faraday_file = FaradayUploadedFile( request.files['file'].read()) instance, created = get_or_create(db.session, File, object_id=vuln_id, object_type='vulnerability', name=filename, filename=filename, content=faraday_file) db.session.commit() message = 'Evidence upload was successful' return flask.jsonify({'message': message}) else: flask.abort(404, "Vulnerability not found")
def manage(action, json_data, name): load_settings() if name: name = name.lower() available_settings = get_all_settings() if action in ('show', 'update'): if not name: click.secho(f"You must indicate a settings name to {action}", fg="red") sys.exit(1) else: if name not in available_settings: click.secho(f'Invalid settings: {name}', fg='red') return settings = get_settings(name) if action == "show": click.secho(f"Settings for: {name}", fg="green") for key, value in settings.value.items(): click.secho(f"{key}: {value}") elif action == "update": new_settings = {} click.secho(f"Update settings for: {name}", fg="green") for key, value in settings.value.items(): if json_data is not None: json_value = json_data.get(key, None) if type(json_value) != type(value) or json_value is None: click.secho( f"Missing or Invalid value for {key} [{json_value}]", fg="red") sys.exit(1) else: new_value = json_value else: new_value = click.prompt(f'{key}', default=value) new_settings[key] = new_value try: settings.validate_configuration(new_settings) except InvalidConfigurationError as e: click.secho(f"Invalid configuration for: {name}", fg="red") click.secho(e, fg="red") sys.exit(1) else: settings_message = "\n".join( [f"{key}: {value}" for key, value in new_settings.items()]) confirm = json_data is not None if not confirm: confirm = click.confirm( f"Do you confirm your changes on {name}?" f"\n----------------------" f"\n{settings_message}\n", default=True) if confirm: with get_app().app_context(): saved_config, created = get_or_create( db.session, Configuration, key=settings.settings_key) if created: saved_config.value = settings.update_configuration( new_settings) else: # SQLAlchemy doesn't detect in-place mutations to the structure of a JSON type. # Thus, we make a deepcopy of the JSON so SQLAlchemy can detect the changes. saved_config.value = settings.update_configuration( new_settings, saved_config.value) db.session.commit() click.secho("Updated!!", fg='green') else: click.secho("No changes where made to the settings", fg="green") else: click.secho("Available settings:", fg="green") for i in available_settings: click.secho(i)