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/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 diff --git a/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs b/.script/tests/detectionTemplateSchemaValidation/DetectionTemplateSchemaValidationTests.cs index 8a7c4e9111f..deb649f9693 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"); } - + [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(); diff --git a/Detections/ASimFileEvent/imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml b/Detections/ASimFileEvent/imFileEvent_Dev-0228FilePathHashesNovember2021-ASIM.yaml new file mode 100644 index 00000000000..d7bb0c2271a --- /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 = ActorUsername +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 diff --git a/Detections/AWSGuardDuty/AWS_GuardDuty_template.YAML b/Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml similarity index 88% rename from Detections/AWSGuardDuty/AWS_GuardDuty_template.YAML rename to Detections/AWSGuardDuty/AWS_GuardDuty_template.yaml index 9a5d48bb845..ad49891fd2c 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,13 @@ queryPeriod: 5h triggerOperator: gt triggerThreshold: 0 tactics: [] -query: >- +relevantTechniques: [] +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 @@ -39,3 +40,4 @@ alertDetailsOverride: alertDescriptionFormat: '{{Description}}' alertTacticsColumnName: ThreatPurpose alertSeverityColumnName: Severity +kind: Scheduled diff --git a/Detections/MultipleDataSources/Dev-0228FilePathHashesNovember2021.yaml b/Detections/MultipleDataSources/Dev-0228FilePathHashesNovember2021.yaml new file mode 100644 index 00000000000..68b3842cf2c --- /dev/null +++ b/Detections/MultipleDataSources/Dev-0228FilePathHashesNovember2021.yaml @@ -0,0 +1,57 @@ +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 +version: 1.0.0 +kind: Scheduled 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 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 @@ -