class SubmissionSummary(odm.Model): classification = odm.Classification(default=Classification.UNRESTRICTED) # Classification of the cache filtered = odm.Boolean(default=False) # Has this cache entry been filtered expiry_ts = odm.Date(index=True) # Expiry date tags = odm.Text() # Tags cache attack_matrix = odm.Text() # Att&ck Matrix cache heuristics = odm.Text() # Heuristics cache
class Submission(odm.Model): archive_ts = odm.Date(store=False) # Archiving timestamp classification = odm.Classification() # Classification of the submission error_count = odm.Integer() # Total number of errors in the submission errors = odm.List(odm.Keyword(), store=False) # List of error keys expiry_ts = odm.Optional(odm.Date(store=False)) # Expiry timestamp file_count = odm.Integer() # Total number of files in the submission files: List[File] = odm.List( odm.Compound(File)) # List of files that were originally submitted max_score = odm.Integer() # Maximum score of all the files in the scan metadata = odm.FlattenedObject( store=False) # Metadata associated to the submission params: SubmissionParams = odm.Compound( SubmissionParams) # Submission detail blocs results: List[str] = odm.List(odm.Keyword(), store=False) # List of result keys sid = odm.UUID(copyto="__text__") # Submission ID state = odm.Enum(values=SUBMISSION_STATES) # Status of the submission times = odm.Compound(Times, default={}) # Timing bloc verdict = odm.Compound(Verdict, default={}) # Verdict timing def is_submit(self): return self.state == 'submitted' def is_complete(self): return self.state == 'completed' def is_initial(self): return self.is_submit() and not self.params.psid
class UpdateSource(odm.Model): name: str = odm.Keyword(description="Name of source") password: Opt[str] = odm.Optional( odm.Keyword(default=""), description="Password used to authenticate with source") pattern: Opt[str] = odm.Optional( odm.Keyword(default=""), description="Pattern used to find files of interest from source") private_key: Opt[str] = odm.Optional( odm.Keyword(default=""), description="Private key used to authenticate with source") ca_cert: Opt[str] = odm.Optional(odm.Keyword(default=""), description="CA cert for source") ssl_ignore_errors: bool = odm.Boolean( default=False, description="Ignore SSL errors when reaching out to source?") proxy: Opt[str] = odm.Optional(odm.Keyword(default=""), description="Proxy server for source") uri: str = odm.Keyword(description="URI to source") username: Opt[str] = odm.Optional( odm.Keyword(default=""), description="Username used to authenticate with source") headers: list[EnvironmentVariable] = odm.List( odm.Compound(EnvironmentVariable), default=[], description="Headers") default_classification = odm.Classification( default=Classification.UNRESTRICTED, description= "Default classification used in absence of one defined in files from source" )
class UserSettings(odm.Model): # User's default settings classification = odm.Classification(default=Classification.UNRESTRICTED ) # Default submission classification deep_scan = odm.Boolean(default=False) # Should a deep scan be performed description = odm.Keyword(default="") # Default description download_encoding = odm.Enum( values=ENCODINGS, default="cart") # Default download encoding when downloading files expand_min_score = odm.Integer( default=500) # Auto-expand section when score bigger then this ignore_cache = odm.Boolean(default=False) # Ignore service caching ignore_dynamic_recursion_prevention = odm.Boolean( default=False) # Ignore dynamic recursion prevention ignore_filtering = odm.Boolean(default=False) # Ignore filtering services priority = odm.Integer( default=1000) # Default priority for the submissions profile = odm.Boolean( default=False) # Should the submission do extra profiling service_spec = odm.Mapping(odm.Keyword(), default={}) # Default service specific settings services = odm.Compound(ServiceSelection, default={}) # Default service selection submission_view = odm.Enum( values=VIEWS, default="report") # Default view for completed submissions ttl = odm.Integer(default=0) # Default submission Time to Live (days)
class Alert(odm.Model): alert_id = odm.Keyword(copyto="__text__") # ID of the alert al = odm.Compound(ALResults) # Assemblyline result block archive_ts = odm.Date(store=False) # Archiving timestamp attack = odm.Compound(Attack) # Attack result block classification = odm.Classification() # Classification of the alert expiry_ts = odm.Optional(odm.Date(store=False)) # Expiry timestamp extended_scan = odm.Enum(values=EXTENDED_SCAN_VALUES, store=False) # Status of the extended scan file = odm.Compound(File) # File block filtered = odm.Boolean(default=False) # Are the alert result filtered heuristic = odm.Compound(Heuristic) # Heuristic result block label = odm.List(odm.Keyword(), copyto="__text__", default=[]) # List of labels applied to the alert metadata = odm.FlattenedObject( default={}, store=False) # Metadata submitted with the file owner = odm.Optional(odm.Keyword()) # Owner of the alert priority = odm.Optional( odm.Enum(values=PRIORITIES)) # Priority applied to the alert reporting_ts = odm.Date() # Time at which the alert was created sid = odm.UUID(store=False) # ID of the submission related to this alert status = odm.Optional( odm.Enum(values=STATUSES)) # Status applied to the alert ts = odm.Date() # Timestamp at which the file was submitted type = odm.Keyword() # Type of alert verdict = odm.Compound(Verdict, default={}) # Verdict timing
class Task(odm.Model): sid = odm.UUID() metadata = odm.FlattenedObject() # Metadata associated to the submission min_classification = odm.Classification( ) # Minimum classification of the file being scanned fileinfo: FileInfo = odm.Compound(FileInfo) # File info block filename = odm.Keyword() service_name = odm.Keyword() service_config = odm.Mapping(odm.Any(), default={}) # Service specific parameters depth = odm.Integer(default=0) max_files = odm.Integer() ttl = odm.Integer(default=0) tags = odm.List(odm.Compound(TagItem), default=[]) temporary_submission_data = odm.List(odm.Compound(DataItem), default=[]) deep_scan = odm.Boolean(default=False) # Whether the service cache should be ignored during the processing of this task ignore_cache = odm.Boolean(default=False) # Whether the service should ignore the dynamic recursion prevention or not ignore_dynamic_recursion_prevention = odm.Boolean(default=False) # Priority for processing order priority = odm.Integer(default=0) @staticmethod def make_key(sid, service_name, sha): return f"{sid}_{service_name}_{sha}" def key(self): return Task.make_key(self.sid, self.service_name, self.fileinfo.sha256)
class Favorite(odm.Model): created_by = odm.Keyword() # Who created the favorite classification = odm.Classification( is_user_classification=True, copyto="__text__", default=Classification.UNRESTRICTED) # Classification of the favorite name = odm.Keyword() # Name of the favorite query = odm.Keyword() # Query for the favorite
class Section(odm.Model): body = odm.Optional(odm.Text(copyto="__text__")) # Text body of the result section classification = odm.Classification() # Classification of the section body_format = odm.Enum(values=BODY_FORMAT, index=False) # Type of body in this section depth = odm.Integer(index=False) # Depth of the section heuristic = odm.Optional(odm.Compound(Heuristic)) # Heuristic used to score result section tags = odm.Compound(Tagging, default={}) # List of tags associated to this section title_text = odm.Text(copyto="__text__") # Title of the section
class Heuristic(odm.Model): attack_id = odm.Optional(odm.Enum(values=PATTERNS, copyto="__text__")) # Att&ck matrix pattern classification = odm.Classification(default=Classification.UNRESTRICTED) # Classification of the heuristic description = odm.Text(copyto="__text__") # Description of the heuristic filetype = odm.Keyword(copyto="__text__") # Type of file targeted heur_id = odm.Keyword(copyto="__text__") # Heuristic ID name = odm.Keyword(copyto="__text__") # Name of the heuristic score = odm.Integer() # Score of the heuristic
class Task(odm.Model): sid = odm.UUID(description="Submission ID") metadata = odm.FlattenedObject( description="Metadata associated to the submission") min_classification = odm.Classification( description="Minimum classification of the file being scanned") fileinfo: FileInfo = odm.Compound(FileInfo, description="File info block") filename = odm.Keyword(description="File name") service_name = odm.Keyword(description="Service name") service_config = odm.Mapping(odm.Any(), default={}, description="Service specific parameters") depth = odm.Integer( default=0, description="File depth relative to initital submitted file") max_files = odm.Integer( description="Maximum number of files that submission can have") ttl = odm.Integer(default=0, description="Task TTL") tags = odm.List(odm.Compound(TagItem), default=[], description="List of tags") temporary_submission_data = odm.List( odm.Compound(DataItem), default=[], description="Temporary submission data") deep_scan = odm.Boolean(default=False, description="Perform deep scanning") ignore_cache = odm.Boolean( default=False, description= "Whether the service cache should be ignored during the processing of this task" ) ignore_dynamic_recursion_prevention = odm.Boolean( default=False, description= "Whether the service should ignore the dynamic recursion prevention or not" ) ignore_filtering = odm.Boolean( default=False, description="Should the service filter it's output?") priority = odm.Integer(default=0, description="Priority for processing order") safelist_config = odm.Compound( ServiceSafelist, description= "Safelisting configuration (as defined in global configuration)", default={'enabled': False}) @staticmethod def make_key(sid, service_name, sha): return f"{sid}_{service_name}_{sha}" def key(self): return Task.make_key(self.sid, self.service_name, self.fileinfo.sha256)
class User(odm.Model): agrees_with_tos = odm.Optional( odm.Date(index=False, store=False), description="Date the user agree with terms of service") api_quota = odm.Integer( default=10, store=False, description="Maximum number of concurrent API requests") apikeys = odm.Mapping(odm.Compound(ApiKey), default={}, index=False, store=False, description="Mapping of API keys") apps = odm.Mapping(odm.Compound(Apps), default={}, index=False, store=False, description="Applications with access to the account") can_impersonate = odm.Boolean( default=False, index=False, store=False, description="Allowed to query on behalf of others?") classification = odm.Classification( is_user_classification=True, copyto="__text__", default=Classification.UNRESTRICTED, description="Maximum classification for the user") dn = odm.Optional(odm.Keyword(store=False, copyto="__text__"), description="User's LDAP DN") email = odm.Optional(odm.Email(copyto="__text__"), description="User's email address") groups = odm.List(odm.Keyword(), copyto="__text__", default=["USERS"], description="List of groups the user submits to") is_active = odm.Boolean(default=True, description="Is the user active?") name = odm.Keyword(copyto="__text__", description="Full name of the user") otp_sk = odm.Optional( odm.Keyword(index=False, store=False), description="Secret key to generate one time passwords") password = odm.Keyword(index=False, store=False, description="BCrypt hash of the user's password") submission_quota = odm.Integer( default=5, store=False, description="Maximum number of concurrent submissions") type = odm.List(odm.Enum(values=USER_TYPES), default=['user'], description="Type of user") security_tokens = odm.Mapping(odm.Keyword(), index=False, store=False, default={}, description="Map of security tokens") uname = odm.Keyword(copyto="__text__", description="Username")
class UpdateSourceDelta(odm.Model): headers = odm.Optional(odm.List(odm.Compound(EnvironmentVariable))) name = odm.Optional(odm.Keyword()) password = odm.Optional(odm.Keyword()) pattern = odm.Optional(odm.Keyword()) private_key = odm.Optional(odm.Keyword()) uri = odm.Optional(odm.Keyword()) username = odm.Optional(odm.Keyword()) default_classification = odm.Optional(odm.Classification())
class UpdateSource(odm.Model): name = odm.Keyword() password = odm.Optional(odm.Keyword()) pattern = odm.Optional(odm.Keyword()) private_key = odm.Optional(odm.Keyword()) uri = odm.Keyword() username = odm.Optional(odm.Keyword()) headers = odm.List(odm.Compound(EnvironmentVariable), default=[]) default_classification = odm.Classification(default=Classification.UNRESTRICTED)
class Favorite(odm.Model): created_by = odm.Keyword(description="Who created the favorite") classification = odm.Classification( is_user_classification=True, copyto="__text__", default=Classification.UNRESTRICTED, description="Classification of the favorite") name = odm.Keyword(description="Name of the favorite") query = odm.Keyword(description="Query for the favorite")
class SubmissionTree(odm.Model): classification = odm.Classification( default=Classification.UNRESTRICTED, description="Classification of the cache") filtered = odm.Boolean(default=False, description="Has this cache entry been filtered?") expiry_ts = odm.Date(description="Expiry timestamp") supplementary = odm.Text(index=False, description="Tree of supplementary files") tree = odm.Text(index=False, description="File tree cache")
class TCSignature(odm.Model): al_score = odm.Enum(values=SCORES, default="HIGH") al_status = odm.Enum(values=STATUSES, default="TESTING") callback = odm.Optional(odm.Keyword()) classification = odm.Classification(default=Classification.UNRESTRICTED) comment = odm.Optional(odm.Keyword()) implant_family = odm.Optional(odm.Keyword()) last_modified = odm.Date(default="NOW") name = odm.Keyword(copyto="__text__") threat_actor = odm.Optional(odm.Keyword()) values = odm.List(odm.Keyword())
class UpdateSourceDelta(odm.Model): headers = odm.Optional(odm.List(odm.Compound(EnvironmentVariable))) name = odm.Optional(odm.Keyword()) password = odm.Optional(odm.Keyword(default="")) pattern = odm.Optional(odm.Keyword(default="")) private_key = odm.Optional(odm.Keyword(default="")) ca_cert = odm.Optional(odm.Keyword(default="")) ssl_ignore_errors = odm.Boolean(default=False) proxy = odm.Optional(odm.Keyword(default="")) uri = odm.Optional(odm.Keyword()) username = odm.Optional(odm.Keyword(default="")) default_classification = odm.Optional(odm.Classification())
class SubmissionSummary(odm.Model): classification = odm.Classification( default=Classification.UNRESTRICTED, description="Classification of the cache") filtered = odm.Boolean(default=False, description="Has this cache entry been filtered?") expiry_ts = odm.Date(index=True, description="Expiry timestamp") tags = odm.Text(description="Tags cache") attack_matrix = odm.Text(description="ATT&CK Matrix cache") heuristics = odm.Text(description="Heuristics cache") heuristic_sections = odm.Text( description="All sections mapping to the heuristics") heuristic_name_map = odm.Text(description="Map of heuristic names to IDs")
class Heuristic(odm.Model): attack_id = odm.List(odm.Keyword(copyto="__text__"), default=[], description="List of all associated ATT&CK IDs") classification = odm.Classification(default=Classification.UNRESTRICTED, description="Classification of the heuristic") description = odm.Text(copyto="__text__", description="Description of the heuristic") filetype = odm.Keyword(copyto="__text__", description="What type of files does this heuristic target?") heur_id = odm.Keyword(copyto="__text__", description="ID of the Heuristic") name = odm.Keyword(copyto="__text__", description="Name of the heuristic") score = odm.Integer(description="Default score of the heuristic") signature_score_map = odm.Mapping(odm.Integer(), default={}, description="Score of signatures for this heuristic") stats = odm.Compound(Statistics, default={}, description="Statistics related to the Heuristic") max_score = odm.Optional(odm.Integer(), description="Maximum score for heuristic")
class BaseTestModel(odm.Model): classification = odm.Classification(default="UNRESTRICTED", yml_config=yml_config) flavour = odm.Text(copyto='features', default="EMPTY") height = odm.Integer() no_store = odm.Optional(odm.Keyword(store=False)) no_index = odm.Optional(odm.Keyword(index=False, store=False)) dots = odm.Mapping(odm.Compound(Position), default={}) birthday = odm.Date() tags = odm.List(odm.Enum({'silly', 'cats', '10'}), default=[], copyto='features') size = odm.Compound(MeasurementModel, default={'depth': 100, 'width': 100}) features = odm.List(odm.Text(), default=[]) metadata = odm.Mapping(odm.Text(), default={}) things = odm.List(odm.Compound(ThingsModel), default=[])
class Heuristic(odm.Model): attack_id = odm.List(odm.Enum(values=ATTACK_ID_LIST, copyto="__text__"), default=[]) # List of all associated Att&ck IDs classification = odm.Classification( default=Classification.UNRESTRICTED) # Classification of the heuristic description = odm.Text(copyto="__text__") # Description of the heuristic filetype = odm.Keyword(copyto="__text__") # Type of file targeted heur_id = odm.Keyword(copyto="__text__") # Heuristic ID name = odm.Keyword(copyto="__text__") # Name of the heuristic score = odm.Integer() # Default score of the heuristic signature_score_map = odm.Mapping( odm.Integer(), default={}) # Score of signatures for this heuristic max_score = odm.Optional(odm.Integer()) # Maximum score for heuristic
class Signature(odm.Model): classification = odm.Classification(store=True, default=Classification.UNRESTRICTED) data = odm.Text(index=False, store=False) last_modified = odm.Date(default="NOW") name = odm.Keyword(copyto="__text__") order = odm.Integer(default=1, store=False) revision = odm.Keyword(default="1") signature_id = odm.Optional(odm.Keyword()) source = odm.Keyword() state_change_date = odm.Optional(odm.Date(store=False)) state_change_user = odm.Optional(odm.Keyword(store=False)) status = odm.Enum(values=RULE_STATUSES, copyto="__text__") type = odm.Keyword(copyto="__text__")
class Result(odm.Model): archive_ts = odm.Date(store=False) # Archiving timestamp classification = odm.Classification( ) # Aggregate classification for the result created = odm.Date( default="NOW") # Date at which the result object got created expiry_ts = odm.Optional(odm.Date(store=False)) # Expiry time stamp response: ResponseBody = odm.Compound( ResponseBody) # The body of the response from the service result: ResultBody = odm.Compound(ResultBody, default={}) # The result body sha256 = odm.SHA256( store=False) # SHA256 of the file the result object relates to drop_file = odm.Boolean( default=False) # Do not pass to other stages after this run def build_key(self, service_tool_version=None, task=None): return self.help_build_key(self.sha256, self.response.service_name, self.response.service_version, self.is_empty(), service_tool_version=service_tool_version, task=task) @staticmethod def help_build_key(sha256, service_name, service_version, is_empty, service_tool_version=None, task=None): key_list = [ sha256, service_name.replace('.', '_'), f"v{service_version.replace('.', '_')}", f"c{generate_conf_key(service_tool_version=service_tool_version, task=task)}", ] if is_empty: key_list.append("e") return '.'.join(key_list) def is_empty(self): if len(self.response.extracted) == 0 and \ len(self.response.supplementary) == 0 and \ len(self.result.sections) == 0 and \ self.result.score == 0: return True return False
class FileTask(odm.Model): """Dispatcher internal model for tracking each file in a submission.""" sid = odm.Keyword() min_classification = odm.Classification() # Minimum classification of the file being scanned parent_hash = odm.Optional(odm.Keyword()) file_info: FileInfo = odm.Compound(FileInfo) depth = odm.Integer() max_files = odm.Integer() def get_tag_set_name(self) -> str: """Get the name of a redis set where the task tags are collected.""" return get_tag_set_name(self.sid, self.file_info.sha256) def get_temporary_submission_data_name(self) -> str: """Get the name of a redis hash where tags for a submission are collected.""" return get_temporary_submission_data_name(self.sid, self.file_info.sha256)
class Submission(odm.Model): archive_ts = odm.Date(store=False, description="Archiving timestamp") classification = odm.Classification( description="Classification of the submission") error_count = odm.Integer( description="Total number of errors in the submission") errors: list[str] = odm.List(odm.Keyword(), store=False, description="List of error keys") expiry_ts = odm.Optional(odm.Date(store=False), description="Expiry timestamp") file_count = odm.Integer( description="Total number of files in the submission") files: list[File] = odm.List( odm.Compound(File), description="List of files that were originally submitted") max_score = odm.Integer( description="Maximum score of all the files in the scan") metadata = odm.FlattenedObject( store=False, description="Metadata associated to the submission") params: SubmissionParams = odm.Compound( SubmissionParams, description="Submission parameter details") results: list[str] = odm.List(odm.Keyword(), store=False, description="List of result keys") sid = odm.UUID(copyto="__text__", description="Submission ID") state = odm.Enum(values=SUBMISSION_STATES, description="Status of the submission") times = odm.Compound(Times, default={}, description="Submission-specific times") verdict = odm.Compound(Verdict, default={}, description="Malicious verdict details") # the filescore key, used in deduplication. This is a non-unique key, that is # shared by submissions that may be processed as duplicates. scan_key = odm.Optional(odm.Keyword(store=False, index=False)) def is_submit(self): return self.state == 'submitted' def is_complete(self): return self.state == 'completed' def is_initial(self): return self.is_submit() and not self.params.psid
class UpdateSourceDelta(odm.Model): name = odm.Optional( odm.Keyword(), description= "Refer to:<br>[Service - UpdateSource](../service/#updatesource)") password = odm.Optional( odm.Keyword(default=""), description= "Refer to:<br>[Service - UpdateSource](../service/#updatesource)") pattern = odm.Optional( odm.Keyword(default=""), description= "Refer to:<br>[Service - UpdateSource](../service/#updatesource)") private_key = odm.Optional( odm.Keyword(default=""), description= "Refer to:<br>[Service - UpdateSource](../service/#updatesource)") ca_cert = odm.Optional( odm.Keyword(default=""), description= "Refer to:<br>[Service - UpdateSource](../service/#updatesource)") ssl_ignore_errors = odm.Boolean( default=False, description= "Refer to:<br>[Service - UpdateSource](../service/#updatesource)") proxy = odm.Optional( odm.Keyword(default=""), description= "Refer to:<br>[Service - UpdateSource](../service/#updatesource)") uri = odm.Optional( odm.Keyword(), description= "Refer to:<br>[Service - UpdateSource](../service/#updatesource)") username = odm.Optional( odm.Keyword(default=""), description= "Refer to:<br>[Service - UpdateSource](../service/#updatesource)") headers = odm.Optional( odm.List(odm.Compound(EnvironmentVariable)), description= "Refer to:<br>[Service - UpdateSource](../service/#updatesource)") default_classification = odm.Optional( odm.Classification(), description= "Refer to:<br>[Service - UpdateSource](../service/#updatesource)")
class UserSettings(odm.Model): classification = odm.Classification( default=Classification.UNRESTRICTED, description="Default submission classification") deep_scan = odm.Boolean(default=False, description="Should a deep scan be performed?") description = odm.Keyword(default="", description="Default description") download_encoding = odm.Enum( values=ENCODINGS, default="cart", description="Default download encoding when downloading files") default_zip_password = odm.Text( default="zippy", description= "Default user-defined password for creating password protected ZIPs when downloading files" ) expand_min_score = odm.Integer( default=500, description="Auto-expand section when score bigger then this") ignore_cache = odm.Boolean(default=False, description="Ignore service caching?") ignore_dynamic_recursion_prevention = odm.Boolean( default=False, description="Ignore dynamic recursion prevention?") ignore_filtering = odm.Boolean(default=False, description="Ignore filtering services?") malicious = odm.Boolean( default=False, description="Is the file submitted already known to be malicious?") priority = odm.Integer(default=1000, description="Default priority for the submissions") profile = odm.Boolean( default=False, description="Should the submission do extra profiling?") service_spec = odm.Mapping(odm.Mapping(odm.Any()), default={}, description="Default service specific settings") services = odm.Compound(ServiceSelection, default={}, description="Default service selection") submission_view = odm.Enum( values=VIEWS, default="report", description="Default view for completed submissions") ttl = odm.Integer(default=30, description="Default submission TTL, in days")
class File(odm.Model): archive_ts = odm.Date(store=False, description="Archiving timestamp") ascii = odm.Keyword(index=False, store=False, description="Dotted ASCII representation of the first 64 bytes of the file") classification = odm.Classification(description="Classification of the file") entropy = odm.Float(description="Entropy of the file") expiry_ts = odm.Optional(odm.Date(store=False), description="Expiry timestamp") is_section_image = odm.Boolean(default=False, description="Is this an image from an Image Result Section?") hex = odm.Keyword(index=False, store=False, description="Hex dump of the first 64 bytes of the file") md5 = odm.MD5(copyto="__text__", description="MD5 of the file") magic = odm.Keyword(store=False, description="Output from libmagic related to the file") mime = odm.Optional(odm.Keyword(store=False), description="MIME type of the file as identified by libmagic") seen = odm.Compound(Seen, default={}, description="Details about when the file was seen") sha1 = odm.SHA1(copyto="__text__", description="SHA1 hash of the file") sha256 = odm.SHA256(copyto="__text__", description="SHA256 hash of the file") size = odm.Integer(description="Size of the file in bytes") ssdeep = odm.SSDeepHash(store=False, description="SSDEEP hash of the file") type = odm.Keyword(copyto="__text__", description="Type of file as identified by Assemblyline")
class Workflow(odm.Model): classification = odm.Classification( copyto="__text__", default=Classification.UNRESTRICTED) # Classification of the workflow creation_date = odm.Date(default="NOW") # Creation date of the workflow creator = odm.Keyword() # UID of the creator edited_by = odm.Keyword() # UID of the last edit user hit_count = odm.Integer(default=0) # Number of time workflow hit labels = odm.List(odm.Keyword(), copyto="__text__", default=[]) # Labels applied by the workflow last_edit = odm.Date(default="NOW") # Last edit date last_seen = odm.Optional(odm.Date()) # Last hit date name = odm.Keyword(copyto="__text__") # Name of the workflow priority = odm.Optional( odm.Enum(copyto="__text__", values=PRIORITIES)) # Priority applied by the workflow query = odm.Keyword() # Query that the workflow runs status = odm.Optional(odm.Enum( copyto="__text__", values=STATUSES)) # Status applied by the workflow workflow_id = odm.Optional(odm.UUID()) # ID of the workflow
class Alert(odm.Model): alert_id = odm.Keyword(copyto="__text__", description="ID of the alert") al = odm.Compound(ALResults, description="Assemblyline Result Block") archive_ts = odm.Date(store=False, description="Archiving timestamp") attack = odm.Compound(Attack, description="ATT&CK Block") classification = odm.Classification(description="Classification of the alert") expiry_ts = odm.Optional(odm.Date(store=False), description="Expiry timestamp") extended_scan = odm.Enum(values=EXTENDED_SCAN_VALUES, description="Status of the extended scan") file = odm.Compound(File, description="File Block") filtered = odm.Boolean(default=False, description="Are the alert results filtered?") heuristic = odm.Compound(Heuristic, description="Heuristic Block") label = odm.List(odm.Keyword(), copyto="__text__", default=[], description="List of labels applied to the alert") metadata = odm.FlattenedObject(default={}, store=False, description="Metadata submitted with the file") owner = odm.Optional(odm.Keyword(), description="Owner of the alert") priority = odm.Optional(odm.Enum(values=PRIORITIES), description="Priority applied to the alert") reporting_ts = odm.Date(description="Alert creation timestamp") sid = odm.UUID(description="Submission ID related to this alert") status = odm.Optional(odm.Enum(values=STATUSES), description="Status applied to the alert") ts = odm.Date(description="File submission timestamp") type = odm.Keyword(description="Type of alert") verdict = odm.Compound(Verdict, default={}, description="Verdict Block") workflows_completed = odm.Boolean(default=False, description="Have all workflows ran on this alert?")