From 1fa3315eaa0035627df75f8ad7cea0114cba3505 Mon Sep 17 00:00:00 2001 From: "Ajeet Prakash (MSTIC)" Date: Wed, 17 Nov 2021 19:34:51 -0800 Subject: [PATCH 01/18] Blog Support Queries --- ...v-0228FilePathHashesNovember2021-ASIM.yaml | 52 ++++++++++++++++ .../Dev-0228FilePathHashesNovember2021.yaml | 61 +++++++++++++++++++ ...6CommandLineActivityNovember2021-ASIM.yaml | 43 +++++++++++++ ...v-0056CommandLineActivityNovember2021.yaml | 54 ++++++++++++++++ 4 files changed, 210 insertions(+) create mode 100644 Detections/ASimFileEvent/imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml create mode 100644 Detections/MultipleDataSources/Dev-0228FilePathHashesNovember2021.yaml create mode 100644 Hunting Queries/ASimProcess/imProcess_Dev-0056CommandLineActivityNovember2021-ASIM.yaml create mode 100644 Hunting Queries/MultipleDataSources/Dev-0056CommandLineActivityNovember2021.yaml diff --git a/Detections/ASimFileEvent/imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml b/Detections/ASimFileEvent/imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml new file mode 100644 index 00000000000..8c5a979f24a --- /dev/null +++ b/Detections/ASimFileEvent/imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml @@ -0,0 +1,52 @@ +id: 29a29e5d-354e-4f5e-8321-8b39d25047bf +name: Dev-0228 File Path Hashes November 2021 - ASIM +description: | + 'This hunting query looks for file paths/hashes related to observed activity by Dev-0228. The actor is known to use custom version of popular tool like PsExec, Procdump etc. to carry its activity. + The risk score associated with each result is based on a number of factors, hosts with higher risk events should be investigated first. + This query uses the Microsoft Sentinel Information Model - https://docs.microsoft.com/azure/sentinel/normalization' +severity: High +requiredDataConnectors:[] +queryFrequency: 6h +queryPeriod: 6h +triggerOperator: gt +triggerThreshold: 0 +tactics: + - CredentialAccess + - Execution +relevantTechniques: + - T1103 + - T1569 +query: | + let files1 = dynamic(["C:\\Windows\\TAPI\\lsa.exe", "C:\\Windows\\TAPI\\pa.exe", "C:\\Windows\\TAPI\\pc.exe", "C:\\Windows\\TAPI\\Rar.exe"]); + let files2 = dynamic(["svchost.exe","wdmsvc.exe"]); + let FileHash1 = dynamic(["43109fbe8b752f7a9076eaafa417d9ae5c6e827cd5374b866672263fdebd5ec3", "ab50d8d707b97712178a92bbac74ccc2a5699eb41c17aa77f713ff3e568dcedb", "010e32be0f86545e116a8bc3381a8428933eb8789f32c261c81fd5e7857d4a77", "56cd102b9fc7f3523dad01d632525ff673259dbc9a091be0feff333c931574f7"]); + let FileHash2 = dynamic(["2a1044e9e6e87a032f80c6d9ea6ae61bbbb053c0a21b186ecb3b812b49eb03b7", "9ab7e99ed84f94a7b6409b87e56dc6e1143b05034a5e4455e8c555dbbcd0d2dd", "18a072ccfab239e140d8f682e2874e8ff19d94311fc8bb9564043d3e0deda54b"]); + imFileEvent + | where (FilePath has_any (files1) and ActingProcessSHA256 has_any (FileHash1)) or (FilePath has_any (files2) and ActingProcessSHA256 has_any (FileHash2)) + // Increase risk score if recent alerts for the host + | join kind=leftouter (SecurityAlert + | where ProviderName =~ "MDATP" + | extend ThreatName = tostring(parse_json(ExtendedProperties).ThreatName) + | mv-expand todynamic(Entities) + | extend DvcId = tostring(parse_json(Entities).MdatpDeviceId) + | where isnotempty(DvcId) + // Higher risk score are for Defender alerts related to threat actor + | extend AlertRiskScore = iif(ThreatName has_any ("Backdoor:MSIL/ShellClient.A", "Backdoor:MSIL/ShellClient.A!dll", "Trojan:MSIL/Mimikatz.BA!MTB"), 1.0, 0.5) + | project DvcId, AlertRiskScore) on DvcId + | extend AlertRiskScore = iif(isempty(AlertRiskScore), 0.0, AlertRiskScore) + | extend timestamp = TimeGenerated, HostCustomEntity = Dvc, AccountCustomEntity = AccountName +entityMappings: + - entityType: Host + fieldMappings: + - identifier: HostName + columnName: HostCustomEntity + - entityType: Account + fieldMappings: + - identifier: Name + columnName: AccountCustomEntity + - entityType: File + fieldMappings: + - identifier: Name + columnName: FileName +version: 1.1.0 +kind: Scheduled \ No newline at end of file diff --git a/Detections/MultipleDataSources/Dev-0228FilePathHashesNovember2021.yaml b/Detections/MultipleDataSources/Dev-0228FilePathHashesNovember2021.yaml new file mode 100644 index 00000000000..6333652f6c3 --- /dev/null +++ b/Detections/MultipleDataSources/Dev-0228FilePathHashesNovember2021.yaml @@ -0,0 +1,61 @@ +id: 3b443f22-9be9-4c35-ac70-a94757748439 +name: Dev-0228 File Path Hashes November 2021 +description: | + 'This hunting query looks for file paths/hashes related to observed activity by Dev-0228. The actor is known to use custom version of popular tool like PsExec, Procdump etc. to carry its activity. + The risk score associated with each result is based on a number of factors, hosts with higher risk events should be investigated first.' +severity: High +requiredDataConnectors: + - connectorId: MicrosoftDefenderAdvancedThreatProtection + dataTypes: + - SecurityAlert (MDATP) + - connectorId: MicrosoftThreatProtection + dataTypes: + - DeviceProcessEvents +queryFrequency: 6h +queryPeriod: 6h +triggerOperator: gt +triggerThreshold: 0 +tactics: + - CredentialAccess + - Execution +relevantTechniques: + - T1103 + - T1569 +query: | + let files1 = dynamic(["C:\\Windows\\TAPI\\lsa.exe", "C:\\Windows\\TAPI\\pa.exe", "C:\\Windows\\TAPI\\pc.exe", "C:\\Windows\\TAPI\\Rar.exe"]); + let files2 = dynamic(["svchost.exe","wdmsvc.exe"]); + let FileHash1 = dynamic(["43109fbe8b752f7a9076eaafa417d9ae5c6e827cd5374b866672263fdebd5ec3", "ab50d8d707b97712178a92bbac74ccc2a5699eb41c17aa77f713ff3e568dcedb", "010e32be0f86545e116a8bc3381a8428933eb8789f32c261c81fd5e7857d4a77", "56cd102b9fc7f3523dad01d632525ff673259dbc9a091be0feff333c931574f7"]); + let FileHash2 = dynamic(["2a1044e9e6e87a032f80c6d9ea6ae61bbbb053c0a21b186ecb3b812b49eb03b7", "9ab7e99ed84f94a7b6409b87e56dc6e1143b05034a5e4455e8c555dbbcd0d2dd", "18a072ccfab239e140d8f682e2874e8ff19d94311fc8bb9564043d3e0deda54b"]); + DeviceProcessEvents + | where ( FolderPath has_any (files1) and SHA256 has_any (FileHash1)) or (FolderPath has_any (files2) and SHA256 has_any (FileHash2)) + | extend DvcId = DeviceId + | join kind=leftouter (SecurityAlert + | where ProviderName =~ "MDATP" + | extend ThreatName = tostring(parse_json(ExtendedProperties).ThreatName) + | mv-expand todynamic(Entities) + | extend DvcId = tostring(parse_json(Entities).MdatpDeviceId) + | where isnotempty(DvcId) + // Higher risk score are for Defender alerts related to threat actor + | extend AlertRiskScore = iif(ThreatName has_any ("Backdoor:MSIL/ShellClient.A", "Backdoor:MSIL/ShellClient.A!dll", "Trojan:MSIL/Mimikatz.BA!MTB"), 1.0, 0.5) + | project DvcId, AlertRiskScore) on DvcId + | extend AlertRiskScore = iif(isempty(AlertRiskScore), 0.0, AlertRiskScore) + | extend timestamp = TimeGenerated, HostCustomEntity = DeviceName, AccountCustomEntity = AccountName +entityMappings: + - entityType: Host + fieldMappings: + - identifier: FullName + columnName: HostCustomEntity + - entityType: Account + fieldMappings: + - identifier: Name + columnName: AccountCustomEntity + - entityType: File + fieldMappings: + - identifier: Name + columnName: FileName + - entityType: FileHash + fieldMappings: + - identifier: Value + columnName: SHA256 +version: 1.0.0 +kind: Scheduled \ No newline at end of file diff --git a/Hunting Queries/ASimProcess/imProcess_Dev-0056CommandLineActivityNovember2021-ASIM.yaml b/Hunting Queries/ASimProcess/imProcess_Dev-0056CommandLineActivityNovember2021-ASIM.yaml new file mode 100644 index 00000000000..56fb25367ca --- /dev/null +++ b/Hunting Queries/ASimProcess/imProcess_Dev-0056CommandLineActivityNovember2021-ASIM.yaml @@ -0,0 +1,43 @@ +id: 98fdd28d-9c13-431b-aca9-e6cfbb90a5a9 +name: Dev-0056 Command Line Activity November 2021 - MSIM +description: | + ' This hunting query looks for process command line activity related to activity observed by Dev-0056.The command lines this query hunts for are used as part of the threat actor's post exploitation activity. + This query uses the Microsoft Sentinel Information Model - https://docs.microsoft.com/azure/sentinel/normalization' +requiredDataConnectors: [] +tactics: + - CommandAndControl +relevantTechniques: + - T1071 +query: | + imProcess + | where ( CommandLine has_any("/q /c color f7&", "Net.We$()bClient", "$b,15,$b.Length-15")) or (CommandLine has "FromBase64String" and CommandLine has_all("-nop", "iex", "(iex")) + | summarize count(), FirstSeen=min(TimeGenerated), LastSeen = max(TimeGenerated) by DvcId, Dvc, CommandLine, AccountName, FilePath + // Base risk score on number of command lines seen for each host + | extend RiskScore = count_ + // Increase risk score if host has recent security alerts + | join kind=leftouter (SecurityAlert + | where ProviderName =~ "MDATP" + | extend ThreatName = tostring(parse_json(ExtendedProperties).ThreatName) + | mv-expand todynamic(Entities) + | extend DvcId = tostring(parse_json(Entities).MdatpDeviceId) + | where isnotempty(DvcId) + // Increase risk score further if alerts relate to malware assocaited with threat actor + | extend AlertRiskScore = iif(ThreatName has_any ("Backdoor:MSIL/ShellClient.A", "Backdoor:MSIL/ShellClient.A!dll", "Trojan:MSIL/Mimikatz.BA!MTB"), 1.0, 0.5)) on DvcId + // Create aggregate risk score + | extend AlertRiskScore = iif(isempty(AlertRiskScore), 0.0 , AlertRiskScore) + | extend RiskScore = RiskScore + AlertRiskScore + | project-reorder FirstSeen, LastSeen, RiskScore, Dvc, DvcId, CommandLine, AccountName + | extend timestamp = FirstSeen, AccountCustomEntity = AccountName, HostCustomEntity = Dvc +entityMappings: + - entityType: Account + fieldMappings: + - identifier: Name + columnName: AccountCustomEntity + - entityType: Host + fieldMappings: + - identifier: HostName + columnName: HostCustomEntity + - entityType: File + fieldMappings: + - identifier: Name + columnName: File \ No newline at end of file diff --git a/Hunting Queries/MultipleDataSources/Dev-0056CommandLineActivityNovember2021.yaml b/Hunting Queries/MultipleDataSources/Dev-0056CommandLineActivityNovember2021.yaml new file mode 100644 index 00000000000..679de155ee9 --- /dev/null +++ b/Hunting Queries/MultipleDataSources/Dev-0056CommandLineActivityNovember2021.yaml @@ -0,0 +1,54 @@ +id: e2629949-2043-4421-8064-bca23c8491dd +name: Dev-0056 Command Line Activity November 2021 +description: | + 'This hunting query looks for process command line activity related to activity observed by Dev-0056.The command lines this query hunts for are used as part of the threat actor's post exploitation activity.' +requiredDataConnectors: + - connectorId: MicrosoftDefenderAdvancedThreatProtection + dataTypes: + - SecurityAlert (MDATP) + - connectorId: MicrosoftThreatProtection + dataTypes: + - DeviceProcessEvents + - connectorId: WindowsSecurityEvents + dataTypes: + - SecurityEvent +tactics: + - CommandAndControl +relevantTechniques: + - T1071 +query: | + (union isfuzzy=true + (DeviceProcessEvents + | where ProcessCommandLine has_any("/q /c color f7&", "Net.We$()bClient", "$b,15,$b.Length-15") or (ProcessCommandLine has "FromBase64String" and ProcessCommandLine has_all("-nop", "iex", "(iex")) + | join kind=leftouter (SecurityAlert + | where ProviderName =~ "MDATP" + | extend ThreatName = tostring(parse_json(ExtendedProperties).ThreatName) + | mv-expand todynamic(Entities) + | extend DeviceId = tostring(parse_json(Entities).MdatpDeviceId) + | where isnotempty(DeviceId) + // Increase risk score further if alerts relate to malware assocaited with threat actor + | extend AlertRiskScore =iif(ThreatName has_any ("Backdoor:MSIL/ShellClient.A", "Backdoor:MSIL/ShellClient.A!dll", "Trojan:MSIL/Mimikatz.BA!MTB"), 1.0, 0.5)) on DeviceId + | extend AlertRiskScore = iif(isempty(AlertRiskScore), 0.0 , AlertRiskScore) + | project-reorder TimeGenerated, DeviceName, DeviceId, ProcessCommandLine, AccountName + | extend timestamp = TimeGenerated, AccountCustomEntity = AccountName, HostCustomEntity = DeviceName, ProcessCustomEntity = InitiatingProcessFileName + ), + (SecurityEvent + | where EventID == '4688' + | where ( CommandLine has_any("/q /c color f7&", "Net.We$()bClient", "$b,15,$b.Length-15")) or (CommandLine has "FromBase64String" and CommandLine has_all("-nop", "iex", "(iex")) + | project TimeGenerated, Computer, NewProcessName, ParentProcessName, Account, NewProcessId, Type, CommandLine + | extend timestamp = TimeGenerated, HostCustomEntity = Computer , AccountCustomEntity = Account, ProcessCustomEntity = NewProcessName + ) + ) +entityMappings: + - entityType: Account + fieldMappings: + - identifier: FullName + columnName: AccountCustomEntity + - entityType: Host + fieldMappings: + - identifier: FullName + columnName: HostCustomEntity + - entityType: Process + fieldMappings: + - identifier: ProcessId + columnName: ProcessCustomEntity \ No newline at end of file From d184cf9f396430102660fd8bffb622ffdc16a4c9 Mon Sep 17 00:00:00 2001 From: aprakash13 <37783395+aprakash13@users.noreply.github.com> Date: Wed, 17 Nov 2021 19:52:19 -0800 Subject: [PATCH 02/18] Update Dev-0228FilePathHashesNovember2021.yaml --- .../Dev-0228FilePathHashesNovember2021.yaml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Detections/MultipleDataSources/Dev-0228FilePathHashesNovember2021.yaml b/Detections/MultipleDataSources/Dev-0228FilePathHashesNovember2021.yaml index 6333652f6c3..68b3842cf2c 100644 --- a/Detections/MultipleDataSources/Dev-0228FilePathHashesNovember2021.yaml +++ b/Detections/MultipleDataSources/Dev-0228FilePathHashesNovember2021.yaml @@ -53,9 +53,5 @@ entityMappings: fieldMappings: - identifier: Name columnName: FileName - - entityType: FileHash - fieldMappings: - - identifier: Value - columnName: SHA256 version: 1.0.0 -kind: Scheduled \ No newline at end of file +kind: Scheduled From 4aaf507f8af0c4cafb33dcab9ccfb6343122cf29 Mon Sep 17 00:00:00 2001 From: aprakash13 <37783395+aprakash13@users.noreply.github.com> Date: Wed, 17 Nov 2021 19:57:01 -0800 Subject: [PATCH 03/18] Update imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml --- .../imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Detections/ASimFileEvent/imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml b/Detections/ASimFileEvent/imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml index 8c5a979f24a..9de4b1200a1 100644 --- a/Detections/ASimFileEvent/imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml +++ b/Detections/ASimFileEvent/imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml @@ -5,7 +5,7 @@ description: | The risk score associated with each result is based on a number of factors, hosts with higher risk events should be investigated first. This query uses the Microsoft Sentinel Information Model - https://docs.microsoft.com/azure/sentinel/normalization' severity: High -requiredDataConnectors:[] +requiredDataConnectors: [] queryFrequency: 6h queryPeriod: 6h triggerOperator: gt @@ -49,4 +49,4 @@ entityMappings: - identifier: Name columnName: FileName version: 1.1.0 -kind: Scheduled \ No newline at end of file +kind: Scheduled From 2fc4f139c69d8d93f9a748caa33de3a6a504979d Mon Sep 17 00:00:00 2001 From: aprakash13 <37783395+aprakash13@users.noreply.github.com> Date: Wed, 17 Nov 2021 20:04:04 -0800 Subject: [PATCH 04/18] Update imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml --- .../imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detections/ASimFileEvent/imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml b/Detections/ASimFileEvent/imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml index 9de4b1200a1..d81198f8e45 100644 --- a/Detections/ASimFileEvent/imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml +++ b/Detections/ASimFileEvent/imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml @@ -34,7 +34,7 @@ query: | | extend AlertRiskScore = iif(ThreatName has_any ("Backdoor:MSIL/ShellClient.A", "Backdoor:MSIL/ShellClient.A!dll", "Trojan:MSIL/Mimikatz.BA!MTB"), 1.0, 0.5) | project DvcId, AlertRiskScore) on DvcId | extend AlertRiskScore = iif(isempty(AlertRiskScore), 0.0, AlertRiskScore) - | extend timestamp = TimeGenerated, HostCustomEntity = Dvc, AccountCustomEntity = AccountName + | extend timestamp = TimeGenerated, HostCustomEntity = Dvc, AccountCustomEntity = ActorUsername entityMappings: - entityType: Host fieldMappings: From aae9d1b4aef12332133ca67b677979a66f933c43 Mon Sep 17 00:00:00 2001 From: aprakash13 <37783395+aprakash13@users.noreply.github.com> Date: Wed, 17 Nov 2021 20:25:58 -0800 Subject: [PATCH 05/18] Update imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml --- .../imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detections/ASimFileEvent/imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml b/Detections/ASimFileEvent/imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml index d81198f8e45..d7bb0c2271a 100644 --- a/Detections/ASimFileEvent/imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml +++ b/Detections/ASimFileEvent/imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml @@ -22,7 +22,7 @@ query: | let FileHash1 = dynamic(["43109fbe8b752f7a9076eaafa417d9ae5c6e827cd5374b866672263fdebd5ec3", "ab50d8d707b97712178a92bbac74ccc2a5699eb41c17aa77f713ff3e568dcedb", "010e32be0f86545e116a8bc3381a8428933eb8789f32c261c81fd5e7857d4a77", "56cd102b9fc7f3523dad01d632525ff673259dbc9a091be0feff333c931574f7"]); let FileHash2 = dynamic(["2a1044e9e6e87a032f80c6d9ea6ae61bbbb053c0a21b186ecb3b812b49eb03b7", "9ab7e99ed84f94a7b6409b87e56dc6e1143b05034a5e4455e8c555dbbcd0d2dd", "18a072ccfab239e140d8f682e2874e8ff19d94311fc8bb9564043d3e0deda54b"]); imFileEvent - | where (FilePath has_any (files1) and ActingProcessSHA256 has_any (FileHash1)) or (FilePath has_any (files2) and ActingProcessSHA256 has_any (FileHash2)) + | where ((FilePath has_any (files1)) and (ActingProcessSHA256 has_any (FileHash1))) or ((FilePath has_any (files2)) and (ActingProcessSHA256 has_any (FileHash2))) // Increase risk score if recent alerts for the host | join kind=leftouter (SecurityAlert | where ProviderName =~ "MDATP" From eb3e99883efac7a37b1b63692ad74be16332f9a2 Mon Sep 17 00:00:00 2001 From: Pete Bryan Date: Wed, 17 Nov 2021 20:27:01 -0800 Subject: [PATCH 06/18] Removing Un-needed file --- Solutions/Cisco ISE/Hunting Queries/README.md | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Solutions/Cisco ISE/Hunting Queries/README.md diff --git a/Solutions/Cisco ISE/Hunting Queries/README.md b/Solutions/Cisco ISE/Hunting Queries/README.md deleted file mode 100644 index 8b137891791..00000000000 --- a/Solutions/Cisco ISE/Hunting Queries/README.md +++ /dev/null @@ -1 +0,0 @@ - From e5794b6cd0e6d27bb20af688b797bc817ab793af Mon Sep 17 00:00:00 2001 From: Pete Bryan Date: Wed, 17 Nov 2021 20:30:29 -0800 Subject: [PATCH 07/18] Updated imFileEvent schema --- .../tests/KqlvalidationsTests/CustomTables/imFileEvent.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.script/tests/KqlvalidationsTests/CustomTables/imFileEvent.json b/.script/tests/KqlvalidationsTests/CustomTables/imFileEvent.json index b6eaee6e9c8..fa9638f6e75 100644 --- a/.script/tests/KqlvalidationsTests/CustomTables/imFileEvent.json +++ b/.script/tests/KqlvalidationsTests/CustomTables/imFileEvent.json @@ -256,6 +256,10 @@ { "Name": "HttpUserAgent", "Type": "String" + }, + { + "Name": "ActingProcessSHA256", + "Type": "String" } ] } \ No newline at end of file From 7ef62d9c5d5ffee57126b3fe428c53adcd026094 Mon Sep 17 00:00:00 2001 From: Pete Bryan Date: Wed, 17 Nov 2021 21:01:08 -0800 Subject: [PATCH 08/18] test update for debugging --- .../DetectionTemplateSchemaValidationTests.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs b/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs index 8a7c4e9111f..3ddddcde729 100644 --- a/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs +++ b/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs @@ -31,7 +31,7 @@ public void Validate_DetectionTemplates_HasValidTemplateStructure(string detecti return; } } - + var exception = Record.Exception(() => { var templateObject = JsonConvert.DeserializeObject(ConvertYamlToJson(yaml)); @@ -92,7 +92,7 @@ public void Validate_DetectionTemplates_TemplatesThatAreInTheWhiteListShouldNotP var validationContext = new ValidationContext(templateObject); Validator.ValidateObject(templateObject, validationContext, true); }); - + } catch (Exception) { @@ -106,7 +106,7 @@ public void Validate_DetectionTemplates_TemplatesThatAreInTheWhiteListShouldNotP } } } - + [Fact] public void Validate_DetectionTemplates_AllFilesAreYamls() { @@ -116,9 +116,9 @@ public void Validate_DetectionTemplates_AllFilesAreYamls() var AllFiles = Directory.GetFiles(detectionPath[0],"*", SearchOption.AllDirectories).ToList(); AllFiles.AddRange(Directory.GetFiles(detectionPath[1], "*", SearchOption.AllDirectories).ToList().Where(s => s.Contains("Analytic Rules"))); var numberOfNotYamlFiles = 1; //This is the readme.md file in the directory - Assert.True(AllFiles.Count == yamlFiles.Count + numberOfNotYamlFiles, "All the files in detections and solution (Analytics rules) folder are supposed to end with .yaml"); + Assert.True(AllFiles.Count == yamlFiles.Count + numberOfNotYamlFiles, $"All the files in detections and solution (Analytics rules) folder are supposed to end with .yaml {numberOfNotYamlFiles}"); } - + [Fact] public void Validate_DetectionTemplates_NoSameTemplateIdTwice() { @@ -131,7 +131,7 @@ public void Validate_DetectionTemplates_NoSameTemplateIdTwice() var duplicationsById = templatesAsObjects.GroupBy(a => a["id"]).Where(group => group.Count() > 1); //Finds duplications -> ids that there are more than 1 template from var duplicatedId = ""; if (duplicationsById.Count() > 0){ - + duplicatedId = duplicationsById.Last().Select(x => x["id"]).First().ToString(); } Assert.True(duplicationsById.Count() == 0, $"There should not be 2 templates with the same ID, but the id {duplicatedId} is duplicated."); @@ -140,7 +140,7 @@ public void Validate_DetectionTemplates_NoSameTemplateIdTwice() private string GetYamlFileAsString(string detectionsYamlFileName) { var detectionsYamlFile = ""; - // Get file present in detection folder or else check in solution analytics rules folder + // Get file present in detection folder or else check in solution analytics rules folder try { detectionsYamlFile = Directory.GetFiles(RootDetectionPaths, detectionsYamlFileName, SearchOption.AllDirectories).Where(s => s.Contains("Detection")).Single(); From d682c32a84e5d22d36c2960ccb9b37478bf8fe03 Mon Sep 17 00:00:00 2001 From: Pete Bryan Date: Wed, 17 Nov 2021 21:06:45 -0800 Subject: [PATCH 09/18] more test debugging --- .../DetectionTemplateSchemaValidationTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs b/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs index 3ddddcde729..c02e6f52ed5 100644 --- a/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs +++ b/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs @@ -116,7 +116,7 @@ public void Validate_DetectionTemplates_AllFilesAreYamls() var AllFiles = Directory.GetFiles(detectionPath[0],"*", SearchOption.AllDirectories).ToList(); AllFiles.AddRange(Directory.GetFiles(detectionPath[1], "*", SearchOption.AllDirectories).ToList().Where(s => s.Contains("Analytic Rules"))); var numberOfNotYamlFiles = 1; //This is the readme.md file in the directory - Assert.True(AllFiles.Count == yamlFiles.Count + numberOfNotYamlFiles, $"All the files in detections and solution (Analytics rules) folder are supposed to end with .yaml {numberOfNotYamlFiles}"); + Assert.True(AllFiles.Count == yamlFiles.Count + numberOfNotYamlFiles, $"All the files in detections and solution (Analytics rules) folder are supposed to end with .yaml {numberOfNotYamlFiles} {AllFiles.Count} {yamlFiles.Count}"); } [Fact] From 896e0a6b4443d6bf83c6af5cc3334a5f44e205eb Mon Sep 17 00:00:00 2001 From: Pete Bryan Date: Wed, 17 Nov 2021 21:12:10 -0800 Subject: [PATCH 10/18] more debugging --- .../DetectionTemplateSchemaValidationTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs b/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs index c02e6f52ed5..f4ba575a881 100644 --- a/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs +++ b/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs @@ -116,7 +116,7 @@ public void Validate_DetectionTemplates_AllFilesAreYamls() var AllFiles = Directory.GetFiles(detectionPath[0],"*", SearchOption.AllDirectories).ToList(); AllFiles.AddRange(Directory.GetFiles(detectionPath[1], "*", SearchOption.AllDirectories).ToList().Where(s => s.Contains("Analytic Rules"))); var numberOfNotYamlFiles = 1; //This is the readme.md file in the directory - Assert.True(AllFiles.Count == yamlFiles.Count + numberOfNotYamlFiles, $"All the files in detections and solution (Analytics rules) folder are supposed to end with .yaml {numberOfNotYamlFiles} {AllFiles.Count} {yamlFiles.Count}"); + Assert.True(AllFiles.Count == yamlFiles.Count + numberOfNotYamlFiles, $"All the files in detections and solution (Analytics rules) folder are supposed to end with .yaml {numberOfNotYamlFiles} {AllFiles.Count} {yamlFiles.Count} {AllFiles}"); } [Fact] From dd65a24b089b07bc352db15df0fb4342874f4894 Mon Sep 17 00:00:00 2001 From: Pete Bryan Date: Wed, 17 Nov 2021 21:19:36 -0800 Subject: [PATCH 11/18] more debugging --- .../DetectionTemplateSchemaValidationTests.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs b/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs index f4ba575a881..ede32be2c43 100644 --- a/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs +++ b/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs @@ -116,7 +116,11 @@ public void Validate_DetectionTemplates_AllFilesAreYamls() var AllFiles = Directory.GetFiles(detectionPath[0],"*", SearchOption.AllDirectories).ToList(); AllFiles.AddRange(Directory.GetFiles(detectionPath[1], "*", SearchOption.AllDirectories).ToList().Where(s => s.Contains("Analytic Rules"))); var numberOfNotYamlFiles = 1; //This is the readme.md file in the directory - Assert.True(AllFiles.Count == yamlFiles.Count + numberOfNotYamlFiles, $"All the files in detections and solution (Analytics rules) folder are supposed to end with .yaml {numberOfNotYamlFiles} {AllFiles.Count} {yamlFiles.Count} {AllFiles}"); + string test = "" + foreach(var fil in AllFiles) + Console.WriteLine(fil); + string test = test + "," file.Print(); + Assert.True(AllFiles.Count == yamlFiles.Count + numberOfNotYamlFiles, $"All the files in detections and solution (Analytics rules) folder are supposed to end with .yaml {numberOfNotYamlFiles} {AllFiles.Count} {yamlFiles.Count} {test}"); } [Fact] From c50f61dd54584384b36a79b47ca5fe9ffcbbd633 Mon Sep 17 00:00:00 2001 From: Pete Bryan Date: Wed, 17 Nov 2021 21:23:44 -0800 Subject: [PATCH 12/18] debugging --- .../DetectionTemplateSchemaValidationTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs b/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs index ede32be2c43..26420da141d 100644 --- a/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs +++ b/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs @@ -116,11 +116,11 @@ public void Validate_DetectionTemplates_AllFilesAreYamls() var AllFiles = Directory.GetFiles(detectionPath[0],"*", SearchOption.AllDirectories).ToList(); AllFiles.AddRange(Directory.GetFiles(detectionPath[1], "*", SearchOption.AllDirectories).ToList().Where(s => s.Contains("Analytic Rules"))); var numberOfNotYamlFiles = 1; //This is the readme.md file in the directory - string test = "" foreach(var fil in AllFiles) + { Console.WriteLine(fil); - string test = test + "," file.Print(); - Assert.True(AllFiles.Count == yamlFiles.Count + numberOfNotYamlFiles, $"All the files in detections and solution (Analytics rules) folder are supposed to end with .yaml {numberOfNotYamlFiles} {AllFiles.Count} {yamlFiles.Count} {test}"); + } + Assert.True(AllFiles.Count == yamlFiles.Count + numberOfNotYamlFiles, $"All the files in detections and solution (Analytics rules) folder are supposed to end with .yaml {numberOfNotYamlFiles} {AllFiles.Count} {yamlFiles.Count}"); } [Fact] From 1776382e4ea58c356d69891b8febc446e56e39ac Mon Sep 17 00:00:00 2001 From: Pete Bryan Date: Wed, 17 Nov 2021 21:32:40 -0800 Subject: [PATCH 13/18] debugging tests --- .../DetectionTemplateSchemaValidationTests.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs b/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs index 26420da141d..5e5a0b03af8 100644 --- a/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs +++ b/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs @@ -120,6 +120,11 @@ public void Validate_DetectionTemplates_AllFilesAreYamls() { Console.WriteLine(fil); } + Console.WriteLine("----------------------------"); + foreach(var yfil in yamlFiles) + { + Console.WriteLine(yfil); + } Assert.True(AllFiles.Count == yamlFiles.Count + numberOfNotYamlFiles, $"All the files in detections and solution (Analytics rules) folder are supposed to end with .yaml {numberOfNotYamlFiles} {AllFiles.Count} {yamlFiles.Count}"); } From 7cf90f7175c08337bf026eb34cb1d03928ad1f35 Mon Sep 17 00:00:00 2001 From: Pete Bryan Date: Wed, 17 Nov 2021 21:49:10 -0800 Subject: [PATCH 14/18] Rename AWS_GuardDuty_template.YAML to AWS_GuardDuty_template.yaml updating file extension --- .../{AWS_GuardDuty_template.YAML => AWS_GuardDuty_template.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Detections/AWSGuardDuty/{AWS_GuardDuty_template.YAML => AWS_GuardDuty_template.yaml} (100%) diff --git a/Detections/AWSGuardDuty/AWS_GuardDuty_template.YAML b/Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml similarity index 100% rename from Detections/AWSGuardDuty/AWS_GuardDuty_template.YAML rename to Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml From 97d1ed31acb25aaabcc9a13d49c1271ba366e72d Mon Sep 17 00:00:00 2001 From: Pete Bryan Date: Wed, 17 Nov 2021 21:56:44 -0800 Subject: [PATCH 15/18] Adding AWSGuardDuty Table Schema and removing debugging --- .../CustomTables/AWSGuardDuty.json | 73 +++++++++++++++++++ .../DetectionTemplateSchemaValidationTests.cs | 11 +-- 2 files changed, 74 insertions(+), 10 deletions(-) create mode 100644 .script/tests/KqlvalidationsTests/CustomTables/AWSGuardDuty.json diff --git a/.script/tests/KqlvalidationsTests/CustomTables/AWSGuardDuty.json b/.script/tests/KqlvalidationsTests/CustomTables/AWSGuardDuty.json new file mode 100644 index 00000000000..16db3360e5e --- /dev/null +++ b/.script/tests/KqlvalidationsTests/CustomTables/AWSGuardDuty.json @@ -0,0 +1,73 @@ +{ + "Name": "AWSGuardDuty", + "Properties": [ + { + "name": "TimeGenerated", + "type": "DateTime" + }, + { + "name": "Type", + "type": "String" + }, + { + "name": "Title", + "type": "String" + }, + { + "name": "TimeCreated", + "type": "DateTime" + }, + { + "name": "TenantId", + "type": "String" + }, + { + "name": "SourceSystem", + "type": "String" + }, + { + "name": "Severity", + "type": "Int" + }, + { + "name": "ServiceDetails", + "type": "Dynamic" + }, + { + "name": "SchemaVersion", + "type": "String" + }, + { + "name": "ResourceDetails", + "type": "Dynamic" + }, + { + "name": "Region", + "type": "String" + }, + { + "name": "Partition", + "type": "String" + }, + { + "name": "Id", + "type": "String" + }, + { + "name": "Description", + "type": "String" + }, + { + "name": "Arn", + "type": "String" + }, + { + "name": "ActivityType", + "type": "String" + }, + { + "name": "AccountId", + "type": "String" + } + ] +} \ No newline at end of file diff --git a/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs b/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs index 5e5a0b03af8..deb649f9693 100644 --- a/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs +++ b/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs @@ -116,16 +116,7 @@ public void Validate_DetectionTemplates_AllFilesAreYamls() var AllFiles = Directory.GetFiles(detectionPath[0],"*", SearchOption.AllDirectories).ToList(); AllFiles.AddRange(Directory.GetFiles(detectionPath[1], "*", SearchOption.AllDirectories).ToList().Where(s => s.Contains("Analytic Rules"))); var numberOfNotYamlFiles = 1; //This is the readme.md file in the directory - foreach(var fil in AllFiles) - { - Console.WriteLine(fil); - } - Console.WriteLine("----------------------------"); - foreach(var yfil in yamlFiles) - { - Console.WriteLine(yfil); - } - Assert.True(AllFiles.Count == yamlFiles.Count + numberOfNotYamlFiles, $"All the files in detections and solution (Analytics rules) folder are supposed to end with .yaml {numberOfNotYamlFiles} {AllFiles.Count} {yamlFiles.Count}"); + Assert.True(AllFiles.Count == yamlFiles.Count + numberOfNotYamlFiles, $"All the files in detections and solution (Analytics rules) folder are supposed to end with .yaml"); } [Fact] From 8b9b827810e301d85064c10c620f33667360bd65 Mon Sep 17 00:00:00 2001 From: Pete Bryan Date: Wed, 17 Nov 2021 22:01:42 -0800 Subject: [PATCH 16/18] Fixed Guard Duty Query --- Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml b/Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml index 9a5d48bb845..aa605cf0c9a 100644 --- a/Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml +++ b/Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml @@ -1,6 +1,6 @@ id: bf0cde21-0c41-48f6-a40c-6b5bd71fa106 -name: 'AwsGuardDuty' -description: 'Amazon GuardDuty is a threat detection service that continuously monitors your AWS accounts and workloads for malicious activity and delivers detailed security findings for visibility and remediation. This template create an alert for each Amazon GuardDuty finding.' +name: AWS Guard Duty Alert +description: 'Amazon GuardDuty is a threat detection service that continuously monitors your AWS accounts and workloads for malicious activity and delivers detailed security findings for visibility and remediation. This templates create an alert for each Amazon GuardDuty finding.' severity: Medium requiredDataConnectors: - connectorId: AWSGuardDuty @@ -11,12 +11,12 @@ queryPeriod: 5h triggerOperator: gt triggerThreshold: 0 tactics: [] -query: >- +query: AWSGuardDuty | extend tokens = split(ActivityType,":") | extend ThreatPurpose = tokens[0], tokens= split(tokens[1],"/") | extend ResourceTypeAffected = tokens[0], ThreatFamilyName= tokens[1] - | extend UniqueFindingId = Id + | extend UniqueFindingId = Id | extend AWSAcoundId = AccountId | project-away tokens,ActivityType, Id, AccountId | project-away TimeGenerated, TenantId, SchemaVersion, Region, Partition From 2d3599939decf8a6bc04955e523114b8afe79659 Mon Sep 17 00:00:00 2001 From: Pete Bryan Date: Wed, 17 Nov 2021 22:08:58 -0800 Subject: [PATCH 17/18] More fixes for AWS Guard Duty Query --- Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml b/Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml index aa605cf0c9a..627c90d28b7 100644 --- a/Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml +++ b/Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml @@ -11,6 +11,7 @@ queryPeriod: 5h triggerOperator: gt triggerThreshold: 0 tactics: [] +relevantTechniques: [] query: AWSGuardDuty | extend tokens = split(ActivityType,":") From 32f3fc0f88f52ed28fdf9d9124beecc78e003e4a Mon Sep 17 00:00:00 2001 From: Pete Bryan Date: Wed, 17 Nov 2021 22:13:50 -0800 Subject: [PATCH 18/18] Fixes to AWS Guard Duty Query --- Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml b/Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml index 627c90d28b7..ad49891fd2c 100644 --- a/Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml +++ b/Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml @@ -40,3 +40,4 @@ alertDetailsOverride: alertDescriptionFormat: '{{Description}}' alertTacticsColumnName: ThreatPurpose alertSeverityColumnName: Severity +kind: Scheduled