From e8808adb0d3c44df8ae2bad6b4cfbac7a2d9eff5 Mon Sep 17 00:00:00 2001 From: tlee Date: Wed, 19 Jul 2023 17:54:26 -0400 Subject: [PATCH 1/9] Added enumeration menu --- .../src/assets/builder.config.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/attack_flow_builder/src/assets/builder.config.ts b/src/attack_flow_builder/src/assets/builder.config.ts index 16487de2..05a0d87f 100644 --- a/src/attack_flow_builder/src/assets/builder.config.ts +++ b/src/attack_flow_builder/src/assets/builder.config.ts @@ -407,7 +407,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 }}) From 37113b997576b2754c601c72e58710c606a122b3 Mon Sep 17 00:00:00 2001 From: tlee Date: Thu, 20 Jul 2023 00:17:56 -0400 Subject: [PATCH 2/9] Added enumeration field for malware analysis results, however blocking publishing is not yet functional. --- .../src/assets/builder.config.publisher.ts | 14 +++++++++++++- .../src/assets/builder.config.validator.ts | 9 +++++++++ stix/oasis-open/sdos/malware-analysis.json | 2 +- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/attack_flow_builder/src/assets/builder.config.publisher.ts b/src/attack_flow_builder/src/assets/builder.config.publisher.ts index b8475b1f..b281714a 100644 --- a/src/attack_flow_builder/src/assets/builder.config.publisher.ts +++ b/src/attack_flow_builder/src/assets/builder.config.publisher.ts @@ -258,8 +258,20 @@ class AttackFlowPublisher extends DiagramPublisher { throw new Error("Basic dictionaries cannot contain dictionaries."); case PropertyType.Enum: if (prop instanceof EnumProperty && prop.isDefined()) { + console.log(node); + console.log(node.props); + console.log(node.props.value) let value = prop.toReferenceValue()!.toRawValue()!; - node[key] = value === "True"; + if(["True", "False"].includes(value.toString())) { + // case(BoolEnum) + node[key] = value === "True"; + } + else { + // case(String | List | Dictionary | null) + value = value.toString(); + value = value.toLowerCase().replace(' ', '-'); + node[key] = value; + } } break; case PropertyType.List: diff --git a/src/attack_flow_builder/src/assets/builder.config.validator.ts b/src/attack_flow_builder/src/assets/builder.config.validator.ts index dc4e76f9..ef851f05 100644 --- a/src/attack_flow_builder/src/assets/builder.config.validator.ts +++ b/src/attack_flow_builder/src/assets/builder.config.validator.ts @@ -62,6 +62,15 @@ class AttackFlowValidator extends DiagramValidator { this.addError(id, "A Note must point to at least one object."); } break; + case "malware-analysis": + // This validation case is broken + if(node.next.length === 0) { + // Check for if "result" is filled + if(node.props.value.get("result")?.toString() ?? false) { + // If "result" is not filled out, then "analysis_sco_refs" must be filled out to pass validation. + this.addError(id, "A Malware Analysis must have the Result field filled out or point to at least one object captured during analysis."); + } + } } } diff --git a/stix/oasis-open/sdos/malware-analysis.json b/stix/oasis-open/sdos/malware-analysis.json index e12dd32f..6a803df0 100644 --- a/stix/oasis-open/sdos/malware-analysis.json +++ b/stix/oasis-open/sdos/malware-analysis.json @@ -146,7 +146,7 @@ {"required": ["analysis_sco_refs"]} ], "definitions": { - "malware-av-result-ov": { + "malware-result-ov": { "type": "string", "enum": [ "malicious", From ee99b7d6d1da034af3969deb4dfb281820664196 Mon Sep 17 00:00:00 2001 From: tlee Date: Thu, 20 Jul 2023 10:01:40 -0400 Subject: [PATCH 3/9] removed testing statements --- src/attack_flow_builder/src/assets/builder.config.publisher.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/attack_flow_builder/src/assets/builder.config.publisher.ts b/src/attack_flow_builder/src/assets/builder.config.publisher.ts index 2403caf8..60399a9a 100644 --- a/src/attack_flow_builder/src/assets/builder.config.publisher.ts +++ b/src/attack_flow_builder/src/assets/builder.config.publisher.ts @@ -258,9 +258,6 @@ class AttackFlowPublisher extends DiagramPublisher { throw new Error("Basic dictionaries cannot contain dictionaries."); case PropertyType.Enum: if (prop instanceof EnumProperty && prop.isDefined()) { - console.log(node); - console.log(node.props); - console.log(node.props.value) let value = prop.toReferenceValue()!.toRawValue()!; if(["True", "False"].includes(value.toString())) { // case(BoolEnum) From b31d308ba28a22690396eed633d119af25d474a5 Mon Sep 17 00:00:00 2001 From: tlee Date: Thu, 20 Jul 2023 13:58:34 -0400 Subject: [PATCH 4/9] resolved validator properly blocking incorrectly-created object --- .../src/assets/builder.config.publisher.ts | 20 +++++++++++++++++++ .../src/assets/builder.config.validator.ts | 13 ++++++------ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/attack_flow_builder/src/assets/builder.config.publisher.ts b/src/attack_flow_builder/src/assets/builder.config.publisher.ts index 60399a9a..3eba5189 100644 --- a/src/attack_flow_builder/src/assets/builder.config.publisher.ts +++ b/src/attack_flow_builder/src/assets/builder.config.publisher.ts @@ -366,6 +366,9 @@ class AttackFlowPublisher extends DiagramPublisher { sro = this.tryEmbedInDefault(parent, c.obj); } break; + case "malware_analysis": + this.tryEmbedInMalwareAnalysis(parent, c.obj); + break; case "network-traffic": sro = this.tryEmbedInNetworkTraffic(parent, c.obj); break; @@ -568,6 +571,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. diff --git a/src/attack_flow_builder/src/assets/builder.config.validator.ts b/src/attack_flow_builder/src/assets/builder.config.validator.ts index 3f802ae5..b8bcf96c 100644 --- a/src/attack_flow_builder/src/assets/builder.config.validator.ts +++ b/src/attack_flow_builder/src/assets/builder.config.validator.ts @@ -143,15 +143,14 @@ class AttackFlowValidator extends DiagramValidator { } // Validate links switch(node.template.id) { - case "malware-analysis": - // This validation case is broken - if(node.next.length === 0) { - // Check for if "result" is filled - if(node.props.value.get("result")?.toString() ?? false) { - // If "result" is not filled out, then "analysis_sco_refs" must be filled out to pass validation. - this.addError(id, "A Malware Analysis must have the Result field filled out or point to at least one object captured during analysis."); + case "malware_analysis": + if(node.props.value.get("result")?.toString() == "Null") { + // 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; From 1275a9248811d677cf257290911d82b2531a4aeb Mon Sep 17 00:00:00 2001 From: tlee Date: Thu, 20 Jul 2023 17:29:26 -0400 Subject: [PATCH 5/9] publishing with references functional --- src/attack_flow_builder/src/assets/builder.config.publisher.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/attack_flow_builder/src/assets/builder.config.publisher.ts b/src/attack_flow_builder/src/assets/builder.config.publisher.ts index f2788e5d..6279bb29 100644 --- a/src/attack_flow_builder/src/assets/builder.config.publisher.ts +++ b/src/attack_flow_builder/src/assets/builder.config.publisher.ts @@ -331,7 +331,7 @@ class AttackFlowPublisher extends DiagramPublisher { sro = this.tryEmbedInDefault(parent, c.obj); } break; - case "malware_analysis": + case "malware-analysis": this.tryEmbedInMalwareAnalysis(parent, c.obj); break; case "network-traffic": From d9390e1722a3d4be8709acda933f2abbc5628a2f Mon Sep 17 00:00:00 2001 From: tlee Date: Fri, 21 Jul 2023 17:02:12 -0400 Subject: [PATCH 6/9] Removed md5 hashing for ListProperty.ts value map. --- .../src/assets/scripts/BlockDiagram/Property/ListProperty.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/attack_flow_builder/src/assets/scripts/BlockDiagram/Property/ListProperty.ts b/src/attack_flow_builder/src/assets/scripts/BlockDiagram/Property/ListProperty.ts index 35a5f945..5fd6a008 100644 --- a/src/attack_flow_builder/src/assets/scripts/BlockDiagram/Property/ListProperty.ts +++ b/src/attack_flow_builder/src/assets/scripts/BlockDiagram/Property/ListProperty.ts @@ -46,7 +46,7 @@ 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) { @@ -54,7 +54,7 @@ export class ListProperty extends CollectionProperty { 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); } } } From 54adf308d07097662c9e302ace7674195978abeb Mon Sep 17 00:00:00 2001 From: tlee Date: Fri, 21 Jul 2023 17:05:09 -0400 Subject: [PATCH 7/9] cleaned up test statements, added in changes to validator.ts --- .../src/assets/builder.config.publisher.ts | 8 +++----- .../src/assets/builder.config.validator.ts | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/attack_flow_builder/src/assets/builder.config.publisher.ts b/src/attack_flow_builder/src/assets/builder.config.publisher.ts index 6279bb29..40ea0c4f 100644 --- a/src/attack_flow_builder/src/assets/builder.config.publisher.ts +++ b/src/attack_flow_builder/src/assets/builder.config.publisher.ts @@ -223,15 +223,13 @@ 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()!; - if(["True", "False"].includes(value.toString())) { + let value = prop.toRawValue()!; + if(["true", "false"].includes(value.toString())) { // case(BoolEnum) - node[key] = value === "True"; + node[key] = value === "true"; } else { // case(String | List | Dictionary | null) - value = value.toString(); - value = value.toLowerCase().replace(' ', '-'); node[key] = value; } } diff --git a/src/attack_flow_builder/src/assets/builder.config.validator.ts b/src/attack_flow_builder/src/assets/builder.config.validator.ts index 6fc0adcf..447d5d2e 100644 --- a/src/attack_flow_builder/src/assets/builder.config.validator.ts +++ b/src/attack_flow_builder/src/assets/builder.config.validator.ts @@ -152,7 +152,7 @@ class AttackFlowValidator extends DiagramValidator { // Validate links switch(node.template.id) { case "malware_analysis": - if(node.props.value.get("result")?.toString() == "Null") { + 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.") From c91010f0b0a01f62a0f6c58e534a43353f34871f Mon Sep 17 00:00:00 2001 From: tlee Date: Mon, 24 Jul 2023 13:12:53 -0400 Subject: [PATCH 8/9] Fixing incorrect indent for a break statement --- src/attack_flow_builder/src/assets/builder.config.validator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/attack_flow_builder/src/assets/builder.config.validator.ts b/src/attack_flow_builder/src/assets/builder.config.validator.ts index 2676edb7..65fb9939 100644 --- a/src/attack_flow_builder/src/assets/builder.config.validator.ts +++ b/src/attack_flow_builder/src/assets/builder.config.validator.ts @@ -155,7 +155,7 @@ class AttackFlowValidator extends DiagramValidator { if(node.next.length === 0) { this.addError(id, "A Grouping must point to at least one object."); } - break; + break; case "malware_analysis": if(!node.props.value.get("result")?.isDefined()) { // If "result" is empty, check for "analysis_sco_refs" From aac324d3b98132a095b9288c61f807f8a3f0c7b5 Mon Sep 17 00:00:00 2001 From: tlee Date: Mon, 24 Jul 2023 13:22:38 -0400 Subject: [PATCH 9/9] rearranged order of cases --- .../src/assets/builder.config.validator.ts | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/attack_flow_builder/src/assets/builder.config.validator.ts b/src/attack_flow_builder/src/assets/builder.config.validator.ts index 65fb9939..80943494 100644 --- a/src/attack_flow_builder/src/assets/builder.config.validator.ts +++ b/src/attack_flow_builder/src/assets/builder.config.validator.ts @@ -151,11 +151,32 @@ 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; + 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" @@ -182,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; } }