Skip to content

Commit

Permalink
Merge pull request #8622 from KustoKing/asim/kustoking/add-microsoft-…
Browse files Browse the repository at this point in the history
…securityevents-usermanagement

Fix-Filtering
  • Loading branch information
v-atulyadav authored Sep 18, 2023
2 parents 52c2784 + 30bd25d commit f5dbc0d
Show file tree
Hide file tree
Showing 11 changed files with 2,230 additions and 1 deletion.
1 change: 0 additions & 1 deletion Parsers/ASimNetworkSession/Parsers/imNetworkSession.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
39 changes: 39 additions & 0 deletions Parsers/ASimUserManagement/Parsers/ASimUserManagement.yaml
Original file line number Diff line number Diff line change
@@ -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
)
Original file line number Diff line number Diff line change
@@ -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=@'<Data Name="(\w+)">{?([^<]*?)}?</Data>')
| 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=@'<Data Name="(\w+)">{?([^<]*?)}?</Data>')
| 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=@'<Data Name="(\w+)">{?([^<]*?)}?</Data>')
| 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=@'<Data Name="(\w+)">{?([^<]*?)}?</Data>')
| 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)
72 changes: 72 additions & 0 deletions Parsers/ASimUserManagement/Parsers/imUserManagement.yaml
Original file line number Diff line number Diff line change
@@ -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
)
Loading

0 comments on commit f5dbc0d

Please sign in to comment.