diff --git a/ASIM/schemas/ASimFileEvent.yaml b/ASIM/schemas/ASimFileEvent.yaml index c261903452e..47a6d10a1f8 100644 --- a/ASIM/schemas/ASimFileEvent.yaml +++ b/ASIM/schemas/ASimFileEvent.yaml @@ -1,6 +1,6 @@ Schema: Schema: FileEvent - Version: '0.2.2' + Version: '0.2.3' Last Updated: Sept 12 2023 References: - Title: ASIM File Event Schema @@ -183,9 +183,9 @@ Fields: - Name: Hash Type: string - Class: Conditional + Class: Alias Description: Alias to the best available Target File hash. - Follows: [TargetFileMD5, TargetFileSHA1, TargetFileSHA256, TargetFileSHA512] + Aliases: [TargetFileMD5, TargetFileSHA1, TargetFileSHA256, TargetFileSHA512] - Name: HashType Class: Conditional diff --git a/ASIM/schemas/ASimProcessEvent.yaml b/ASIM/schemas/ASimProcessEvent.yaml index e1f791ec06a..8ccb4cdfe93 100644 --- a/ASIM/schemas/ASimProcessEvent.yaml +++ b/ASIM/schemas/ASimProcessEvent.yaml @@ -1,6 +1,6 @@ Schema: Schema: ProcessEvent - Version: '0.1.4' + Version: '0.1.5' Last Updated: Mar 06, 2023 References: - Title: ASIM Process Event Schema @@ -17,6 +17,8 @@ Include: # Common fields - Name: Event Fields File: common/ASimEventFields.yaml +- Name: Inspection fields + File: common/ASimInspectionFields.yaml # Entities - Name: Dvc diff --git a/Parsers/ASimNetworkSession/Parsers/imNetworkSession.yaml b/Parsers/ASimNetworkSession/Parsers/imNetworkSession.yaml index b1ce1681144..53a2b63de9d 100644 --- a/Parsers/ASimNetworkSession/Parsers/imNetworkSession.yaml +++ b/Parsers/ASimNetworkSession/Parsers/imNetworkSession.yaml @@ -73,7 +73,6 @@ ParserParams: - Name: pack Type: bool Default: false - ParserQuery: | let DisabledParsers=materialize(_GetWatchlist('ASimDisabledParsers') | where SearchKey in ('Any', 'ExcludevimNetworkSession') | extend SourceSpecificParser=column_ifexists('SourceSpecificParser','') | distinct SourceSpecificParser | where isnotempty(SourceSpecificParser)); let ASimBuiltInDisabled=toscalar('ExcludevimNetworkSession' in (DisabledParsers) or 'Any' in (DisabledParsers)); diff --git a/Parsers/ASimUserManagement/Parsers/ASimUserManagement.yaml b/Parsers/ASimUserManagement/Parsers/ASimUserManagement.yaml new file mode 100644 index 00000000000..0f812cc8625 --- /dev/null +++ b/Parsers/ASimUserManagement/Parsers/ASimUserManagement.yaml @@ -0,0 +1,39 @@ +Parser: + Title: User Management ASIM parser + Version: '0.1.0' + LastUpdated: 16 Jul, 2023 +Product: + Name: Source agnostic +Normalization: + Schema: UserManagement + Version: '0.1' +References: +- Title: ASIM UserManagement Schema + Link: https://aka.ms/ASimUserManagementDoc +- Title: ASIM + Link: https://aka.ms/AboutASIM +Description: | + This ASIM parser supports normalizing User Management logs from all supported sources to the ASIM User Management normalized schema. +ParserName: ASimUserManagement +EquivalentBuiltInParser: _ASim_UserManagement +Parsers: + - _Im_UserManagement_Empty + - _ASim_UserManagement_MicrosoftSecurityEvent +ParserParams: + - Name: pack + Type: bool + Default: false +ParserQuery: | + let DisabledParsers=materialize(_GetWatchlist('ASimDisabledParsers') | where SearchKey in ('Any', 'ExcludeASimUserManagement') | extend SourceSpecificParser=column_ifexists('SourceSpecificParser','') | distinct SourceSpecificParser); + let ASimBuiltInDisabled=toscalar('ExcludeASimUserManagement' in (DisabledParsers) or 'Any' in (DisabledParsers)); + let parser=( + pack:bool=false + ){ + union isfuzzy=true + vimUserManagementEmpty, + ASimUserManagementMicrosoftSecurityEvent (ASimBuiltInDisabled or ('ExcludeASimUserManagementMicrosoftSecurityEvent' in (DisabledParsers))), + ASimUserManagementCiscoISE (ASimBuiltInDisabled or ('ExcludeASimUserManagementCiscoISE in (DisabledParsers))) + }; + parser ( + pack=pack + ) \ No newline at end of file diff --git a/Parsers/ASimUserManagement/Parsers/ASimUserManagementMicrosoftSecurityEvent.yaml b/Parsers/ASimUserManagement/Parsers/ASimUserManagementMicrosoftSecurityEvent.yaml new file mode 100644 index 00000000000..e12186b78d5 --- /dev/null +++ b/Parsers/ASimUserManagement/Parsers/ASimUserManagementMicrosoftSecurityEvent.yaml @@ -0,0 +1,252 @@ +Parser: + Title: User Management ASIM parser for Microsoft Security Event logs + Version: '0.1.0' + LastUpdated: 16 Jul, 2023 +Product: + Name: Microsoft +Normalization: + Schema: UserManagement + Version: '0.1.1' +References: +- Title: ASIM User Management Schema + Link: https://aka.ms/ASimUserManagementDoc +- Title: ASIM + Link: https:/aka.ms/AboutASIM +- Title: Audit User Account Management + Link: https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/audit-user-account-management +Description: | + This ASIM parser supports normalizing Microsoft Security Event logs delivered using AMA to the ASIM UserManagement normalized schema. +ParserName: ASimUserManagementMicrosoftSecurityEvent +EquivalentBuiltInParser: _ASim_UserManagement_MicrosoftSecurityEvent +ParserParams: + - Name: disabled + Type: bool + Default: false +ParserQuery: | + let parser = ( + disabled:bool = false + ) { + let EventIDLookup = datatable(EventID:int, EventType:string, EventSubType:string, GroupType:string) + [ + "4720", "UserCreated", "UserCreated", "", + "4722", "UserEnabled", "UserModified", "", + "4723", "PasswordChanged", "UserModified", "", + "4724", "PasswordReset", "UserModified", "", + "4725", "UserDisabled", "UserModified", "", + "4726", "UserDeleted", "UserModified", "", + "4727", "GroupCreated", "GroupCreated", "Global Security Enabled", + "4728", "UserAddedToGroup", "GroupModified", "Global Security Enabled", + "4729", "UserRemovedFromGroup", "GroupModified", "Global Security Enabled", + "4730", "GroupDeleted", "GroupModified", "Global Security Enabled", + "4731", "GroupCreated", "GroupCreated", "Local Security Enabled", + "4732", "UserAddedToGroup", "GroupModified", "Local Security Enabled", + "4733", "UserRemovedFromGroup", "GroupModified", "Local Security Enabled", + "4734", "GroupDeleted", "GroupModified", "Local Security Enabled", + "4738", "UserModified", "UserModified", "", + "4740", "UserLocked", "UserModified", "", + "4744", "GroupCreated", "GroupCreated", "Local Distribution", + "4748", "GroupDeleted", "GroupModified", "Local Distribution", + "4749", "GroupCreated", "GroupCreated", "Global Distribution", + "4753", "GroupDeleted", "GroupModified", "Global Distribution", + "4754", "GroupCreated", "GroupCreated", "Universal Security Enabled", + "4756", "UserAddedToGroup", "GroupModified", "Universal Security Enabled", + "4757", "UserRemovedFromGroup", "GroupModified", "Universal Security Enabled", + "4758", "GroupDeleted", "GroupModified", "Universal Security Enabled", + "4759", "GroupCreated", "GroupCreated", "Universal Distribution", + "4763", "GroupDeleted", "GroupModified", "Universal Distribution", + "4767", "UserLocked", "UserModified", "", + "4781", "UserModified", "UserModified", "" + ]; + let UserTypeLookup = datatable (ActorOriginalUserType:string, ActorUserType:string) + [ + 'User', 'Regular', + 'Machine', 'Machine' + ]; + let UserEventID = toscalar( + EventIDLookup + | where not(disabled) + | where EventSubType in("UserCreated","UserModified") + | summarize make_set(EventID) + ); + let GroupEventID = toscalar( + EventIDLookup + | where not(disabled) + | where EventSubType in("GroupCreated","GroupModified") + | summarize make_set(EventID) + ); + union ( + WindowsEvent + | where not(disabled) + | where EventID in(UserEventID) + | extend + ActorOriginalUserType = tostring(EventData.AccountType), + ActorSessionId = tostring(EventData.SubjectLogonId), + ActorUserId = tostring(EventData.SubjectUserSid), + NewTargetUserName = tostring(EventData.NewTargetUserName), + OldTargetUserName = tostring(EventData.OldTargetUserName), + SubjectDomainName = tostring(EventData.SubjectDomainName), + SubjectUserName = tostring(EventData.SubjectUserName), + TargetDomain = tostring(EventData.TargetDomainName), + TargetUserId = tostring(EventData.TargetSid), + TargetUsername = tostring(EventData.TargetUserName), + EventMessage = tostring(EventData.Activity) + | project-rename + NewPropertyValue = NewTargetUserName, + PreviousPropertyValue = OldTargetUserName + | extend + TargetUsername = coalesce(TargetUsername, PreviousPropertyValue) + | project TimeGenerated, EventID, Computer, _ResourceId, _ItemId, TargetDomain, TargetUserId, TargetUsername, ActorUserId, SubjectDomainName, SubjectUserName, ActorOriginalUserType, ActorSessionId, NewPropertyValue, PreviousPropertyValue, EventMessage + | extend + TargetUserIdType = iif(isnotempty(TargetUserId), "SID",""), + TargetUsername = iff (TargetDomain == "", TargetUsername, strcat (TargetDomain, '\\', TargetUsername)) + ),( + SecurityEvent + | where not(disabled) + | where EventID in(UserEventID) + | project-rename + ActorOriginalUserType = AccountType, + ActorSessionId = SubjectLogonId, + ActorUserId = SubjectUserSid, + TargetDomain = TargetDomainName, + TargetUserId = TargetSid, + TargetUsername = TargetUserName, + EventMessage = Activity + | parse-kv EventData as + ( + OldTargetUserName:string, + NewTargetUserName:string + ) + with (regex=@'{?([^<]*?)}?') + | project-rename + NewPropertyValue = NewTargetUserName, + PreviousPropertyValue = OldTargetUserName + | extend + TargetUsername = coalesce(TargetUsername, PreviousPropertyValue) + | project TimeGenerated, EventID, Computer, _ResourceId, _ItemId, TargetDomain, TargetUserId, TargetUsername, ActorUserId, SubjectDomainName, SubjectUserName, ActorOriginalUserType, ActorSessionId, NewPropertyValue, PreviousPropertyValue, SourceComputerId, EventMessage + | extend + TargetUserIdType = iif(isnotempty(TargetUserId), "SID",""), + TargetUsername = iff (TargetDomain == "", TargetUsername, strcat (TargetDomain, '\\', TargetUsername)) + ),( + WindowsEvent + | where not(disabled) + | where EventID in(GroupEventID) + | extend + ActorOriginalUserType = tostring(EventData.AccountType), + ActorSessionId = tostring(EventData.SubjectLogonId), + ActorUserId = tostring(EventData.SubjectUserSid), + GroupDomain = tostring(EventData.TargetDomainName), + GroupId = tostring(EventData.TargetSid), + GroupName = tostring(EventData.TargetUserName), + MemberName = tostring(EventData.MemberName), + MemberSid = tostring(EventData.MemberSid), + NewTargetUserName = tostring(EventData.NewTargetUserName), + OldTargetUserName = tostring(EventData.OldTargetUserName), + SubjectDomainName = tostring(EventData.SubjectDomainName), + SubjectUserName = tostring(EventData.SubjectUserName), + EventMessage = tostring(EventData.Activity) + | extend + GroupName = iff (GroupDomain == "", GroupName, strcat (GroupDomain, "\\" ,GroupName)), + TargetUserId = MemberSid, + TargetUsername = MemberName + | project TimeGenerated, EventID, Computer, _ResourceId, _ItemId, GroupId, GroupName, ActorUserId, SubjectDomainName, SubjectUserName, ActorOriginalUserType, ActorSessionId, TargetUsername, TargetUserId, EventMessage + | extend + GroupIdType = iif(isnotempty(GroupId), "SID","") + ),( + SecurityEvent + | where not(disabled) + | where not (EventID in (4744, 4748, 4749, 4753, 4759, 4763)) + | where EventID in(GroupEventID) + | project-rename + ActorOriginalUserType = AccountType, + ActorSessionId = SubjectLogonId, + ActorUserId = SubjectUserSid, + GroupDomain = TargetDomainName, + GroupId = TargetSid, + GroupName = TargetUserName, + EventMessage = Activity + | extend GroupName = iff (GroupDomain == "", GroupName, strcat (GroupDomain, "\\" ,GroupName)) + | parse-kv EventData as + ( + MemberName:string, + MemberSid:string + ) + with (regex=@'{?([^<]*?)}?') + | project-rename + TargetUsername = MemberName, + TargetUserId = MemberSid + | project TimeGenerated, EventID, Computer, _ResourceId, _ItemId, GroupId, GroupName, ActorUserId, SubjectDomainName, SubjectUserName, ActorOriginalUserType, ActorSessionId, TargetUsername, TargetUserId, SourceComputerId, EventMessage + | extend + GroupIdType = iif(isnotempty(GroupId), "SID","") + ),( + SecurityEvent + | where not(disabled) + | where EventID in (4744, 4748, 4749, 4753, 4759, 4763) + | parse-kv EventData as + ( + TargetUserName:string, + TargetDomainName:string, + TargetSid:string, + SubjectUserSid:string, + AccountType:string, + SubjectLogonId:string, + SubjectDomainName:string, + SubjectUserName:string + ) + with (regex=@'{?([^<]*?)}?') + | project-rename + ActorOriginalUserType = AccountType, + ActorSessionId = SubjectLogonId, + ActorUserId = SubjectUserSid, + GroupDomain = TargetDomainName, + GroupId = TargetSid, + GroupName = TargetUserName, + EventMessage = Activity + | extend GroupName = iff (GroupDomain == "", GroupName, strcat (GroupDomain, "\\" ,GroupName)) + | parse-kv EventData as + ( + MemberName:string, + MemberSid:string + ) + with (regex=@'{?([^<]*?)}?') + | project-rename + TargetUserId = MemberSid, + TargetUsername = MemberName + | project TimeGenerated, EventID, Computer, _ResourceId, _ItemId, GroupId, GroupName, ActorUserId, SubjectDomainName, SubjectUserName, ActorOriginalUserType, ActorSessionId, TargetUsername, TargetUserId, SourceComputerId, EventMessage + | extend + GroupIdType = iif(isnotempty(GroupId), "SID","") + ) + | lookup EventIDLookup on EventID + | extend UpdatedPropertyName = EventSubType + | invoke _ASIM_ResolveDvcFQDN ("Computer") + | lookup UserTypeLookup on ActorOriginalUserType + | extend + DvcId = coalesce(_ResourceId, SourceComputerId), + EventOriginalType = tostring(EventID) + | project-rename + EventUid = _ItemId + | extend + ActorDomain = SubjectDomainName, + DvcIdType = iff (isnotempty(_ResourceId), "AzureResourceID", ""), + ActorUsername = iff (SubjectDomainName == "", SubjectUserName, strcat (SubjectDomainName, '\\', SubjectUserName)), + Dvc = DvcHostname, + DvcOs = "Windows", + EventCount = int(1), + EventEndTime = TimeGenerated, + EventProduct = 'Security Events', + EventResult = "Success", + EventSchema = "UserManagement", + EventSchemaVersion = "0.1.1", + EventSeverity = "Informational", + EventStartTime = TimeGenerated, + EventVendor = 'Microsoft', + Hostname = DvcHostname + | project-away Subject*, Computer, _ResourceId, SourceComputerId,EventID + | extend + ActorUsernameType = _ASIM_GetUsernameType(ActorUsername), + ActorUserType = _ASIM_GetUserType(ActorUsername,ActorUserId), + GroupNameType = _ASIM_GetUsernameType(GroupName), + TargetUsernameType = _ASIM_GetUsernameType(TargetUsername), + TargetUserType = _ASIM_GetUserType(TargetUsername,TargetUserId), + User = ActorUsername + }; + parser (disabled=disabled) \ No newline at end of file diff --git a/Parsers/ASimUserManagement/Parsers/imUserManagement.yaml b/Parsers/ASimUserManagement/Parsers/imUserManagement.yaml new file mode 100644 index 00000000000..142878b70c9 --- /dev/null +++ b/Parsers/ASimUserManagement/Parsers/imUserManagement.yaml @@ -0,0 +1,72 @@ +Parser: + Title: User Management ASIM filtering parser + Version: '0.1.0' + LastUpdated: 16 Jul, 2023 +Product: + Name: Source agnostic +Normalization: + Schema: UserManagement + Version: '0.1' +References: +- Title: ASIM UserManagement Schema + Link: https://aka.ms/ASimUserManagementDoc +- Title: ASIM + Link: https://aka.ms/AboutASIM +Description: | + This ASIM parser supports normalizing User Management logs from all supported sources to the ASIM User Management normalized schema. +ParserName: imUserManagement +EquivalentBuiltInParser: _Im_UserManagement +Parsers: + - _Im_UserManagement_Empty + - _Im_UserManagement_MicrosoftSecurityEvent +ParserParams: + - Name: starttime + Type: datetime + Default: datetime(null) + - Name: endtime + Type: datetime + Default: datetime(null) + - Name: targetusername_has + Type: string + Default: '*' + - Name: actorusername_has + Type: string + Default: '*' + - Name: targetdomain_has_any + Type: dynamic + Default: dynamic([]) + - Name: anydomain_has_any + Type: dynamic + Default: dynamic([]) + - Name: pack + Type: bool + Default: false +ParserQuery: | + let DisabledParsers=materialize(_GetWatchlist('ASimDisabledParsers') | where SearchKey in ('Any', 'ExcludevimUserManagement') | extend SourceSpecificParser=column_ifexists('SourceSpecificParser','') | distinct SourceSpecificParser | where isnotempty(SourceSpecificParser)); + let ASimBuiltInDisabled=toscalar('ExcludevimUserManagement' in (DisabledParsers) or 'Any' in (DisabledParsers)); + let parser=( + starttime:datetime=datetime(null), + endtime:datetime=datetime(null), + targetusername_has:string="*", + actorusername_has:string="", + targetdomain_has_any:dynamic=dynamic([]), + anydomain_has_any:dynamic=dynamic([]), + pack:bool=false) + { + union isfuzzy=true + vimUserManagementEmpty, + vimUserManagementMicrosoftSecurityEvent(starttime, endtime, targetusername_has, actorusername_has, targetdomain_has_any, anydomain_has_any, ASimBuiltInDisabled or ('ExcludevimUserManagementMicrosoftSecurityEvent' in (DisabledParsers) )), + vimUserManagementCiscoISE(starttime, endtime, targetusername_has, actorusername_has, targetdomain_has_any, anydomain_has_any, ASimBuiltInDisabled or ('ExcludevimUserManagementCiscoISE' in (DisabledParsers) )) + }; + parser ( + starttime=starttime, + endtime=endtime, + targetusername_has=targetusername_has, + actorusername_has=actorusername_has, + targetdomain_has_any=targetdomain_has_any, + anydomain_has_any=anydomain_has_any, + hostname_has_any=hostname_has_any, + dvcaction=dvcaction, + eventresult=eventresult, + pack=pack + ) diff --git a/Parsers/ASimUserManagement/Parsers/vimUserManagementEmpty.yaml b/Parsers/ASimUserManagement/Parsers/vimUserManagementEmpty.yaml new file mode 100644 index 00000000000..5fc49692299 --- /dev/null +++ b/Parsers/ASimUserManagement/Parsers/vimUserManagementEmpty.yaml @@ -0,0 +1,111 @@ +Parser: + Title: User Management ASIM schema function + Version: '0.1.0' + LastUpdated: 17 Jul2023 +Product: + Name: Source Agnostic +Normalization: + Schema: UserManagement + Version: '0.1.1' +References: +- Title: ASIM User Management Schema + Link: https://aka.ms/ASimUserManagementDoc +- Title: ASIM + Link: https:/aka.ms/AboutASIM +Description: | + This function returns an empty ASIM UserManagement schema +ParserName: vimUserManagementEmpty +EquivalentBuiltInParser: _Im_UserManagement_Empty +ParserQuery: | + let parser=datatable( + TimeGenerated:datetime, + _ResourceId:string, + Type:string, + ActorUsername:string, // Mandatory + ActorUsernameType:string, // Mandatory + Dvc:string, // Mandatory + EventCount:int, // Mandatory + EventEndTime:datetime, // Mandatory + EventProduct:string, // Mandatory + EventResult:string, // Mandatory + EventSchema:string, // Mandatory + EventSchemaVersion:string, // Mandatory + EventSeverity:string, // Mandatory + EventStartTime:datetime, // Mandatory + EventType:string, // Mandatory + EventVendor:string, // Mandatory + DvcAction:string, // Recommended + DvcDomain:string, // Recommended + DvcDomainType:string, // Recommended + DvcFQDN:string, // Recommended + DvcHostname:string, // Recommended + DvcId:string, // Recommended + DvcIdType:string, // Recommended + DvcIpAddr:string, // Recommended + EventResultDetails:string, // Recommended + EventUid:string, // Recommended + Src:string, // Recommended + SrcDomain:string, // Recommended + SrcDomainType:string, // Recommended + SrcHostname:string, // Recommended + SrcIpAddr:string, // Recommended + ActingAppId:string, // Optional + ActingAppType:string, // Optional + ActiveAppName:string, // Optional + ActorOriginalUserType:string, // Optional + ActorSessionId:string, // Optional + ActorUserId:string, // Optional + ActorUserIdType:string, // Optional + ActorUserType:string, // Optional + AdditionalFields:dynamic, // Optional + DvcDescription:string, // Optional + DvcInterface:string, // Optional + DvcMacAddr:string, // Optional + DvcOriginalAction:string, // Optional + DvcOs:string, // Optional + DvcOsVersion:string, // Optional + DvcScope:string, // Optional + DvcScopeId:string, // Optional + DvcZone:string, // Optional + EventMessage:string, // Optional + EventOriginalResultDetails:string, // Optional + EventOriginalSeverity:string, // Optional + EventOriginalSubType:string, // Optional + EventOriginalType:string, // Optional + EventOriginalUid:string, // Optional + EventOwner:string, // Optional + EventProductVersion:string, // Optional + EventReportUrl:string, // Optional + EventSubType:string, // Optional + GroupId:string, // Optional + GroupIdType:string, // Optional + GroupName:string, // Optional + GroupNameType:string, // Optional + GroupOriginalType:string, // Optional + GroupType:string, // Optional + HttpUserAgent:string, // Optional + NewPropertyValue:string, // Optional + PreviousPropertyValue:string, // Optional + SrcDeviceType:string, // Optional + SrcDvcId:string, // Optional + SrcDvcIdType:string, // Optional + SrcDvcScope:string, // Optional + SrcDvcScopeId:string, // Optional + SrcFQDN:string, // Optional + SrcGeoCity:string, // Optional + SrcGeoCountry:string, // Optional + SrcGeoLatitude:string, // Optional + SrcGeoLongitude:string, // Optional + SrcGeoRegion:string, // Optional + TargetOriginalUserType:string, // Optional + TargetUserId:string, // Optional + TargetUserIdType:string, // Optional + TargetUsername:string, // Optional + TargetUsernameType:string, // Optional + TargetUserType:string, // Optional + Hostname:string, // Alias + IpAddr:string, // Alias + UpdatedPropertyName:string, // Alias + User:string // Alias + )[]; + parser \ No newline at end of file diff --git a/Parsers/ASimUserManagement/Parsers/vimUserManagementMicrosoftSecurityEvent.yaml b/Parsers/ASimUserManagement/Parsers/vimUserManagementMicrosoftSecurityEvent.yaml new file mode 100644 index 00000000000..d66c022d0a1 --- /dev/null +++ b/Parsers/ASimUserManagement/Parsers/vimUserManagementMicrosoftSecurityEvent.yaml @@ -0,0 +1,328 @@ +Parser: + Title: User Management ASIM parser for Microsoft Security Event logs + Version: '0.1.0' + LastUpdated: 16 Jul, 2023 +Product: + Name: Microsoft +Normalization: + Schema: UserManagement + Version: '0.1.1' +References: +- Title: ASIM User Management Schema + Link: https://aka.ms/ASimUserManagementDoc +- Title: ASIM + Link: https:/aka.ms/AboutASIM +- Title: Audit User Account Management + Link: https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/audit-user-account-management +Description: | + This ASIM parser supports normalizing Microsoft Security Event logs delivered using AMA to the ASIM UserManagement normalized schema. +ParserName: ASimUserManagementMicrosoftSecurityEvent +EquivalentBuiltInParser: _ASim_UserManagement_MicrosoftSecurityEvent +ParserParams: + - Name: starttime + Type: datetime + Default: datetime(null) + - Name: endtime + Type: datetime + Default: datetime(null) + - Name: targetusername_has + Type: string + Default: '*' + - Name: actorusername_has + Type: string + Default: '*' + - Name: targetdomain_has_any + Type: dynamic + Default: dynamic([]) + - Name: anydomain_has_any + Type: dynamic + Default: dynamic([]) + - Name: disabled + Type: bool + Default: false +ParserQuery: | + let parser = ( + starttime:datetime=datetime(null), + endtime:datetime=datetime(null), + targetusername_has:string="*", + actorusername_has:string="", + targetdomain_has_any:dynamic=dynamic([]), + anydomain_has_any:dynamic=dynamic([]), + disabled:bool=false + ) { + let EventIDLookup = datatable(EventID:int, EventType:string, EventSubType:string, GroupType:string) + [ + "4720", "UserCreated", "UserCreated", "", + "4722", "UserEnabled", "UserModified", "", + "4723", "PasswordChanged", "UserModified", "", + "4724", "PasswordReset", "UserModified", "", + "4725", "UserDisabled", "UserModified", "", + "4726", "UserDeleted", "UserModified", "", + "4727", "GroupCreated", "GroupCreated", "Global Security Enabled", + "4728", "UserAddedToGroup", "GroupModified", "Global Security Enabled", + "4729", "UserRemovedFromGroup", "GroupModified", "Global Security Enabled", + "4730", "GroupDeleted", "GroupModified", "Global Security Enabled", + "4731", "GroupCreated", "GroupCreated", "Local Security Enabled", + "4732", "UserAddedToGroup", "GroupModified", "Local Security Enabled", + "4733", "UserRemovedFromGroup", "GroupModified", "Local Security Enabled", + "4734", "GroupDeleted", "GroupModified", "Local Security Enabled", + "4738", "UserModified", "UserModified", "", + "4740", "UserLocked", "UserModified", "", + "4744", "GroupCreated", "GroupCreated", "Local Distribution", + "4748", "GroupDeleted", "GroupModified", "Local Distribution", + "4749", "GroupCreated", "GroupCreated", "Global Distribution", + "4753", "GroupDeleted", "GroupModified", "Global Distribution", + "4754", "GroupCreated", "GroupCreated", "Universal Security Enabled", + "4756", "UserAddedToGroup", "GroupModified", "Universal Security Enabled", + "4757", "UserRemovedFromGroup", "GroupModified", "Universal Security Enabled", + "4758", "GroupDeleted", "GroupModified", "Universal Security Enabled", + "4759", "GroupCreated", "GroupCreated", "Universal Distribution", + "4763", "GroupDeleted", "GroupModified", "Universal Distribution", + "4767", "UserLocked", "UserModified", "", + "4781", "UserModified", "UserModified", "" + ]; + let UserTypeLookup = datatable (ActorOriginalUserType:string, ActorUserType:string) + [ + 'Machine', 'Machine', + 'User', 'Regular' + ]; + let UserEventID = toscalar( + EventIDLookup + | where not(disabled) + | where EventSubType in("UserCreated","UserModified") + | summarize make_set(EventID) + ); + let GroupEventID = toscalar( + EventIDLookup + | where not(disabled) + | where EventSubType in("GroupCreated","GroupModified") + | summarize make_set(EventID) + ); + union ( + WindowsEvent + | where not(disabled) + | where (isnull(starttime) or TimeGenerated >= starttime) + and (isnull(endtime) or TimeGenerated <= endtime) + | where EventID in(UserEventID) + | where (targetusername_has=='*' or (EventData has targetusername_has)) and + (actorusername_has=='*' or (EventData has actorusername_has)) and + (array_length(targetdomain_has_any) == 0 or (EventData has_any (targetdomain_has_any))) and + (array_length(anydomain_has_any) == 0 or (EventData has_any (anydomain_has_any))) + | extend + ActorOriginalUserType = tostring(EventData.AccountType), + ActorSessionId = tostring(EventData.SubjectLogonId), + ActorUserId = tostring(EventData.SubjectUserSid), + NewTargetUserName = tostring(EventData.NewTargetUserName), + OldTargetUserName = tostring(EventData.OldTargetUserName), + SubjectDomainName = tostring(EventData.SubjectDomainName), + SubjectUserName = tostring(EventData.SubjectUserName), + TargetDomain = tostring(EventData.TargetDomainName), + TargetUserId = tostring(EventData.TargetSid), + TargetUsername = tostring(EventData.TargetUserName), + EventMessage = tostring(EventData.Activity) + | where (targetusername_has=='*' or (TargetUsername has targetusername_has)) and + (actorusername_has=='*' or (SubjectUserName has actorusername_has)) and + (array_length(targetdomain_has_any) == 0 or (TargetDomain has_any (targetdomain_has_any))) and + (array_length(anydomain_has_any) == 0 or (TargetDomain has_any (anydomain_has_any)) or (SubjectDomainName has_any (anydomain_has_any))) + | project-rename + NewPropertyValue = NewTargetUserName, + PreviousPropertyValue = OldTargetUserName + | extend + TargetUsername = coalesce(TargetUsername, PreviousPropertyValue) + | project TimeGenerated, EventID, Computer, _ResourceId, _ItemId, TargetDomain, TargetUserId, TargetUsername, ActorUserId, SubjectDomainName, SubjectUserName, ActorOriginalUserType, ActorSessionId, NewPropertyValue, PreviousPropertyValue, EventMessage + | extend + TargetUserIdType = iif(isnotempty(TargetUserId), "SID",""), + TargetUsername = iff (TargetDomain == "", TargetUsername, strcat (TargetDomain, '\\', TargetUsername)) + ),( + SecurityEvent + | where not(disabled) + | where (isnull(starttime) or TimeGenerated >= starttime) + and (isnull(endtime) or TimeGenerated <= endtime) + | where EventID in(UserEventID) + | where (targetusername_has=='*' or (TargetUserName has targetusername_has)) and + (actorusername_has=='*' or (SubjectUserName has actorusername_has)) and + (array_length(targetdomain_has_any) == 0 or (TargetDomainName has_any (targetdomain_has_any))) and + (array_length(anydomain_has_any) == 0 or (TargetDomainName has_any (anydomain_has_any)) or (SubjectDomainName has_any (anydomain_has_any))) + | project-rename + ActorOriginalUserType = AccountType, + ActorSessionId = SubjectLogonId, + ActorUserId = SubjectUserSid, + TargetDomain = TargetDomainName, + TargetUserId = TargetSid, + TargetUsername = TargetUserName, + EventMessage = Activity + | parse-kv EventData as + ( + OldTargetUserName:string, + NewTargetUserName:string + ) + with (regex=@'{?([^<]*?)}?') + | project-rename + NewPropertyValue = NewTargetUserName, + PreviousPropertyValue = OldTargetUserName + | extend + TargetUsername = coalesce(TargetUsername, PreviousPropertyValue) + | project TimeGenerated, EventID, Computer, _ResourceId, _ItemId, TargetDomain, TargetUserId, TargetUsername, ActorUserId, SubjectDomainName, SubjectUserName, ActorOriginalUserType, ActorSessionId, NewPropertyValue, PreviousPropertyValue, SourceComputerId, EventMessage + | extend + TargetUserIdType = iif(isnotempty(TargetUserId), "SID",""), + TargetUsername = iff (TargetDomain == "", TargetUsername, strcat (TargetDomain, '\\', TargetUsername)) + ),( + WindowsEvent + | where not(disabled) + | where (isnull(starttime) or TimeGenerated >= starttime) + and (isnull(endtime) or TimeGenerated <= endtime) + | where EventID in(GroupEventID) + | where (targetusername_has=='*' or (EventData has targetusername_has)) and + (actorusername_has=='*' or (EventData has actorusername_has)) and + (array_length(targetdomain_has_any) == 0 or (EventData has_any (targetdomain_has_any))) and + (array_length(anydomain_has_any) == 0 or (EventData has_any (anydomain_has_any))) + | extend + ActorOriginalUserType = tostring(EventData.AccountType), + ActorSessionId = tostring(EventData.SubjectLogonId), + ActorUserId = tostring(EventData.SubjectUserSid), + GroupDomain = tostring(EventData.TargetDomainName), + GroupId = tostring(EventData.TargetSid), + GroupName = tostring(EventData.TargetUserName), + MemberName = tostring(EventData.MemberName), + MemberSid = tostring(EventData.MemberSid), + NewTargetUserName = tostring(EventData.NewTargetUserName), + OldTargetUserName = tostring(EventData.OldTargetUserName), + SubjectDomainName = tostring(EventData.SubjectDomainName), + SubjectUserName = tostring(EventData.SubjectUserName), + EventMessage = tostring(EventData.Activity) + | where (targetusername_has=='*' or (NewTargetUserName has targetusername_has) or (OldTargetUserName has targetusername_has) or (MemberName has targetusername_has)) and + (actorusername_has=='*' or (SubjectUserName has actorusername_has)) and + (array_length(targetdomain_has_any) == 0 or (GroupDomain has_any (targetdomain_has_any))) and + (array_length(anydomain_has_any) == 0 or (GroupDomain has_any (anydomain_has_any)) or (SubjectDomainName has_any (anydomain_has_any))) + | extend + GroupName = iff (GroupDomain == "", GroupName, strcat (GroupDomain, "\\" ,GroupName)), + TargetUserId = MemberSid, + TargetUsername = MemberName + | project TimeGenerated, EventID, Computer, _ResourceId, _ItemId, GroupId, GroupName, ActorUserId, SubjectDomainName, SubjectUserName, ActorOriginalUserType, ActorSessionId, TargetUsername, TargetUserId, EventMessage + | extend + GroupIdType = iif(isnotempty(GroupId), "SID","") + ),( + SecurityEvent + | where not(disabled) + | where (isnull(starttime) or TimeGenerated >= starttime) + and (isnull(endtime) or TimeGenerated <= endtime) + | where not (EventID in (4744, 4748, 4749, 4753, 4759, 4763)) + | where EventID in(GroupEventID) + | where (targetusername_has=='*' or (EventData has targetusername_has)) and + (actorusername_has=='*' or (SubjectUserName has actorusername_has)) and + (array_length(targetdomain_has_any) == 0 or (TargetDomainName has_any (targetdomain_has_any))) and + (array_length(anydomain_has_any) == 0 or (TargetDomainName has_any (anydomain_has_any)) or (SubjectDomainName has_any (anydomain_has_any))) + | project-rename + ActorOriginalUserType = AccountType, + ActorSessionId = SubjectLogonId, + ActorUserId = SubjectUserSid, + GroupDomain = TargetDomainName, + GroupId = TargetSid, + GroupName = TargetUserName, + EventMessage = Activity + | extend GroupName = iff (GroupDomain == "", GroupName, strcat (GroupDomain, "\\" ,GroupName)) + | parse-kv EventData as + ( + MemberName:string, + MemberSid:string + ) + with (regex=@'{?([^<]*?)}?') + | where (targetusername_has=='*' or (MemberName has targetusername_has)) + | project-rename + TargetUserId = MemberSid, + TargetUsername = MemberName + | project TimeGenerated, EventID, Computer, _ResourceId, _ItemId, GroupId, GroupName, ActorUserId, SubjectDomainName, SubjectUserName, ActorOriginalUserType, ActorSessionId, TargetUsername, TargetUserId, SourceComputerId, EventMessage + | extend + GroupIdType = iif(isnotempty(GroupId), "SID","") + ),( + SecurityEvent + | where not(disabled) + | where (isnull(starttime) or TimeGenerated >= starttime) + and (isnull(endtime) or TimeGenerated <= endtime) + | where EventID in (4744, 4748, 4749, 4753, 4759, 4763) + | where (targetusername_has=='*' or (EventData has targetusername_has)) and + (actorusername_has=='*' or (EventData has actorusername_has)) and + (array_length(targetdomain_has_any) == 0 or (EventData has_any (targetdomain_has_any))) and + (array_length(anydomain_has_any) == 0 or (EventData has_any (anydomain_has_any))) + | parse-kv EventData as + ( + TargetUserName:string, + TargetDomainName:string, + TargetSid:string, + SubjectUserSid:string, + AccountType:string, + SubjectLogonId:string, + SubjectDomainName:string, + SubjectUserName:string + ) + with (regex=@'{?([^<]*?)}?') + | where (actorusername_has=='*' or (SubjectUserName has actorusername_has)) and + (array_length(targetdomain_has_any) == 0 or (TargetDomainName has_any (targetdomain_has_any))) and + (array_length(anydomain_has_any) == 0 or (TargetDomainName has_any (anydomain_has_any)) or (SubjectDomainName has_any (anydomain_has_any))) + | project-rename + ActorOriginalUserType = AccountType, + ActorSessionId = SubjectLogonId, + ActorUserId = SubjectUserSid, + GroupDomain = TargetDomainName, + GroupId = TargetSid, + GroupName = TargetUserName, + EventMessage = Activity + | extend GroupName = iff (GroupDomain == "", GroupName, strcat (GroupDomain, "\\" ,GroupName)) + | parse-kv EventData as + ( + MemberName:string, + MemberSid:string + ) + with (regex=@'{?([^<]*?)}?') + | where (targetusername_has=='*' or (MemberName has targetusername_has)) + | project-rename + TargetUserId = MemberSid, + TargetUsername = MemberName + | project TimeGenerated, EventID, Computer, _ResourceId, _ItemId, GroupId, GroupName, ActorUserId, SubjectDomainName, SubjectUserName, ActorOriginalUserType, ActorSessionId, TargetUsername, TargetUserId, SourceComputerId, EventMessage + | extend + GroupIdType = iif(isnotempty(GroupId), "SID","") + ) + | lookup EventIDLookup on EventID + | extend UpdatedPropertyName = EventSubType + | invoke _ASIM_ResolveDvcFQDN ("Computer") + | lookup UserTypeLookup on ActorOriginalUserType + | extend + DvcId = coalesce(_ResourceId, SourceComputerId), + EventOriginalType = tostring(EventID) + | project-rename + EventUid = _ItemId + | extend + ActorDomain = SubjectDomainName, + ActorUserIdType = iif(isnotempty(ActorUserId), "SID",""), + ActorUsername = iff (SubjectDomainName == "", SubjectUserName, strcat (SubjectDomainName, '\\', SubjectUserName)), + Dvc = DvcHostname, + DvcIdType = iff (isnotempty(_ResourceId), "AzureResourceID", ""), + DvcOs = "Windows", + EventCount = int(1), + EventEndTime = TimeGenerated, + EventProduct = 'Security Events', + EventResult = "Success", + EventSchema = "UserManagement", + EventSchemaVersion = "0.1.1", + EventSeverity = "Informational", + EventStartTime = TimeGenerated, + EventVendor = 'Microsoft', + Hostname = DvcHostname + | project-away Subject*, Computer, _ResourceId, SourceComputerId,EventID + | extend + ActorUsernameType = _ASIM_GetUsernameType(ActorUsername), + ActorUserType = _ASIM_GetUserType(ActorUsername,ActorUserId), + GroupNameType = _ASIM_GetUsernameType(GroupName), + TargetUsernameType = _ASIM_GetUsernameType(TargetUsername), + TargetUserType = _ASIM_GetUserType(TargetUsername,TargetUserId), + User = ActorUsername + }; + parser ( + starttime = starttime, + endtime = endtime, + targetusername_has = targetusername_has, + actorusername_has = actorusername_has, + targetdomain_has = targetdomain_has, + anydomain_has = anydomain_has, + disabled=disabled + ) \ No newline at end of file diff --git a/Parsers/ASimUserManagement/README.md b/Parsers/ASimUserManagement/README.md new file mode 100644 index 00000000000..7ab17039b52 --- /dev/null +++ b/Parsers/ASimUserManagement/README.md @@ -0,0 +1,17 @@ +# Advanced Security Information Model (ASIM) UserManagement parsers + +This template deploys all ASIM UserManagement parsers. + +The Advanced Security Information Mode (ASIM) enables you to use and create source-agnostic content, simplifying your analysis of the data in your Microsoft Sentinel workspace. + +For more information, see: + +- [Normalization and the Advanced Security Information Model (ASIM)](https://aka.ms/AboutASIM) +- [Deploy all of ASIM](https://aka.ms/DeployASIM) +- [ASIM UserManagement normalization schema reference](https://aka.ms/ASimUserManagementDoc) + +
+ +[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/ASimUserManagementARM) [![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://aka.ms/ASimUserManagementARMgov) + +
\ No newline at end of file diff --git a/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Add_Contributor_Role_1.png b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Add_Contributor_Role_1.png new file mode 100644 index 00000000000..7f7e9b0484a Binary files /dev/null and b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Add_Contributor_Role_1.png differ diff --git a/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Add_Contributor_Role_2.png b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Add_Contributor_Role_2.png new file mode 100644 index 00000000000..a9a4ebedbce Binary files /dev/null and b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Add_Contributor_Role_2.png differ diff --git a/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Add_Contributor_Role_3.png b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Add_Contributor_Role_3.png new file mode 100644 index 00000000000..00ad6caabfe Binary files /dev/null and b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Add_Contributor_Role_3.png differ diff --git a/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Add_Contributor_Role_4.png b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Add_Contributor_Role_4.png new file mode 100644 index 00000000000..b1bcace7c4d Binary files /dev/null and b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Add_Contributor_Role_4.png differ diff --git a/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Demo_1.png b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Demo_1.png new file mode 100644 index 00000000000..9a102b40bc7 Binary files /dev/null and b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Demo_1.png differ diff --git a/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Deploy_1.png b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Deploy_1.png new file mode 100644 index 00000000000..6247dc3d03d Binary files /dev/null and b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Deploy_1.png differ diff --git a/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Deploy_2.png b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Deploy_2.png new file mode 100644 index 00000000000..9d923b95a6e Binary files /dev/null and b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Deploy_2.png differ diff --git a/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Deploy_3.png b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Deploy_3.png new file mode 100644 index 00000000000..4fa23a03ac4 Binary files /dev/null and b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Deploy_3.png differ diff --git a/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Deploy_4.png b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Deploy_4.png new file mode 100644 index 00000000000..ef53a245e28 Binary files /dev/null and b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Deploy_4.png differ diff --git a/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Deploy_5.png b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Deploy_5.png new file mode 100644 index 00000000000..d7b0dc71639 Binary files /dev/null and b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Deploy_5.png differ diff --git a/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Deploy_6.png b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Deploy_6.png new file mode 100644 index 00000000000..25e58fc3962 Binary files /dev/null and b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Deploy_6.png differ diff --git a/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Sentinel_Workspace_1.png b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Sentinel_Workspace_1.png new file mode 100644 index 00000000000..2db6c2e8bbf Binary files /dev/null and b/Playbooks/AS-Recurring-Host-Entity/Images/RecurringHostEntity_Sentinel_Workspace_1.png differ diff --git a/Playbooks/AS-Recurring-Host-Entity/README.md b/Playbooks/AS-Recurring-Host-Entity/README.md new file mode 100644 index 00000000000..3ac6877e837 --- /dev/null +++ b/Playbooks/AS-Recurring-Host-Entity/README.md @@ -0,0 +1,103 @@ +# AS-Recurring-Host-Entity + +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%2FAccelerynt-Security%2FAS-Recurring-Host-Entity%2Fmain%2Fazuredeploy.json) +[![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAccelerynt-Security%2FAS-Recurring-Host-Entity%2Fmain%2Fazuredeploy.json) + +This playbook is intended to be run from a Microsoft Sentinel Incident. It will take the Hosts from the Incident entities list and search the Microsoft Sentinel SecurityAlert logs for other entities containing the same Hosts. A comment noting the alerts the Hosts have previously appeared in will be added to the Incident. + +![RecurringHostEntity_Demo_1](Images/RecurringHostEntity_Demo_1.png) + + +# +### Requirements + +The following items are required under the template settings during deployment: + +* The [Microsoft Sentinel Workspace Name](https://github.com/Accelerynt-Security/AS-Recurring-Host-Entity#microsoft-sentinel-workspace-name) your SecurityAlert logs will be pulled from. + +# +### Setup + +#### Microsoft Sentinel Workspace Name: + +Navigate to the Microsoft Sentinel page and take note of the Resource/Workspace name this Logic App will be deployed to: + +https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/microsoft.securityinsightsarg%2Fsentinel + +![RecurringHostEntity_Sentinel_Workspace_1](Images/RecurringHostEntity_Sentinel_Workspace_1.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-Recurring-Host-Entity + +[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAccelerynt-Security%2FAS-Recurring-Host-Entity%2Fmain%2Fazuredeploy.json) +[![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAccelerynt-Security%2FAS-Recurring-Host-Entity%2Fmain%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-Recurring-Host-Entity**" or you may change it. + +* **Sentinel Resource Name**: Enter the name of the Sentinel Resource/Workspace name noted in [Microsoft Sentinel Workspace Name](https://github.com/Accelerynt-Security/AS-Recurring-Host-Entity#microsoft-sentinel-workspace-name) + +Towards the bottom, click on "**Review + create**". + +![RecurringHostEntity_Deploy_1](Images/RecurringHostEntity_Deploy_1.png) + +Once the resources have validated, click on "**Create**". + +![RecurringHostEntity_Deploy_2](Images/RecurringHostEntity_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. + +![RecurringHostEntity_Deploy_3](Images/RecurringHostEntity_Deploy_3.png) + +Click on the “**Edit**” button. This will bring you into the Logic Apps Designer. + +![RecurringHostEntity_Deploy_4](Images/RecurringHostEntity_Deploy_4.png) + +Before the playbook can be run successfully, the "**azuremonitorlogs**" connection used in the first for each loop needs to be authorized, or an existing authorized connection may be alternatively selected. To validate the "**azuremonitorlogs**" connection, expand the first step in the for each loop labeled "**Connections**" and click the exclamation point icon next to the name matching the playbook. + +![RecurringHostEntity_Deploy_5](Images/RecurringHostEntity_Deploy_5.png) + +Select "**Logic Apps Managed Identity**" for the "**Authentication Type**", then click "**Create**". + +![RecurringHostEntity_Deploy_6](Images/RecurringHostEntity_Deploy_6.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 the Logic App 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**". + +![RecurringHostEntity_Add_Contributor_Role_1](Images/RecurringHostEntity_Add_Contributor_Role_1.png) + +Select the "**Microsoft Sentinel Contributor**" role, then click "**Next**". + +![RecurringHostEntity_Add_Contributor_Role_2](Images/RecurringHostEntity_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-Recurring-Host-Entity**", or the alternative playbook name used during deployment, in the field labeled "**Select**". Select the playbook, then click "**Select**". + +![RecurringHostEntity_Add_Contributor_Role_3](Images/RecurringHostEntity_Add_Contributor_Role_3.png) + +Continue on to the "**Review + assign**" tab and click "**Review + assign**". + +![RecurringHostEntity_Add_Contributor_Role_4](Images/RecurringHostEntity_Add_Contributor_Role_4.png) \ No newline at end of file diff --git a/Playbooks/AS-Recurring-Host-Entity/azuredeploy.json b/Playbooks/AS-Recurring-Host-Entity/azuredeploy.json new file mode 100644 index 00000000000..e9dbad72a43 --- /dev/null +++ b/Playbooks/AS-Recurring-Host-Entity/azuredeploy.json @@ -0,0 +1,301 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "title": "AS-Recurring-Host-Entity", + "description": "This playbook is intended to be run from a Microsoft Sentinel Incident. It will take the Hosts from the Incident entities list and search the Microsoft Sentinel SecurityAlert logs for other entities containing the same Hosts. A comment noting the Alerts the Hosts appear in, and their occurrence count, will be added to the Incident.", + "postDeployment": ["The Microsoft Sentinel Contributor role must be applied to the playbook"], + "lastUpdateTime": "2023-09-08T16:21:43Z", + "entities": ["Host"], + "tags": ["Microsoft Sentinel", "Incident", "Log Analytics Workspace"], + "support": { + "tier": "partner" + }, + "author": { + "name": "Accelerynt" + } + }, + "parameters": { + "PlaybookName": { + "defaultValue": "AS-Recurring-Host-Entity", + "type": "string", + "metadata": { + "description": "Name of the Logic App resource to be created" + } + }, + "SentinelResourceName": { + "type": "string", + "metadata": { + "description": "Name of the Microsoft Sentinel Workspace SecurityAlerts will be queried from" + } + } + }, + "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('azuremonitorlogs'))]", + "[resourceId('Microsoft.Web/connections', variables('azuresentinel'))]" + ], + "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": { + "actions": { + "Add_comment_to_incident_(V3)": { + "inputs": { + "body": { + "incidentArmId": "@triggerBody()?['object']?['id']", + "message": "

Incident Hosts Appeared in Entities in the Last 7 Days
\n
@{variables('Recurring Hosts')}

" + }, + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "post", + "path": "/Incidents/Comment" + }, + "runAfter": {}, + "type": "ApiConnection" + } + }, + "expression": { + "and": [ + { + "not": { + "equals": [ + "@variables('Recurring Hosts')", + "@null" + ] + } + } + ] + }, + "runAfter": { + "For_each_-_Hosts": [ + "Succeeded" + ] + }, + "type": "If" + }, + "Entities_-_Get_Hosts": { + "inputs": { + "body": "@triggerBody()?['object']?['properties']?['relatedEntities']", + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "post", + "path": "/entities/host" + }, + "runAfter": {}, + "type": "ApiConnection" + }, + "For_each_-_Hosts": { + "actions": { + "Condition_-_Query_has_results": { + "actions": { + "Append_to_string_variable_-_HTML_formatting": { + "inputs": { + "name": "Recurring Hosts", + "value": "" + }, + "runAfter": { + "For_each_-_Related_Alert": [ + "Succeeded" + ] + }, + "type": "AppendToStringVariable" + }, + "Append_to_string_variable_-_Host_Name_Header": { + "inputs": { + "name": "Recurring Hosts", + "value": "\n@{items('For_each_-_Hosts')?['HostName']} appeared in the following Alerts:\n