Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Af150 malware analysis #87

Merged
merged 13 commits into from
Jul 24, 2023
Merged
31 changes: 29 additions & 2 deletions src/attack_flow_builder/src/assets/builder.config.publisher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,15 @@ class AttackFlowPublisher extends DiagramPublisher {
throw new Error("Basic dictionaries cannot contain dictionaries.");
case PropertyType.Enum:
if (prop instanceof EnumProperty && prop.isDefined()) {
let value = prop.toReferenceValue()!.toRawValue()!;
node[key] = value === "True";
let value = prop.toRawValue()!;
if(["true", "false"].includes(value.toString())) {
// case(BoolEnum)
node[key] = value === "true";
}
else {
// case(String | List | Dictionary | null)
node[key] = value;
}
}
break;
case PropertyType.List:
Expand Down Expand Up @@ -325,6 +332,9 @@ class AttackFlowPublisher extends DiagramPublisher {
case "grouping":
this.tryEmbedInNote(parent, c.obj);
break;
case "malware-analysis":
this.tryEmbedInMalwareAnalysis(parent, c.obj);
break;
case "network-traffic":
sro = this.tryEmbedInNetworkTraffic(parent, c.obj);
break;
Expand Down Expand Up @@ -530,6 +540,23 @@ class AttackFlowPublisher extends DiagramPublisher {
parent.object_refs.push(child.id);
}

/**
* Embed a reference to the child in the malware analysis. If the child cannot be
* embedded, return a new SRO.
* @param parent
* A STIX malware analysis node.
* @param child
* A STIX child node.
* @returns
* An SRO, if one was created.
*/
private tryEmbedInMalwareAnalysis(parent: Sdo, child: Sdo): void {
if (!parent.analysis_sco_refs) {
parent.analysis_sco_refs = [];
}
parent.analysis_sco_refs.push(child.id);
}

/**
* Embed a reference to the child in the parent. If the child cannot be
* embedded, return a new SRO.
Expand Down
15 changes: 14 additions & 1 deletion src/attack_flow_builder/src/assets/builder.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,20 @@ const config: AppConfiguration = {
submitted : { type: PropertyType.Date },
analysis_started : { type: PropertyType.Date },
analysis_ended : { type: PropertyType.Date },
av_result : { type: PropertyType.String},
result : {
type: PropertyType.Enum,
options: {
type: PropertyType.List,
form: { type: PropertyType.String },
value: [
["malicious", "Malicious"],
["suspicious", "Suspicious"],
["benign", "Benign"],
["unknown", "Unknown"]
]
},
value: null
},
},
anchor_template: "@__builtin__anchor",
style: DarkTheme.DictionaryBlock({ head: { ...Colors.Gray }})
Expand Down
52 changes: 30 additions & 22 deletions src/attack_flow_builder/src/assets/builder.config.validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,40 @@ class AttackFlowValidator extends DiagramValidator {
}
// Validate links
switch(node.template.id) {
case "email_address": // Additional validation for email addresses
if (!AttackFlowValidator.Emailregex.test(String(node.props.value.get("value")))) {
this.addError(id, "Invalid email address.")
}
break;
case "grouping":
if(node.next.length === 0) {
this.addError(id, "A Grouping must point to at least one object.");
}
break;
break;
case "location": // Additional validation for location object
const region = node.props.value.get("region");
const country = node.props.value.get("country");
const latitude = node.props.value.get("latitude");
const longitude = node.props.value.get("longitude");

// Verify one of the required properties is set
if(!region?.isDefined() && !country?.isDefined() && !(latitude?.isDefined() || longitude?.isDefined())) {
this.addError(id, "Location requires one of the following properties: Region, Country, Latitude+Longitude.");
}

// Latitude + Longitude check
if(latitude?.isDefined() !== longitude?.isDefined()) {
this.addError(id, "Latitude and Longitude must be supplied together.");
}
break;
case "malware_analysis":
if(!node.props.value.get("result")?.isDefined()) {
// If "result" is empty, check for "analysis_sco_refs"
if(node.next.length === 0) {
this.addError(id, "A Malware Analysis must have the Result field filled out or point to at least one object captured during analysis.")
}
}
break;
case "network_traffic":
this.validateNetworkTrafficLinks(id, node);
break;
Expand All @@ -174,27 +203,6 @@ class AttackFlowValidator extends DiagramValidator {
this.addError(id, "Invalid Windows registry key.");
}
break;
case "email_address": // Additional validation for email addresses
if (!AttackFlowValidator.Emailregex.test(String(node.props.value.get("value")))) {
this.addError(id, "Invalid email address.")
}
break;
case "location": // Additional validation for location object
const region = node.props.value.get("region");
const country = node.props.value.get("country");
const latitude = node.props.value.get("latitude");
const longitude = node.props.value.get("longitude");

// Verify one of the required properties is set
if(!region?.isDefined() && !country?.isDefined() && !(latitude?.isDefined() || longitude?.isDefined())) {
this.addError(id, "Location requires one of the following properties: Region, Country, Latitude+Longitude.");
}

// Latitude + Longitude check
if(latitude?.isDefined() !== longitude?.isDefined()) {
this.addError(id, "Latitude and Longitude must be supplied together.");
}
break;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ export class ListProperty extends CollectionProperty {
// Create property
let prop = Property.create(this, descriptor.form, value);
// Add property
this.value.set(MD5(id), prop);
this.value.set(id, prop);
}
} else {
for(let id in descriptor.value) {
// Create property
let value = descriptor.value[id];
let prop = Property.create(this, descriptor.form, value);
// Add property
this.value.set(MD5(id), prop);
this.value.set(id, prop);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion stix/oasis-open/sdos/malware-analysis.json
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@
{"required": ["analysis_sco_refs"]}
],
"definitions": {
"malware-av-result-ov": {
"malware-result-ov": {
"type": "string",
"enum": [
"malicious",
Expand Down
Loading