Fixed the createui related suggested changes and resolved the conflicts.
|
@ -60,7 +60,7 @@ function traverseAttributes(jsonContent: any, attributeNames: string[], errors:
|
|||
}
|
||||
|
||||
function validateAttribute(attributeValue: string, attributeName: string, errors: string[]): void {
|
||||
const sentinelRegex = /(?<!Microsoft\s)(?<!-)\bSentinel\b/g;
|
||||
const sentinelRegex = /(?<!Microsoft\s)(?<!\S)Sentinel(?!\S)/g;
|
||||
const updatedValue = attributeValue.replace(sentinelRegex, "Microsoft Sentinel");
|
||||
|
||||
if (attributeValue !== updatedValue) {
|
||||
|
|
|
@ -20,13 +20,18 @@ export function IsValidSolutionID(filePath: string): ExitCode {
|
|||
|
||||
// Validate if the solution ID is empty
|
||||
if (!solutionId) {
|
||||
throw new InvalidSolutionIDValidationError(`Empty solution ID. Expected format: publisherID.solutionID and Solution ID must be in lowercase. Found empty value.`);
|
||||
throw new InvalidSolutionIDValidationError(`Empty solution ID. Expected format: publisherID.offerID. and it must be in lowercase. Found empty value.`);
|
||||
}
|
||||
|
||||
// Validate the solution ID format
|
||||
const regex = /^[a-z0-9]+\.[a-z0-9_]+$/;
|
||||
const regex = /^[^.]+\.[^.]+$/;
|
||||
if (!regex.test(solutionId)) {
|
||||
throw new InvalidSolutionIDValidationError(`Invalid solution ID format. Expected format: publisherID.solutionID and Solution ID must be in lowercase. Found: ${solutionId}`);
|
||||
throw new InvalidSolutionIDValidationError(`Invalid solution ID format. Expected format: publisherID.offerID. and it must be in lowercase. Found: ${solutionId}`);
|
||||
}
|
||||
|
||||
// Validate the solution ID case (lowercase)
|
||||
if (solutionId !== solutionId.toLowerCase()) {
|
||||
throw new InvalidSolutionIDValidationError(`Invalid solution ID format. Expected format: publisherID.offerID. and it must be in lowercase. Found: ${solutionId}`);
|
||||
}
|
||||
} else {
|
||||
throw new InvalidSolutionIDValidationError(`Missing 'solutionId' attribute in the file. File path: ${filePath}`);
|
||||
|
|
|
@ -183,6 +183,10 @@
|
|||
{
|
||||
"Name": "Process",
|
||||
"Type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "Username",
|
||||
"Type": "string"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
{
|
||||
"Name": "AZFWThreatIntel",
|
||||
"Properties": [
|
||||
{
|
||||
"Name": "Action",
|
||||
"Type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "DestinationIp",
|
||||
"Type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "DestinationPort",
|
||||
"Type": "int"
|
||||
},
|
||||
{
|
||||
"Name": "Fqdn",
|
||||
"Type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "IsTlsInspected",
|
||||
"Type": "bool"
|
||||
},
|
||||
{
|
||||
"Name": "Protocol",
|
||||
"Type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "_ResourceId",
|
||||
"Type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "SourceIp",
|
||||
"Type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "SourcePort",
|
||||
"Type": "int"
|
||||
},
|
||||
{
|
||||
"Name": "SourceSystem",
|
||||
"Type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "_SubscriptionId",
|
||||
"Type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "_ResourceId",
|
||||
"Type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "TargetUrl",
|
||||
"Type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "TenantId",
|
||||
"Type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "ThreatDescription",
|
||||
"Type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "TimeGenerated",
|
||||
"Type": "datetime"
|
||||
},
|
||||
{
|
||||
"Name": "Type",
|
||||
"Type": "string"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -104,6 +104,10 @@
|
|||
{
|
||||
"Name": "Count",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "timestamp_t",
|
||||
"Type": "datetime"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
{
|
||||
"Name": "NXLogFIM_CL",
|
||||
"Properties": [
|
||||
{
|
||||
"Name": "Computer",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "DigestName_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "Digest_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "EventReceivedTime_t",
|
||||
"Type": "DateTime"
|
||||
},
|
||||
{
|
||||
"Name": "EventTime_t",
|
||||
"Type": "DateTime"
|
||||
},
|
||||
{
|
||||
"Name": "EventType_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "FileName_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "FileSize_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "HostIP_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "Hostname_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ModificationTime_t",
|
||||
"Type": "DateTime"
|
||||
},
|
||||
{
|
||||
"Name": "Object_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "PrevDigest_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "PrevFileName_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "PrevFileSize_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "PrevModificationTime_t",
|
||||
"Type": "DateTime"
|
||||
},
|
||||
{
|
||||
"Name": "RawData",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "SeverityValue_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "Severity_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "SourceModuleName_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "SourceModuleType_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "TimeGenerated",
|
||||
"Type": "DateTime"
|
||||
},
|
||||
{
|
||||
"Name": "Type",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "_BilledSize",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "_IsBillable",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "_ResourceId",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "_SubscriptionId",
|
||||
"Type": "String"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,189 @@
|
|||
{
|
||||
"Name": "Netclean_Incidents_CL",
|
||||
"Properties": [
|
||||
{
|
||||
"Name": "TenantId",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "SourceSystem",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "MG",
|
||||
"type": "Guid"
|
||||
},
|
||||
{
|
||||
"Name": "ManagementGroupName",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "TimeGenerated",
|
||||
"type": "datetime"
|
||||
},
|
||||
{
|
||||
"Name": "Computer",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "RawData",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "Hostname_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "agentType_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "Identifier_g",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "type_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "version_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "foundTime_t",
|
||||
"type": "datetime"
|
||||
},
|
||||
{
|
||||
"Name": "detectionMethod_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "agentInformatonIdentifier_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "osVersion_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "machineName_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "microsoftCultureId_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "timeZoneId_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "microsoftGeoId_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "domainname_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "Agentversion_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "Agentidentifier_g",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "loggedOnUsers_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "size_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "creationTime_t",
|
||||
"type": "datetime"
|
||||
},
|
||||
{
|
||||
"Name": "lastAccessTime_t",
|
||||
"type": "datetime"
|
||||
},
|
||||
{
|
||||
"Name": "lastWriteTime_t",
|
||||
"type": "datetime"
|
||||
},
|
||||
{
|
||||
"Name": "sha1_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "nearbyFiles_sha1_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "externalIP_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "domain_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "hasCollectedNearbyFiles_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "filePath_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "m365WebUrl_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "m365CreatedBymail_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "m365LastModifiedByMail_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "m365LibraryId_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "m365LibraryDisplayName_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "m365Librarytype_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "m365siteid_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "m365sitedisplayName_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "m365sitename_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "countOfAllNearByFiles_s",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "Type",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"Name": "_ResourceId",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -44,6 +44,7 @@
|
|||
{"Name":"ParentProcessGuid","Type":"string"},
|
||||
{"Name":"Dvc","Type":"string"},
|
||||
{"Name":"User","Type":"string"},
|
||||
{"Name":"Process","Type":"string"}
|
||||
{"Name":"Process","Type":"string"},
|
||||
{"Name":"Username","Type":"string"}
|
||||
]
|
||||
}
|
|
@ -51,7 +51,6 @@ namespace Kqlvalidations.Tests
|
|||
ValidateKql(id, queryStr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreach (var sampleQuery in dataConnector.SampleQueries)
|
||||
|
@ -86,6 +85,7 @@ namespace Kqlvalidations.Tests
|
|||
|
||||
var queryStr = (string)res["query"];
|
||||
ValidateKql(id, queryStr);
|
||||
ValidateKqlForLatestTIData(id, queryStr);
|
||||
}
|
||||
|
||||
// We pass File name to test because in the result file we want to show an informative name for the test
|
||||
|
@ -104,6 +104,7 @@ namespace Kqlvalidations.Tests
|
|||
|
||||
var queryStr = (string)res["query"];
|
||||
ValidateKql(id, queryStr);
|
||||
ValidateKqlForLatestTIData(id, queryStr);
|
||||
}
|
||||
|
||||
|
||||
|
@ -119,8 +120,8 @@ namespace Kqlvalidations.Tests
|
|||
if (ShouldSkipTemplateValidation(id) && res.ContainsKey("query"))
|
||||
{
|
||||
var queryStr = (string)res["query"];
|
||||
var validationRes = _queryValidator.ValidateSyntax(queryStr);
|
||||
Assert.False(validationRes.IsValid, string.Format(UserMessageTemplate, id));
|
||||
bool validationRes = _queryValidator.ValidateSyntax(queryStr).IsValid && ValidateKqlForLatestTI(queryStr);
|
||||
Assert.False(validationRes, string.Format(UserMessageTemplate, id));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -137,8 +138,8 @@ namespace Kqlvalidations.Tests
|
|||
if (ShouldSkipTemplateValidation(id) && res.ContainsKey("query"))
|
||||
{
|
||||
var queryStr = (string)res["query"];
|
||||
var validationRes = _queryValidator.ValidateSyntax(queryStr);
|
||||
Assert.False(validationRes.IsValid, string.Format(UserMessageTemplate, id));
|
||||
bool validationRes = _queryValidator.ValidateSyntax(queryStr).IsValid && ValidateKqlForLatestTI(queryStr);
|
||||
Assert.False(validationRes, string.Format(UserMessageTemplate, id));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -228,6 +229,51 @@ namespace Kqlvalidations.Tests
|
|||
ValidateKql(parserName, queryStr, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the KQL query for the latest Threat Intelligence data.
|
||||
/// </summary>
|
||||
/// <param name="id">template id</param>
|
||||
/// <param name="queryStr">query string</param>
|
||||
private void ValidateKqlForLatestTIData(string id, string queryStr)
|
||||
{
|
||||
bool queryMatch = ValidateKqlForLatestTI(queryStr);
|
||||
Assert.True(
|
||||
queryMatch,
|
||||
queryMatch
|
||||
? string.Empty
|
||||
: @$"Template Id: {id} is not valid
|
||||
Errors: Content needs to use the latest Threat Intelligence data. Sample queries to get the latest Threat Intelligence data:
|
||||
ThreatIntelligenceIndicator
|
||||
| where TimeGenerated >= ago(ioc_lookBack)
|
||||
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
|
||||
| where Active == true and ExpirationDateTime > now()
|
||||
|
||||
or
|
||||
|
||||
ThreatIntelligenceIndicator
|
||||
| where TimeGenerated >= ago(ioc_lookBack)
|
||||
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
|
||||
| where ExpirationDateTime > now() and Active == true");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the KQL query for the latest Threat Intelligence data.
|
||||
/// </summary>
|
||||
/// <param name="queryStr">query string</param>
|
||||
/// <returns>returns true if query is valid</returns>
|
||||
private bool ValidateKqlForLatestTI(string queryStr)
|
||||
{
|
||||
//Condition to check below logic only when queryStr it contains "ThreatIntelligenceIndicator" followed by "|"
|
||||
string tiTablepattern = @"ThreatIntelligenceIndicator\s*\|\s*";
|
||||
bool match = Regex.IsMatch(queryStr, tiTablepattern);
|
||||
if (match)
|
||||
{
|
||||
string queryPattern = @"ThreatIntelligenceIndicator\s*\|\s*where\s*TimeGenerated\s*>=\s*ago\(\w+\)\s*\|\s*summarize\s*LatestIndicatorTime\s*=\s*arg_max\(TimeGenerated,\s*\*\)\s*by\s*IndicatorId\s*\|\s*where\s*(?:ExpirationDateTime\s*>\s*now\(\)\s*and\s*Active\s*==\s*true|Active\s*==\s*true\s*and\s*ExpirationDateTime\s*>\s*now\(\))";
|
||||
return Regex.IsMatch(queryStr, queryPattern);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ValidateKql(string id, string queryStr, bool ignoreNoTabularExpressionError = true)
|
||||
{
|
||||
|
||||
|
|
|
@ -2470,16 +2470,6 @@
|
|||
"validationFailReason": "Since the content moved to new location, created dummy file with guidence for redirecting the customers to new location"
|
||||
},
|
||||
//Skipping templates with hunting query issues temporarily, we will remove these gradually once we fix the issue
|
||||
{
|
||||
"id": "ccef3c74-4b4f-445b-8109-06d38687e4a4",
|
||||
"templateName": "Unusual Number of Repository Clones.yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "611ebbc2-c789-42ad-93e3-6dc02bfa5e3d",
|
||||
"templateName": "unusual-volume-of-file-deletion.yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "e091e85d-4376-48cd-9bff-4beaa2ed4280",
|
||||
"templateName": "terminatedEmployeeActivity.yaml",
|
||||
|
@ -2490,86 +2480,11 @@
|
|||
"templateName": "terminatedEmployeeAccessHVA.yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "959f8d6a-53b8-488f-a628-999b3410702e",
|
||||
"templateName": "SuspiciousUrlClicked.yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "2d1a3e86-f1a0-49d0-b88a-55789e1d6660",
|
||||
"templateName": "PossibleCommandInjectionagainstAzureIR.yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "f82c89fa-c969-4d12-832f-04d55d14522c",
|
||||
"templateName": "PersistViaIFEORegistryKey.yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "f090f8f4a-b986-42d2-b536-e0795c723e25",
|
||||
"templateName": "NylonTyphoonRegIOCPatterns.yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "bb30abbc-9af6-4a37-9536-e9207e023989",
|
||||
"templateName": "NylonTyphoonCommandLineActivity-Nov2021.yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "767b8f6d-8029-4c92-afe1-282167d9d49a",
|
||||
"templateName": "NetworkConnectiontoOMIPorts.yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "dd2c4f48-b732-4a75-b2c4-b44bacc66d00",
|
||||
"templateName": "LocalAdminGroupChanges.yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "c3f1606e-48eb-464e-a60c-d53af5a5796e",
|
||||
"templateName": "imProcess_SolarWindsInventory.yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "24e66452-2aaa-455f-b0c6-a0d8216bbe79",
|
||||
"templateName": "imProcess_ProcessEntropy.yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "93a4ed6c-83e6-4202-8df4-e340dbd20a38",
|
||||
"templateName": "imProcess_powershell_downloads.yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "98fdd28d-9c13-431b-aca9-e6cfbb90a5a9",
|
||||
"templateName": "imProcess_Dev-0056CommandLineActivityNovember2021(ASIMVersion).yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "4cda0673-37f9-4765-af1f-556de2295cd7",
|
||||
"templateName": "HuntingQuery-BooleanBlindSQLi.yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "afe13b7c-test-11ec-8d3d-0242ac130003",
|
||||
"templateName": "Empty.yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "3169dc83-9e97-452c-afcc-baebdb0ddf7c",
|
||||
"templateName": "Discorddownloadinvokedfromcmdline(ASIMVersion).yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "6bfea14f-2122-46b3-8f8b-3947e0fb6d92",
|
||||
"templateName": "Dev-0322CommandLineActivityNovember2021(ASIMVersion).yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "fbcb7ff3-0d5a-4565-9caa-fc454138081f",
|
||||
"templateName": "devices_with_vuln_and_users_received_payload.yaml",
|
||||
"validationFailReason": "Temporarily Added for Hunting Query validation"
|
||||
},
|
||||
{
|
||||
"id": "669e1338-b1a2-4d73-b720-a1e60d5d1474",
|
||||
"templateName": "AWSBucketAPILogs-SuspiciousDataAccessToS3BucketsfromUnknownIP",
|
||||
|
@ -3316,6 +3231,268 @@
|
|||
"id": "CofenseTriage",
|
||||
"templateName": "CofenseTriage_API_FunctionApp.json",
|
||||
"validationFailReason": "Temporarily Added for Data Connector KQL Queries validation"
|
||||
},
|
||||
// Temporarily adding Data connector template id's for KQL Validations - End
|
||||
|
||||
|
||||
// Temporarily adding Analytic rules and hunting queries id's for TI KQL Validations - Start
|
||||
|
||||
{
|
||||
"id": "85aca4d1-5d15-4001-abd9-acb86ca1786a",
|
||||
"templateName": "DomainEntity_DnsEvents.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "b1832f60-6c3d-4722-a0a5-3d564ee61a63",
|
||||
"templateName": "DomainEntity_imWebSession.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "ec21493c-2684-4acd-9bc2-696dbad72426",
|
||||
"templateName": "DomainEntity_PaloAlto.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "87890d78-3e05-43ec-9ab9-ba32f4e01250",
|
||||
"templateName": "DomainEntity_SecurityAlert.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "532f62c1-fba6-4baa-bbb6-4a32a4ef32fa",
|
||||
"templateName": "DomainEntity_Syslog.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "cca3b4d9-ac39-4109-8b93-65bb284003e6",
|
||||
"templateName": "EmailEntity_AzureActivity.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "4a3f5ed7-8da5-4ce2-af6f-c9ada45060f2",
|
||||
"templateName": "EmailEntity_OfficeActivity.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "ffcd575b-3d54-482a-a6d8-d0de13b6ac63",
|
||||
"templateName": "EmailEntity_PaloAlto.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "a2e36ce0-da4d-4b6e-88c6-4e40161c5bfc",
|
||||
"templateName": "EmailEntity_SecurityAlert.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "2fc5d810-c9cc-491a-b564-841427ae0e50",
|
||||
"templateName": "EmailEntity_SecurityEvent.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "30fa312c-31eb-43d8-b0cc-bcbdfb360822",
|
||||
"templateName": "EmailEntity_SigninLogs.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "5d33fc63-b83b-4913-b95e-94d13f0d379f",
|
||||
"templateName": "FileHashEntity_CommonSecurityLog.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "a7427ed7-04b4-4e3b-b323-08b981b9b4bf",
|
||||
"templateName": "FileHashEntity_SecurityEvent.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "7241740a-5280-4b74-820a-862312d721a8",
|
||||
"templateName": "GitLab_MaliciousIP.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "999e9f5d-db4a-4b07-a206-29c4e667b7e8",
|
||||
"templateName": "imDns_DomainEntity_DnsEvents.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "67775878-7f8b-4380-ac54-115e1e828901",
|
||||
"templateName": "imDns_IPEntity_DnsEvents.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "f9949656-473f-4503-bf43-a9d9890f7d08",
|
||||
"templateName": "IPEntity_AppServiceHTTPLogs.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "f110287e-1358-490d-8147-ed804b328514",
|
||||
"templateName": "IPEntity_AWSCloudTrail.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "2441bce9-02e4-407b-8cc7-7d597f38b8b0",
|
||||
"templateName": "IPEntity_AzureActivity.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "0b904747-1336-4363-8d84-df2710bfe5e7",
|
||||
"templateName": "IPEntity_AzureFirewall.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "57c7e832-64eb-411f-8928-4133f01f4a25",
|
||||
"templateName": "IPEntity_AzureKeyVault.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "a4025a76-6490-4e6b-bb69-d02be4b03f07",
|
||||
"templateName": "IPEntity_AzureNetworkAnalytics.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "d0aa8969-1bbe-4da3-9e76-09e5f67c9d85",
|
||||
"templateName": "IPEntity_AzureSQL.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "66c81ae2-1f89-4433-be00-2fbbd9ba5ebe",
|
||||
"templateName": "IPEntity_CustomSecurityLog.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "69b7723c-2889-469f-8b55-a2d355ed9c87",
|
||||
"templateName": "IPEntity_DnsEvents.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "d23ed927-5be3-4902-a9c1-85f841eb4fa1",
|
||||
"templateName": "IPEntity_DuoSecurity.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "e2399891-383c-4caf-ae67-68a008b9f89e",
|
||||
"templateName": "IPEntity_imNetworkSession.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "e2559891-383c-4caf-ae67-55a008b9f89e",
|
||||
"templateName": "IPEntity_imWebSession.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "f15370f4-c6fa-42c5-9be4-1d308f40284e",
|
||||
"templateName": "IPEntity_OfficeActivity.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "f2eb15bd-8a88-4b24-9281-e133edfba315",
|
||||
"templateName": "IPentity_SigninLogs.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "9713e3c0-1410-468d-b79e-383448434b2d",
|
||||
"templateName": "IPEntity_VMConnection.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "5e45930c-09b1-4430-b2d1-cc75ada0dc0f",
|
||||
"templateName": "IPEntity_W3CIISLog.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "35a0792a-1269-431e-ac93-7ae2980d4dde",
|
||||
"templateName": "ProofpointPODEmailSenderInTIList.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "78979d32-e63f-4740-b206-cfb300c735e0",
|
||||
"templateName": "ProofpointPODEmailSenderIPinTIList.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "a1c02815-4248-4728-a9ae-dac73c67db23",
|
||||
"templateName": "RecordedFutureDomainMalwareC2inDNSEvents.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "dffd068f-fdab-440e-bbc0-34c14b623c89",
|
||||
"templateName": "RecordedFutureDomainMalwareC2inSyslogEvents.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "388e197d-ec9e-46b6-addb-947d74d2a5c4",
|
||||
"templateName": "RecordedFutureHashObservedInUndergroundinCommonSecurityLog.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "aac495a9-feb1-446d-b08e-a1164a539452",
|
||||
"templateName": "Threat Intel Matches to GitHub Audit Logs.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "2a723664-22c2-4d3e-bbec-5843b90166f3",
|
||||
"templateName": "TIMapIPEntityToLastPass.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "db60ca0b-b668-439b-b889-b63b57ef20fb",
|
||||
"templateName": "UbiquitiDestinationInTiList.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "712fab52-2a7d-401e-a08c-ff939cc7c25e",
|
||||
"templateName": "URLEntity_AuditLogs.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "36a9c9e5-3dc1-4ed9-afaa-1d13617bfc2b",
|
||||
"templateName": "URLEntity_OfficeActivity.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "106813db-679e-4382-a51b-1bfc463befc3",
|
||||
"templateName": "URLEntity_PaloAlto.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "f30a47c1-65fb-42b1-a7f4-00941c12550b",
|
||||
"templateName": "URLEntity_SecurityAlerts.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "b31037ea-6f68-4fbd-bab2-d0d0f44c2fcf",
|
||||
"templateName": "URLEntity_Syslog.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "410da56d-4a63-4d22-b68c-9fb1a303be6d",
|
||||
"templateName": "FileEntity_OfficeActivity.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "233441b9-cc92-4c9b-87fa-73b855fcd4b8",
|
||||
"templateName": "FileEntity_SecurityEvent.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "18f7de84-de55-4983-aca3-a18bc846b4e0",
|
||||
"templateName": "FileEntity_Syslog.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "172a321b-c46b-4508-87c6-e2691c778107",
|
||||
"templateName": "FileEntity_VMConnection.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "689a9475-440b-4e69-8ab1-a5e241685f39",
|
||||
"templateName": "FileEntity_WireData.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
},
|
||||
{
|
||||
"id": "388e197d-ec9e-46b6-addb-947d74d2a5c4",
|
||||
"templateName": "RecordedFutureHashObservedInUndergroundinCommonSecurityLog.yaml",
|
||||
"validationFailReason": "Temporarily Added for Threat Intelligence KQL Queries validation"
|
||||
}
|
||||
// Temporarily adding Data connector template id's for KQL Validations - Start
|
||||
// Temporarily adding Analytic rules and hunting queries id's for TI KQL Validations - End
|
||||
|
||||
|
||||
]
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
[
|
||||
"Netclean_ProActive_Incidents",
|
||||
"42CrunchAPIProtection",
|
||||
"AIVectraDetect",
|
||||
"AIVectraStream",
|
||||
|
|
|
@ -514,5 +514,7 @@
|
|||
"a8f689e5-7f84-4658-b816-75aa94c8b833",
|
||||
"a2b67846-d66b-4047-bc84-78bfc993d5f3",
|
||||
"9699e4c9-dca9-404b-be0b-6e342dd31aff",
|
||||
"6084abc3-c4be-47d0-86f5-3c20fea63cea"
|
||||
"6084abc3-c4be-47d0-86f5-3c20fea63cea",
|
||||
"cd8faa84-4464-4b4e-96dc-b22f50c27541",
|
||||
"5533fe80-905e-49d5-889a-df27d2c3976d"
|
||||
]
|
|
@ -15,9 +15,9 @@
|
|||
"type": "Microsoft.OperationalInsights/workspaces/providers/Watchlists",
|
||||
"kind": "",
|
||||
"properties": {
|
||||
"displayName": "ASimSourceType",
|
||||
"source": "ASimSourceType.csv",
|
||||
"description": "The watchlist is used by ASim to specify Sources and their types.",
|
||||
"displayName": "Sources_by_SourceType",
|
||||
"source": "Sources_by_SourceType.csv",
|
||||
"description": "The watchlist is used by ASim Prarsers / regular parsers to specify Sources and their types.",
|
||||
"provider": "Custom",
|
||||
"isDeleted": false,
|
||||
"labels": [
|
||||
|
@ -31,4 +31,4 @@
|
|||
"apiVersion": "2022-08-01"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
azure-functions
|
||||
boto3==1.9.180
|
||||
requests==2.22.0
|
||||
requests==2.31.0
|
Двоичные данные
DataConnectors/AWS-S3-AzureFunction/AzFun-AWS-S3-Ingestion.zip
|
@ -4,4 +4,4 @@
|
|||
|
||||
azure-functions
|
||||
boto3==1.9.180
|
||||
requests==2.22.0
|
||||
requests==2.31.0
|
|
@ -4,14 +4,14 @@
|
|||
|
||||
azure-functions==1.8.0
|
||||
boto3==1.9.180
|
||||
requests==2.22.0
|
||||
requests==2.31.0
|
||||
adal==1.2.2
|
||||
aiohttp==3.6.2
|
||||
asn1crypto==0.24.0
|
||||
azure-common==1.1.24
|
||||
azure-core==1.21.0
|
||||
botocore==1.12.10
|
||||
cryptography==35.0.0
|
||||
cryptography==41.0.0
|
||||
pyasn1==0.4.2
|
||||
pyasn1-modules==0.2.1
|
||||
cffi==1.14.6
|
||||
|
|
|
@ -0,0 +1,945 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"location": {
|
||||
"defaultValue": "[resourceGroup().location]",
|
||||
"minLength": 1,
|
||||
"type": "String",
|
||||
"metadata": {
|
||||
"description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace"
|
||||
}
|
||||
},
|
||||
"workspace-location": {
|
||||
"defaultValue": "",
|
||||
"type": "String",
|
||||
"metadata": {
|
||||
"description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]"
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
"type": "String"
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"solutionId": "azuresentinel.azure-sentinel-solution-gcpscclogs-api",
|
||||
"_solutionId": "[variables('solutionId')]",
|
||||
"dataCollectionRuleImmutableId": "data collection rule immutableId",
|
||||
"_dataCollectionRuleImmutableId": "[variables('dataCollectionRuleImmutableId')]",
|
||||
"dataCollectionEndpointId": "[concat('/subscriptions/',variables('subscription'),'/resourceGroups/',variables('resourceGroupName'),'/providers/Microsoft.Insights/dataCollectionEndpoints/',parameters('workspace'))]",
|
||||
"_dataCollectionEndpointId": "[variables('dataCollectionEndpointId')]",
|
||||
"workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]",
|
||||
"uiConfigId1": "GoogleSCCDefinition",
|
||||
"_uiConfigId1": "[variables('uiConfigId1')]",
|
||||
"dataConnectorContentId1": "GoogleSCCDefinition",
|
||||
"_dataConnectorContentId1": "[variables('dataConnectorContentId1')]",
|
||||
"dataConnectorId1": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectorDefinitions', variables('_dataConnectorContentId1'))]",
|
||||
"_dataConnectorId1": "[variables('dataConnectorId1')]",
|
||||
"dataConnectorTemplateSpecName1": "[concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId1')))]",
|
||||
"dataConnectorVersion1": "1.0.0",
|
||||
"dataConnectorContentId2": "GoogleSCC",
|
||||
"_dataConnectorContentId2": "[variables('dataConnectorContentId2')]",
|
||||
"dataConnectorId2": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId2'))]",
|
||||
"_dataConnectorId2": "[variables('dataConnectorId2')]",
|
||||
"dataConnectorTemplateSpecName2": "[concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId2')))]",
|
||||
"dataConnectorVersion2": "1.0.0",
|
||||
"resourceGroupName": "[resourceGroup().name]",
|
||||
"subscription": "[last(split(subscription().id, '/'))]",
|
||||
"dataCollectionRuleId": "GoogleSCC",
|
||||
"streamName": "GoogleCloudSCC_CL",
|
||||
"logAnalyticsTableId": "[concat('Custom-', variables('streamName'))]",
|
||||
"dataType": "GoogleSCC",
|
||||
"destinationName": "clv2ws1"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Resources/templateSpecs",
|
||||
"apiVersion": "2021-05-01",
|
||||
"name": "[variables('dataConnectorTemplateSpecName1')]",
|
||||
"location": "[parameters('workspace-location')]",
|
||||
"tags": {
|
||||
"hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
|
||||
"hidden-sentinelContentType": "DataConnector"
|
||||
},
|
||||
"properties": {
|
||||
"description": "GoogleSCC data connector with template",
|
||||
"displayName": "GoogleSCC uditLogs template"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Resources/templateSpecs/versions",
|
||||
"apiVersion": "2021-05-01",
|
||||
"name": "[concat(variables('dataConnectorTemplateSpecName1'),'/',variables('dataConnectorVersion1'))]",
|
||||
"location": "[parameters('workspace-location')]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Resources/templateSpecs', variables('dataConnectorTemplateSpecName1'))]"
|
||||
],
|
||||
"tags": {
|
||||
"hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
|
||||
"hidden-sentinelContentType": "DataConnector"
|
||||
},
|
||||
"properties": {
|
||||
"description": "GoogleSCC data connector with template version 1.0.0",
|
||||
"mainTemplate": {
|
||||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
|
||||
"contentVersion": "[variables('dataConnectorVersion1')]",
|
||||
"parameters": {},
|
||||
"variables": {},
|
||||
"resources": [
|
||||
{
|
||||
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]",
|
||||
"apiVersion": "2022-09-01-preview",
|
||||
"type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectorDefinitions",
|
||||
"location": "[parameters('workspace-location')]",
|
||||
"kind": "Customizable",
|
||||
"properties": {
|
||||
"connectorUiConfig": {
|
||||
"title": "Google SCC",
|
||||
"publisher": "Microsoft",
|
||||
"descriptionMarkdown": "The Google Cloud Platform (GCP) Security Command Center is a comprehensive security and risk management platform for Google Cloud, ingested from Sentinel's connector. It offers features such as asset inventory and discovery, vulnerability and threat detection, and risk mitigation and remediation to help you gain insight into your organization's security and data attack surface. This integration enables you to perform tasks related to findings and assets more effectively.",
|
||||
"graphQueriesTableName": "GoogleCloudSCC_CL",
|
||||
"graphQueries": [
|
||||
{
|
||||
"metricName": "Total events received",
|
||||
"legend": "Google SCC",
|
||||
"baseQuery": "{{graphQueriesTableName}}"
|
||||
}
|
||||
],
|
||||
"sampleQueries": [
|
||||
{
|
||||
"description": "Get Sample of Google SCC",
|
||||
"query": "{{graphQueriesTableName}}\n | take 10"
|
||||
}
|
||||
],
|
||||
"dataTypes": [
|
||||
{
|
||||
"name": "{{graphQueriesTableName}}",
|
||||
"lastDataReceivedQuery": "{{graphQueriesTableName}}\n | where TimeGenerated > ago(12h) | where name_s == \"no data test\" | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
|
||||
}
|
||||
],
|
||||
"connectivityCriteria": [
|
||||
{
|
||||
"type": "HasDataConnectors",
|
||||
"value": null
|
||||
}
|
||||
],
|
||||
"availability": {
|
||||
"status": 1,
|
||||
"isPreview": false
|
||||
},
|
||||
"permissions": {
|
||||
"tenant": null,
|
||||
"licenses": null,
|
||||
"resourceProvider": [
|
||||
{
|
||||
"provider": "Microsoft.OperationalInsights/workspaces",
|
||||
"permissionsDisplayText": "Read and Write permissions are required.",
|
||||
"providerDisplayName": "Workspace",
|
||||
"scope": "Workspace",
|
||||
"requiredPermissions": {
|
||||
"read": true,
|
||||
"write": true,
|
||||
"delete": true,
|
||||
"action": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
|
||||
"permissionsDisplayText": "Read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key)",
|
||||
"providerDisplayName": "Keys",
|
||||
"scope": "Workspace",
|
||||
"requiredPermissions": {
|
||||
"read": false,
|
||||
"write": false,
|
||||
"delete": false,
|
||||
"action": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"instructionSteps": [
|
||||
{
|
||||
"title": "Connect Google to Microsoft Sentinel",
|
||||
"description": "To enable Google SCC for Microsoft Sentinel, provide the required information below and click on Connect.",
|
||||
"instructions": [
|
||||
{
|
||||
"parameters": {
|
||||
"label": "GCP Project id",
|
||||
"placeholder": "GCP_project_id",
|
||||
"type": "text",
|
||||
"name": "ProjectId"
|
||||
},
|
||||
"type": "Textbox"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"label": "GCP Project number",
|
||||
"placeholder": "GCP_project_number",
|
||||
"type": "text",
|
||||
"name": "ProjectNumber"
|
||||
},
|
||||
"type": "Textbox"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"disabled": false,
|
||||
"label": "toggle",
|
||||
"isPrimary": true,
|
||||
"name": "toggle",
|
||||
"transformation": {
|
||||
"dataCollectionRuleTemplateSpecName": "",
|
||||
"logAnalyticsTableTemplateSpecName": "",
|
||||
"outputStream": "",
|
||||
"transformationType": "predefinedTransformation"
|
||||
}
|
||||
},
|
||||
"type": "ToggleConnectionButton"
|
||||
}
|
||||
],
|
||||
"innerSteps": null
|
||||
}
|
||||
],
|
||||
"isConnectivityCriteriasMatchSome": false
|
||||
},
|
||||
"connectionsConfig": {
|
||||
"templateSpecName": "[concat('/subscriptions/',variables('subscription'),'/resourceGroups/',variables('resourceGroupName'),'/providers/Microsoft.Resources/templateSpecs/',variables('dataConnectorTemplateSpecName2'))]",
|
||||
"templateSpecVersion": "[variables('dataConnectorVersion2')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "[variables('streamName')]",
|
||||
"type": "Microsoft.OperationalInsights/workspaces",
|
||||
"apiVersion": "2021-03-01-privatepreview",
|
||||
"location": "[parameters('workspace-location')]",
|
||||
"tags": {},
|
||||
"properties": {
|
||||
"totalRetentionInDays": 30,
|
||||
"archiveRetentionInDays": 0,
|
||||
"plan": "Analytics",
|
||||
"retentionInDaysAsDefault": true,
|
||||
"totalRetentionInDaysAsDefault": true,
|
||||
"schema": {
|
||||
"tableSubType": "DataCollectionRuleBased",
|
||||
"name": "[variables('streamName')]",
|
||||
"tableType": "CustomLog",
|
||||
"columns": [
|
||||
{
|
||||
"name": "findings",
|
||||
"type": "dynamic",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "resource",
|
||||
"type": "dynamic",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "sourceProperties",
|
||||
"type": "dynamic",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "TimeGenerated",
|
||||
"type": "datetime",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "canonicalName",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "category",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "finding_access",
|
||||
"type": "dynamic",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "assetDisplayName",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "assetId",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "cloudDlpDataProfile",
|
||||
"type": "dynamic",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "cloudDlpInspection",
|
||||
"type": "dynamic",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "createTime",
|
||||
"type": "datetime",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "finding_database",
|
||||
"type": "dynamic",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "compliance",
|
||||
"type": "dynamic",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "description",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "eventTime",
|
||||
"type": "datetime",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "exfiltration",
|
||||
"type": "dynamic",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "externalUri",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "findingClass",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "findingProviderId",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "indicator",
|
||||
"type": "dynamic",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "kernelRootkit",
|
||||
"type": "dynamic",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "kubernetes",
|
||||
"type": "dynamic",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "mitreAttack",
|
||||
"type": "dynamic",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "mute",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "parent",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "parentDisplayName",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "resourceName",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "severity",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "state",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "vulnerability",
|
||||
"type": "dynamic",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "workflowState",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "resource_name",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "resource_DisplayName",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "resource_project",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "projectDisplayName",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "resource_parent",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "resource_parentDisplayName",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "resource_type",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "folders",
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
}
|
||||
],
|
||||
"standardColumns": [
|
||||
{
|
||||
"name": "TenantId",
|
||||
"type": "guid",
|
||||
"isDefaultDisplay": false,
|
||||
"isHidden": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "[variables('dataCollectionRuleId')]",
|
||||
"apiVersion": "2021-09-01-preview",
|
||||
"type": "Microsoft.Insights/dataCollectionRules",
|
||||
"location": "[parameters('workspace-location')]",
|
||||
"properties": {
|
||||
"dataCollectionEndpointId": "[variables('_dataCollectionEndpointId')]",
|
||||
"streamDeclarations": {
|
||||
"[concat('Custom-', variables('streamName'))]": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "TimeGenerated",
|
||||
"type": "datetime"
|
||||
},
|
||||
{
|
||||
"name": "finding",
|
||||
"type": "dynamic"
|
||||
},
|
||||
{
|
||||
"name": "resource",
|
||||
"type": "dynamic"
|
||||
},
|
||||
{
|
||||
"name": "sourceProperties",
|
||||
"type": "dynamic"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"destinations": {
|
||||
"logAnalytics": [
|
||||
{
|
||||
"workspaceResourceId": "[variables('workspaceResourceId')]",
|
||||
"name": "[variables('destinationName')]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"dataFlows": [
|
||||
{
|
||||
"streams": [
|
||||
"[concat('Custom-', variables('streamName'))]"
|
||||
],
|
||||
"destinations": [
|
||||
"[variables('destinationName')]"
|
||||
],
|
||||
"transformKql": "source\n| extend TimeGenerated = todatetime(finding.eventTime), findings = parse_json(finding), resource = parse_json(resource), sourceProperties = parse_json(sourceProperties)\n | extend canonicalName = tostring(findings.canonicalName)\n | extend category = tostring(findings.category)\n | extend finding_access = findings.access\n | extend assetDisplayName = tostring(findings.assetDisplayName)\n | extend assetId = tostring(findings.assetId)\n | extend cloudDlpDataProfile = todynamic(findings.cloudDlpDataProfile)\n | extend cloudDlpInspection = todynamic(findings.cloudDlpInspection)\n | extend createTime = todatetime(findings.createTime)\n | extend finding_database = todynamic(findings.database)\n | extend compliances = todynamic(findings.compliance)\n| extend description = tostring(findings.description)\n | extend eventTime = todatetime(findings.eventTime)\n | extend exfiltration = todynamic(findings.exfiltration)\n | extend externalUri = tostring(findings.externalUri)\n | extend findingClass = tostring(findings.findingClass)\n | extend findingProviderId = tostring(findings.findingProviderId)\n | extend indicator = todynamic(findings.indicator)\n | extend kernelRootkit = todynamic(findings.kernelRootkit)\n | extend kubernetes = todynamic(findings.kubernetes)\n| extend mitreAttack = todynamic(findings.mitreAttack)\n | extend mute = tostring(findings.mute)\n | extend name = tostring(findings.name)\n | extend parent = tostring(findings.parent)\n | extend parentDisplayName = tostring(findings.parentDisplayName) \n | extend resourceName = tostring(findings.resourceName)\n | extend severity = tostring(findings.severity)\n | extend state = tostring(findings.state)\n | extend vulnerability = todynamic(findings.vulnerability)\n | extend workflowState = tostring(findings.workflowState)\n | extend resource_name = tostring(resource.name)\n | extend resource_DisplayName = tostring(resource.DisplayName)\n | extend resource_project = tostring(resource.['project'])\n | extend projectDisplayName = tostring(resource.projectDisplayName)\n | extend resource_parent = tostring(resource.parent)\n | extend resource_parentDisplayName = tostring(resource.parentDisplayName) \n| extend resource_type = tostring(resource.type)\n | extend folders = tostring(resource.folders)\n ",
|
||||
"outputStream": "[concat('Custom-', variables('streamName'))]"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
|
||||
"apiVersion": "2022-01-01-preview",
|
||||
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]",
|
||||
"properties": {
|
||||
"parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectorDefinitions', variables('_dataConnectorContentId1'))]",
|
||||
"contentId": "[variables('_dataConnectorContentId1')]",
|
||||
"kind": "DataConnector",
|
||||
"version": "[variables('dataConnectorVersion1')]",
|
||||
"source": {
|
||||
"kind": "Solution",
|
||||
"name": "Google Cloud Platform Security Command Center",
|
||||
"sourceId": "[variables('_solutionId')]"
|
||||
},
|
||||
"author": {
|
||||
"name": "Microsoft"
|
||||
},
|
||||
"support": {
|
||||
"name": "Microsoft Corporation",
|
||||
"email": "support@microsoft.com",
|
||||
"tier": "Microsoft",
|
||||
"link": "https://support.microsoft.com"
|
||||
},
|
||||
"dependencies": {
|
||||
"criteria": [
|
||||
{
|
||||
"kind": "DataConnector",
|
||||
"contentId": "[variables('_dataConnectorContentId2')]",
|
||||
"version": "[variables('dataConnectorVersion2')]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
|
||||
"apiVersion": "2022-01-01-preview",
|
||||
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]",
|
||||
"properties": {
|
||||
"parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectorDefinitions', variables('_dataConnectorContentId1'))]",
|
||||
"contentId": "[variables('_dataConnectorContentId1')]",
|
||||
"kind": "DataConnector",
|
||||
"version": "[variables('dataConnectorVersion1')]",
|
||||
"source": {
|
||||
"kind": "Solution",
|
||||
"name": "Google Cloud Platform Security Command Center",
|
||||
"sourceId": "[variables('_solutionId')]"
|
||||
},
|
||||
"author": {
|
||||
"name": "Microsoft"
|
||||
},
|
||||
"support": {
|
||||
"name": "Microsoft Corporation",
|
||||
"email": "support@microsoft.com",
|
||||
"tier": "Microsoft",
|
||||
"link": "https://support.microsoft.com"
|
||||
},
|
||||
"dependencies": {
|
||||
"criteria": [
|
||||
{
|
||||
"kind": "DataConnector",
|
||||
"contentId": "[variables('_dataConnectorContentId2')]",
|
||||
"version": "[variables('dataConnectorVersion2')]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectorDefinitions",
|
||||
"apiVersion": "2022-09-01-preview",
|
||||
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]",
|
||||
"location": "[parameters('workspace-location')]",
|
||||
"kind": "Customizable",
|
||||
"properties": {
|
||||
"connectorUiConfig": {
|
||||
"title": "Google Security Command Center",
|
||||
"publisher": "Microsoft",
|
||||
"descriptionMarkdown": "The Google Cloud Platform (GCP) Security Command Center is a comprehensive security and risk management platform for Google Cloud, ingested from Sentinel's connector. It offers features such as asset inventory and discovery, vulnerability and threat detection, and risk mitigation and remediation to help you gain insight into your organization's security and data attack surface. This integration enables you to perform tasks related to findings and assets more effectively.",
|
||||
"graphQueriesTableName": "GoogleCloudSCC_CL",
|
||||
"graphQueries": [
|
||||
{
|
||||
"metricName": "Total events received",
|
||||
"legend": "Google Security Command Center",
|
||||
"baseQuery": "{{graphQueriesTableName}}"
|
||||
}
|
||||
],
|
||||
"sampleQueries": [
|
||||
{
|
||||
"description": "Get Sample of Google SCC",
|
||||
"query": "{{graphQueriesTableName}}\n | take 10"
|
||||
}
|
||||
],
|
||||
"dataTypes": [
|
||||
{
|
||||
"name": "{{graphQueriesTableName}}",
|
||||
"lastDataReceivedQuery": "{{graphQueriesTableName}}\n | where TimeGenerated > ago(12h) | where name_s == \"no data test\" | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
|
||||
}
|
||||
],
|
||||
"connectivityCriteria": [
|
||||
{
|
||||
"type": "HasDataConnectors",
|
||||
"value": null
|
||||
}
|
||||
],
|
||||
"availability": {
|
||||
"status": 1,
|
||||
"isPreview": false
|
||||
},
|
||||
"permissions": {
|
||||
"tenant": null,
|
||||
"licenses": null,
|
||||
"resourceProvider": [
|
||||
{
|
||||
"provider": "Microsoft.OperationalInsights/workspaces",
|
||||
"permissionsDisplayText": "Read and Write permissions are required.",
|
||||
"providerDisplayName": "Workspace",
|
||||
"scope": "Workspace",
|
||||
"requiredPermissions": {
|
||||
"read": true,
|
||||
"write": true,
|
||||
"delete": true,
|
||||
"action": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
|
||||
"permissionsDisplayText": "Read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key)",
|
||||
"providerDisplayName": "Keys",
|
||||
"scope": "Workspace",
|
||||
"requiredPermissions": {
|
||||
"read": false,
|
||||
"write": false,
|
||||
"delete": false,
|
||||
"action": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"instructionSteps": [
|
||||
{
|
||||
"instructions": [
|
||||
{
|
||||
"type": "Markdown",
|
||||
"parameters": {
|
||||
"content": "#### 1. Set up your GCP environment \n You must have the following GCP resources defined and configured: topic, subscription for the topic, workload identity pool, workload identity provider and service account with permissions to get and consume from subscription. \n Terraform provides API for the IAM that creates the resources. [Link to Terraform scripts](https://github.com/Azure/Azure-Sentinel/tree/master/DataConnectors/GCP/Terraform/sentinel_resources_creation)."
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "CopyableLabel",
|
||||
"parameters": {
|
||||
"label": "Tenant ID: A unique identifier that is used as an input in the Terraform configuration within a GCP environment.",
|
||||
"fillWith": [
|
||||
"TenantId"
|
||||
],
|
||||
"name": "PoolId",
|
||||
"disabled": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Markdown",
|
||||
"parameters": {
|
||||
"content": "#### 2. Connect new collectors \n To enable GCP Audit Logs for Microsoft Sentinel, click the Add new collector button, fill the required information in the context pane and click on Connect."
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "GCPGrid",
|
||||
"parameters": {}
|
||||
},
|
||||
{
|
||||
"type": "GCPContextPane",
|
||||
"parameters": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"isConnectivityCriteriasMatchSome": false
|
||||
},
|
||||
"connectionsConfig": {
|
||||
"templateSpecName": "[concat('/subscriptions/',variables('subscription'),'/resourceGroups/',variables('resourceGroupName'),'/providers/Microsoft.Resources/templateSpecs/',variables('dataConnectorTemplateSpecName2'))]",
|
||||
"templateSpecVersion": "[variables('dataConnectorVersion2')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Resources/templateSpecs",
|
||||
"apiVersion": "2021-05-01",
|
||||
"name": "[variables('dataConnectorTemplateSpecName2')]",
|
||||
"location": "[parameters('workspace-location')]",
|
||||
"tags": {
|
||||
"hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
|
||||
"hidden-sentinelContentType": "LogicAppsCustomConnector"
|
||||
},
|
||||
"properties": {
|
||||
"description": "GoogleSCC data connector with template",
|
||||
"displayName": "GoogleSCC template"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Resources/templateSpecs/versions",
|
||||
"apiVersion": "2021-05-01",
|
||||
"name": "[concat(variables('dataConnectorTemplateSpecName2'),'/',variables('dataConnectorVersion2'))]",
|
||||
"location": "[parameters('workspace-location')]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Resources/templateSpecs', variables('dataConnectorTemplateSpecName2'))]"
|
||||
],
|
||||
"tags": {
|
||||
"hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
|
||||
"hidden-sentinelContentType": "LogicAppsCustomConnector"
|
||||
},
|
||||
"properties": {
|
||||
"description": "GoogleSCC data connector with template version 2.0.0",
|
||||
"mainTemplate": {
|
||||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
|
||||
"contentVersion": "[variables('dataConnectorVersion2')]",
|
||||
"parameters": {
|
||||
"GCPProjectId": {
|
||||
"type": "String",
|
||||
"minLength": 4
|
||||
},
|
||||
"GCPProjectNumber": {
|
||||
"type": "String",
|
||||
"minLength": 1
|
||||
},
|
||||
"GCPWorkloadIdentityProviderId": {
|
||||
"type": "String"
|
||||
},
|
||||
"GCPServiceAccountEmail": {
|
||||
"type": "String",
|
||||
"minLength": 1
|
||||
},
|
||||
"GCPSubscriptionName": {
|
||||
"type": "String",
|
||||
"minLength": 3
|
||||
},
|
||||
"connectorDefinitionName": {
|
||||
"defaultValue": "connectorDefinitionName",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"metadata": {
|
||||
"description": "connectorDefinitionName"
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
"defaultValue": "[parameters('workspace')]",
|
||||
"type": "string"
|
||||
},
|
||||
"dcrConfig": {
|
||||
"type": "object",
|
||||
"defaultValue": {
|
||||
"dataCollectionEndpoint": "data collection Endpoint",
|
||||
"dataCollectionRuleImmutableId": "[variables('_dataCollectionRuleImmutableId')]"
|
||||
}
|
||||
},
|
||||
"guidValue": {
|
||||
"type": "string",
|
||||
"defaultValue": "[[newGuid()]"
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"_dataConnectorContentId2": "[variables('_dataConnectorContentId2')]",
|
||||
"connectorName": "[[concat('GoogleSCC', parameters('guidValue'))]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"name": "[[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('connectorName'))]",
|
||||
"apiVersion": "2023-05-01-preview",
|
||||
"type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
|
||||
"location": "[parameters('workspace-location')]",
|
||||
"kind": "GCP",
|
||||
"properties": {
|
||||
"connectorDefinitionName": "[[parameters('connectorDefinitionName')]",
|
||||
"dcrConfig": {
|
||||
"streamName": "[variables('logAnalyticsTableId')]",
|
||||
"dataCollectionEndpoint": "[[parameters('dcrConfig').dataCollectionEndpoint]",
|
||||
"dataCollectionRuleImmutableId": "[[parameters('dcrConfig').dataCollectionRuleImmutableId]"
|
||||
},
|
||||
"dataType": "[variables('dataType')]",
|
||||
"auth": {
|
||||
"serviceAccountEmail": "[[parameters('GCPServiceAccountEmail')]",
|
||||
"projectNumber": "[[parameters('GCPProjectNumber')]",
|
||||
"workloadIdentityProviderId": "[[parameters('GCPWorkloadIdentityProviderId')]"
|
||||
},
|
||||
"request": {
|
||||
"projectId": "[[parameters('GCPProjectId')]",
|
||||
"subscriptionNames": [
|
||||
"[[parameters('GCPSubscriptionName')]"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
|
||||
"apiVersion": "2022-01-01-preview",
|
||||
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId2'),'/'))))]",
|
||||
"properties": {
|
||||
"parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectorDefinitions', variables('_dataConnectorContentId2'))]",
|
||||
"contentId": "[variables('_dataConnectorContentId2')]",
|
||||
"kind": "LogicAppsCustomConnector",
|
||||
"version": "[variables('dataConnectorVersion2')]",
|
||||
"source": {
|
||||
"kind": "Solution",
|
||||
"name": "Google Cloud Platform Security Command Center",
|
||||
"sourceId": "[variables('_solutionId')]"
|
||||
},
|
||||
"author": {
|
||||
"name": "Microsoft"
|
||||
},
|
||||
"support": {
|
||||
"name": "Microsoft Corporation",
|
||||
"email": "support@microsoft.com",
|
||||
"tier": "Microsoft",
|
||||
"link": "https://support.microsoft.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
|
||||
"apiVersion": "2022-01-01-preview",
|
||||
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('_solutionId'))]",
|
||||
"location": "[parameters('workspace-location')]",
|
||||
"properties": {
|
||||
"version": "2.0.0",
|
||||
"kind": "Solution",
|
||||
"contentSchemaVersion": "2.0.0",
|
||||
"contentId": "[variables('_solutionId')]",
|
||||
"parentId": "[variables('_solutionId')]",
|
||||
"source": {
|
||||
"kind": "Solution",
|
||||
"name": "Google Cloud Platform Security Command Center",
|
||||
"sourceId": "[variables('_solutionId')]"
|
||||
},
|
||||
"author": {
|
||||
"name": "Microsoft"
|
||||
},
|
||||
"support": {
|
||||
"name": "Microsoft Corporation",
|
||||
"email": "support@microsoft.com",
|
||||
"tier": "Microsoft",
|
||||
"link": "https://support.microsoft.com/"
|
||||
},
|
||||
"dependencies": {
|
||||
"operator": "AND",
|
||||
"criteria": [
|
||||
{
|
||||
"kind": "DataConnector",
|
||||
"contentId": "[variables('_dataConnectorContentId1')]",
|
||||
"version": "[variables('dataConnectorVersion1')]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"firstPublishDate": "2022-06-24",
|
||||
"providers": [
|
||||
"Microsoft"
|
||||
],
|
||||
"categories": {
|
||||
"domains": [
|
||||
"Cloud Provider"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": {}
|
||||
}
|
|
@ -5,28 +5,21 @@ import re
|
|||
import argparse
|
||||
import sys
|
||||
|
||||
SCRIPT_VERSION = 2.1
|
||||
SCRIPT_VERSION = 2.2
|
||||
PY3 = sys.version_info.major == 3
|
||||
|
||||
# GENERAL SCRIPT CONSTANTS
|
||||
DEFAULT_MACHINE_ENV = "Prod"
|
||||
LOG_OUTPUT_FILE = "/tmp/cef_troubleshooter_output_file.log"
|
||||
LOG_OUTPUT_FILE = "/tmp/troubleshooter_output_file.log"
|
||||
PATH_FOR_CSS_TICKET = {
|
||||
"Prod": "https://ms.portal.azure.com/#blade/Microsoft_Azure_Support/HelpAndSupportBlade/overview",
|
||||
"MK": "https://portal.azure.cn/#blade/Microsoft_Azure_Support/HelpAndSupportBlade/overview",
|
||||
"Gov": "https://portal.azure.us/#blade/Microsoft_Azure_Support/HelpAndSupportBlade/overview"}
|
||||
AGENT_CONF_FILE = "/etc/opt/microsoft/azuremonitoragent/config-cache/mdsd.hr.json"
|
||||
FAILED_TESTS_COUNT = 0
|
||||
STREAM_SCENARIO = "cef" # default value
|
||||
WARNING_TESTS_COUNT = 0
|
||||
NOT_RUN_TESTS_COUNT = 0
|
||||
SCRIPT_HELP_MESSAGE = "Usage: python cef_AMA_troubleshoot.py [OPTION]\n" \
|
||||
"Runs CEF validation tests on the collector machine and generates a log file here- /tmp/cef_troubleshooter_output_file.log\n\n" \
|
||||
" collect, runs the script in collect mode. Useful in case you want to open a ticket. Generates an output file here- /tmp/cef_troubleshooter_collection_output.log\n" \
|
||||
" -h, --help display the help and exit\n\n" \
|
||||
"Example:\n" \
|
||||
" python cef_AMA_troubleshoot.py\n" \
|
||||
" python cef_AMA_troubleshoot.py collect\n\n" \
|
||||
"This script verifies the installation of the CEF connector on the collector machine. It returns a status for each test and action items to fix detected issues."
|
||||
DELIMITER = "\n" + "-" * 20 + "\n"
|
||||
|
||||
|
||||
|
@ -66,6 +59,7 @@ class CommandShellExecution(object):
|
|||
"""
|
||||
This class is for executing all the shell related commands in the terminal for each test.
|
||||
"""
|
||||
|
||||
def __init__(self, command_name, command_to_run, result_keywords_array=None, fault_keyword=None,
|
||||
command_result=None,
|
||||
command_result_err=None):
|
||||
|
@ -111,11 +105,13 @@ class CommandVerification(CommandShellExecution):
|
|||
"""
|
||||
This class is running all the necessary verifications for the running test.
|
||||
"""
|
||||
|
||||
def __init__(self, command_name, command_to_run, result_keywords_array=None, fault_keyword=None,
|
||||
command_result=None,
|
||||
command_result_err=None,
|
||||
is_successful=False):
|
||||
super(CommandVerification, self).__init__(command_name, command_to_run, result_keywords_array, fault_keyword, command_result, command_result_err)
|
||||
super(CommandVerification, self).__init__(command_name, command_to_run, result_keywords_array, fault_keyword,
|
||||
command_result, command_result_err)
|
||||
self.is_successful = is_successful
|
||||
|
||||
def __repr__(self):
|
||||
|
@ -245,11 +241,13 @@ class AgentInstallationVerifications:
|
|||
AGENT_INSTALLATION_DOC = "https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-manage"
|
||||
AGENT_NOT_INSTALLED_ERROR_MESSAGE = "Could not detect an AMA service running and listening on the machine." \
|
||||
" Please follow this documentation in order to install it and verify your" \
|
||||
" machine's operating system is in the supported list- {}".format(AGENT_INSTALLATION_DOC)
|
||||
" machine's operating system is in the supported list- {}".format(
|
||||
AGENT_INSTALLATION_DOC)
|
||||
AGENT_NOT_RUNNING_ERROR_MESSAGE = "Detected AMA is installed on the machine but not running. Please start the agent by running " \
|
||||
"\'service azuremonitoragent start\' \nif the agent service fails to start," \
|
||||
" please run the following command to review the agent error log file here- " \
|
||||
"\'cat /var/opt/microsoft/azuremonitoragent/log/mdsd.err | tail -n 15\'".format(AGENT_INSTALLATION_DOC)
|
||||
"\'cat /var/opt/microsoft/azuremonitoragent/log/mdsd.err | tail -n 15\'".format(
|
||||
AGENT_INSTALLATION_DOC)
|
||||
|
||||
OMS_RUNNING_ERROR_MESSAGE = "Detected the OMS Agent running on your machine. If not necessary please remove it to avoid duplicated data in the workspace, which can result in an increase in costs"
|
||||
|
||||
|
@ -320,14 +318,16 @@ class DCRConfigurationVerifications:
|
|||
DCR_DOC = "https://docs.microsoft.com/azure/azure-monitor/agents/data-collection-rule-overview"
|
||||
DCRA_DOC = "https://docs.microsoft.com/rest/api/monitor/data-collection-rule-associations"
|
||||
CEF_STREAM_NAME = "SECURITY_CEF_BLOB"
|
||||
CISCO_STREAM_NAME = "SECURITY_CISCO_ASA_BLOB"
|
||||
STREAM_NAME = {"cef": CEF_STREAM_NAME, "asa": CISCO_STREAM_NAME}
|
||||
DCR_MISSING_ERR = "Could not detect any data collection rule on the machine. The data reaching this server will not be forwarded to any workspace." \
|
||||
" For explanation on how to install a Data collection rule please browse- {} \n " \
|
||||
"In order to read about how to associate a DCR to a machine please review- {}".format(DCR_DOC,
|
||||
DCRA_DOC)
|
||||
DCR_MISSING_CEF_STREAM_ERR = "Could not detect any data collection rule for CEF data. No CEF events will " \
|
||||
"be collected from this machine to any workspace. Please create a CEF DCR using the following documentation- " \
|
||||
DCR_MISSING_CEF_STREAM_ERR = "Could not detect any data collection rule for the provided datatype. No such events will " \
|
||||
"be collected from this machine to any workspace. Please create a DCR using the following documentation- " \
|
||||
"{} and run again".format(DCR_DOC)
|
||||
CEF_MULTI_HOMING_MESSAGE = "Detected multiple collection rules sending the CEF stream. This scenario is called multi-homing and might have effect on the agent's performance"
|
||||
MULTI_HOMING_MESSAGE = "Detected multiple collection rules sending the same stream. This scenario is called multi-homing and might have effect on the agent's performance"
|
||||
|
||||
def verify_dcr_exists(self):
|
||||
"""
|
||||
|
@ -343,14 +343,15 @@ class DCRConfigurationVerifications:
|
|||
return False
|
||||
return True
|
||||
|
||||
def verify_dcr_content_has_cef_stream(self):
|
||||
def verify_dcr_content_has_stream(self, dcr_stream):
|
||||
"""
|
||||
Verifying there is a DCR on the machine for forwarding cef data
|
||||
"""
|
||||
command_name = "verify_DCR_content_has_CEF_stream"
|
||||
global STREAM_SCENARIO
|
||||
command_name = "verify_DCR_content_has_stream"
|
||||
command_to_run = "sudo grep -ri \"{}\" /etc/opt/microsoft/azuremonitoragent/config-cache/configchunks/".format(
|
||||
self.CEF_STREAM_NAME)
|
||||
result_keywords_array = [self.CEF_STREAM_NAME]
|
||||
self.STREAM_NAME[dcr_stream])
|
||||
result_keywords_array = [self.STREAM_NAME[dcr_stream]]
|
||||
command_object = CommandVerification(command_name, command_to_run, result_keywords_array)
|
||||
command_object.run_full_test()
|
||||
if not command_object.is_successful:
|
||||
|
@ -358,13 +359,14 @@ class DCRConfigurationVerifications:
|
|||
return False
|
||||
return True
|
||||
|
||||
def verify_dcr_has_valid_content(self):
|
||||
def verify_dcr_has_valid_content(self, dcr_stream):
|
||||
"""
|
||||
Verifying that the CEF DCR on the machine has valid content with all necessary DCR components
|
||||
"""
|
||||
command_name = "verify_CEF_dcr_has_valid_content"
|
||||
global STREAM_SCENARIO
|
||||
command_name = "verify_dcr_has_valid_content"
|
||||
command_to_run = "sudo grep -ri \"{}\" /etc/opt/microsoft/azuremonitoragent/config-cache/configchunks/".format(
|
||||
self.CEF_STREAM_NAME)
|
||||
self.STREAM_NAME[dcr_stream])
|
||||
result_keywords_array = ["stream", "kind", "syslog", "dataSources", "configuration", "facilityNames",
|
||||
"logLevels", "SecurityInsights", "endpoint", "channels", "sendToChannels", "ods-",
|
||||
"opinsights.azure", "id"]
|
||||
|
@ -372,7 +374,8 @@ class DCRConfigurationVerifications:
|
|||
command_object.run_command(should_decode=False)
|
||||
command_object.command_result = command_object.command_result.decode('UTF-8').split('\n')[:-1]
|
||||
for dcr in command_object.command_result:
|
||||
dcr_path = re.search("(/etc/opt/microsoft/azuremonitoragent/config-cache/configchunks/.*.json)", str(dcr)).group()
|
||||
dcr_path = re.search("(/etc/opt/microsoft/azuremonitoragent/config-cache/configchunks/.*.json)",
|
||||
str(dcr)).group()
|
||||
for key_word in command_object.result_keywords_array:
|
||||
if str(key_word) not in str(dcr):
|
||||
command_object.is_command_successful(should_fail=True)
|
||||
|
@ -382,19 +385,20 @@ class DCRConfigurationVerifications:
|
|||
return False
|
||||
command_object.run_full_verification()
|
||||
|
||||
def check_cef_multi_homing(self):
|
||||
def check_multi_homing(self, dcr_stream):
|
||||
"""
|
||||
Counting the amount of DCRs forwarding CEF data in order to alert from multi-homing scenarios.
|
||||
"""
|
||||
command_name = "check_cef_multi_homing"
|
||||
global STREAM_SCENARIO
|
||||
command_name = "check_multi_homing"
|
||||
command_to_run = "sudo grep -ri \"{}\" /etc/opt/microsoft/azuremonitoragent/config-cache/configchunks/ | wc -l".format(
|
||||
self.CEF_STREAM_NAME)
|
||||
self.STREAM_NAME[dcr_stream])
|
||||
command_object = CommandVerification(command_name, command_to_run)
|
||||
command_object.run_command()
|
||||
try:
|
||||
if int(command_object.command_result) > 1:
|
||||
command_object.run_full_verification(should_fail=True)
|
||||
print_warning(self.CEF_MULTI_HOMING_MESSAGE)
|
||||
print_warning(self.MULTI_HOMING_MESSAGE)
|
||||
else:
|
||||
command_object.is_successful = True
|
||||
command_object.document_result()
|
||||
|
@ -406,18 +410,20 @@ class DCRConfigurationVerifications:
|
|||
"""
|
||||
This function is only called by main and runs all the tests in this class
|
||||
"""
|
||||
dcr_stream = 'asa' if STREAM_SCENARIO == 'ftd' else STREAM_SCENARIO
|
||||
if not self.verify_dcr_exists():
|
||||
return False
|
||||
if not self.verify_dcr_content_has_cef_stream():
|
||||
if not self.verify_dcr_content_has_stream(dcr_stream):
|
||||
return False
|
||||
self.verify_dcr_has_valid_content()
|
||||
self.check_cef_multi_homing()
|
||||
self.verify_dcr_has_valid_content(dcr_stream)
|
||||
self.check_multi_homing(dcr_stream)
|
||||
|
||||
|
||||
class SyslogDaemonVerifications:
|
||||
"""
|
||||
This class is for Syslog daemon related verifications
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.command_name = "verify_Syslog_daemon_listening"
|
||||
self.SYSLOG_DAEMON = ""
|
||||
|
@ -431,8 +437,10 @@ class SyslogDaemonVerifications:
|
|||
"""
|
||||
This function is in order to determine what Syslog daemon is running on the machine (Rsyslog or Syslog-ng)
|
||||
"""
|
||||
is_rsyslog_running = CommandVerification("find_Rsyslog_daemon", "if [ `ps -ef | grep rsyslog | grep -v grep | wc -l` -gt 0 ]; then echo \"True\"; else echo \"False\"; fi")
|
||||
is_syslog_ng_running = CommandVerification("find_Syslog-ng_daemon", "if [ `ps -ef | grep syslog-ng | grep -v grep | wc -l` -gt 0 ]; then echo \"True\"; else echo \"False\"; fi")
|
||||
is_rsyslog_running = CommandVerification("find_Rsyslog_daemon",
|
||||
"if [ `ps -ef | grep rsyslog | grep -v grep | wc -l` -gt 0 ]; then echo \"True\"; else echo \"False\"; fi")
|
||||
is_syslog_ng_running = CommandVerification("find_Syslog-ng_daemon",
|
||||
"if [ `ps -ef | grep syslog-ng | grep -v grep | wc -l` -gt 0 ]; then echo \"True\"; else echo \"False\"; fi")
|
||||
is_rsyslog_running.run_command(), is_syslog_ng_running.run_command()
|
||||
if "True" in str(is_rsyslog_running.command_result):
|
||||
self.SYSLOG_DAEMON = "rsyslog"
|
||||
|
@ -507,7 +515,8 @@ class OperatingSystemVerifications:
|
|||
SELINUX_DOCUMENTATION = "https://access.redhat.com/documentation/red_hat_enterprise_linux/8/html/using_selinux/changing-selinux-states-and-modes_using-selinux#changing-selinux-modes_changing-selinux-states-and-modes"
|
||||
SELINUX_RUNNING_ERROR_MESSAGE = "Detected SELinux running on the machine. The CEF connector does not support any form of hardening at the moment," \
|
||||
"and having SELinux in Enforcing mode can harm the forwarding of data. Please disable SELinux by running the command \'setenforce 0\'." \
|
||||
"This will disable SELinux temporarily. In order to disable permemently please follow this documentation- {}".format(SELINUX_DOCUMENTATION)
|
||||
"This will disable SELinux temporarily. In order to disable permemently please follow this documentation- {}".format(
|
||||
SELINUX_DOCUMENTATION)
|
||||
IPTABLES_BLOCKING_TRAFFIC_ERROR_MESSAGE = "Iptables might be blocking incoming traffic to the agent." \
|
||||
" Please verify there are no firewall rules blocking incoming traffic to port 514 and run again."
|
||||
FULL_DISK_ERROR_MESSAGE = "There is less than 1 GB of free disk space left on this machine." \
|
||||
|
@ -577,37 +586,40 @@ class IncomingEventsVerifications:
|
|||
"""
|
||||
# CONSTANTS
|
||||
FIXED_CEF_MESSAGE = "0|TestCommonEventFormat|MOCK|common=event-format-test|end|TRAFFIC|1|rt=$common=event-formatted-receive_time deviceExternalId=0002D01655 src=1.1.1.1 dst=2.2.2.2 sourceTranslatedAddress=1.1.1.1 destinationTranslatedAddress=3.3.3.3 cs1Label=Rule cs1=CEF_TEST_InternetDNS"
|
||||
FIXED_CISCO_MESSAGE = "Deny inbound TCP src inet:1.1.1.1 dst inet:2.2.2.2"
|
||||
FIXED_FTD_MESSAGE = "Teardown dynamic UDP translation from inside:10.51.100.1/54453 to outside:10.0.2.3/54453 duration 0:00:00"
|
||||
STREAM_MESSAGE = {"cef": FIXED_CEF_MESSAGE, "asa": FIXED_CISCO_MESSAGE, "ftd": FIXED_FTD_MESSAGE}
|
||||
IDENT_NAME = {"cef": "CEF", "asa": "%ASA-7-106010", 'ftd': "%FTD-6-305012"}
|
||||
TCPDUMP_NOT_INSTALLED_ERROR_MESSAGE = "Notice that \'tcpdump\' is not installed in your Linux machine.\nWe cannot monitor traffic without it.\nPlease install \'tcpdump\'."
|
||||
LOGGER_NOT_INSTALLED_ERROR_MESSAGE = "Warning: Could not execute \'logger\' command. This means that no mock message was sent to your workspace."
|
||||
CEF_EVENTS_FOUND_MESSAGE = "Found CEF events in stream. Please verify CEF events arrived at your workspace"
|
||||
CEF_EVENTS_NOT_FOUND_ERROR_MESSAGE = "Could not locate \"CEF\" message in tcpdump. Please verify CEF events can be sent to the machine and there is not firewall blocking incoming traffic"
|
||||
|
||||
@staticmethod
|
||||
def handle_tcpdump_line(line):
|
||||
def check_stream_in_line(line, ident):
|
||||
"""
|
||||
Validate there are incoming CEF events.
|
||||
Validate there are incoming events for the relevant stream.
|
||||
:param line: a text line from the tcpdump stream
|
||||
:return: True if CEF exists in the line. Otherwise, false.
|
||||
:param ident: The message tag to look for in the message line.
|
||||
:return: True if the stream exists in the line. Otherwise, false.
|
||||
"""
|
||||
if "CEF" in line:
|
||||
if ident in line:
|
||||
return True
|
||||
return False
|
||||
|
||||
def incoming_logs_validations(self, mock_message=False):
|
||||
"""
|
||||
Validate that there is incoming traffic of CEF messages
|
||||
Validate that there is incoming traffic of the stream type
|
||||
:param mock_message: Tells if to generate mock messages
|
||||
:return: True if successfully captured CEF events.
|
||||
:return: True if successfully captured events of the relevant stream.
|
||||
"""
|
||||
tcpdump_time_restriction = 10
|
||||
start_seconds = int(round(time.time()))
|
||||
end_seconds = int(round(time.time()))
|
||||
mock_message_counter = 0
|
||||
command_name = "listen_to_incoming_cef_events"
|
||||
command_to_run = "sudo tcpdump -A -ni any port 514 -vv"
|
||||
result_keywords_array = ["CEF"]
|
||||
command_name = "listen_to_incoming_events"
|
||||
command_to_run = "sudo tcpdump -A -l -ni any port 514 -vv"
|
||||
result_keywords_array = [STREAM_SCENARIO.upper()]
|
||||
command_object = CommandVerification(command_name, command_to_run, result_keywords_array)
|
||||
print("Attempting to capture CEF events using tcpdump. This could take up to " + str(
|
||||
print("Attempting to capture events using tcpdump. This could take up to " + str(
|
||||
tcpdump_time_restriction) + " seconds.")
|
||||
tcp_dump = subprocess.Popen(command_object.command_to_run, shell=True, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
|
@ -621,25 +633,27 @@ class IncomingEventsVerifications:
|
|||
poll_obj = select.poll()
|
||||
poll_obj.register(tcp_dump.stdout, select.POLLIN)
|
||||
while (end_seconds - start_seconds) < tcpdump_time_restriction:
|
||||
if mock_message is True:
|
||||
if mock_message and mock_message_counter < 10:
|
||||
# Sending mock messages
|
||||
mock_message_counter += 1
|
||||
self.send_cef_message_local(514, 1)
|
||||
self.send_message_local(514, 1)
|
||||
poll_result = poll_obj.poll(0)
|
||||
if poll_result:
|
||||
line = str(tcp_dump.stdout.readline().decode('utf-8').strip("\n"))
|
||||
if self.handle_tcpdump_line(line):
|
||||
line = tcp_dump.stdout.readline().decode('utf-8').strip("\n")
|
||||
if self.check_stream_in_line(line, STREAM_SCENARIO.upper()):
|
||||
command_object.command_result = line
|
||||
command_object.run_full_verification()
|
||||
print_ok(self.CEF_EVENTS_FOUND_MESSAGE)
|
||||
print_ok("Found {0} in stream. Please verify {0} events arrived at your workspace".format(
|
||||
STREAM_SCENARIO.upper()))
|
||||
return True
|
||||
end_seconds = int(round(time.time()))
|
||||
print_error(self.CEF_EVENTS_NOT_FOUND_ERROR_MESSAGE)
|
||||
print_error("Could not locate {0} message in tcpdump. Please verify {0} events can be sent to the machine and"
|
||||
" there is not firewall blocking incoming traffic".format(STREAM_SCENARIO.upper()))
|
||||
command_object.command_result = str(line)
|
||||
command_object.run_full_verification()
|
||||
return False
|
||||
|
||||
def send_cef_message_local(self, port, amount):
|
||||
def send_message_local(self, port, amount):
|
||||
"""
|
||||
Generate local CEF events in a given amount to a given port
|
||||
:param port: A destination port to send the events
|
||||
|
@ -647,13 +661,12 @@ class IncomingEventsVerifications:
|
|||
"""
|
||||
try:
|
||||
for index in range(0, amount):
|
||||
command_tokens = ["logger", "-p", "local4.warn", "-t", "CEF:", self.FIXED_CEF_MESSAGE, "-P", str(port),
|
||||
"-n",
|
||||
"127.0.0.1"]
|
||||
command_tokens = ["logger", "-p", "local4.warn", "-t", self.IDENT_NAME[STREAM_SCENARIO],
|
||||
self.STREAM_MESSAGE[STREAM_SCENARIO], "--rfc3164", "-P", str(port), "-n", "127.0.0.1"]
|
||||
logger = subprocess.Popen(command_tokens, stdout=subprocess.PIPE)
|
||||
o, e = logger.communicate()
|
||||
if e is not None:
|
||||
print("Error could not send cef mock message")
|
||||
print("Error could not send mock message")
|
||||
except OSError:
|
||||
print(self.LOGGER_NOT_INSTALLED_ERROR_MESSAGE)
|
||||
|
||||
|
@ -662,7 +675,7 @@ class IncomingEventsVerifications:
|
|||
This function is only called by main and runs all the tests in this class
|
||||
"""
|
||||
if not self.incoming_logs_validations():
|
||||
print_notice("Generating CEF mock events and trying again")
|
||||
print_notice("\nGenerating mock events and trying again")
|
||||
self.incoming_logs_validations(mock_message=True)
|
||||
|
||||
|
||||
|
@ -713,7 +726,8 @@ class SystemInfo:
|
|||
command_object.command_result) + DELIMITER).replace(
|
||||
'%', '%%').replace('\\n', '\n')
|
||||
|
||||
def trace_activation(self):
|
||||
@staticmethod
|
||||
def trace_activation():
|
||||
flag = '-T 0x1002'
|
||||
file_path = '/etc/default/azuremonitoragent'
|
||||
# Check if the flag already exists
|
||||
|
@ -783,28 +797,48 @@ def find_dcr_cloud_environment():
|
|||
return DEFAULT_MACHINE_ENV
|
||||
|
||||
|
||||
def getargs(should_print=True):
|
||||
def getargs():
|
||||
"""
|
||||
Get execution args using argparse lib
|
||||
"""
|
||||
parser = argparse.ArgumentParser(description=SCRIPT_HELP_MESSAGE)
|
||||
parser.add_argument('collect', nargs='?', help='Collect syslog message samples to file')
|
||||
# parser.add_argument('--CEF', '--cef', action='store_true', default=False, help='Validate CEF DCR and events')
|
||||
# parser.add_argument('--ASA', '--asa', action='store_true', default=False, help='Validate Cisco ASA DCR and events')
|
||||
global STREAM_SCENARIO
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('collect', nargs='?',
|
||||
help='runs the script in collect mode. Useful in case you want to open a ticket.')
|
||||
parser.add_argument('--CEF', '--cef', action='store_true', default=False,
|
||||
help='run the troubleshooting script for the CEF scenario.')
|
||||
parser.add_argument('--ASA', '--asa', action='store_true', default=False,
|
||||
help='run the troubleshooting script for the Cisco ASA scenario.')
|
||||
parser.add_argument('--FTD', '--ftd', action='store_true', default=False,
|
||||
help='run the troubleshooting script for the Cisco FTD scenario.')
|
||||
args = parser.parse_args()
|
||||
if should_print:
|
||||
for arg in vars(args):
|
||||
if getattr(args, arg):
|
||||
print_notice(arg)
|
||||
print('\n')
|
||||
if args.ASA:
|
||||
STREAM_SCENARIO = "asa"
|
||||
elif args.FTD:
|
||||
STREAM_SCENARIO = "ftd"
|
||||
else:
|
||||
STREAM_SCENARIO = "cef"
|
||||
return args
|
||||
|
||||
|
||||
def print_scenario(args):
|
||||
"""
|
||||
param: args: the arguments returned from the getargs function
|
||||
"""
|
||||
if list(vars(args).values()).count(True) > 1:
|
||||
print_error("More than 1 stream provided. Please run the script again with only one scenario.\n"
|
||||
"For more information run 'python Sentinel_AMA_troubleshoot.py -h'. Exiting.")
|
||||
sys.exit(1)
|
||||
else:
|
||||
print_notice("The scenario chosen is: {}".format(STREAM_SCENARIO.upper()))
|
||||
|
||||
|
||||
def main():
|
||||
args = getargs()
|
||||
verify_root_privileges()
|
||||
subprocess.Popen(['rm', '-f', LOG_OUTPUT_FILE],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
|
||||
print_scenario(args)
|
||||
if args.collect:
|
||||
print_notice("Starting to collect data. This may take a couple of seconds")
|
||||
machine_env = find_dcr_cloud_environment()
|
||||
|
@ -812,7 +846,8 @@ def main():
|
|||
system_info = SystemInfo()
|
||||
system_info.handle_commands()
|
||||
print(
|
||||
"Finished collecting data \nIn order to open a support case please browse: {}".format(PATH_FOR_CSS_TICKET[machine_env]))
|
||||
"Finished collecting data \nIn order to open a support case please browse: {}".format(
|
||||
PATH_FOR_CSS_TICKET[machine_env]))
|
||||
with open(LOG_OUTPUT_FILE, 'a') as file:
|
||||
file.write('*' * 10 + 'FINISHED COLLECTION' + '*' * 10)
|
||||
time.sleep(1)
|
||||
|
@ -823,7 +858,7 @@ def main():
|
|||
(SyslogDaemonVerifications(), "Starting validation tests for the Syslog daemon"),
|
||||
(OperatingSystemVerifications(), "Starting validation tests for the operating system"),
|
||||
(IncomingEventsVerifications(), "Starting validation tests for capturing incoming events")]
|
||||
print_notice("\nStarting to run the CEF validation script")
|
||||
print_notice("\nStarting to run the validation script for the {} scenario".format(STREAM_SCENARIO))
|
||||
time.sleep(1)
|
||||
print_notice("Please validate you are sending CEF messages to the agent machine")
|
||||
for class_test in class_tests_array:
|
||||
|
@ -839,11 +874,12 @@ def main():
|
|||
else:
|
||||
print_ok("All tests passed successfully")
|
||||
print_notice("This script generated an output file located here - {}"
|
||||
"\nPlease review it if you would like to get more information on failed tests.".format(LOG_OUTPUT_FILE))
|
||||
"\nPlease review it if you would like to get more information on failed tests.".format(
|
||||
LOG_OUTPUT_FILE))
|
||||
if not args.collect:
|
||||
print_notice(
|
||||
"\nIf you would like to open a support case please run this script with the \'collect\' feature flag in order to collect additional system data for troubleshooting."
|
||||
"\'python cef_AMA_troubleshoot.py collect\'")
|
||||
"\'python Sentinel_AMA_troubleshoot.py [STREAM_OPTION] collect\'")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
|
@ -0,0 +1,81 @@
|
|||
{
|
||||
"id": "DATA CONNECTOR ID",
|
||||
"title": "DATA CONNECTOR TITLE",
|
||||
"publisher": "PROVIDER NAME",
|
||||
"descriptionMarkdown": "Use this template if you want to use Upload Indicators REST API to push indicators into Azure Sentinel Threat Intelligence. Please replace the PLACEHOLDERS.",
|
||||
"graphQueries": [
|
||||
{
|
||||
"metricName": "Total indicators received",
|
||||
"legend": "Connection Events",
|
||||
"baseQuery": "ThreatIntelligenceIndicator | where SourceSystem == 'PROVIDER SOURCE SYSTEM NAME'"
|
||||
}
|
||||
],
|
||||
"sampleQueries": [
|
||||
{
|
||||
"description": "All Threat Intelligence APIs Indicators",
|
||||
"query": "ThreatIntelligenceIndicator | where SourceSystem == 'PROVIDER SOURCE SYSTEM NAME'| sort by TimeGenerated desc"
|
||||
}
|
||||
],
|
||||
"dataTypes": [
|
||||
{
|
||||
"name": "ThreatIntelligenceIndicator",
|
||||
"lastDataReceivedQuery": "ThreatIntelligenceIndicator| where isnotempty(TimeGenerated) and SourceSystem == 'PROVIDER SOURCE SYSTEM NAME' | summarize Time = max(TimeGenerated)"
|
||||
}
|
||||
],
|
||||
"connectivityCriteria": [
|
||||
{
|
||||
"type": "IsConnectedQuery",
|
||||
"value": [
|
||||
"ThreatIntelligenceIndicator| where SourceSystem == 'PROVIDER SOURCE SYSTEM NAME' | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"availability": {
|
||||
"status": 1,
|
||||
"isPreview": true
|
||||
},
|
||||
"permissions": {
|
||||
"resourceProvider": [
|
||||
{
|
||||
"provider": "Microsoft.SecurityInsights/threatintelligence/write",
|
||||
"permissionsDisplayText": "write permissions are required.",
|
||||
"providerDisplayName": "Workspace",
|
||||
"scope": "Workspace",
|
||||
"requiredPermissions": {
|
||||
"write": true,
|
||||
"read": true,
|
||||
"delete": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"instructionSteps": [
|
||||
{
|
||||
"title": "You can connect your threat intelligence data sources to Microsoft Sentinel by either: ",
|
||||
"description": "\n>Using an integrated Threat Intelligence Platform (TIP), such as Threat Connect, Palo Alto Networks MineMeld, MISP, and others. \n\n>Calling the Microsoft Sentinel data plane API directly from another application. "
|
||||
},
|
||||
{
|
||||
"title": "Follow These Steps to Connect to your Threat Intelligence: ",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"title": "1. Get AAD Access Token",
|
||||
"description": "To send request to the APIs, you need to acquire Azure Active Directory access token. You can follow instruction in this page: https://docs.microsoft.com/azure/databricks/dev-tools/api/latest/aad/app-aad-token#get-an-azure-ad-access-token \n - Notice: Please request AAD access token with scope value: https://management.azure.com/.default "
|
||||
},
|
||||
{
|
||||
"title": "2. Send indicators to Sentinel",
|
||||
"description": "You can send indicators by calling our Upload Indicators API. For more information about the API, click here. \n\n>HTTP method: POST \n\n>Endpoint: https://sentinelus.azure-api.net/workspaces/{WORKSPACEID}/threatintelligenceindicators:upload?api-version=2022-07-01 \n\n>WORKSPACEID: the workspace that the indicators are uploaded to (can be copied from the following). \n\n\n>Header Value 1: \"Authorization\" = \"Bearer [AAD Access Token from step 1]\" \n\n\n> Header Value 2: \"Content-Type\" = \"application/json\" \n \n>Body: The body is a JSON object containing an array of indicators in STIX format. For more information about the API, click here",
|
||||
"instructions":[
|
||||
{
|
||||
"parameters": {
|
||||
"fillWith": [
|
||||
"WorkspaceId"
|
||||
],
|
||||
"label": "Workspace ID"
|
||||
},
|
||||
"type": "CopyableLabel"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
# Connect \<Provider Name\> Upload Indicators API to Microsoft Sentinel
|
||||
|
||||
Partners (Providers) can use Connector_UploadIndicatorsAPI_template.json template to create a customized Upload Indicators API data connector for partners' solution.
|
||||
|
||||
Please replace the following placeholders in the template:
|
||||
- DATA CONNECTOR ID: The id of the data connector. It will be used to differential with other data connectors.
|
||||
- DATA CONNECTOR TITLE: The title of the data connector which will be shown in UI.
|
||||
- PROVIDER NAME: Name of the partners. This will be used as the publisher of the data connector
|
||||
- PROVIDER SOURCE SYSTEM NAME: The source system of the indicators sent to Microsoft Sentinel.
|
||||
|
||||
On top of the placeholders, partners can customize the instruction steps. For more information about Codeless Data Connector, please visit this page: https://learn.microsoft.com/azure/sentinel/create-codeless-connector?tabs=deploy-via-arm-template%2Cconnect-via-the-azure-portal
|
|
@ -23,8 +23,8 @@ Install the microsoft-logstash-output-azure-loganalytics, use [Logstash Working
|
|||
For offline setup follow [Logstash Offline Plugin Management instruction](<https://www.elastic.co/guide/en/logstash/current/offline-plugins.html>).
|
||||
|
||||
This plugin supports the following versions
|
||||
- Logstash 7 Between 7.0 and 7.17.6
|
||||
- Logstash 8 Between 8.0 and 8.4.2
|
||||
- Logstash 7 Between 7.0 and 7.17.10
|
||||
- Logstash 8 Between 8.0 and 8.8.1
|
||||
|
||||
Please note that when using Logstash 8, it is recommended to disable ECS in pipeline. For more information refer to [Logstash documentation.](<https://www.elastic.co/guide/en/logstash/8.4/ecs-ls.html>)
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@ Microsoft Sentinel provides Logstash output plugin to Log analytics workspace us
|
|||
Install the microsoft-sentinel-logstash-output-plugin, use [Logstash Offline Plugin Management instruction](<https://www.elastic.co/guide/en/logstash/current/offline-plugins.html>).
|
||||
|
||||
Microsoft Sentinel's Logstash output plugin supports the following versions
|
||||
- Logstash 7 Between 7.0 and 7.17.6
|
||||
- Logstash 8 Between 8.0 and 8.4.2
|
||||
- Logstash 7 Between 7.0 and 7.17.10
|
||||
- Logstash 8 Between 8.0 and 8.8.1
|
||||
|
||||
Please note that when using Logstash 8, it is recommended to disable ECS in the pipeline. For more information refer to [Logstash documentation.](<https://www.elastic.co/guide/en/logstash/8.4/ecs-ls.html>)
|
||||
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
id: b185ac23-dc27-4573-8192-1134c7a95f4f
|
||||
name: Dynamics Encryption Settings Changed
|
||||
description: |
|
||||
'This query looks for changes to the Data Encryption settings for Dynamics 365.
|
||||
Reference: https://docs.microsoft.com/microsoft-365/compliance/office-365-encryption-in-microsoft-dynamics-365'
|
||||
severity: Medium
|
||||
status: Available
|
||||
requiredDataConnectors:
|
||||
- connectorId: Dynamics365
|
||||
dataTypes:
|
||||
- Dynamics365Activity
|
||||
queryFrequency: 1h
|
||||
queryPeriod: 1h
|
||||
triggerOperator: gt
|
||||
triggerThreshold: 0
|
||||
tactics:
|
||||
- DefenseEvasion
|
||||
relevantTechniques:
|
||||
- T1600
|
||||
query: |
|
||||
Dynamics365Activity
|
||||
| extend Message = tostring(split(OriginalObjectId, ' ')[0])
|
||||
| where Message =~ 'IsDataEncryptionActive'
|
||||
| project-reorder TimeGenerated, Message, UserId, ClientIP, InstanceUrl, UserAgent
|
||||
| extend timestamp = TimeGenerated, AccountCustomEntity = UserId, IPCustomEntity = ClientIP
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
||||
- entityType: IP
|
||||
fieldMappings:
|
||||
- identifier: Address
|
||||
columnName: IPCustomEntity
|
||||
version: 1.0.1
|
||||
kind: Scheduled
|
||||
metadata:
|
||||
source:
|
||||
kind: Community
|
||||
author:
|
||||
name: Microsoft
|
||||
support:
|
||||
tier: Microsoft
|
||||
categories:
|
||||
domains: ["Cloud Provider","IT Operations","Storage"]
|
|
@ -1,64 +0,0 @@
|
|||
id: 05eca115-c4b5-48e4-ba6e-07db57695be2
|
||||
name: Mass Export of Dynamics 365 Records to Excel
|
||||
description: |
|
||||
'The query detects user exporting a large amount of records from Dynamics 365 to Excel, significantly more records exported than any other recent activity by that user.'
|
||||
severity: Medium
|
||||
status: Available
|
||||
requiredDataConnectors:
|
||||
- connectorId: Dynamics365
|
||||
dataTypes:
|
||||
- Dynamics365Activity
|
||||
queryFrequency: 1d
|
||||
queryPeriod: 7d
|
||||
triggerOperator: gt
|
||||
triggerThreshold: 0
|
||||
tactics:
|
||||
- Collection
|
||||
relevantTechniques:
|
||||
- T1530
|
||||
query: |
|
||||
let baseline_time = 7d;
|
||||
let detection_time = 1d;
|
||||
Dynamics365Activity
|
||||
| where TimeGenerated between(ago(baseline_time)..ago(detection_time-1d))
|
||||
| where OriginalObjectId contains 'ExportToExcel'
|
||||
| extend numQueryCount = todouble(QueryResults)
|
||||
| extend QueryCount = iif(QueryResults contains ",", todouble(countof(tostring(QueryResults), ',') + 1), numQueryCount)
|
||||
| extend QueryCount = iif(isnotempty(QueryCount), QueryCount, double(1))
|
||||
| summarize sum(QueryCount) by UserId
|
||||
| extend HistoricalBaseline = sum_QueryCount
|
||||
| join (Dynamics365Activity
|
||||
| where TimeGenerated > ago(detection_time)
|
||||
| where OriginalObjectId contains 'ExportToExcel'
|
||||
| extend numQueryCount = todouble(QueryResults)
|
||||
| extend QueryCount = iif(QueryResults contains ",", todouble(countof(tostring(QueryResults), ',') + 1), numQueryCount)
|
||||
| extend QueryCount = iif(isnotempty(QueryCount), QueryCount, double(1))
|
||||
| summarize sum(QueryCount) by UserId
|
||||
| extend CurrentExportRate = sum_QueryCount) on UserId
|
||||
| where CurrentExportRate > HistoricalBaseline
|
||||
| project UserId, HistoricalBaseline, CurrentExportRate
|
||||
| join kind=inner(Dynamics365Activity
|
||||
| where TimeGenerated > ago(detection_time)
|
||||
| where OriginalObjectId contains 'ExportToExcel'
|
||||
| extend numQueryCount = todouble(QueryResults)
|
||||
| extend QueryCount = iif(QueryResults contains ",", todouble(countof(tostring(QueryResults), ',') + 1), numQueryCount)
|
||||
| extend QueryCount = iif(isnotempty(QueryCount), QueryCount, double(1))) on UserId
|
||||
| project TimeGenerated, UserId, QueryCount, UserAgent, OriginalObjectId, ClientIP, HistoricalBaseline, CurrentExportRate, CorrelationId, CrmOrganizationUniqueName
|
||||
| summarize QuerySizes = make_set(QueryCount), MostRecentQuery = max(TimeGenerated), IPs = make_set(ClientIP), UserAgents = make_set(UserAgent) by UserId, CrmOrganizationUniqueName, HistoricalBaseline, CurrentExportRate
|
||||
| extend timestamp = MostRecentQuery, AccountCustomEntity = UserId
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
||||
version: 1.0.1
|
||||
kind: Scheduled
|
||||
metadata:
|
||||
source:
|
||||
kind: Community
|
||||
author:
|
||||
name: Microsoft
|
||||
support:
|
||||
tier: Microsoft
|
||||
categories:
|
||||
domains: ["Cloud Provider","IT Operations","Storage"]
|
|
@ -1,49 +0,0 @@
|
|||
id: e147e4dc-849c-49e9-9e8b-db4581951ff4
|
||||
name: New Dynamics 365 Admin Activity
|
||||
description: |
|
||||
'Detects users conducting administrative activity in Dynamics 365 where they have not had admin rights before.'
|
||||
severity: Low
|
||||
status: Available
|
||||
requiredDataConnectors:
|
||||
- connectorId: Dynamics365
|
||||
dataTypes:
|
||||
- Dynamics365Activity
|
||||
queryFrequency: 1d
|
||||
queryPeriod: 14d
|
||||
triggerOperator: gt
|
||||
triggerThreshold: 0
|
||||
tactics:
|
||||
- InitialAccess
|
||||
relevantTechniques:
|
||||
- T1078
|
||||
query: |
|
||||
let baseline_time = 14d;
|
||||
let detection_time = 1h;
|
||||
Dynamics365Activity
|
||||
| where TimeGenerated between(ago(baseline_time)..ago(detection_time))
|
||||
| where UserType =~ 'admin'
|
||||
| extend Message = tostring(split(OriginalObjectId, ' ')[0])
|
||||
| summarize by UserId
|
||||
| join kind=rightanti
|
||||
(Dynamics365Activity
|
||||
| where TimeGenerated > ago(detection_time)
|
||||
| where UserType =~ 'admin')
|
||||
on UserId
|
||||
| summarize Actions = make_set(Message), MostRecentAction = max(TimeGenerated), IPs=make_set(ClientIP), UserAgents = make_set(UserAgent) by UserId
|
||||
| extend timestamp = MostRecentAction, AccountCustomEntity = UserId
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
||||
version: 1.0.1
|
||||
kind: Scheduled
|
||||
metadata:
|
||||
source:
|
||||
kind: Community
|
||||
author:
|
||||
name: Microsoft
|
||||
support:
|
||||
tier: Microsoft
|
||||
categories:
|
||||
domains: ["Cloud Provider","IT Operations","Storage"]
|
|
@ -1,57 +0,0 @@
|
|||
id: 8ec3a7f9-9f55-4be3-aeb6-9188f91b278e
|
||||
name: New Dynamics 365 User Agent
|
||||
description: |
|
||||
'Detects users accessing Dynamics from a User Agent that has not been seen the 14 days. Has configurable filter for known good user agents such as PowerApps. Also includes optional section to exclude User Agents to indicate a browser being used.'
|
||||
severity: Low
|
||||
status: Available
|
||||
requiredDataConnectors:
|
||||
- connectorId: Dynamics365
|
||||
dataTypes:
|
||||
- Dynamics365Activity
|
||||
queryFrequency: 1d
|
||||
queryPeriod: 14d
|
||||
triggerOperator: gt
|
||||
triggerThreshold: 0
|
||||
tactics:
|
||||
- InitialAccess
|
||||
relevantTechniques:
|
||||
- T1078
|
||||
query: |
|
||||
let lookback = 14d;
|
||||
let timeframe = 1d;
|
||||
let user_accounts = "(([a-zA-Z]{1,})\\.([a-zA-Z]{1,}))@.*";
|
||||
let known_useragents = dynamic([]);
|
||||
Dynamics365Activity
|
||||
| where TimeGenerated between(ago(lookback)..ago(timeframe))
|
||||
| where isnotempty(UserAgent)
|
||||
| summarize by UserAgent, UserId
|
||||
| join kind = rightanti (Dynamics365Activity
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where isnotempty(UserAgent)
|
||||
| where UserAgent !in~ (known_useragents)
|
||||
| where UserAgent !hasprefix "azure-logic-apps" and UserAgent !hasprefix "PowerApps"
|
||||
| where UserId matches regex user_accounts)
|
||||
on UserAgent, UserId
|
||||
// Uncomment this section to exclude user agents with a rendering engine, indicating browsers.
|
||||
//| join kind = leftanti(
|
||||
//Dynamics365Activity
|
||||
//| where TimeGenerated between(ago(lookback)..ago(timeframe))
|
||||
//| where UserAgent has_any ("Gecko", "WebKit", "Presto", "Trident", "EdgeHTML", "Blink")) on UserAgent
|
||||
| summarize FirstSeen = min(TimeGenerated), IPs = make_set(ClientIP) by UserAgent, UserId
|
||||
| extend timestamp = FirstSeen, AccountCustomEntity = UserId
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
||||
version: 1.0.1
|
||||
kind: Scheduled
|
||||
metadata:
|
||||
source:
|
||||
kind: Community
|
||||
author:
|
||||
name: Microsoft
|
||||
support:
|
||||
tier: Microsoft
|
||||
categories:
|
||||
domains: ["Cloud Provider","IT Operations","Storage"]
|
|
@ -1,48 +0,0 @@
|
|||
id: 572f3951-5fa3-4e42-9640-fe194d859419
|
||||
name: New Office User Agent in Dynamics 365
|
||||
description: |
|
||||
'Detects users accessing Dynamics from a User Agent that has not been seen in any Office 365 workloads in the last 7 days. Has configurable filter for known good user agents such as PowerApps.'
|
||||
severity: Low
|
||||
status: Available
|
||||
requiredDataConnectors:
|
||||
- connectorId: Dynamics365
|
||||
dataTypes:
|
||||
- Dynamics365Activity
|
||||
queryFrequency: 1d
|
||||
queryPeriod: 7d
|
||||
triggerOperator: gt
|
||||
triggerThreshold: 0
|
||||
tactics:
|
||||
- InitialAccess
|
||||
relevantTechniques:
|
||||
- T1078
|
||||
query: |
|
||||
let timeframe = 1h;
|
||||
let lookback = 7d;
|
||||
let known_useragents = dynamic([]);
|
||||
Dynamics365Activity
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| extend Message = tostring(split(OriginalObjectId, ' ')[0])
|
||||
| where Message =~ "UserSignIn"
|
||||
| extend IPAddress = tostring(split(ClientIP, ":")[0])
|
||||
| where isnotempty(UserAgent)
|
||||
// Exclude user agents with a render agent to reduce noise
|
||||
| where UserAgent has_any ("Gecko", "WebKit", "Presto", "Trident", "EdgeHTML", "Blink")
|
||||
| join kind=leftanti(
|
||||
OfficeActivity
|
||||
| where TimeGenerated > ago(lookback)
|
||||
| where UserAgent !in~ (known_useragents))
|
||||
on UserAgent
|
||||
| summarize MostRecentActivity=max(TimeGenerated), IPs=make_set(IPAddress), Users=make_set(UserId), Actions=make_set(OriginalObjectId) by UserAgent
|
||||
| extend timestamp = MostRecentActivity
|
||||
version: 1.0.1
|
||||
kind: Scheduled
|
||||
metadata:
|
||||
source:
|
||||
kind: Community
|
||||
author:
|
||||
name: Microsoft
|
||||
support:
|
||||
tier: Microsoft
|
||||
categories:
|
||||
domains: ["Cloud Provider","IT Operations","Storage"]
|
|
@ -1,67 +0,0 @@
|
|||
id: 93a25f10-593d-4c57-a752-a8a75f031425
|
||||
name: Dynamics 365 - User Bulk Retrieval Outside Normal Activity
|
||||
description: |
|
||||
'This query detects users retrieving significantly more records from Dynamics 365 than they have in the past 2 weeks. This could indicate potentially unauthorized access to data within Dynamics 365.'
|
||||
severity: Medium
|
||||
status: Available
|
||||
requiredDataConnectors:
|
||||
- connectorId: Dynamics365
|
||||
dataTypes:
|
||||
- Dynamics365Activity
|
||||
queryFrequency: 1d
|
||||
queryPeriod: 14d
|
||||
triggerOperator: gt
|
||||
triggerThreshold: 0
|
||||
tactics:
|
||||
- Collection
|
||||
relevantTechniques:
|
||||
- T1530
|
||||
query: |
|
||||
let baseline_time = 14d;
|
||||
let detection_time = 1d;
|
||||
Dynamics365Activity
|
||||
| where TimeGenerated between(ago(baseline_time)..ago(detection_time-1d))
|
||||
| extend Message = tostring(split(OriginalObjectId, ' ')[0])
|
||||
| where Message =~ "RetrieveMultiple"
|
||||
| extend numQueryCount = todouble(QueryResults)
|
||||
| extend QueryCount = iif(QueryResults contains ",", todouble(countof(tostring(QueryResults), ',') + 1), numQueryCount)
|
||||
| extend QueryCount = iif(isnotempty(QueryCount), QueryCount, double(1))
|
||||
| summarize sum(QueryCount) by UserId
|
||||
| extend HistoricalBaseline = sum_QueryCount
|
||||
| join (Dynamics365Activity
|
||||
| where TimeGenerated > ago(detection_time)
|
||||
| extend Message = tostring(split(OriginalObjectId, ' ')[0])
|
||||
| where Message =~ "RetrieveMultiple"
|
||||
| extend numQueryCount = todouble(QueryResults)
|
||||
| extend QueryCount = iif(QueryResults contains ",", todouble(countof(tostring(QueryResults), ',') + 1), numQueryCount)
|
||||
| extend QueryCount = iif(isnotempty(QueryCount), QueryCount, double(1))
|
||||
| summarize sum(QueryCount) by UserId
|
||||
| extend CurrentExportRate = sum_QueryCount) on UserId
|
||||
| where CurrentExportRate > HistoricalBaseline
|
||||
| project UserId, HistoricalBaseline, CurrentExportRate
|
||||
| join kind=inner(Dynamics365Activity
|
||||
| where TimeGenerated > ago(detection_time)
|
||||
| extend Message = tostring(split(OriginalObjectId, ' ')[0])
|
||||
| where Message =~ "RetrieveMultiple"
|
||||
| extend numQueryCount = todouble(QueryResults)
|
||||
| extend QueryCount = iif(QueryResults contains ",", todouble(countof(tostring(QueryResults), ',') + 1), numQueryCount)
|
||||
| extend QueryCount = iif(isnotempty(QueryCount), QueryCount, double(1))) on UserId
|
||||
| project TimeGenerated, UserId, QueryCount, UserAgent, Message, ClientIP, HistoricalBaseline, CurrentExportRate, CorrelationId, CrmOrganizationUniqueName, Query
|
||||
| summarize QuerySizes = make_set(QueryCount), MostRecentQuery = max(TimeGenerated), IPs = make_set(ClientIP), UserAgents = make_set(UserAgent), make_set(Query) by UserId, CrmOrganizationUniqueName, HistoricalBaseline, CurrentExportRate
|
||||
| extend timestamp = MostRecentQuery, AccountCustomEntity = UserId
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
||||
version: 1.0.1
|
||||
kind: Scheduled
|
||||
metadata:
|
||||
source:
|
||||
kind: Community
|
||||
author:
|
||||
name: Microsoft
|
||||
support:
|
||||
tier: Microsoft
|
||||
categories:
|
||||
domains: ["Cloud Provider","IT Operations","Storage"]
|
|
@ -1,10 +1,10 @@
|
|||
id: ef895ada-e8e8-4cf0-9313-b1ab67fab69f
|
||||
name: Authentication Attempt from New Country
|
||||
description: |
|
||||
'Detects when there is a log in attempt from a country that has not seen a successful login in the previous 14 days.
|
||||
Threat actors may attempt to authenticate with credentials from compromised accounts - monitoring attempts from anomalous locations may help identify these attempts.
|
||||
Authentication attempts should be investigated to ensure the activity was legitimate and if there is other similar activity.
|
||||
Ref: https://docs.microsoft.com/azure/active-directory/fundamentals/security-operations-user-accounts#monitoring-for-failed-unusual-sign-ins'
|
||||
Detects when there is a login attempt from a country that has not seen a successful login in the previous 14 days.
|
||||
Threat actors may attempt to authenticate with credentials from compromised accounts - monitoring attempts from anomalous locations may help identify these attempts.
|
||||
Authentication attempts should be investigated to ensure the activity was legitimate and if there is other similar activity.
|
||||
Ref: https://docs.microsoft.com/azure/active-directory/fundamentals/security-operations-user-accounts#monitoring-for-failed-unusual-sign-ins
|
||||
severity: Medium
|
||||
requiredDataConnectors:
|
||||
- connectorId: AzureActiveDirectory
|
||||
|
@ -22,38 +22,79 @@ relevantTechniques:
|
|||
tags:
|
||||
- AADSecOpsGuide
|
||||
query: |
|
||||
let known_locations =
|
||||
union isfuzzy=True AADNonInteractiveUserSignInLogs, SigninLogs
|
||||
| where TimeGenerated between(ago(14d)..ago(1d))
|
||||
let CombinedSignInLogs = union isfuzzy=True AADNonInteractiveUserSignInLogs, SigninLogs;
|
||||
// Combine AADNonInteractiveUserSignInLogs and SigninLogs into a single table
|
||||
// Fetch Azure IP address ranges data from a JSON file hosted on GitHub
|
||||
let AzureRanges = externaldata(changeNumber: string, cloud: string, values: dynamic)
|
||||
["https://raw.githubusercontent.com/microsoft/mstic/master/PublicFeeds/MSFTIPRanges/ServiceTags_Public.json"] with(format='multijson')
|
||||
// Load Azure IP address ranges from the JSON file hosted on GitHub
|
||||
| mv-expand values
|
||||
// Expand the values column into separate rows
|
||||
| extend Name = values.name, AddressPrefixes = tostring(values.properties.addressPrefixes);
|
||||
// Create additional columns for the name and address prefixes
|
||||
// Identify known locations to be excluded from analysis
|
||||
let ExcludedKnownLocations = CombinedSignInLogs
|
||||
// Filter the combined logs based on the specified time range
|
||||
| where TimeGenerated between (ago(14d)..ago(1d))
|
||||
// Filter by specific ResultType
|
||||
| where ResultType == 0
|
||||
// Summarize the logs by location
|
||||
| summarize by Location;
|
||||
union isfuzzy=True AADNonInteractiveUserSignInLogs, SigninLogs
|
||||
// Find sign-in locations matching specific criteria
|
||||
let MatchedLocations = materialize(CombinedSignInLogs
|
||||
// Filter the combined logs based on the specified time range
|
||||
| where TimeGenerated > ago(1d)
|
||||
| where ResultType != 50126
|
||||
| where Location !in (known_locations)
|
||||
// Exclude specific ResultTypes
|
||||
| where ResultType !in (50126, 50053, 50074, 70044)
|
||||
// Exclude known locations
|
||||
| where Location !in (ExcludedKnownLocations));
|
||||
// Match IP addresses of matched locations with Azure IP address ranges
|
||||
let MatchedIPs = MatchedLocations
|
||||
// Use the 'ipv4_lookup' function to match IP addresses with Azure IP address ranges
|
||||
| evaluate ipv4_lookup(AzureRanges, IPAddress, AddressPrefixes)
|
||||
// Project only the IPAddress column
|
||||
| project IPAddress;
|
||||
// Exclude IP addresses that are already matched with Azure IP address ranges
|
||||
let MaxSetSize = 5; // Set the maximum size limit for make_set
|
||||
let ExcludedIPs = MatchedLocations
|
||||
// Filter out IP addresses that are already matched
|
||||
| where not (IPAddress in (MatchedIPs))
|
||||
// Exclude empty or null Location values
|
||||
| where isnotempty(Location)
|
||||
// Handle dynamic and string column values for LocationDetails and DeviceDetail
|
||||
| extend LocationDetails_dynamic = column_ifexists("LocationDetails_dynamic", "")
|
||||
| extend DeviceDetail_dynamic = column_ifexists("DeviceDetail_dynamic", "")
|
||||
| extend LocationDetails = iif(isnotempty(LocationDetails_dynamic), LocationDetails_dynamic, parse_json(LocationDetails_string))
|
||||
| extend DeviceDetail = iif(isnotempty(DeviceDetail_dynamic), DeviceDetail_dynamic, parse_json(DeviceDetail_string))
|
||||
// Extract location details (city and state)
|
||||
| extend City = tostring(LocationDetails.city)
|
||||
| extend State = tostring(LocationDetails.state)
|
||||
| extend Place = strcat(City, " - ", State)
|
||||
| extend DeviceId = tostring(DeviceDetail.deviceId)
|
||||
| extend Result = strcat(tostring(ResultType), " - ", ResultDescription)
|
||||
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), make_set(Result), make_set(IPAddress), make_set(UserAgent), make_set(Place), make_set(DeviceId) by UserPrincipalName, Location, Category
|
||||
// Summarize the data based on UserPrincipalName, Location, and Category
|
||||
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated),
|
||||
make_set(Result, MaxSetSize), make_set(IPAddress, MaxSetSize),
|
||||
make_set(UserAgent, MaxSetSize), make_set(Place, MaxSetSize),
|
||||
make_set(DeviceId, MaxSetSize) by UserPrincipalName, Location, Category
|
||||
// Extract the username prefix and suffix from UserPrincipalName
|
||||
| extend Name = tostring(split(UserPrincipalName,'@',0)[0]), UPNSuffix = tostring(split(UserPrincipalName,'@',1)[0]);
|
||||
ExcludedIPs // Output the final result set
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: UserPrincipalName
|
||||
version: 1.0.1
|
||||
- identifier: Name
|
||||
columnName: Name
|
||||
- identifier: UPNSuffix
|
||||
columnName: UPNSuffix
|
||||
version: 1.1.0
|
||||
kind: Scheduled
|
||||
metadata:
|
||||
source:
|
||||
kind: Community
|
||||
author:
|
||||
name: Pete Bryan
|
||||
support:
|
||||
tier: Community
|
||||
categories:
|
||||
domains: [ "Security - Others" ]
|
||||
source:
|
||||
kind: Community
|
||||
author:
|
||||
name: Pete Bryan
|
||||
support:
|
||||
tier: Community
|
||||
categories:
|
||||
domains: [ "Security - Others" ]
|
||||
|
|
|
@ -2,4 +2,4 @@ id: f8100782-cb35-466b-831a-72ef4c53edfd
|
|||
name: MFA Rejected by User
|
||||
description: |
|
||||
'As part of content migration, this file is moved to a new location. You can find it here https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Azure%20Active%20Directory/Analytic%20Rules/MFARejectedbyUser.yaml'
|
||||
version: 1.0.3
|
||||
version: 1.0.4
|
||||
|
|
|
@ -15,17 +15,27 @@ query: |
|
|||
imProcess
|
||||
| where Process has_any ("powershell.exe", "powershell_ise.exe", "cmd.exe") or CommandLine has "powershell"
|
||||
| where CommandLine has_any ("cdn.discordapp.com", "moc.ppadrocsid.ndc")
|
||||
| project-reorder TimeGenerated, Computer, Account, Process, CommandLine
|
||||
| project-reorder TimeGenerated, Dvc, User, Process, CommandLine
|
||||
| extend NTDomain = tostring(split(User,'\\',0)[0]), Name = tostring(split(User,'\\',1)[0])
|
||||
| extend HostName = tostring(split(Dvc, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Dvc, '.'), 1, -1), '.'))
|
||||
| extend Account_0_Name = Name
|
||||
| extend Account_0_NTDomain = NTDomain
|
||||
| extend Host_0_HostName = HostName
|
||||
| extend Host_0_DnsDomain = DnsDomain
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: Account
|
||||
- identifier: Name
|
||||
columnName: Name
|
||||
- identifier: NTDomain
|
||||
columnName: NTDomain
|
||||
- entityType: Host
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: Computer
|
||||
version: 1.0.0
|
||||
- identifier: HostName
|
||||
columnName: HostName
|
||||
- identifier: DnsDomain
|
||||
columnName: DnsDomain
|
||||
version: 1.0.1
|
||||
metadata:
|
||||
source:
|
||||
kind: Community
|
||||
|
|
|
@ -11,7 +11,7 @@ relevantTechniques:
|
|||
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
|
||||
| summarize count(), FirstSeen=min(TimeGenerated), LastSeen = max(TimeGenerated) by DvcId, Dvc, CommandLine, User
|
||||
// Base risk score on number of command lines seen for each host
|
||||
| extend RiskScore = count_
|
||||
// Increase risk score if host has recent security alerts
|
||||
|
@ -26,18 +26,30 @@ query: |
|
|||
// 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
|
||||
| project-reorder FirstSeen, LastSeen, RiskScore, Dvc, DvcId, CommandLine, User
|
||||
| extend timestamp = FirstSeen
|
||||
| extend NTDomain = tostring(split(User,'\\',0)[0]), Name = tostring(split(User,'\\',1)[0])
|
||||
| extend HostName = tostring(split(Dvc, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Dvc, '.'), 1, -1), '.')), FileName = File
|
||||
| extend Account_0_Name = Name
|
||||
| extend Account_0_NTDomain = NTDomain
|
||||
| extend Host_0_HostName = HostName
|
||||
| extend Host_0_DnsDomain = DnsDomain
|
||||
| extend File_0_Name = FileName
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: Name
|
||||
columnName: AccountCustomEntity
|
||||
columnName: Name
|
||||
- identifier: NTDomain
|
||||
columnName: NTDomain
|
||||
- entityType: Host
|
||||
fieldMappings:
|
||||
- identifier: HostName
|
||||
columnName: HostCustomEntity
|
||||
columnName: HostName
|
||||
- identifier: DnsDomain
|
||||
columnName: DnsDomain
|
||||
- entityType: File
|
||||
fieldMappings:
|
||||
- identifier: Name
|
||||
columnName: File
|
||||
columnName: FileName
|
||||
version: 1.0.0
|
|
@ -12,7 +12,6 @@ requiredDataConnectors: []
|
|||
tactics:
|
||||
- Execution
|
||||
query: |
|
||||
|
||||
// exclude when over # of machines have the process
|
||||
let excludeThreshold = 10;
|
||||
// exclude when more than percent (default 10%)
|
||||
|
@ -25,10 +24,14 @@ query: |
|
|||
let maxLimit = 6*24;
|
||||
let removeHigh = imProcessCreate
|
||||
| where TimeGenerated >= ago(1d)
|
||||
| extend TargetProcessFilePath = TargetProcessName
|
||||
| summarize count() by TargetProcessFilePath = tolower(TargetProcessFilePath) | where count_ > maxLimit
|
||||
| summarize make_set(TargetProcessFilePath);
|
||||
| summarize make_set(TargetProcessFilePath, 200);
|
||||
let SecEvents = imProcessCreate
|
||||
| where TimeGenerated >= ago(1d)
|
||||
| extend TargetProcessFilePath = TargetProcessName
|
||||
| extend ActingProcessFileName = ActingProcessName
|
||||
| extend TargetProcessFileName = TargetProcessFileProduct
|
||||
| where tolower(TargetProcessFilePath) !in~ (removeHigh)
|
||||
// removing common items that may still show up in small environments, add here if you have additional exclusions
|
||||
| where TargetProcessFilePath !has ':\\Windows\\System32\\conhost.exe' and ActingProcessFileName !has ':\\Windows\\System32\\conhost.exe'
|
||||
|
@ -45,7 +48,7 @@ query: |
|
|||
| where TargetProcessFilePath !has ':\\Windows\\servicing\\trustedinstaller.exe'
|
||||
| where ActingProcessFileName !has ':\\Program Files\\Microsoft Dependency Agent\\bin\\MicrosoftDependencyAgent.exe'
|
||||
| where ActingProcessFileName !has ':\\Program Files (x86)\\Microsoft\\EdgeUpdate\\MicrosoftEdgeUpdate.exe'
|
||||
| project TimeGenerated, EventID, DvcHostname, ActorUserId, Account, AccountType, TargetProcessFileName, TargetProcessFilePath, TargetProcessCommandLine, ActingProcessFileName, _ResourceId, DvcId, EventVendor, EventProduct;
|
||||
| project TimeGenerated, EventOriginalUid, DvcHostname, ActorUserId, User, TargetProcessFileName, TargetProcessFilePath, TargetProcessCommandLine, ActingProcessFileName, _ResourceId, DvcId, EventVendor, EventProduct;
|
||||
let Exclude = SecEvents
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), ExcludeCompCount = dcount(DvcHostname), ExcludeProcCount = count() by TargetProcessFileName
|
||||
// Removing general limit for noise in one day
|
||||
|
@ -115,10 +118,29 @@ query: |
|
|||
Results
|
||||
| join kind= inner (
|
||||
SecEvents
|
||||
| project TimeGenerated, EventID, DvcHostname, ActorUserId, Account, AccountType, TargetProcessFileName, TargetProcessFilePath, TargetProcessCommandLine, ActingProcessFileName, _ResourceId, DvcId , EventVendor, EventProduct
|
||||
| project TimeGenerated, EventOriginalUid, DvcHostname, ActorUserId, TargetProcessFileName, User, TargetProcessFilePath, TargetProcessCommandLine, ActingProcessFileName, _ResourceId, DvcId , EventVendor, EventProduct
|
||||
) on DvcHostname, TargetProcessFileName
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), ResultCount = count() by EventID, DvcHostname, ActorUserId, Account, AccountType, Weight, ProcessEntropy,
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), ResultCount = count() by EventOriginalUid, User, DvcHostname, ActorUserId, Weight, ProcessEntropy,
|
||||
TargetProcessFileName, TargetProcessFilePath, TargetProcessCommandLine, ActingProcessFileName, AllHostsProcessCount, ProcessCountOnHost, DistinctHostsProcessCount, _ResourceId, DvcId , EventVendor, EventProduct
|
||||
| project-reorder StartTime, EndTime, ResultCount, EventID, EventVendor, EventProduct, DvcHostname, ActorUserId, Account, AccountType, Weight, ProcessEntropy,TargetProcessFileName, TargetProcessFilePath, TargetProcessCommandLine, ActingProcessFileName, AllHostsProcessCount, ProcessCountOnHost, DistinctHostsProcessCount, _ResourceId, DvcId
|
||||
| project-reorder StartTime, EndTime, ResultCount, EventOriginalUid, EventVendor, EventProduct, DvcHostname, User, ActorUserId, Weight, ProcessEntropy,TargetProcessFileName, TargetProcessFilePath, TargetProcessCommandLine, ActingProcessFileName, AllHostsProcessCount, ProcessCountOnHost, DistinctHostsProcessCount, _ResourceId, DvcId
|
||||
| sort by Weight asc, ProcessEntropy asc, TargetProcessFilePath asc
|
||||
| extend timestamp = StartTime, HostCustomEntity = DvcHostname, AccountCustomEntity = Account
|
||||
| extend timestamp = StartTime, NTDomain = tostring(split(Account,'\\',0)[0]), Name = tostring(split(Account,'\\',1)[0])
|
||||
| extend HostName = tostring(split(DvcHostname, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(DvcHostname, '.'), 1, -1), '.'))
|
||||
| extend Account_0_Name = Name
|
||||
| extend Account_0_NTDomain = NTDomain
|
||||
| extend Host_0_HostName = HostName
|
||||
| extend Host_0_DnsDomain = DnsDomain
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: Name
|
||||
columnName: Name
|
||||
- identifier: NTDomain
|
||||
columnName: NTDomain
|
||||
- entityType: Host
|
||||
fieldMappings:
|
||||
- identifier: HostName
|
||||
columnName: HostName
|
||||
- identifier: DnsDomain
|
||||
columnName: DnsDomain
|
||||
version: 1.0.0
|
|
@ -13,6 +13,7 @@ tags:
|
|||
query: |
|
||||
imProcessCreate
|
||||
| where Process has 'solarwinds'
|
||||
| extend MachineName = DvcHostname , Process = TargetProcessFilePath
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), MachineCount = dcount(Dvc), AccountCount = dcount(User), MachineNames = make_set(Dvc),
|
||||
Accounts = make_set(User) by Process, EventVendor, EventProduct
|
||||
| extend MachineName = DvcHostname , Process = TargetProcessName
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), MachineCount = dcount(Dvc), AccountCount = dcount(User), MachineNames = make_set(Dvc, 200),
|
||||
Accounts = make_set(User, 200) by Process, EventVendor, EventProduct
|
||||
version: 1.0.0
|
|
@ -9,9 +9,10 @@ tactics:
|
|||
query: |
|
||||
imProcessCreate
|
||||
| where Process has_any ("powershell.exe", "powershell_ise.exe") // perfromance pre-filtering
|
||||
| extend FileName=tostring(split(TargetProcessFilePath, '\\')[-1])
|
||||
| extend FileName=tostring(split(TargetProcessName, '\\')[-1])
|
||||
| where FileName in~ ("powershell.exe", "powershell_ise.exe")
|
||||
| where CommandLine has_any ("Net.WebClient", "DownloadFile", "Invoke-WebRequest", "Invoke-Shellcode", "http:")
|
||||
| project TimeGenerated, Dvc, User, InitiatingProcessFileName, FileName, CommandLine, EventVendor, EventProduct
|
||||
| project TimeGenerated, Dvc, User, ActingProcessName, FileName, CommandLine, EventVendor, EventProduct
|
||||
| top 100 by TimeGenerated
|
||||
| extend timestamp = TimeGenerated, HostCustomEntity = Dvc, AccountCustomEntity = User
|
||||
| extend timestamp = TimeGenerated
|
||||
version: 1.0.0
|
|
@ -1,39 +0,0 @@
|
|||
id: 7498594f-e3a7-4e02-9280-a07be9cfd38a
|
||||
name: Dynamics 365 Activity After Azure AD Alerts
|
||||
description: |
|
||||
'This hunting query looks for users conducting Dynamics 365 activity shortly after Azn Azure AD Identity Protection alert for that user. The query only looks for users not seen before or conducting Dynamics activity not previously seen.'
|
||||
requiredDataConnectors:
|
||||
- connectorId: Dynamics365
|
||||
dataTypes:
|
||||
- Dynamics365Activity
|
||||
tactics:
|
||||
- InitialAccess
|
||||
relevantTechniques:
|
||||
- T1078
|
||||
query: |
|
||||
let match_window = 1h;
|
||||
let analysis_window = 1d;
|
||||
let lookback_window = 7d;
|
||||
SecurityAlert
|
||||
| where TimeGenerated > ago(analysis_window)
|
||||
| where ProviderName == 'IPC'
|
||||
| extend UserName = tostring(parse_json(ExtendedProperties).["User Account"])
|
||||
| extend UserName = tolower(UserName)
|
||||
| extend TimeKey = bin(TimeGenerated, match_window)
|
||||
| join kind=inner(Dynamics365Activity
|
||||
| where TimeGenerated > ago(analysis_window)
|
||||
| extend UserName = tolower(UserId)
|
||||
| extend TimeKey = bin(TimeGenerated, match_window))
|
||||
on UserName, TimeKey
|
||||
| join kind=leftanti(Dynamics365Activity
|
||||
| where TimeGenerated between(ago(lookback_window)..ago(analysis_window))
|
||||
| extend UserName = tolower(UserId))
|
||||
on UserName, OriginalObjectId
|
||||
| summarize Actions = make_set(OriginalObjectId), MostRecentAction = max(TimeGenerated1), IPs = make_set(split(tostring(ClientIP), ':')[0]), AADAlerts=make_set(Description), MostRecentAlert = max(TimeGenerated) by UserName
|
||||
| extend timestamp = MostRecentAction, AccountCustomEntity = UserName
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
||||
version: 1.0.1
|
|
@ -1,33 +0,0 @@
|
|||
id: 0ea22925-998d-42ea-9ff6-0c32af4ff835
|
||||
name: Dynamics 365 Activity After Failed Logons
|
||||
description: |
|
||||
'This hunting query looks for users conducting Dynamics 365 activity shortly after a number of failed logons. Use this to look for potential post brute force activity. Adjust the threshold figure based on false positive rate.'
|
||||
requiredDataConnectors:
|
||||
- connectorId: Dynamics365
|
||||
dataTypes:
|
||||
- Dynamics365Activity
|
||||
tactics:
|
||||
- InitialAccess
|
||||
relevantTechniques:
|
||||
- T1078
|
||||
query: |
|
||||
let threshold = 10;
|
||||
SigninLogs
|
||||
| where ResultType in ("50125", "50140", "70043", "70044")
|
||||
| summarize count() by IPAddress
|
||||
| where count_ >= threshold
|
||||
| join (Dynamics365Activity
|
||||
| extend IPAddress = tostring(split(ClientIP, ":")[0]))
|
||||
on IPAddress
|
||||
| project-rename FailedLogonCount = count_
|
||||
| extend timestamp = TimeGenerated, AccountCustomEntity = UserId, IPCustomEntity = IPAddress
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
||||
- entityType: IP
|
||||
fieldMappings:
|
||||
- identifier: Address
|
||||
columnName: IPCustomEntity
|
||||
version: 1.0.1
|
|
@ -25,6 +25,7 @@ query: |
|
|||
[@"https://bazaar.abuse.ch/export/csv/recent/"]
|
||||
with (format = "txt"))
|
||||
| where report !startswith '#'
|
||||
| extend report = trim("\"", report)
|
||||
| extend report = parse_csv(report)
|
||||
| extend FirstSeenUtc = tostring(report[0])
|
||||
| project FirstSeenUtc = todatetime(FirstSeenUtc)
|
||||
|
@ -59,5 +60,7 @@ query: |
|
|||
| join (
|
||||
DeviceImageLoadEvents
|
||||
| where Timestamp > MaxAge
|
||||
| where isnotempty(SHA256)
|
||||
) on SHA256
|
||||
)
|
||||
version: 1.0.0
|
||||
|
|
|
@ -43,12 +43,17 @@ query: |
|
|||
;
|
||||
//
|
||||
deleteEvents
|
||||
| join kind=leftsemi suspUsers on AccountObjectId, SessionId
|
||||
| join kind=leftsemi riskyUsers on AccountObjectId, SessionId
|
||||
| summarize Count=count() , (Timestamp, ReportId)=arg_min(Timestamp, ReportId) by AccountObjectId, AccountDisplayName, ApplicationId, ActionType, Time=bin(Timestamp, 5m)
|
||||
// look for only those scoped users who have generated an increase in file deletion activity.
|
||||
| summarize TotalCount= countif(Count > 50), (Timestamp, ReportId)=arg_min(Timestamp, ReportId) by AccountObjectId, AccountDisplayName, ApplicationId
|
||||
| where TotalCount >= 3
|
||||
| project AccountObjectId, AccountDisplayName, ApplicationId, TotalCount, ReportId, Timestamp
|
||||
| extend NTDomain = tostring(split(AccountDisplayName,'\\',0)[0]), Name = tostring(split(AccountDisplayName,'\\',1)[0])
|
||||
| extend Account_0_Name = Name
|
||||
| extend Account_0_NTDomain = NTDomain
|
||||
| extend Account_0_AadUserId = AccountObjectId
|
||||
| extend CloudApplication_0_AppId = ApplicationId
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
|
@ -56,11 +61,14 @@ entityMappings:
|
|||
columnName: AccountObjectId
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountDisplayName
|
||||
- identifier: Name
|
||||
columnName: Name
|
||||
- identifier: NTDomain
|
||||
columnName: NTDomain
|
||||
- entityType: CloudApplication
|
||||
fieldMappings:
|
||||
- identifier: AppId
|
||||
columnName: ApplicationId
|
||||
customDetails:
|
||||
Count: TotalCount
|
||||
Count: TotalCount
|
||||
version: 1.0.0
|
|
@ -37,6 +37,7 @@ query: |
|
|||
| distinct RemoteUrl, NetworkMessageId, RecipientEmailAddress , RecipientObjectId
|
||||
| join kind = inner IdentityInfo on $left.RecipientObjectId == $right.AccountObjectId
|
||||
// get the UserSid of the Recipient
|
||||
| extend OnPremSid = AccountSID
|
||||
| distinct RemoteUrl, NetworkMessageId, RecipientEmailAddress , RecipientObjectId, OnPremSid
|
||||
// Get the Url click event on the recipient device.
|
||||
| join kind = inner
|
||||
|
@ -49,3 +50,4 @@ query: |
|
|||
| distinct UrlDeviceClickTime, RemoteUrl, NetworkMessageId, RecipientEmailAddress, RecipientObjectId,
|
||||
OnPremSid, UrlClickedByUserSid, DeviceName, DeviceId, InitiatingProcessFileName
|
||||
| sort by UrlDeviceClickTime desc
|
||||
version: 1.0.0
|
|
@ -12,7 +12,8 @@ query: |
|
|||
let ADAZUsers = IdentityInfo
|
||||
| extend DirectoryDomain = AccountDomain
|
||||
| extend DirectoryAccount = AccountName
|
||||
| distinct DirectoryDomain , DirectoryAccount , OnPremSid , CloudSid, AccountUpn, GivenName, Surname;
|
||||
| extend OnPremSid = AccountSID
|
||||
| distinct DirectoryDomain , DirectoryAccount , OnPremSid , AccountCloudSID, AccountUPN, GivenName, Surname;
|
||||
// check for any new created or modified local accounts
|
||||
let NewUsers = DeviceEvents
|
||||
| where ActionType contains "UserAccountCreated" // or ActionType contains "UserAccountModified"
|
||||
|
@ -42,3 +43,4 @@ query: |
|
|||
// | join ADAZUsers
|
||||
// on $left.Actor == $right.DirectoryAccount
|
||||
// | render piechart
|
||||
version: 1.0.0
|
|
@ -18,18 +18,19 @@ query: |
|
|||
let all_computers_with_vlcvln=
|
||||
DeviceTvmSoftwareVulnerabilities
|
||||
| where SoftwareName contains "vlc"
|
||||
| summarize makelist(DeviceName);
|
||||
| summarize makelist(DeviceName, 200);
|
||||
let all_affected_users=
|
||||
DeviceInfo
|
||||
| where DeviceName in (all_computers_with_vlcvln)
|
||||
| mvexpand todynamic(LoggedOnUsers)
|
||||
| extend ParsedFields = parsejson(LoggedOnUsers)
|
||||
| project UserName = ParsedFields.UserName
|
||||
| summarize makelist(tolower(UserName));
|
||||
| summarize makelist(tolower(UserName), 200);
|
||||
let all_email_addresses_aff_users=
|
||||
IdentityInfo
|
||||
| where tolower(AccountName) in (all_affected_users)
|
||||
| summarize makelist(tolower(EmailAddress));
|
||||
| summarize makelist(tolower(MailAddress), 200);
|
||||
EmailAttachmentInfo
|
||||
| where FileName contains ".mkv"
|
||||
| where tolower(RecipientEmailAddress) in (all_email_addresses_aff_users)
|
||||
version: 1.0.0
|
|
@ -36,7 +36,7 @@ query: |
|
|||
| where ParentProcessName endswith "diawp.exe" or ParentProcessName endswith "ReportingServicesService.exe" or ParentProcessName endswith "RSPortal.exe" or ParentProcessName endswith "RsPowerBI.exe" or ParentProcessName endswith "taskexecutor.exe"
|
||||
| where ActingProcessName == "cmd.exe"
|
||||
| where (CommandLine has_any (cmdline_tokens))
|
||||
| extend timestamp = TimeGenerated, HostCustomEntity = DvcHostname , AccountCustomEntity = ActorUsername, ProcessCustomEntity = TargetProcessFilePath
|
||||
| extend timestamp = TimeGenerated, HostCustomEntity = DvcHostname , AccountCustomEntity = ActorUsername, ProcessCustomEntity = TargetProcessName
|
||||
),
|
||||
(SecurityEvent
|
||||
| where EventID == '4688'
|
||||
|
@ -59,19 +59,31 @@ query: |
|
|||
| extend timestamp = TimeGenerated, HostCustomEntity = Computer , AccountCustomEntity = Account, ProcessCustomEntity = NewProcessName
|
||||
)
|
||||
)
|
||||
| extend NTDomain = tostring(split(AccountCustomEntity, '\\', 0)[0]), Name = tostring(split(AccountCustomEntity, '\\', 1)[0])
|
||||
| extend HostName = tostring(split(HostCustomEntity, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(HostCustomEntity, '.'), 1, -1), '.'))
|
||||
| extend Account_0_Name = Name
|
||||
| extend Account_0_NTDomain = NTDomain
|
||||
| extend Host_0_HostName = HostName
|
||||
| extend Host_0_DnsDomain = DnsDomain
|
||||
| extend Process_0_ProcessId = ProcessCustomEntity
|
||||
| extend Process_0_CommandLine = CommandLineCustomEntity
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
||||
- identifier: Name
|
||||
columnName: Name
|
||||
- identifier: NTDomain
|
||||
columnName: NTDomain
|
||||
- entityType: Host
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: HostCustomEntity
|
||||
- identifier: HostName
|
||||
columnName: HostName
|
||||
- identifier: DnsDomain
|
||||
columnName: DnsDomain
|
||||
- entityType: Process
|
||||
fieldMappings:
|
||||
- identifier: ProcessId
|
||||
columnName: ProcessCustomEntity
|
||||
- identifier: CommandLine
|
||||
columnName: CommandLineCustomEntity
|
||||
version: 1.0.0
|
||||
version: 1.0.1
|
|
@ -0,0 +1,74 @@
|
|||
id: 0576750e-6b61-4545-845f-f5b8f29a0cc4
|
||||
name: Email Forwarding Configuration with SAP download
|
||||
description: |
|
||||
'This query could help detect any external email forwarding configuration activity with SAP download for sensitive financial transaction related keywords. Attackers may perform such operation for financial gain, Intellectual Property theft or to cause disruption of operation to an organization.'
|
||||
requiredDataConnectors:
|
||||
- connectorId: SAP
|
||||
dataTypes:
|
||||
- SAPAuditLog
|
||||
- connectorId: MicrosoftThreatProtection
|
||||
dataTypes:
|
||||
- EmailEvents
|
||||
- connectorId: Office365
|
||||
dataTypes:
|
||||
- OfficeActivity
|
||||
tactics:
|
||||
- InitialAccess
|
||||
- Collection
|
||||
- Exfiltration
|
||||
relevantTechniques:
|
||||
- T1078
|
||||
- T1114
|
||||
- T1020
|
||||
query: |
|
||||
let Keywords = dynamic(["payroll", "invoice", "payment", "statement", "confidential", "bank account", "wire", "wire transfer"]);
|
||||
EmailEvents
|
||||
| extend Account = tostring(split(SenderFromAddress, '@', 0)[0]), UPNSuffix = tostring(split(SenderFromAddress, '@', 1)[0])
|
||||
| project NetworkMessageId, Account, RecipientEmailAddress, SenderIPv4, Subject, EmailAction, DeliveryLocation, TenantId
|
||||
| join kind=innerunique
|
||||
(OfficeActivity
|
||||
| where OfficeWorkload =~ "Exchange"
|
||||
| where Operation in~ ("Set-Mailbox", "New-InboxRule", "Set-InboxRule")
|
||||
| where Parameters has_any ("ForwardTo", "RedirectTo", "ForwardingSmtpAddress")
|
||||
| extend Events=todynamic(Parameters)
|
||||
| where UserId has "@"
|
||||
| extend Account = tostring(split(UserId, '@', 0)[0]), UPNSuffix = tostring(split(UserId, '@', 1)[0])
|
||||
| parse Events with * "SubjectContainsWords" SubjectContainsWords '}'*
|
||||
| parse Events with * "BodyContainsWords" BodyContainsWords '}'*
|
||||
| parse Events with * "SubjectOrBodyContainsWords" SubjectOrBodyContainsWords '}'*
|
||||
| where SubjectContainsWords has_any (Keywords) or BodyContainsWords has_any (Keywords) or SubjectOrBodyContainsWords has_any (Keywords)
|
||||
| extend ClientIPAddress = case( ClientIP has ".", tostring(split(ClientIP,":")[0]), ClientIP has "[", tostring(trim_start(@'[[]',tostring(split(ClientIP,"]")[0]))), ClientIP )
|
||||
| extend Keyword = iff(isnotempty(SubjectContainsWords), SubjectContainsWords, (iff(isnotempty(BodyContainsWords),BodyContainsWords,SubjectOrBodyContainsWords )))
|
||||
| extend RuleDetail = case(OfficeObjectId contains '/' , tostring(split(OfficeObjectId, '/')[-1]) , tostring(split(OfficeObjectId, '\\')[-1]))
|
||||
| summarize count(), StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated) by UserId, ClientIPAddress, ResultStatus, Keyword, OriginatingServer, OfficeObjectId, RuleDetail,Account)
|
||||
on Account
|
||||
| join kind=inner
|
||||
(
|
||||
SAPAuditLog
|
||||
| where MessageID == "AUY" //AUY= Download bytes
|
||||
| extend ByteCount= toint(replace_string(replace_string(Variable1, ".",""), ",","")), Code=Variable2, Path= Variable3
|
||||
| summarize DownloadsByUser = count(), Paths= make_set(Variable3, 10), ByteCount=sum(ByteCount) by SystemID, ClientID, User, TerminalIPv6, Email, Host, TransactionCode, Instance
|
||||
| where Paths has_any (Keywords)
|
||||
) on $left.Account == $right.User, $left.RecipientEmailAddress == $right. Email
|
||||
| project StartTimeUtc, Account, SenderIPv4, Email, Host, Keyword, NetworkMessageId, OfficeObjectId, Paths, Subject, SystemID, TenantId, ClientID, DeliveryLocation, TransactionCode
|
||||
| extend UserName = tostring(split(Account, '@', 0)[0]), UPNSuffix = tostring(split(Account, '@', 1)[0])
|
||||
| extend Account_0_Name = UserName
|
||||
| extend Account_0_UPNSuffix = UPNSuffix
|
||||
| extend IP_0_Address = SenderIPv4
|
||||
| extend Host_0_HostName = Host
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: Name
|
||||
columnName: UserName
|
||||
- identifier: UPNSuffix
|
||||
columnName: UPNSuffix
|
||||
- entityType: Host
|
||||
fieldMappings:
|
||||
- identifier: HostName
|
||||
columnName: Host
|
||||
- entityType: IP
|
||||
fieldMappings:
|
||||
- identifier: Address
|
||||
columnName: SenderIPv4
|
||||
version: 1.0.0
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96">
|
||||
<path d="M-.1 0h96v96h-96z" fill="#0e2343"></path>
|
||||
<defs>
|
||||
<path id="32107c20-0d95-48af-bb4f-166c97fbc658" d="M11.3 12.6H82v70.7H11.3z"></path>
|
||||
</defs>
|
||||
<clipPath id="a3cb2b70-ce10-473d-be64-4cd9106404dd">
|
||||
<use href="#32107c20-0d95-48af-bb4f-166c97fbc658"></use>
|
||||
</clipPath>
|
||||
<g clip-path="url(#a3cb2b70-ce10-473d-be64-4cd9106404dd)" fill="#fff">
|
||||
<path d="M79.6 43.3H58.8c-.3 0-.5-.4-.3-.6l16.6-16.6c.2-.2.2-.4.2-.6v-2.3c0-.2-.1-.4-.2-.6l-3-3c-.2-.2-.4-.2-.6-.2h-2.3c-.2 0-.4.1-.6.2L52 36.1c-.2.2-.6.1-.6-.3V15.1c0-.2-.1-.4-.2-.6l-1.7-1.7c-.2-.2-.4-.2-.6-.2h-4.3c-.2 0-.4.1-.6.2l-1.7 1.7c-.2.2-.2.4-.2.6v31.2c0 .2.1.4.2.6l5.4 5.4c.2.2.4.2.6.2h31.2c.2 0 .4-.1.6-.2l1.7-1.7c.2-.2.2-.4.2-.6v-4.3c0-.2-.1-.4-.2-.6l-1.7-1.7c-.1 0-.3-.1-.5-.1h0z" fill-rule="evenodd"></path>
|
||||
<path d="M23.6 64.6l-.6.6c-.2.2-.2.4 0 .6l5.9 5.9a.37.37 0 0 0 .6 0l.7-.7a.37.37 0 0 0 0-.6l-5.9-5.9c-.2-.1-.5-.1-.7.1z"></path>
|
||||
<path d="M18.3 52.6H20c.2 0 .3-.2.1-.4l-7.5-7.5c-.1-.1-.3-.1-.5 0l-.5.5-.3.3c-.1.1-.1.3 0 .5l6.4 6.4c.2.1.4.2.6.2h0z" fill-rule="evenodd"></path>
|
||||
<path d="M25.7 62.5l-.7.6c-.2.2-.2.4 0 .6l5.9 5.9a.37.37 0 0 0 .6 0l.7-.7a.37.37 0 0 0 0-.6l-5.9-5.9a.47.47 0 0 0-.6.1zm4.2-4.2l-.7.7c-.2.2-.2.4 0 .6l5.9 5.9c.2.2.4.2.6 0l.7-.7c.2-.2.2-.4 0-.6l-5.9-5.9c-.2-.1-.5-.1-.6 0zM19.5 68.7l-.7.7a.37.37 0 0 0 0 .6l5.9 5.9a.37.37 0 0 0 .6 0l.7-.7c.2-.2.2-.4 0-.6l-5.9-5.9c-.2-.2-.5-.2-.6 0zm2.1-2.1l-.7.7c-.2.2-.2.4 0 .6l5.9 5.9a.37.37 0 0 0 .6 0l.7-.7a.37.37 0 0 0 0-.6l-5.9-5.9c-.2-.1-.5-.1-.6 0z"></path>
|
||||
<path d="M18.1 71.4v1.7c0 .1 0 .2.1.3l3.1 3.1c.1.1.2.1.3.1h1.6c.2 0 .3-.2.1-.4l-4.9-4.9c0-.1-.3-.1-.3.1h0z" fill-rule="evenodd"></path>
|
||||
<path d="M31.9 56.3l-.7.7c-.2.2-.2.4 0 .6l5.9 5.9a.37.37 0 0 0 .6 0l.7-.7c.2-.2.2-.4 0-.6l-5.9-5.9c-.1-.2-.4-.2-.6 0zm-4.1 4.1l-.7.7c-.2.2-.2.4 0 .6l5.9 5.9c.2.2.4.2.6 0l.7-.7a.37.37 0 0 0 0-.6l-5.9-5.9c-.2-.1-.5-.1-.6 0zm6.2-6.2l-.7.7c-.2.2-.2.4 0 .6l5.9 5.9a.37.37 0 0 0 .6 0l.7-.7c.2-.2.2-.4 0-.6l-5.9-5.9a.37.37 0 0 0-.6 0z"></path>
|
||||
<g fill-rule="evenodd">
|
||||
<path d="M27.6 43.3h-1.7c-.2 0-.3.2-.1.4L51 69c.1.1.4 0 .4-.1V67c0-.1 0-.2-.1-.3L28 43.5c-.1-.1-.2-.2-.4-.2h0zm8.3 0h-1.7c-.2 0-.3.2-.1.4l17 17c.1.1.4 0 .4-.1v-1.8c0-.1 0-.2-.1-.3l-15.1-15c-.1-.1-.2-.2-.4-.2h0zm4.6 2.2v-1.9c0-.1-.1-.2-.2-.2h-1.9c-.2 0-.3.2-.1.4l1.9 1.9s.3 0 .3-.2zm1.6 16.8V64c0 .2.1.3.2.4l8.7 8.7c.1.1.4 0 .4-.1v-1.7c0-.2-.1-.3-.2-.4l-8.7-8.7c-.1-.2-.4-.1-.4.1h0zm9.1-8.1h-2c-.2 0-.3.2-.1.4l2 2c.1.1.4 0 .4-.1v-2c-.1-.2-.2-.3-.3-.3zM31.8 43.3H30c-.2 0-.3.2-.1.4L51 64.8c.1.1.4 0 .4-.1v-1.8c0-.1 0-.2-.1-.3L32.2 43.5a.76.76 0 0 0-.4-.2h0zm-5.2 9.3h1.7c.2 0 .3-.2.1-.4l-8.7-8.7a.76.76 0 0 0-.4-.2h-1.7c-.2 0-.3.2-.1.4l8.7 8.7c0 .1.2.2.4.2h0zm-4.2 0h1.7c.2 0 .3-.2.1-.4l-8.7-8.7a.76.76 0 0 0-.4-.2h-1.7c-.2 0-.3.2-.1.4l8.7 8.7a.76.76 0 0 0 .4.2h0zm-.8-8.9l8.7 8.7a.76.76 0 0 0 .4.2h1.7c.2 0 .3-.2.1-.4l-8.7-8.7a.76.76 0 0 0-.4-.2h-1.7c-.2 0-.3.2-.1.4h0zM14 52.6h1.8c.2 0 .3-.2.1-.4l-4.3-4.3c-.1-.1-.4 0-.4.1v1.8c0 .1 0 .2.1.3l2.3 2.3c.2.1.3.2.4.2h0zm28.1 13.8v1.7c0 .2.1.3.2.4l8.7 8.7c.1.1.4 0 .4-.1v-1.7c0-.2-.1-.3-.2-.4l-8.7-8.7c-.1-.2-.4-.1-.4.1h0zm0 10v-1.7c0-.2.2-.3.4-.1L50 82c.1.1.1.3 0 .5l-.5.5-.3.3c-.1.1-.3.1-.5 0l-6.4-6.4c-.1-.1-.2-.3-.2-.5h0zm0-4.1v-1.7c0-.2.2-.3.4-.1l8.7 8.7a.76.76 0 0 1 .2.4v1.7c0 .2-.2.3-.4.1l-8.7-8.7a.76.76 0 0 1-.2-.4zm0 8.4v-1.8c0-.2.2-.3.4-.1l4.3 4.3c.1.1 0 .4-.1.4h-1.8c-.1 0-.2 0-.3-.1L42.3 81c-.1-.1-.2-.2-.2-.3z"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 3.5 KiB |
|
@ -0,0 +1,33 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18">
|
||||
<defs>
|
||||
<linearGradient id="fc9e0ce2-d7de-4412-bda8-f01e2cc4e66a" x1="9" y1="12.48" x2="9" y2="1.147" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#003067"/>
|
||||
<stop offset="0.037" stop-color="#00346c"/>
|
||||
<stop offset="0.239" stop-color="#004583"/>
|
||||
<stop offset="0.456" stop-color="#005194"/>
|
||||
<stop offset="0.695" stop-color="#00599e"/>
|
||||
<stop offset="1" stop-color="#005ba1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="e9e87259-0875-41e6-886b-2024b496a772" x1="9" y1="684.663" x2="9" y2="689.036" gradientTransform="matrix(1, 0, 0, -1, 0, 701.516)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.15" stop-color="#ccc"/>
|
||||
<stop offset="1" stop-color="#707070"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bf7ae98c-3eed-4cf6-9bb1-28dc4026a25b" x1="0.003" y1="-27.428" x2="0.003" y2="-28.757" gradientTransform="matrix(5, 0, 0, -5, 9.126, -133.758)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#00aeef"/>
|
||||
<stop offset="0.212" stop-color="#0097dc"/>
|
||||
<stop offset="0.519" stop-color="#007cc5"/>
|
||||
<stop offset="0.792" stop-color="#006cb8"/>
|
||||
<stop offset="1" stop-color="#0066b3"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="bc45d939-cf3c-4c56-98de-8197264505ae">
|
||||
<g>
|
||||
<rect x="0.5" y="1.147" width="17" height="11.333" rx="0.567" fill="url(#fc9e0ce2-d7de-4412-bda8-f01e2cc4e66a)"/>
|
||||
<path d="M12.409,15.909c-1.681-.265-1.747-1.474-1.747-3.429H7.328c0,1.955-.056,3.164-1.737,3.429a.944.944,0,0,0-.841.944h8.5A.944.944,0,0,0,12.409,15.909Z" fill="url(#e9e87259-0875-41e6-886b-2024b496a772)"/>
|
||||
<g>
|
||||
<path d="M2.427,10.028H9.215l6.643-6.644H2.427v6.644" fill-rule="evenodd" fill="url(#bf7ae98c-3eed-4cf6-9bb1-28dc4026a25b)"/>
|
||||
<path d="M10.4,4.713H9.071l.005,3.119L7.921,4.711H6.775L5.79,7.318C5.685,6.654,5,6.426,4.46,6.254c-.357-.114-.735-.283-.731-.469,0-.152.2-.294.6-.273a2.171,2.171,0,0,1,.968.262l.459-.8a3.589,3.589,0,0,0-1.5-.354h0A1.822,1.822,0,0,0,2.931,5.1a1.119,1.119,0,0,0-.316.771,1.036,1.036,0,0,0,.454.923,3.107,3.107,0,0,0,.9.412c.367.113.667.212.663.423a.314.314,0,0,1-.087.206.581.581,0,0,1-.426.134,1.825,1.825,0,0,1-1.1-.313l-.408.811a2.842,2.842,0,0,0,1.444.377h.12a1.8,1.8,0,0,0,1.139-.36l.049-.041L5.316,8.7l1.12,0,.2-.514a2.287,2.287,0,0,0,1.4.006l.14.508,2.008,0,0-1.172h.427c1.033,0,1.644-.526,1.644-1.407,0-.982-.594-1.41-1.857-1.41ZM7.342,7.379a1.2,1.2,0,0,1-.423-.074l.419-1.322h.008l.412,1.326a1.251,1.251,0,0,1-.416.07Zm3.133-.759h-.291V5.554h.291c.389,0,.7.129.7.526s-.31.54-.7.54" fill="#fff" fill-rule="evenodd"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 2.6 KiB |
|
@ -1,6 +1,6 @@
|
|||
Parser:
|
||||
Title: Web Session ASIM filtering parser for Windows IIS logs
|
||||
Version: '0.1'
|
||||
Version: '0.1.1'
|
||||
LastUpdated: Apr 19, 2023
|
||||
Product:
|
||||
Name: Internet Information Services (IIS)
|
||||
|
@ -28,9 +28,6 @@ ParserParams:
|
|||
- Name: srcipaddr_has_any_prefix
|
||||
Type: dynamic
|
||||
Default: dynamic([])
|
||||
- Name: dstipaddr_has_any_prefix
|
||||
Type: dynamic
|
||||
Default: dynamic([])
|
||||
- Name: ipaddr_has_any_prefix
|
||||
Type: dynamic
|
||||
Default: dynamic([])
|
||||
|
@ -54,7 +51,6 @@ ParserQuery: |
|
|||
starttime:datetime=datetime(null),
|
||||
endtime:datetime=datetime(null),
|
||||
srcipaddr_has_any_prefix:dynamic=dynamic([]),
|
||||
dstipaddr_has_any_prefix:dynamic=dynamic([]),
|
||||
ipaddr_has_any_prefix:dynamic=dynamic([]),
|
||||
url_has_any:dynamic=dynamic([]),
|
||||
httpuseragent_has_any:dynamic=dynamic([]),
|
||||
|
@ -64,7 +60,6 @@ ParserQuery: |
|
|||
)
|
||||
{
|
||||
let src_or_any=set_union(srcipaddr_has_any_prefix, ipaddr_has_any_prefix);
|
||||
let dst_or_any=set_union(dstipaddr_has_any_prefix, ipaddr_has_any_prefix);
|
||||
W3CIISLog
|
||||
| where not(disabled)
|
||||
| where (isnull(starttime) or TimeGenerated >= starttime)
|
||||
|
@ -76,12 +71,10 @@ ParserQuery: |
|
|||
| where (array_length(httpuseragent_has_any) == 0 or csUserAgent has_any(httpuseragent_has_any))
|
||||
| where (array_length(eventresultdetails_in) == 0 or scStatus has_any (eventresultdetails_in))
|
||||
| extend temp_SrcMatch=has_any_ipv4_prefix(cIP,src_or_any)
|
||||
, temp_DstMatch=has_any_ipv4_prefix(csHost,dst_or_any)
|
||||
| extend ASimMatchingIpAddr=case(
|
||||
array_length(src_or_any) == 0 and array_length(dst_or_any) == 0 ,"-",
|
||||
temp_SrcMatch and temp_DstMatch, "Both",
|
||||
array_length(src_or_any) == 0 ,"-",
|
||||
temp_SrcMatch, "Both",
|
||||
temp_SrcMatch, "SrcIpAddr",
|
||||
temp_DstMatch, "DstIpAddr",
|
||||
"No match"
|
||||
)
|
||||
| where ASimMatchingIpAddr != "No match"
|
||||
|
@ -179,4 +172,4 @@ ParserQuery: |
|
|||
sc*,
|
||||
StorageAccount
|
||||
};
|
||||
parser (starttime=starttime, endtime=endtime, dstipaddr_has_any_prefix=dstipaddr_has_any_prefix, srcipaddr_has_any_prefix=srcipaddr_has_any_prefix, ipaddr_has_any_prefix=ipaddr_has_any_prefix, url_has_any=url_has_any, httpuseragent_has_any=httpuseragent_has_any, eventresultdetails_in=eventresultdetails_in, eventresult=eventresult, disabled=disabled)
|
||||
parser (starttime=starttime, endtime=endtime, srcipaddr_has_any_prefix=srcipaddr_has_any_prefix, ipaddr_has_any_prefix=ipaddr_has_any_prefix, url_has_any=url_has_any, httpuseragent_has_any=httpuseragent_has_any, eventresultdetails_in=eventresultdetails_in, eventresult=eventresult, disabled=disabled)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
Parser:
|
||||
Title: Web Session ASIM Filtering parser for Palo Alto Networks URL Filtering
|
||||
Version: '0.2'
|
||||
Version: '0.2.1'
|
||||
LastUpdated: Mar 12 2023
|
||||
Product:
|
||||
Name: Palo Alto Networks
|
||||
|
@ -30,9 +30,6 @@ ParserParams:
|
|||
- Name: srcipaddr_has_any_prefix
|
||||
Type: dynamic
|
||||
Default: dynamic([])
|
||||
- Name: dstipaddr_has_any_prefix
|
||||
Type: dynamic
|
||||
Default: dynamic([])
|
||||
- Name: ipaddr_has_any_prefix
|
||||
Type: dynamic
|
||||
Default: dynamic([])
|
||||
|
@ -56,7 +53,6 @@ ParserQuery: |
|
|||
starttime:datetime=datetime(null),
|
||||
endtime:datetime=datetime(null),
|
||||
srcipaddr_has_any_prefix:dynamic=dynamic([]),
|
||||
dstipaddr_has_any_prefix:dynamic=dynamic([]),
|
||||
ipaddr_has_any_prefix:dynamic=dynamic([]),
|
||||
url_has_any:dynamic=dynamic([]),
|
||||
httpuseragent_has_any:dynamic=dynamic([]),
|
||||
|
@ -66,8 +62,7 @@ ParserQuery: |
|
|||
)
|
||||
{
|
||||
let src_or_any=set_union(srcipaddr_has_any_prefix, ipaddr_has_any_prefix);
|
||||
let dst_or_any=set_union(dstipaddr_has_any_prefix, ipaddr_has_any_prefix);
|
||||
let ip_any = set_union(srcipaddr_has_any_prefix, dstipaddr_has_any_prefix, ipaddr_has_any_prefix);
|
||||
let ip_any = set_union(srcipaddr_has_any_prefix, ipaddr_has_any_prefix);
|
||||
let EventLookup=datatable(DeviceAction:string, DvcAction:string,EventResult:string,HttpStatusCode:string)
|
||||
[
|
||||
"alert", "Allow", "Success","200",
|
||||
|
@ -110,13 +105,11 @@ ParserQuery: |
|
|||
and DeviceEventClassID == "url"
|
||||
| where (array_length(url_has_any) == 0 or RequestURL has_any (remove_protocol_from_list(url_has_any)))
|
||||
| where (array_length(httpuseragent_has_any) == 0 or RequestClientApplication has_any (httpuseragent_has_any))
|
||||
| extend temp_SrcMatch = has_any_ipv4_prefix(SourceIP,src_or_any),
|
||||
temp_DstMatch = has_any_ipv4_prefix(DestinationIP,dst_or_any)
|
||||
| extend temp_SrcMatch = has_any_ipv4_prefix(SourceIP,src_or_any)
|
||||
| extend ASimMatchingIpAddr = case(
|
||||
array_length(src_or_any) == 0 and array_length(dst_or_any) == 0, "-",
|
||||
temp_SrcMatch and temp_DstMatch, "Both",
|
||||
array_length(src_or_any) == 0, "-",
|
||||
temp_SrcMatch , "Both",
|
||||
temp_SrcMatch, "SrcIpAddr",
|
||||
temp_DstMatch, "DstIpAddr",
|
||||
"No match")
|
||||
| where ASimMatchingIpAddr != "No match"
|
||||
| project-away temp_*
|
||||
|
@ -232,4 +225,4 @@ ParserQuery: |
|
|||
Dst = DstFQDN
|
||||
| project ASimMatchingIpAddr, DeviceVendor, Dst, DstDomainType, DstFQDN, DstHostname, DstIpAddr, DstMacAddr, DstNatIpAddr, DstNatPortNumber, DstPortNumber, DstUsername, DstUsernameType, DstZone, Dvc, DvcAction, DvcHostname, DvcId, DvcIdType, DvcInboundInterface, DvcInterface, DvcOriginalAction, DvcOutboundInterface, EventCount, EventEndTime, EventOriginalSeverity, EventProduct, EventProductVersion, EventResult, EventResultDetails, EventSchema, EventSchemaVersion, EventSeverity, EventStartTime, EventType, EventUid, EventVendor, Hostname, HttpContentFormat, HttpRequestMethod, HttpRequestXff, HttpStatusCode, IpAddr, NetworkDirection, NetworkProtocol, NetworkProtocolVersion, NetworkRuleName, NetworkSessionId, Protocol, RequestContext, Rule, SessionId, Src, SrcHostname, SrcIpAddr, SrcMacAddr, SrcNatIpAddr, SrcNatPortNumber, SrcPortNumber, SrcUsername, SrcUsernameType, SrcZone, ThreatField, ThreatIpAddr, ThreatOriginalConfidence, TimeGenerated, Type, Url, UrlCategory, User
|
||||
};
|
||||
parser (starttime=starttime, endtime=endtime, dstipaddr_has_any_prefix=dstipaddr_has_any_prefix, srcipaddr_has_any_prefix=srcipaddr_has_any_prefix, ipaddr_has_any_prefix=ipaddr_has_any_prefix, url_has_any=url_has_any, httpuseragent_has_any=httpuseragent_has_any, eventresultdetails_in=eventresultdetails_in, eventresult=eventresult, disabled=disabled)
|
||||
parser (starttime=starttime, endtime=endtime, srcipaddr_has_any_prefix=srcipaddr_has_any_prefix, ipaddr_has_any_prefix=ipaddr_has_any_prefix, url_has_any=url_has_any, httpuseragent_has_any=httpuseragent_has_any, eventresultdetails_in=eventresultdetails_in, eventresult=eventresult, disabled=disabled)
|
||||
|
|
|
@ -36,10 +36,9 @@ let FailedLogon = SQlData
|
|||
| where EventLevelName has "error"
|
||||
| where RenderedDescription startswith "Login"
|
||||
| parse kind=regex RenderedDescription with "Login" LogonResult:string
|
||||
"for user '" CurrentUser:string
|
||||
"'. Reason:" Reason:string
|
||||
"provided" *
|
||||
| parse kind=regex RenderedDescription with * "CLIENT" * ":" ClientIP:string
|
||||
"for user '" CurrentUser:string
|
||||
"'. Reason:" Reason:string " \\[" *
|
||||
| parse kind=regex RenderedDescription with * "CLIENT" * ":" ClientIP:string
|
||||
"]" *
|
||||
;
|
||||
let dbfailedLogon = SQlData
|
||||
|
|
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Access_1.png
Normal file
После Ширина: | Высота: | Размер: 62 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Access_2.png
Normal file
После Ширина: | Высота: | Размер: 115 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Access_3.png
Normal file
После Ширина: | Высота: | Размер: 83 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Access_4.png
Normal file
После Ширина: | Высота: | Размер: 103 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Add_Contributor_Role_1.png
Normal file
После Ширина: | Высота: | Размер: 85 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Add_Contributor_Role_2.png
Normal file
После Ширина: | Высота: | Размер: 159 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Add_Contributor_Role_3.png
Normal file
После Ширина: | Высота: | Размер: 58 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Add_Contributor_Role_4.png
Normal file
После Ширина: | Высота: | Размер: 35 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Create_App_Registration_1.png
Normal file
После Ширина: | Высота: | Размер: 42 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Create_App_Registration_2.png
Normal file
После Ширина: | Высота: | Размер: 83 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Create_App_Registration_3.png
Normal file
После Ширина: | Высота: | Размер: 186 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Create_App_Registration_4.png
Normal file
После Ширина: | Высота: | Размер: 74 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Create_App_Registration_5.png
Normal file
После Ширина: | Высота: | Размер: 133 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Create_App_Registration_6.png
Normal file
После Ширина: | Высота: | Размер: 117 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Create_App_Registration_7.png
Normal file
После Ширина: | Высота: | Размер: 159 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Create_App_Registration_8.png
Normal file
После Ширина: | Высота: | Размер: 123 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Demo_1.png
Normal file
После Ширина: | Высота: | Размер: 34 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Demo_2.png
Normal file
После Ширина: | Высота: | Размер: 34 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Deploy_1.png
Normal file
После Ширина: | Высота: | Размер: 106 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Deploy_2.png
Normal file
После Ширина: | Высота: | Размер: 180 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Deploy_3.png
Normal file
После Ширина: | Высота: | Размер: 92 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Key_Vault_1.png
Normal file
После Ширина: | Высота: | Размер: 86 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Key_Vault_2.png
Normal file
После Ширина: | Высота: | Размер: 53 KiB |
Двоичные данные
Playbooks/AS-Delete-App-Registration/Images/DeleteAppRegistration_Key_Vault_3.png
Normal file
После Ширина: | Высота: | Размер: 60 KiB |
|
@ -0,0 +1,176 @@
|
|||
# AS-Delete-App-Registration
|
||||
|
||||
Author: Accelerynt
|
||||
|
||||
For any technical questions, please contact info@accelerynt.com
|
||||
|
||||
[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FPlaybooks%2FAS-Delete-App-Registration%2Fazuredeploy.json)
|
||||
[![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FPlaybooks%2FAS-Delete-App-Registration%2Fazuredeploy.json)
|
||||
|
||||
This playbook is intended to be run from a Microsoft Sentinel incident. If any app registration entities are found (i.e. any entities where kind == CloudApplication), they will be deleted. This playbook matches by name, since a unique app registration ID cannot currently be pulled into the entity list, so if there are multiple app registrations exactly matching the name(s) of the CloudApplication entities, all will be deleted. The deleted app registration(s) will be noted in incident comment(s).
|
||||
|
||||
> **Warning**
|
||||
> If there are multiple app registrations exactly matching the name(s) of the CloudApplication entities in the Microsoft incident used to run this playbook, all of those app registrations will be deleted
|
||||
|
||||
![DeleteAppRegistration_Demo_1](Images/DeleteAppRegistration_Demo_1.png)
|
||||
|
||||
![DeleteAppRegistration_Demo_2](Images/DeleteAppRegistration_Demo_2.png)
|
||||
|
||||
|
||||
#
|
||||
### Requirements
|
||||
|
||||
The following items are required under the template settings during deployment:
|
||||
|
||||
* An [App Registration](https://github.com/Azure/Azure-Sentinel/tree/master/Playbooks/AS-Delete-App-Registration#create-an-app-registration) for using the Microsoft Graph API
|
||||
* An [Azure Key Vault Secret](https://github.com/Azure/Azure-Sentinel/tree/master/Playbooks/AS-Delete-App-Registration#create-an-azure-key-vault-secret) containing your App Registration Secret
|
||||
|
||||
|
||||
#
|
||||
### Setup
|
||||
|
||||
#### Create an App Registration:
|
||||
|
||||
Navigate to the Navigate to the Microsoft Azure Active Directory App Registrations page:
|
||||
|
||||
https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade
|
||||
|
||||
From there, click "**New registration**".
|
||||
|
||||
![DeleteAppRegistration_Create_App_Registration_1](Images/DeleteAppRegistration_Create_App_Registration_1.png)
|
||||
|
||||
Select a name for your App Registration, such as "**AS-Delete-App-Registration-Playbook**", then click "**Register**".
|
||||
|
||||
![DeleteAppRegistration_Create_App_Registration_2](Images/DeleteAppRegistration_Create_App_Registration_2.png)
|
||||
|
||||
From the application menu blade, select "**API permissions**" and then click "**Add a permission**". Click the "**Microsoft Graph**" category.
|
||||
|
||||
![DeleteAppRegistration_Create_App_Registration_3](Images/DeleteAppRegistration_Create_App_Registration_3.png)
|
||||
|
||||
Under "**Application permissions**", search for "**Application.ReadWrite.All**", then select the corresponding checkbox. Click "**Add permissions**".
|
||||
|
||||
![DeleteAppRegistration_Create_App_Registration_4](Images/DeleteAppRegistration_Create_App_Registration_4.png)
|
||||
|
||||
In order for these permissions to be applied, admin consent must also be granted. Click the indicated "**Grant admin consent**" button on the "**API permissions**" page.
|
||||
![DeleteAppRegistration_Create_App_Registration_5_consent](Images/DeleteAppRegistration_Create_App_Registration_5.png)
|
||||
|
||||
Navigate back to the "**Overview**" section on the menu and take note of the "**Application (client) ID**" and "**Directory (tenant) ID**, as each will be needed for the deployment of this playbook. Click "**Add a certificate or secret**".
|
||||
|
||||
![DeleteAppRegistration_Create_App_Registration_6](Images/DeleteAppRegistration_Create_App_Registration_6.png)
|
||||
|
||||
Click "**New client secret"**". After adding a description and selecting an expiration date, click "**Add**".
|
||||
|
||||
![DeleteAppRegistration_Create_App_Registration_7](Images/DeleteAppRegistration_Create_App_Registration_7.png)
|
||||
|
||||
Copy the generated "**Value**" and save it for the next step, [Create an Azure Key Vault Secret](https://github.com/Azure/Azure-Sentinel/tree/master/Playbooks/AS-Delete-App-Registration#create-an-azure-key-vault-secret).
|
||||
|
||||
![DeleteAppRegistration_Create_App_Registration_8](Images/DeleteAppRegistration_Create_App_Registration_8.png)
|
||||
|
||||
|
||||
#### Create an Azure Key Vault Secret:
|
||||
|
||||
Navigate to the Azure Key Vaults page: https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/Microsoft.KeyVault%2Fvaults
|
||||
|
||||
Navigate to an existing Key Vault or create a new one. From the Key Vault overview page, click the "**Secrets**" menu option, found under the "**Settings**" section. Click "**Generate/Import**".
|
||||
|
||||
![DeleteAppRegistration_Key_Vault_1](Images/DeleteAppRegistration_Key_Vault_1.png)
|
||||
|
||||
Choose a name for the secret, such as "**AS-Delete-App-Registration-Playbook-App-Registration-Secret**", and enter the App Registration Secret copied previously in the "**Value**" field. All other settings can be left as is. Click "**Create**".
|
||||
|
||||
![DeleteAppRegistration_Key_Vault_2](Images/DeleteAppRegistration_Key_Vault_2.png)
|
||||
|
||||
Once your secret has been added to the vault, navigate to the "**Access policies**" menu option on the Key Vault page menu. Leave this page open, as you will need to return to it once the playbook has been deployed. See [Granting Access to Azure Key Vault](https://github.com/Azure/Azure-Sentinel/tree/master/Playbooks/AS-Delete-App-Registration#granting-access-to-azure-key-vault).
|
||||
|
||||
![DeleteAppRegistration_Key_Vault_3](Images/DeleteAppRegistration_Key_Vault_3.png)
|
||||
|
||||
|
||||
#
|
||||
### Deployment
|
||||
|
||||
To configure and deploy this playbook:
|
||||
|
||||
Open your browser and ensure you are logged into your Microsoft Sentinel workspace. In a separate tab, open the link to our playbook on the Accelerynt Security GitHub Repository:
|
||||
|
||||
https://github.com/Accelerynt-Security/AS-Delete-App-Registration
|
||||
|
||||
[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FPlaybooks%2FAS-Delete-App-Registration%2Fazuredeploy.json)
|
||||
[![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FPlaybooks%2FAS-Delete-App-Registration%2Fazuredeploy.json)
|
||||
|
||||
Click the "**Deploy to Azure**" button at the bottom and it will bring you to the custom deployment template.
|
||||
|
||||
In the **Project Details** section:
|
||||
|
||||
* Select the "**Subscription**" and "**Resource Group**" from the dropdown boxes you would like the playbook deployed to.
|
||||
|
||||
In the **Instance Details** section:
|
||||
|
||||
* **Playbook Name**: This can be left as "**AS-Delete-App-Registration**" or you may change it.
|
||||
|
||||
* **App Registration ID**: Enter the value of the Application (client) ID referenced in [Create an App Registration](https://github.com/Azure/Azure-Sentinel/tree/master/Playbooks/AS-Delete-App-Registration#create-an-app-registration).
|
||||
|
||||
* **App Registration Tenant**: Enter the value of the Directory (tenant) ID referenced in [Create an App Registration](https://github.com/Azure/Azure-Sentinel/tree/master/Playbooks/AS-Delete-App-Registration#create-an-app-registration).
|
||||
|
||||
* **Key Vault Name**: Enter the name of the Key Vault referenced in [Create an Azure Key Vault Secret](https://github.com/Azure/Azure-Sentinel/tree/master/Playbooks/AS-Delete-App-Registration#create-an-azure-key-vault-secret).
|
||||
|
||||
* **Secret Name**: Enter the name of the Key Vault Secret created in [Create an Azure Key Vault Secret](https://github.com/Azure/Azure-Sentinel/tree/master/Playbooks/AS-Delete-App-Registration#create-an-azure-key-vault-secret).
|
||||
|
||||
Towards the bottom, click on "**Review + create**".
|
||||
|
||||
![DeleteAppRegistration_Deploy_1](Images/DeleteAppRegistration_Deploy_1.png)
|
||||
|
||||
Once the resources have validated, click on "**Create**".
|
||||
|
||||
![DeleteAppRegistration_Deploy_2](Images/DeleteAppRegistration_Deploy_2.png)
|
||||
|
||||
The resources should take around a minute to deploy. Once the deployment is complete, you can expand the "**Deployment details**" section to view them.
|
||||
Click the one corresponding to the Logic App.
|
||||
|
||||
![DeleteAppRegistration_Deploy_3](Images/DeleteAppRegistration_Deploy_3.png)
|
||||
|
||||
|
||||
#
|
||||
### Granting Access to Azure Key Vault
|
||||
|
||||
Before the Logic App can run successfully, the Key Vault connection created during deployment must be granted access to the Key Vault storing your App Registration Secret.
|
||||
|
||||
From the Key Vault "**Access policies**" page, click "**Create**".
|
||||
|
||||
![DeleteAppRegistration_Access_1](Images/DeleteAppRegistration_Access_1.png)
|
||||
|
||||
Select the "**Get**" checkbox in the "**Secret permissions**" section. Then click "**Next**".
|
||||
|
||||
![DeleteAppRegistration_Access_2](Images/DeleteAppRegistration_Access_2.png)
|
||||
|
||||
From the "**Principal**" page, paste "**AS-Delete-App-Registration**", or the alternative playbook name you used, into the search box and click the option that appears. Click "**Next**".
|
||||
|
||||
* Note that if the same name is used for the app registration and playbook, you will see two options here, which can be hard to differentiate. In this case, you would want to select the option whose ID does **not** match the app registration (client) ID.
|
||||
|
||||
![DeleteAppRegistration_Access_3](Images/DeleteAppRegistration_Access_3.png)
|
||||
|
||||
Click "**Next**" in the application section. Then from the "**Review + create**" page, click "**Create**".
|
||||
|
||||
![DeleteAppRegistration_Access_4](Images/DeleteAppRegistration_Access_4.png)
|
||||
|
||||
|
||||
#
|
||||
### Microsoft Sentinel Contributor Role
|
||||
|
||||
After deployment, you will need to give the system assigned managed identity the "**Microsoft Sentinel Contributor**" role. This will enable it to add comments to incidents. Navigate to the Log Analytics Workspaces page and select the same workspace the playbook is located in:
|
||||
|
||||
https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/Microsoft.OperationalInsights%2Fworkspaces
|
||||
|
||||
Select the "**Access control (IAM)**" option from the menu blade, then click "**Add role assignment**".
|
||||
|
||||
![DeleteAppRegistration_Add_Contributor_Role_1](Images/DeleteAppRegistration_Add_Contributor_Role_1.png)
|
||||
|
||||
Select the "**Microsoft Sentinel Contributor**" role, then click "**Next**".
|
||||
|
||||
![DeleteAppRegistration_Add_Contributor_Role_2](Images/DeleteAppRegistration_Add_Contributor_Role_2.png)
|
||||
|
||||
Select the "**Managed identity**" option, then click "**Select Members**". Under the subscription the logic app is located, set the value of "**Managed identity**" to "**Logic app**". Next, enter "**AS-Delete-App-Registration**", or the alternative playbook name used during deployment, in the field labeled "**Select**". Select the playbook, then click "**Select**".
|
||||
|
||||
![DeleteAppRegistration_Add_Contributor_Role_3](Images/DeleteAppRegistration_Add_Contributor_Role_3.png)
|
||||
|
||||
Continue on to the "**Review + assign**" tab and click "**Review + assign**".
|
||||
|
||||
![DeleteAppRegistration_Add_Contributor_Role_4](Images/DeleteAppRegistration_Add_Contributor_Role_4.png)
|
|
@ -0,0 +1,283 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"metadata": {
|
||||
"title": "AS-Delete-App-Registration",
|
||||
"description": "This playbook is intended to be run from a Microsoft Sentinel incident. If any app registration entities are found (i.e., any entities where kind == CloudApplication), they will be deleted. This playbook matches by name, since a unique app registration ID cannot currently be pulled into the entity list, so if there are multiple app registrations exactly matching the name(s) of the CloudApplication entities, all will be deleted.",
|
||||
"prerequisites": "1. A Microsoft Azure App Registration is needed for the Microsoft Graph API. 2. A Microsoft Azure key vault containing the app registration secret must also be set up. Support for the set up and configuration of each of these items can be found here: https://github.com/Accelerynt-Security/AS-Delete-App-Registration",
|
||||
"lastUpdateTime": "2023-06-15T19:35:47Z",
|
||||
"entities": ["CloudApplication"],
|
||||
"tags": ["Microsoft Sentinel", "Incident", "App Registration", "CloudApplication"],
|
||||
"support": {
|
||||
"tier": "partner"
|
||||
},
|
||||
"author": {
|
||||
"name": "Accelerynt"
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
"PlaybookName": {
|
||||
"defaultValue": "AS-Delete-App-Registration",
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Name of the Logic Apps resource to be created"
|
||||
}
|
||||
},
|
||||
"AppRegistrationID": {
|
||||
"type": "string",
|
||||
"metadata" : {
|
||||
"description" : "Application (client) ID of the App Registration"
|
||||
}
|
||||
},
|
||||
"AppRegistrationTenant": {
|
||||
"type": "string",
|
||||
"metadata" : {
|
||||
"description" : "Directory (tenant) ID of the App Registration"
|
||||
}
|
||||
},
|
||||
"KeyVaultName": {
|
||||
"type": "string",
|
||||
"metadata" : {
|
||||
"description" : "Name of the Key Vault that stores the App Registration Secret"
|
||||
}
|
||||
},
|
||||
"SecretName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Name of Key Vault Secret that contains the value of the App Registration Secret"
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"azuresentinel": "[concat('azuresentinel-', parameters('PlaybookName'))]",
|
||||
"keyvault": "[concat('keyvault-', parameters('PlaybookName'))]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Web/connections",
|
||||
"apiVersion": "2016-06-01",
|
||||
"name": "[variables('azuresentinel')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"kind": "V1",
|
||||
"properties": {
|
||||
"displayName": "[parameters('PlaybookName')]",
|
||||
"customParameterValues": {},
|
||||
"parameterValueType": "Alternative",
|
||||
"api": {
|
||||
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuresentinel')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Web/connections",
|
||||
"apiVersion": "2016-06-01",
|
||||
"name": "[variables('keyvault')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"kind": "V1",
|
||||
"properties": {
|
||||
"displayName": "[parameters('PlaybookName')]",
|
||||
"parameterValueType": "Alternative",
|
||||
"alternativeParameterValues": {
|
||||
"vaultName": "[parameters('KeyVaultName')]"
|
||||
},
|
||||
"customParameterValues": {
|
||||
},
|
||||
"api": {
|
||||
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/keyvault')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Logic/workflows",
|
||||
"apiVersion": "2017-07-01",
|
||||
"name": "[parameters('PlaybookName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"LogicAppsCategory": "security"
|
||||
},
|
||||
"identity": {
|
||||
"type": "SystemAssigned"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Web/connections', variables('azuresentinel'))]",
|
||||
"[resourceId('Microsoft.Web/connections', variables('keyvault'))]"
|
||||
],
|
||||
"properties": {
|
||||
"state": "Enabled",
|
||||
"definition": {
|
||||
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"$connections": {
|
||||
"defaultValue": {},
|
||||
"type": "Object"
|
||||
}
|
||||
},
|
||||
"triggers": {
|
||||
"Microsoft_Sentinel_incident": {
|
||||
"type": "ApiConnectionWebhook",
|
||||
"inputs": {
|
||||
"body": {
|
||||
"callback_url": "@{listCallbackUrl()}"
|
||||
},
|
||||
"host": {
|
||||
"connection": {
|
||||
"name": "@parameters('$connections')['azuresentinel']['connectionId']"
|
||||
}
|
||||
},
|
||||
"path": "/incident-creation"
|
||||
}
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
"Get_Secret": {
|
||||
"runAfter": {},
|
||||
"type": "ApiConnection",
|
||||
"inputs": {
|
||||
"host": {
|
||||
"connection": {
|
||||
"name": "@parameters('$connections')['keyvault']['connectionId']"
|
||||
}
|
||||
},
|
||||
"method": "get",
|
||||
"path": "[concat('/secrets/@{encodeURIComponent(''', parameters('SecretName'), ''')}/value')]"
|
||||
}
|
||||
},
|
||||
"For_each_-_Entity": {
|
||||
"foreach": "@triggerBody()?['object']?['properties']?['relatedEntities']",
|
||||
"actions": {
|
||||
"Condition_-_Check_if_entity_is_app_registration": {
|
||||
"actions": {
|
||||
"For_each_-_App_Registration": {
|
||||
"foreach": "@body('HTTP_-_Get_App_Registrations')?['value']",
|
||||
"actions": {
|
||||
"Condition_-_Check_for_name_match": {
|
||||
"actions": {
|
||||
"Add_comment_to_incident_(V3)": {
|
||||
"inputs": {
|
||||
"body": {
|
||||
"incidentArmId": "@triggerBody()?['object']?['id']",
|
||||
"message": "<p>- <strong>Deleted App Registration</strong> -<br>\nName: @{items('For_each_-_App_Registration')?['displayName']}<br>\nID: @{items('For_each_-_App_Registration')?['id']}</p>"
|
||||
},
|
||||
"host": {
|
||||
"connection": {
|
||||
"name": "@parameters('$connections')['azuresentinel']['connectionId']"
|
||||
}
|
||||
},
|
||||
"method": "post",
|
||||
"path": "/Incidents/Comment"
|
||||
},
|
||||
"runAfter": {
|
||||
"HTTP_-_Delete_App_Registration": [
|
||||
"Succeeded"
|
||||
]
|
||||
},
|
||||
"type": "ApiConnection"
|
||||
},
|
||||
"HTTP_-_Delete_App_Registration": {
|
||||
"runAfter": {},
|
||||
"type": "Http",
|
||||
"inputs": {
|
||||
"authentication": {
|
||||
"audience": "https://graph.microsoft.com",
|
||||
"clientId": "[parameters('AppRegistrationID')]",
|
||||
"secret": "@body('Get_Secret')?['value']",
|
||||
"tenant": "[parameters('AppRegistrationTenant')]",
|
||||
"type": "ActiveDirectoryOAuth"
|
||||
},
|
||||
"method": "DELETE",
|
||||
"uri": "https://graph.microsoft.com/v1.0/applications/@{items('For_each_-_App_Registration')?['id']}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"runAfter": {},
|
||||
"expression": {
|
||||
"and": [
|
||||
{
|
||||
"equals": [
|
||||
"@items('For_each_-_App_Registration')?['displayName']",
|
||||
"@items('For_each_-_Entity')?['properties']?['appName']"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "If"
|
||||
}
|
||||
},
|
||||
"runAfter": {
|
||||
"HTTP_-_Get_App_Registrations": [
|
||||
"Succeeded"
|
||||
]
|
||||
},
|
||||
"type": "Foreach"
|
||||
},
|
||||
"HTTP_-_Get_App_Registrations": {
|
||||
"runAfter": {},
|
||||
"type": "Http",
|
||||
"inputs": {
|
||||
"authentication": {
|
||||
"audience": "https://graph.microsoft.com",
|
||||
"clientId": "[parameters('AppRegistrationID')]",
|
||||
"secret": "@body('Get_Secret')?['value']",
|
||||
"tenant": "[parameters('AppRegistrationTenant')]",
|
||||
"type": "ActiveDirectoryOAuth"
|
||||
},
|
||||
"method": "GET",
|
||||
"uri": "https://graph.microsoft.com/v1.0/applications?$select=id,displayName"
|
||||
}
|
||||
}
|
||||
},
|
||||
"runAfter": {},
|
||||
"expression": {
|
||||
"and": [
|
||||
{
|
||||
"equals": [
|
||||
"@items('For_each_-_Entity')?['kind']",
|
||||
"CloudApplication"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "If"
|
||||
}
|
||||
},
|
||||
"runAfter": {
|
||||
"Get_Secret": [
|
||||
"Succeeded"
|
||||
]
|
||||
},
|
||||
"type": "Foreach"
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
},
|
||||
"parameters": {
|
||||
"$connections": {
|
||||
"value": {
|
||||
"azuresentinel": {
|
||||
"connectionId": "[resourceId('Microsoft.Web/connections', variables('azuresentinel'))]",
|
||||
"connectionName": "[variables('azuresentinel')]",
|
||||
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuresentinel')]",
|
||||
"connectionProperties": {
|
||||
"authentication": {
|
||||
"type": "ManagedServiceIdentity"
|
||||
}
|
||||
}
|
||||
},
|
||||
"keyvault": {
|
||||
"connectionId": "[resourceId('Microsoft.Web/connections', variables('keyvault'))]",
|
||||
"connectionName": "[variables('keyvault')]",
|
||||
"id": "[concat('/subscriptions/', subscription().subscriptionId,'/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/keyvault')]",
|
||||
"connectionProperties": {
|
||||
"authentication": {
|
||||
"type": "ManagedServiceIdentity"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
Двоичные данные
Playbooks/AS-Incident-IP-Matched-on-Watchlist/Images/IPMatchedOnWatchlist_Add_Contributor_Role_1.png
Normal file
После Ширина: | Высота: | Размер: 85 KiB |
Двоичные данные
Playbooks/AS-Incident-IP-Matched-on-Watchlist/Images/IPMatchedOnWatchlist_Add_Contributor_Role_2.png
Normal file
После Ширина: | Высота: | Размер: 159 KiB |
Двоичные данные
Playbooks/AS-Incident-IP-Matched-on-Watchlist/Images/IPMatchedOnWatchlist_Add_Contributor_Role_3.png
Normal file
После Ширина: | Высота: | Размер: 114 KiB |
Двоичные данные
Playbooks/AS-Incident-IP-Matched-on-Watchlist/Images/IPMatchedOnWatchlist_Add_Contributor_Role_4.png
Normal file
После Ширина: | Высота: | Размер: 71 KiB |
Двоичные данные
Playbooks/AS-Incident-IP-Matched-on-Watchlist/Images/IPMatchedOnWatchlist_Create_Watchlist_1.png
Normal file
После Ширина: | Высота: | Размер: 74 KiB |
Двоичные данные
Playbooks/AS-Incident-IP-Matched-on-Watchlist/Images/IPMatchedOnWatchlist_Create_Watchlist_2.png
Normal file
После Ширина: | Высота: | Размер: 19 KiB |
Двоичные данные
Playbooks/AS-Incident-IP-Matched-on-Watchlist/Images/IPMatchedOnWatchlist_Create_Watchlist_3.png
Normal file
После Ширина: | Высота: | Размер: 49 KiB |
Двоичные данные
Playbooks/AS-Incident-IP-Matched-on-Watchlist/Images/IPMatchedOnWatchlist_Create_Watchlist_4.png
Normal file
После Ширина: | Высота: | Размер: 25 KiB |
Двоичные данные
Playbooks/AS-Incident-IP-Matched-on-Watchlist/Images/IPMatchedOnWatchlist_Create_Watchlist_5.png
Normal file
После Ширина: | Высота: | Размер: 102 KiB |
Двоичные данные
Playbooks/AS-Incident-IP-Matched-on-Watchlist/Images/IPMatchedOnWatchlist_Demo_1.png
Normal file
После Ширина: | Высота: | Размер: 5.3 KiB |
Двоичные данные
Playbooks/AS-Incident-IP-Matched-on-Watchlist/Images/IPMatchedOnWatchlist_Demo_2.png
Normal file
После Ширина: | Высота: | Размер: 3.1 KiB |
Двоичные данные
Playbooks/AS-Incident-IP-Matched-on-Watchlist/Images/IPMatchedOnWatchlist_Deploy_1.png
Normal file
После Ширина: | Высота: | Размер: 100 KiB |
Двоичные данные
Playbooks/AS-Incident-IP-Matched-on-Watchlist/Images/IPMatchedOnWatchlist_Deploy_2.png
Normal file
После Ширина: | Высота: | Размер: 167 KiB |
Двоичные данные
Playbooks/AS-Incident-IP-Matched-on-Watchlist/Images/IPMatchedOnWatchlist_Deploy_3.png
Normal file
После Ширина: | Высота: | Размер: 86 KiB |
Двоичные данные
Playbooks/AS-Incident-IP-Matched-on-Watchlist/Images/IPMatchedOnWatchlist_Resource_Group_Name_1.png
Normal file
После Ширина: | Высота: | Размер: 75 KiB |
Двоичные данные
Playbooks/AS-Incident-IP-Matched-on-Watchlist/Images/IPMatchedOnWatchlist_Resource_Group_Name_2.png
Normal file
После Ширина: | Высота: | Размер: 73 KiB |
|
@ -0,0 +1,138 @@
|
|||
# AS-Incident-IP-Matched-on-Watchlist
|
||||
|
||||
Author: Accelerynt
|
||||
|
||||
For any technical questions, please contact info@accelerynt.com
|
||||
|
||||
[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FPlaybooks%2FAS-Incident-IP-Matched-on-Watchlist%2Fazuredeploy.json)
|
||||
[![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FPlaybooks%2FAS-Incident-IP-Matched-on-Watchlist%2Fazuredeploy.json)
|
||||
|
||||
This playbook is intended to be run from a Microsoft Sentinel incident. If any IP entities are found to match those in a specified watchlist containing a list of subnets, a comment noting the match(es) will be added to the incident and the incident will be tagged with a label of your choosing.
|
||||
|
||||
![IPMatchedOnWatchlist_Demo_1](Images/IPMatchedOnWatchlist_Demo_1.png)
|
||||
|
||||
![IPMatchedOnWatchlist_Demo_2](Images/IPMatchedOnWatchlist_Demo_2.png)
|
||||
|
||||
|
||||
#
|
||||
### Requirements
|
||||
|
||||
The following items are required under the template settings during deployment:
|
||||
|
||||
* A [Microsoft Sentinel Watchlist](https://github.com/Azure/Azure-Sentinel/tree/master/Playbooks/AS-Incident-IP-Matched-on-Watchlist#create-a-microsoft-sentinel-watchlist) containing subnets is needed
|
||||
|
||||
|
||||
#
|
||||
### Setup
|
||||
|
||||
#### Create a Microsoft Sentinel Watchlist:
|
||||
|
||||
If you already have a Microsoft Sentinel watchlist with subnet values, take note of the name and skip this step.
|
||||
|
||||
Otherwise, navigate to the Microsoft Sentinel page and select a workspace:
|
||||
|
||||
https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/microsoft.securityinsightsarg%2Fsentinel
|
||||
|
||||
Under the "**Configuration**" section of the menu, click "**Watchlist**", then click "**Add new**".
|
||||
|
||||
![IPMatchedOnWatchlist_Create_Watchlist_1](Images/IPMatchedOnWatchlist_Create_Watchlist_1.png)
|
||||
|
||||
Fill out the required fields and take note of the value you use for "**Alias**" as this will be needed for deployment. Then click "**Next: Source**".
|
||||
|
||||
![IPMatchedOnWatchlist_Create_Watchlist_2](Images/IPMatchedOnWatchlist_Create_Watchlist_2.png)
|
||||
|
||||
The watchlist cannot be created without initial data. A template for a watchlist containing subnets can be found here: https://learn.microsoft.com/en-us/azure/sentinel/watchlist-schemas#network-mapping
|
||||
|
||||
Upload your .csv file and be sure to select the field containing the subnet values as the search key. Then click "**Next: Review and create**".
|
||||
|
||||
![IPMatchedOnWatchlist_Create_Watchlist_3](Images/IPMatchedOnWatchlist_Create_Watchlist_3.png)
|
||||
|
||||
Review the information, then click "**Create**".
|
||||
|
||||
![IPMatchedOnWatchlist_Create_Watchlist_4](Images/IPMatchedOnWatchlist_Create_Watchlist_4.png)
|
||||
|
||||
Once your watchlist has been created, you can view the entries by clicking the watchlist name from the "**Overview**" page, and then clicking "**View in logs**". This will run a Kusto query for your watchlist and you should be able to see the initializing data that was just uploaded. Please note it may take a minute after the creation of your watchlist for the query to show results. Alternatively, the watchlist items can be edited by clicking "**Update watchlist**".
|
||||
|
||||
![IPMatchedOnWatchlist_Create_Watchlist_5](Images/IPMatchedOnWatchlist_Create_Watchlist_5.png)
|
||||
|
||||
|
||||
#### Microsoft Sentinel Resource Group Name:
|
||||
|
||||
Navigate to the Microsoft Sentinel page and select the same workspace as before:
|
||||
|
||||
https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/microsoft.securityinsightsarg%2Fsentinel
|
||||
|
||||
Under the "**Configuration**" section of the menu, click "**Settings**", then click the "**Workspace settings**" tab.
|
||||
|
||||
![IPMatchedOnWatchlist_Resource_Group_Name_1](Images/IPMatchedOnWatchlist_Resource_Group_Name_1.png)
|
||||
|
||||
Copy the value of the "**Resource Group Name**" field and save it for deployment. You will also need to take note of the workspace name.
|
||||
|
||||
![IPMatchedOnWatchlist_Resource_Group_Name_2](Images/IPMatchedOnWatchlist_Resource_Group_Name_2.png)
|
||||
|
||||
|
||||
#
|
||||
### Deployment
|
||||
|
||||
To configure and deploy this playbook:
|
||||
|
||||
Open your browser and ensure you are logged into your Microsoft Sentinel workspace. In a separate tab, open the link to our playbook on the Accelerynt Security GitHub Repository:
|
||||
|
||||
https://github.com/Accelerynt-Security/AS-Incident-IP-Matched-on-Watchlist
|
||||
|
||||
[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FPlaybooks%2FAS-Incident-IP-Matched-on-Watchlist%2Fazuredeploy.json)
|
||||
[![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FPlaybooks%2FAS-Incident-IP-Matched-on-Watchlist%2Fazuredeploy.json)
|
||||
|
||||
Click the "**Deploy to Azure**" button at the bottom and it will bring you to the custom deployment template.
|
||||
|
||||
In the **Project Details** section:
|
||||
|
||||
* Select the "**Subscription**" and "**Resource Group**" from the dropdown boxes you would like the playbook deployed to.
|
||||
|
||||
In the **Instance Details** section:
|
||||
|
||||
* **Playbook Name**: This can be left as "**AS-Incident-IP-Matched-on-Watchlist**" or you may change it.
|
||||
|
||||
* **Watchlist Name**: The name of the watchlist referenced in [Create a Microsoft Sentinel Watchlist](https://github.com/Accelerynt-Security/AS-Import-AD-Group-Users-to-MS-Watchlist#create-a-microsoft-sentinel-watchlist)
|
||||
|
||||
* **Workspace Name**: The name of the Microsoft Sentinel workspace the watchlist was created in, referenced in [Microsoft Sentinel Resource Group Name](https://github.com/Accelerynt-Security/AS-Import-AD-Group-Users-to-MS-Watchlist#microsoft-sentinel-resource-group-name)
|
||||
|
||||
* **Resource Group Name**: The name of the Microsoft Sentinel resource group the workspace is housed in, referenced in [Microsoft Sentinel Resource Group Name](https://github.com/Accelerynt-Security/AS-Import-AD-Group-Users-to-MS-Watchlist#microsoft-sentinel-resource-group-name)
|
||||
|
||||
* **Incident Tag**: The name of the tag to add to the Microsoft Sentinel incident
|
||||
|
||||
Towards the bottom, click on "**Review + create**".
|
||||
|
||||
![IPMatchedOnWatchlist_Deploy_1](Images/IPMatchedOnWatchlist_Deploy_1.png)
|
||||
|
||||
Once the resources have validated, click on "**Create**".
|
||||
|
||||
![IPMatchedOnWatchlist_Deploy_2](Images/IPMatchedOnWatchlist_Deploy_2.png)
|
||||
|
||||
The resources should take around a minute to deploy. Once the deployment is complete, you can expand the "**Deployment details**" section to view them.
|
||||
Click the one corresponding to the Logic App.
|
||||
|
||||
![IPMatchedOnWatchlist_Deploy_3](Images/IPMatchedOnWatchlist_Deploy_3.png)
|
||||
|
||||
#
|
||||
### Microsoft Sentinel Contributor Role
|
||||
|
||||
After deployment, you will need to give the system assigned managed identity the "**Microsoft Sentinel Contributor**" role. This will enable it to add comments to incidents. Navigate to the Log Analytics Workspaces page and select the same workspace the playbook is located in:
|
||||
|
||||
https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/Microsoft.OperationalInsights%2Fworkspaces
|
||||
|
||||
Select the "**Access control (IAM)**" option from the menu blade, then click "**Add role assignment**".
|
||||
|
||||
![IPMatchedOnWatchlist_Add_Contributor_Role_1](Images/IPMatchedOnWatchlist_Add_Contributor_Role_1.png)
|
||||
|
||||
Select the "**Microsoft Sentinel Contributor**" role, then click "**Next**".
|
||||
|
||||
![IPMatchedOnWatchlist_Add_Contributor_Role_2](Images/IPMatchedOnWatchlist_Add_Contributor_Role_2.png)
|
||||
|
||||
Select the "**Managed identity**" option, then click "**Select Members**". Under the subscription the logic app is located, set the value of "**Managed identity**" to "**Logic app**". Next, enter "**AS-Incident-IP-Matched-on-Watchlist**", or the alternative playbook name used during deployment, in the field labeled "**Select**". Select the playbook, then click "**Select**".
|
||||
|
||||
![IPMatchedOnWatchlist_Add_Contributor_Role_3](Images/IPMatchedOnWatchlist_Add_Contributor_Role_3.png)
|
||||
|
||||
Continue on to the "**Review + assign**" tab and click "**Review + assign**".
|
||||
|
||||
![IPMatchedOnWatchlist_Add_Contributor_Role_4](Images/IPMatchedOnWatchlist_Add_Contributor_Role_4.png)
|
|
@ -0,0 +1,328 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"metadata": {
|
||||
"title": "AS-Incident-IP-Matched-on-Watchlist",
|
||||
"description": "This playbook is intended to be run from a Microsoft Sentinel incident. If any IP entities are found to match those in a specified watchlist containing a list of subnets, a comment noting this match will be added to the incident and the incident will be tagged with a label of your choosing.",
|
||||
"prerequisites": "1. A Microsoft Sentinel watchlist containing subnets is needed",
|
||||
"postDeployment": ["Assign Microsoft Sentinel Contributor role to playbook over Log Analytics Workspace."],
|
||||
"lastUpdateTime": "2023-05-30T17:19:47Z",
|
||||
"entities": ["IP"],
|
||||
"tags": ["Microsoft Sentinel", "Incident", "Watchlist", "Subnet"],
|
||||
"support": {
|
||||
"tier": "partner"
|
||||
},
|
||||
"author": {
|
||||
"name": "Accelerynt"
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
"PlaybookName": {
|
||||
"defaultValue": "AS-Incident-IP-Matched-on-Watchlist",
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Name of the Logic App resource to be created"
|
||||
}
|
||||
},
|
||||
"WatchlistName": {
|
||||
"type": "string",
|
||||
"metadata" : {
|
||||
"description" : "Name of the watchlist to check incident IP addresses against"
|
||||
}
|
||||
},
|
||||
"WorkspaceName": {
|
||||
"type": "string",
|
||||
"metadata" : {
|
||||
"description" : "Name of the Microsoft Sentinel workspace the watchlist is housed in"
|
||||
}
|
||||
},
|
||||
"ResourceGroupName": {
|
||||
"type": "string",
|
||||
"metadata" : {
|
||||
"description" : "Name of the Microsoft Sentinel resource group the workspace is housed in"
|
||||
}
|
||||
},
|
||||
"IncidentTag": {
|
||||
"type": "string",
|
||||
"metadata" : {
|
||||
"description" : "Name of the tag to add to the Microsoft Sentinel incident"
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"azuremonitorlogs": "[concat('azuremonitorlogs-', parameters('PlaybookName'))]",
|
||||
"azuresentinel": "[concat('azuresentinel-', parameters('PlaybookName'))]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Web/connections",
|
||||
"apiVersion": "2016-06-01",
|
||||
"name": "[variables('azuremonitorlogs')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"displayName": "[parameters('PlaybookName')]",
|
||||
"customParameterValues": {},
|
||||
"api": {
|
||||
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuremonitorlogs')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Web/connections",
|
||||
"apiVersion": "2016-06-01",
|
||||
"name": "[variables('azuresentinel')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"kind": "V1",
|
||||
"properties": {
|
||||
"displayName": "[parameters('PlaybookName')]",
|
||||
"customParameterValues": {},
|
||||
"parameterValueType": "Alternative",
|
||||
"api": {
|
||||
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuresentinel')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Logic/workflows",
|
||||
"apiVersion": "2017-07-01",
|
||||
"name": "[parameters('PlaybookName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"LogicAppsCategory": "security"
|
||||
},
|
||||
"identity": {
|
||||
"type": "SystemAssigned"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Web/connections', variables('azuresentinel'))]",
|
||||
"[resourceId('Microsoft.Web/connections', variables('azuremonitorlogs'))]"
|
||||
],
|
||||
"properties": {
|
||||
"state": "Enabled",
|
||||
"definition": {
|
||||
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"$connections": {
|
||||
"defaultValue": {},
|
||||
"type": "Object"
|
||||
}
|
||||
},
|
||||
"triggers": {
|
||||
"Microsoft_Sentinel_incident": {
|
||||
"type": "ApiConnectionWebhook",
|
||||
"inputs": {
|
||||
"body": {
|
||||
"callback_url": "@{listCallbackUrl()}"
|
||||
},
|
||||
"host": {
|
||||
"connection": {
|
||||
"name": "@parameters('$connections')['azuresentinel']['connectionId']"
|
||||
}
|
||||
},
|
||||
"path": "/incident-creation"
|
||||
}
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
"Condition_-_Check_for_IPs": {
|
||||
"actions": {
|
||||
"Add_comment_to_incident_(V3)": {
|
||||
"runAfter": {
|
||||
"For_each_-_Query_result": [
|
||||
"Succeeded"
|
||||
]
|
||||
},
|
||||
"type": "ApiConnection",
|
||||
"inputs": {
|
||||
"body": {
|
||||
"incidentArmId": "@triggerBody()?['object']?['id']",
|
||||
"message": "<p>@{variables('Incident Comment')}</p>"
|
||||
},
|
||||
"host": {
|
||||
"connection": {
|
||||
"name": "@parameters('$connections')['azuresentinel']['connectionId']"
|
||||
}
|
||||
},
|
||||
"method": "post",
|
||||
"path": "/Incidents/Comment"
|
||||
}
|
||||
},
|
||||
"For_each_-_Query_result": {
|
||||
"foreach": "@body('Run_query_and_list_results')?['value']",
|
||||
"actions": {
|
||||
"Append_to_string_variable": {
|
||||
"runAfter": {},
|
||||
"type": "AppendToStringVariable",
|
||||
"inputs": {
|
||||
"name": "Incident Comment",
|
||||
"value": "[concat('IP address @{items(''For_each_-_Query_result'')?[''address'']} matched in ', parameters('WatchlistName'), ' watchlist \nSubnet: @{items(''For_each_-_Query_result'')?[''SearchKey'']}\n\n')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
"runAfter": {
|
||||
"Run_query_and_list_results": [
|
||||
"Succeeded"
|
||||
]
|
||||
},
|
||||
"type": "Foreach"
|
||||
},
|
||||
"Run_query_and_list_results": {
|
||||
"runAfter": {},
|
||||
"type": "ApiConnection",
|
||||
"inputs": {
|
||||
"body": "[concat('let Incident_IPs = datatable(address:string)\n@{variables(''IP Addresses'')};\nIncident_IPs\n| evaluate ipv4_lookup(_GetWatchlist(''', parameters('WatchlistName'),'''), address, SearchKey)\n')]",
|
||||
"host": {
|
||||
"connection": {
|
||||
"name": "@parameters('$connections')['azuremonitorlogs']['connectionId']"
|
||||
}
|
||||
},
|
||||
"method": "post",
|
||||
"path": "/queryData",
|
||||
"queries": {
|
||||
"resourcegroups": "[parameters('ResourceGroupName')]",
|
||||
"resourcename": "[parameters('WorkspaceName')]",
|
||||
"resourcetype": "Log Analytics Workspace",
|
||||
"subscriptions": "[subscription().subscriptionId]",
|
||||
"timerange": "@{addDays(utcNow(), -10000)}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Update_incident": {
|
||||
"runAfter": {
|
||||
"Add_comment_to_incident_(V3)": [
|
||||
"Succeeded"
|
||||
]
|
||||
},
|
||||
"type": "ApiConnection",
|
||||
"inputs": {
|
||||
"body": {
|
||||
"incidentArmId": "@triggerBody()?['object']?['id']",
|
||||
"tagsToAdd": {
|
||||
"TagsToAdd": [
|
||||
{
|
||||
"Tag": "[parameters('IncidentTag')]"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"host": {
|
||||
"connection": {
|
||||
"name": "@parameters('$connections')['azuresentinel']['connectionId']"
|
||||
}
|
||||
},
|
||||
"method": "put",
|
||||
"path": "/Incidents"
|
||||
}
|
||||
}
|
||||
},
|
||||
"runAfter": {
|
||||
"Initialize_variable_-_Incident_Comment": [
|
||||
"Succeeded"
|
||||
]
|
||||
},
|
||||
"expression": {
|
||||
"and": [
|
||||
{
|
||||
"greater": [
|
||||
"@length(variables('IP Addresses'))",
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "If"
|
||||
},
|
||||
"Entities_-_Get_IPs": {
|
||||
"runAfter": {},
|
||||
"type": "ApiConnection",
|
||||
"inputs": {
|
||||
"body": "@triggerBody()?['object']?['properties']?['relatedEntities']",
|
||||
"host": {
|
||||
"connection": {
|
||||
"name": "@parameters('$connections')['azuresentinel']['connectionId']"
|
||||
}
|
||||
},
|
||||
"method": "post",
|
||||
"path": "/entities/ip"
|
||||
}
|
||||
},
|
||||
"For_each_-_Entity_IP": {
|
||||
"foreach": "@body('Entities_-_Get_IPs')?['IPs']",
|
||||
"actions": {
|
||||
"Append_to_array_variable": {
|
||||
"runAfter": {},
|
||||
"type": "AppendToArrayVariable",
|
||||
"inputs": {
|
||||
"name": "IP Addresses",
|
||||
"value": "@items('For_each_-_Entity_IP')?['Address']"
|
||||
}
|
||||
}
|
||||
},
|
||||
"runAfter": {
|
||||
"Initialize_variable_-_IP_Addresses": [
|
||||
"Succeeded"
|
||||
]
|
||||
},
|
||||
"type": "Foreach"
|
||||
},
|
||||
"Initialize_variable_-_IP_Addresses": {
|
||||
"runAfter": {
|
||||
"Entities_-_Get_IPs": [
|
||||
"Succeeded"
|
||||
]
|
||||
},
|
||||
"type": "InitializeVariable",
|
||||
"inputs": {
|
||||
"variables": [
|
||||
{
|
||||
"name": "IP Addresses",
|
||||
"type": "array"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"Initialize_variable_-_Incident_Comment": {
|
||||
"runAfter": {
|
||||
"For_each_-_Entity_IP": [
|
||||
"Succeeded"
|
||||
]
|
||||
},
|
||||
"type": "InitializeVariable",
|
||||
"inputs": {
|
||||
"variables": [
|
||||
{
|
||||
"name": "Incident Comment",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
},
|
||||
"parameters": {
|
||||
"$connections": {
|
||||
"value": {
|
||||
"azuremonitorlogs": {
|
||||
"connectionId": "[resourceId('Microsoft.Web/connections', variables('azuremonitorlogs'))]",
|
||||
"connectionName": "[variables('azuremonitorlogs')]",
|
||||
"id": "[concat('/subscriptions/', subscription().subscriptionId,'/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuremonitorlogs')]"
|
||||
},
|
||||
"azuresentinel": {
|
||||
"connectionId": "[resourceId('Microsoft.Web/connections', variables('azuresentinel'))]",
|
||||
"connectionName": "[variables('azuresentinel')]",
|
||||
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuresentinel')]",
|
||||
"connectionProperties": {
|
||||
"authentication": {
|
||||
"type": "ManagedServiceIdentity"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
"metadata": {
|
||||
"title": "Enrich multiple entities - AlienVault-OTX",
|
||||
"description": "This playbook will enrich a Sentinel Incident with pulse information from AlienVault OTX. If any pulses are found the Incident will also be tagged and the severity raised to High.",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"mainSteps": [ "The following entity types will be enriched with this playbook: \n\n - IP \n\n - URL \n\n - File hash \n\n - DNS" ],
|
||||
"prerequisites": [ "After deploying the the playbook you will need to grant the playbook's Managed Identity \n\n **Microsoft Sentinel Responder** \n\n (or greater) access to the resource group where Microsoft Sentinel is installed. This gives the Managed Identity the necessary permissions to add comments, tags, and change incident severity." ],
|
||||
"lastUpdateTime": "2022-07-25T10:00:00.000Z",
|
||||
|
@ -20,6 +20,13 @@
|
|||
"name": "Brian Delaney"
|
||||
},
|
||||
"releaseNotes": [
|
||||
{
|
||||
"version": "1.0.1",
|
||||
"title": "Enrich multiple entities - AlienVault-OTX",
|
||||
"notes": [
|
||||
"Added encodeUriComponent(..) to HTTP_-_OTX_URL step to avoid 404 when URL contains special characters"
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"title": "Enrich multiple entities - AlienVault-OTX",
|
||||
|
@ -555,7 +562,7 @@
|
|||
"type": "Http",
|
||||
"inputs": {
|
||||
"method": "GET",
|
||||
"uri": "https://otx.alienvault.com/api/v1/indicators/url/@{items('For_each_URL')?['Url']}/general"
|
||||
"uri": "https://otx.alienvault.com/api/v1/indicators/url/@{encodeUriComponent(items('For_each_URL')?['Url'])}/general"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|