assemblyline_models/datastore/
alert.rs

1
2use std::collections::HashMap;
3
4use chrono::{DateTime, Utc};
5use serde::{Deserialize, Serialize};
6use serde_with::{SerializeDisplay, DeserializeFromStr};
7use struct_metadata::Described;
8
9use crate::types::{Wildcard, Domain, ExpandingClassification, Sha1, Sha256, Uri, Uuid, MD5};
10use crate::ElasticMeta;
11use super::workflow::{Statuses, Priorities};
12
13
14#[derive(SerializeDisplay, DeserializeFromStr, strum::Display, strum::EnumString, Described, Debug)]
15#[metadata_type(ElasticMeta)]
16#[strum(serialize_all = "lowercase")]
17pub enum ExtendedScanValues {
18    Submitted,
19    Skipped,
20    Incomplete,
21    Complete,
22}
23
24#[derive(SerializeDisplay, DeserializeFromStr, strum::Display, strum::EnumString, Described)]
25#[metadata_type(ElasticMeta)]
26#[strum(serialize_all = "lowercase")]
27pub enum ItemVerdict {
28    Safe,
29    Info,
30    Suspicious,
31    Malicious,
32}
33
34#[derive(SerializeDisplay, DeserializeFromStr, strum::Display, strum::EnumString, Described)]
35#[metadata_type(ElasticMeta)]
36#[strum(serialize_all = "lowercase")]
37pub enum EntityType {
38    User,
39    Workflow,
40}
41
42
43#[derive(SerializeDisplay, DeserializeFromStr, strum::Display, strum::EnumString, Described)]
44#[metadata_type(ElasticMeta)]
45#[strum(serialize_all = "UPPERCASE")]
46pub enum Subtype {
47    Exp,
48    Cfg,
49    Ob,
50    Imp,
51    Ta,
52}
53
54
55/// Assemblyline Results Block
56#[derive(Serialize, Deserialize, Described)]
57#[metadata_type(ElasticMeta)]
58#[metadata(index=true, store=false)]
59pub struct DetailedItem {
60    /// Type of data that generated this item
61    #[serde(rename = "type")]
62    pub item_type: String,
63    /// Value of the item
64    pub value: String,
65    /// Verdict of the item
66    pub verdict: ItemVerdict,
67    /// Sub-type of the item
68    pub subtype: Option<Subtype>,
69}
70
71/// Assemblyline Detailed result block
72#[derive(Serialize, Deserialize, Described)]
73#[metadata_type(ElasticMeta)]
74#[metadata(index=true, store=false)]
75pub struct DetailedResults {
76    /// List of detailed Att&ck patterns
77    #[serde(default)]
78    pub attack_pattern: Vec<DetailedItem>,
79    /// List of detailed Att&ck categories
80    #[serde(default)]
81    pub attack_category: Vec<DetailedItem>,
82    /// List of detailed attribution
83    #[serde(default)]
84    pub attrib: Vec<DetailedItem>,
85    /// List of detailed AV hits
86    #[serde(default)]
87    pub av: Vec<DetailedItem>,
88    /// List of detailed behaviors for the alert
89    #[serde(default)]
90    pub behavior: Vec<DetailedItem>,
91    /// List of detailed domains
92    #[serde(default)]
93    pub domain: Vec<DetailedItem>,
94    /// List of detailed heuristics
95    #[serde(default)]
96    pub heuristic: Vec<DetailedItem>,
97    /// List of detailed IPs
98    #[serde(default)]
99    pub ip: Vec<DetailedItem>,
100    /// List of detailed URIs
101    #[serde(default)]
102    pub uri: Vec<DetailedItem>,
103    /// List of detailed YARA rule hits
104    #[serde(default)]
105    pub yara: Vec<DetailedItem>,
106}
107
108/// Assemblyline Results Block
109#[derive(Serialize, Deserialize, Described)]
110#[metadata_type(ElasticMeta)]
111#[metadata(index=true, store=false)]
112pub struct ALResults {
113    /// List of attribution
114    #[serde(default)]
115    #[metadata(store=true, copyto="__text__")]
116    pub attrib: Vec<String>,
117    /// List of AV hits
118    #[serde(default)]
119    #[metadata(store=true, copyto="__text__")]
120    pub av: Vec<String>,
121    /// List of behaviors for the alert
122    #[serde(default)]
123    #[metadata(copyto="__text__")]
124    pub behavior: Vec<String>,
125    /// Assemblyline Detailed result block
126    pub detailed: DetailedResults,
127    /// List of all domains
128    #[serde(default)]
129    #[metadata(copyto="__text__")]
130    pub domain: Vec<Domain>,
131    /// List of domains found during Dynamic Analysis
132    #[serde(default)]
133    pub domain_dynamic: Vec<Domain>,
134    /// List of domains found during Static Analysis
135    #[serde(default)]
136    pub domain_static: Vec<Domain>,
137    /// List of all IPs
138    #[serde(default)]
139    #[metadata(copyto="__text__")]
140    pub ip: Vec<std::net::IpAddr>,
141    /// List of IPs found during Dynamic Analysis
142    #[serde(default)]
143    pub ip_dynamic: Vec<std::net::IpAddr>,
144    /// List of IPs found during Static Analysis
145    #[serde(default)]
146    pub ip_static: Vec<std::net::IpAddr>,
147    /// Finish time of the Assemblyline submission
148    #[serde(default)]
149    #[metadata(index=false)]
150    pub request_end_time: DateTime<Utc>,
151    /// Maximum score found in the submission
152    #[serde(default)]
153    #[metadata(store=true)]
154    pub score: i32,
155    /// List of all URIs
156    #[serde(default)]
157    #[metadata(copyto="__text__")]
158    pub uri: Vec<Uri>,
159    /// List of URIs found during Dynamic Analysis
160    #[serde(default)]
161    pub uri_dynamic: Vec<Uri>,
162    /// List of URIs found during Static Analysis
163    #[serde(default)]
164    pub uri_static: Vec<Uri>,
165    /// List of YARA rule hits
166    #[serde(default)]
167    #[metadata(copyto="__text__")]
168    pub yara: Vec<String>,
169}
170
171/// File Block Associated to the Top-Level/Root File of Submission
172#[derive(Serialize, Deserialize, Described)]
173#[metadata_type(ElasticMeta)]
174#[metadata(index=true, store=true)]
175pub struct File {
176    /// MD5 hash of file
177    #[metadata(copyto="__text__")]
178    pub md5: MD5,
179    /// Name of the file
180    #[metadata(copyto="__text__")]
181    pub name: String,
182    /// SHA1 hash of the file
183    #[metadata(copyto="__text__")]
184    pub sha1: Sha1,
185    /// SHA256 hash of the file
186    #[metadata(copyto="__text__")]
187    pub sha256: Sha256,
188    /// Size of the file in bytes
189    #[metadata(store=false)]
190    pub size: i64,
191    /// Type of file as identified by Assemblyline
192    #[serde(rename = "type")]
193    #[metadata(copyto="__text__")]
194    pub file_type: String,
195    /// Screenshots taken of the file during analysis, if applicable.
196    #[serde(default)]
197    pub screenshots: Vec<Screenshot>,
198}
199
200/// Stores information about screenshots taken during the analysis of the file. Each screenshot has a name, description, and the hashes of the image and its thumbnail, offering a visual reference that can aid in manual review processes.
201#[derive(Serialize, Deserialize, Described)]
202#[metadata_type(ElasticMeta)]
203#[metadata(index=true, store=false)]
204pub struct Screenshot {
205    /// The name or title of the screenshot.
206    pub name: String,
207    /// A brief description of the screenshot's content.
208    pub description: String,
209    /// The SHA256 hash of the full-size screenshot image.
210    pub img: Sha256,
211    /// The SHA256 hash of the thumbnail version of the screenshot.
212    pub thumb: Sha256,
213}
214
215/// Verdict Block of Submission
216#[derive(Serialize, Deserialize, Default, Described)]
217#[metadata_type(ElasticMeta)]
218#[metadata(index=true, store=false)]
219pub struct Verdict {
220    /// List of users that claim submission as malicious
221    #[serde(default)]
222    pub malicious: Vec<String>,
223    /// List of users that claim submission as non-malicious
224    #[serde(default)]
225    pub non_malicious: Vec<String>,
226}
227
228/// Heuristic Block
229#[derive(Serialize, Deserialize, Described)]
230#[metadata_type(ElasticMeta)]
231#[metadata(index=true, store=false)]
232pub struct Heuristic {
233    /// List of related Heuristic names
234    #[serde(default)]
235    pub name: Vec<String>,
236}
237
238/// ATT&CK Block
239#[derive(Serialize, Deserialize, Described)]
240#[metadata_type(ElasticMeta)]
241#[metadata(index=true, store=false)]
242pub struct Attack {
243    /// List of related ATT&CK patterns
244    #[serde(default)]
245    pub pattern: Vec<String>,
246    /// List of related ATT&CK categories
247    #[serde(default)]
248    pub category: Vec<String>,
249}
250
251/// Model of Workflow Event
252#[derive(Serialize, Deserialize, Described)]
253#[metadata_type(ElasticMeta)]
254#[metadata(index=true, store=false)]
255pub struct Event {
256    /// Type of entity associated to event
257    pub entity_type: EntityType,
258    /// ID of entity associated to event
259    pub entity_id: String,
260    /// Name of entity
261    pub entity_name: String,
262    /// Timestamp of event
263    #[serde(default="chrono::Utc::now")]
264    pub ts: DateTime<Utc>,
265    /// Labels added during event
266    #[serde(default)]
267    pub labels: Vec<String>,
268    /// Labels that were removed from the alert during the event.
269    #[serde(default)]    
270    pub labels_removed: Vec<String>, 
271    /// Status applied during event
272    #[serde(default)]    
273    pub status: Option<Statuses>,
274    /// Priority applied during event
275    #[serde(default)]    
276    pub priority: Option<Priorities>,
277}
278
279/// Describes the relationship between different submissions that are linked to the formation of the alert, highlighting parent-child connections.
280#[derive(Serialize, Deserialize, Described)]
281#[metadata_type(ElasticMeta)]
282#[metadata(index=true, store=true)]
283pub struct Relationship {
284    /// The identifier of the child submission in the relationship.
285    pub child: Uuid,
286    /// The identifier of the parent submission, if applicable.
287    #[serde(default)]
288    pub parent: Option<Uuid>,
289}
290
291/// Model for Alerts
292#[derive(Serialize, Deserialize, Described)]
293#[metadata_type(ElasticMeta)]
294#[metadata(index=true, store=true)]
295pub struct Alert {
296    /// ID of the alert
297    #[metadata(copyto="__text__")]
298    pub alert_id: String,
299    /// Assemblyline Result Block
300    pub al: ALResults,
301    /// Timestamp indicating when the alert was archived in the system.
302    pub archive_ts: Option<chrono::DateTime<chrono::Utc>>,
303    /// ATT&CK Block
304    pub attack: Attack,
305    /// Classification of the alert
306    #[serde(flatten)]
307    pub classification: ExpandingClassification,
308    /// Expiry timestamp
309    #[metadata(store=false)]
310    pub expiry_ts: Option<DateTime<Utc>>,
311    /// Status of the extended scan
312    pub extended_scan: ExtendedScanValues,
313    /// File Block
314    pub file: File,
315    /// Are the alert results filtered?
316    #[serde(default)]
317    pub filtered: bool,
318    /// Heuristic Block
319    pub heuristic: Heuristic,
320    /// List of labels applied to the alert
321    #[serde(default)]
322    #[metadata(copyto="__text__")]
323    pub label: Vec<String>,
324    /// Metadata submitted with the file
325    #[serde(default)]
326    #[metadata(store=false, mapping="flattenedobject", copyto="__text__")]
327    pub metadata: HashMap<String, Wildcard>,
328    /// Owner of the alert
329    pub owner: Option<String>,
330    /// Priority applied to the alert
331    pub priority: Option<Priorities>,
332    /// Alert creation timestamp
333    pub reporting_ts: DateTime<Utc>,
334    /// Describes the hierarchical relationships between submissions that contributed to this alert.
335    pub submission_relations: Vec<Relationship>,
336    /// Submission ID related to this alert
337    pub sid: String,
338    /// Status applied to the alert
339    pub status: Option<Statuses>,
340    /// File submission timestamp
341    pub ts: DateTime<Utc>,
342    /// Type of alert
343    #[serde(rename = "type")]
344    pub alert_type: String,
345    /// Verdict Block
346    #[serde(default)]
347    pub verdict: Verdict,
348    /// An audit of events applied to alert
349    #[serde(default)]
350    pub events: Vec<Event>,
351    /// Have all workflows ran on this alert?
352    #[serde(default)]
353    pub workflows_completed: bool,
354}