Skip to content

Commit

Permalink
Merge pull request #9217 from jayeshprajapaticrest/SentinelOneUserMan…
Browse files Browse the repository at this point in the history
…agement

Added few more activities related to Two Factor authentication as UseManagement suggested by reviewer
  • Loading branch information
v-atulyadav authored Mar 7, 2024
2 parents 474565a + 9367a3b commit 70ca645
Show file tree
Hide file tree
Showing 8 changed files with 823 additions and 90 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Parser:
Title: User Management ASIM parser for SentinelOne
Version: '0.1.0'
LastUpdated: Aug 24, 2023
Version: '0.1.1'
LastUpdated: Nov 07, 2023
Product:
Name: SentinelOne
Normalization:
Expand Down Expand Up @@ -48,22 +48,55 @@ ParserQuery: |
5006, "GroupDeleted", "Group Deleted", "",
5008, "GroupCreated", "User created a Manual or Pinned Group", "",
5011, "GroupModified", "Group Policy Reverted", "Newpolicy",
67, "", "User 2FA Modified", "",
145, "UserModified", "Enroll 2FA", "",
146, "UserModified", "Reset 2FA", "",
42, "", "Global 2FA modified", "",
147, "UserModified", "User Configured 2FA", ""
];
let UsermanagementactivityIds = dynamic([23, 24, 25, 37, 102, 110, 111, 140, 141, 142, 3522, 3523, 3524, 3710, 3711, 3715, 5006, 5008, 5011, 67, 145, 146, 42, 147]);
let parser = (disabled: bool=false) {
SentinelOne_CL
| where not(disabled)
and event_name_s == "Activities."
and activityType_d in (23, 24, 25, 37, 102, 110, 111, 140, 141, 142, 3522, 3523, 3524, 3710, 3711, 3715, 5006, 5008, 5011)
| parse-kv DataFields_s as (byUser: string, username: string, email: string, ipAddress: string, group: string, groupName: string, name: string, oldDescription: string, oldRole: string, description: string, role: string, userScope: string, scopeLevelName: string, scopeName: string, roleName: string, modifiedFields: string, deactivationPeriodInDays: string, descriptionChanged: string, groupType: string) with (pair_delimiter=",", kv_delimiter=":", quote='"')
| parse modifiedFields with 'Modified fields: ' ModifiedFields:string
| where event_name_s == "Activities."
and activityType_d in (UsermanagementactivityIds)
| parse-kv DataFields_s as (byUser: string, username: string, email: string, ipAddress: string, group: string, groupName: string, name: string, oldDescription: string, oldRole: string, description: string, role: string, userScope: string, scopeLevelName: string, scopeName: string, roleName: string, modifiedFields: string, deactivationPeriodInDays: string, descriptionChanged: string, groupType: string, newValue: string) with (pair_delimiter=",", kv_delimiter=":", quote='"')
| parse modifiedFields with 'Modified fields: ' ModifiedFields: string
| parse description_s with * "with id=" id: string "," restOfMessage
| lookup EventTypeLookup on activityType_d
| extend
| extend
EventType = case (
activityType_d in (67, 42) and primaryDescription_s has "enabled",
"UserEnabled",
activityType_d in (67, 42) and primaryDescription_s has "disabled",
"UserDisabled",
EventType
),
PreviousPropertyValue = case(
activityType_d in (67, 42) and primaryDescription_s has "enabled",
"disabled",
activityType_d in (67, 42) and primaryDescription_s has "disabled",
"enabled",
activityType_d == 141 and descriptionChanged == "true",
oldDescription,
activityType_d == 141 and descriptionChanged == "false",
oldRole,
""
),
NewPropertyValue = case(
activityType_d in (67, 42) and primaryDescription_s has "enabled",
"enabled",
activityType_d in (67, 42) and primaryDescription_s has "disabled",
"disabled",
activityType_d == 141 and descriptionChanged == "true",
description,
activityType_d == 141 and descriptionChanged == "false",
role,
""
),
ActorUsername = iff(activityType_d == 102, "SentinelOne", coalesce(byUser, username, email)),
GroupName = coalesce(group, groupName, name),
TargetUsername = iff(isnotempty(byUser), username, ""),
PreviousPropertyValue = coalesce(oldDescription, oldRole),
NewPropertyValue = coalesce(description, role)
TargetUsername = iff(isnotempty(byUser) or activityType_d in (147, 42), username, "")
| extend GroupName = iff(GroupName == "null", "", GroupName)
| project-rename
EventStartTime = createdAt_t,
Expand All @@ -89,8 +122,8 @@ ParserQuery: |
IpAddr = SrcIpAddr,
User = ActorUsername,
UpdatedPropertyName = EventSubType,
ActorUserIdType = iff(isnotempty(ActorUserId),"Other",""),
ActorUserType = _ASIM_GetUserType(ActorUsername,ActorUserId),
ActorUserIdType = iff(isnotempty(ActorUserId), "Other", ""),
ActorUserType = _ASIM_GetUserType(ActorUsername, ActorUserId),
ActorUsernameType = _ASIM_GetUsernameType(ActorUsername),
GroupIdType = iff(isnotempty(GroupId), "UID", ""),
GroupNameType = iff(isnotempty(GroupName), "Simple", ""),
Expand Down Expand Up @@ -139,6 +172,7 @@ ParserQuery: |
Computer,
MG,
ManagementGroupName,
SourceSystem
SourceSystem,
newValue
};
parser(disabled=disabled)
parser(disabled=disabled)
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Parser:
Title: User Management ASIM parser for SentinelOne
Version: '0.1.0'
LastUpdated: Aug 24, 2023
Version: '0.1.1'
LastUpdated: Nov 07, 2023
Product:
Name: SentinelOne
Normalization:
Expand Down Expand Up @@ -66,36 +66,70 @@ ParserQuery: |
5006, "GroupDeleted", "Group Deleted", "",
5008, "GroupCreated", "User created a Manual or Pinned Group", "",
5011, "GroupModified", "Group Policy Reverted", "Newpolicy",
67, "", "User 2FA Modified", "",
145, "UserModified", "Enroll 2FA", "",
146, "UserModified", "Reset 2FA", "",
42, "", "Global 2FA modified", "",
147, "UserModified", "User Configured 2FA", ""
];
let UsermanagementactivityIds = dynamic([23, 24, 25, 37, 102, 110, 111, 140, 141, 142, 3522, 3523, 3524, 3710, 3711, 3715, 5006, 5008, 5011, 67, 145, 146, 42, 147]);
let parser = (
starttime:datetime=datetime(null),
endtime:datetime=datetime(null),
srcipaddr_has_any_prefix: dynamic=dynamic([]),
targetusername_has_any: dynamic=dynamic([]),
actorusername_has_any: dynamic=dynamic([]),
eventtype_in: dynamic=dynamic([]),
disabled:bool=false
) {
starttime: datetime=datetime(null),
endtime: datetime=datetime(null),
srcipaddr_has_any_prefix: dynamic=dynamic([]),
targetusername_has_any: dynamic=dynamic([]),
actorusername_has_any: dynamic=dynamic([]),
eventtype_in: dynamic=dynamic([]),
disabled: bool=false
) {
SentinelOne_CL
| where not(disabled)
and event_name_s == "Activities."
| where event_name_s == "Activities."
and (isnull(starttime) or TimeGenerated >= starttime) and (isnull(endtime) or TimeGenerated <= endtime)
and activityType_d in (23, 24, 25, 37, 102, 110, 111, 140, 141, 142, 3522, 3523, 3524, 3710, 3711, 3715, 5006, 5008, 5011)
and activityType_d in (UsermanagementactivityIds)
and (array_length(srcipaddr_has_any_prefix) == 0 or has_any_ipv4_prefix(DataFields_s, srcipaddr_has_any_prefix))
and (array_length(targetusername_has_any) == 0 or DataFields_s has_any (targetusername_has_any))
and (array_length(actorusername_has_any) == 0 or DataFields_s has_any (actorusername_has_any))
| parse-kv DataFields_s as (byUser: string, username: string, email: string, ipAddress: string, group: string, groupName: string, name: string, oldDescription: string, oldRole: string, description: string, role: string, userScope: string, scopeLevelName: string, scopeName: string, roleName: string, modifiedFields: string, deactivationPeriodInDays: string, descriptionChanged: string, groupType: string) with (pair_delimiter=",", kv_delimiter=":", quote='"')
| parse-kv DataFields_s as (byUser: string, username: string, email: string, ipAddress: string, group: string, groupName: string, name: string, oldDescription: string, oldRole: string, description: string, role: string, userScope: string, scopeLevelName: string, scopeName: string, roleName: string, modifiedFields: string, deactivationPeriodInDays: string, descriptionChanged: string, groupType: string, newValue: string) with (pair_delimiter=",", kv_delimiter=":", quote='"')
| where array_length(srcipaddr_has_any_prefix) == 0 or has_any_ipv4_prefix(ipAddress, srcipaddr_has_any_prefix)
| parse modifiedFields with 'Modified fields: ' ModifiedFields:string
| parse modifiedFields with 'Modified fields: ' ModifiedFields: string
| parse description_s with * "with id=" id: string "," restOfMessage
| lookup EventTypeLookup on activityType_d
| extend
EventType = case (
activityType_d in (67, 42) and primaryDescription_s has "enabled",
"UserEnabled",
activityType_d in (67, 42) and primaryDescription_s has "disabled",
"UserDisabled",
EventType
)
| where (array_length(eventtype_in) == 0 or (EventType in (eventtype_in)))
| extend
PreviousPropertyValue = case(
activityType_d in (67, 42) and primaryDescription_s has "enabled",
"disabled",
activityType_d in (67, 42) and primaryDescription_s has "disabled",
"enabled",
activityType_d == 141 and descriptionChanged == "true",
oldDescription,
activityType_d == 141 and descriptionChanged == "false",
oldRole,
""
),
NewPropertyValue = case(
activityType_d in (67, 42) and primaryDescription_s has "enabled",
"enabled",
activityType_d in (67, 42) and primaryDescription_s has "disabled",
"disabled",
activityType_d == 141 and descriptionChanged == "true",
description,
activityType_d == 141 and descriptionChanged == "false",
role,
""
),
ActorUsername = iff(activityType_d == 102, "SentinelOne", coalesce(byUser, username, email)),
GroupName = coalesce(group, groupName, name),
TargetUsername = iff(isnotempty(byUser), username, ""),
PreviousPropertyValue = coalesce(oldDescription, oldRole),
NewPropertyValue = coalesce(description, role)
TargetUsername = iff(isnotempty(byUser) or activityType_d in (147, 42), username, "")
| where (array_length(targetusername_has_any) == 0 or TargetUsername has_any (targetusername_has_any))
and (array_length(actorusername_has_any) == 0 or ActorUsername has_any (actorusername_has_any))
| extend GroupName = iff(GroupName == "null", "", GroupName)
Expand Down Expand Up @@ -123,8 +157,8 @@ ParserQuery: |
IpAddr = SrcIpAddr,
User = ActorUsername,
UpdatedPropertyName = EventSubType,
ActorUserIdType = iff(isnotempty(ActorUserId),"Other",""),
ActorUserType = _ASIM_GetUserType(ActorUsername,ActorUserId),
ActorUserIdType = iff(isnotempty(ActorUserId), "Other", ""),
ActorUserType = _ASIM_GetUserType(ActorUsername, ActorUserId),
ActorUsernameType = _ASIM_GetUsernameType(ActorUsername),
GroupIdType = iff(isnotempty(GroupId), "UID", ""),
GroupNameType = iff(isnotempty(GroupName), "Simple", ""),
Expand Down Expand Up @@ -173,14 +207,15 @@ ParserQuery: |
Computer,
MG,
ManagementGroupName,
SourceSystem
SourceSystem,
newValue
};
parser(
starttime = starttime,
endtime = endtime,
srcipaddr_has_any_prefix = srcipaddr_has_any_prefix ,
targetusername_has_any = targetusername_has_any,
actorusername_has_any = actorusername_has_any,
eventtype_in = eventtype_in,
disabled = disabled
)
starttime = starttime,
endtime = endtime,
srcipaddr_has_any_prefix = srcipaddr_has_any_prefix,
targetusername_has_any = targetusername_has_any,
actorusername_has_any = actorusername_has_any,
eventtype_in = eventtype_in,
disabled = disabled
)
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
Result
"(0) Error: 4 invalid value(s) (up to 10 listed) in 32 records (52.46%) for field [EventSubType] of type [Enumerated]: [""MultipleProperties"",""PreviousPermissions"",""NewPermissions"",""Newpolicy""] (Schema:UserManagement)"
"(0) Error: 4 invalid value(s) (up to 10 listed) in 32 records (35.96%) for field [EventSubType] of type [Enumerated]: [""MultipleProperties"",""PreviousPermissions"",""NewPermissions"",""Newpolicy""] (Schema:UserManagement)"
"(0) Error: type mismatch for column [SrcIpAddr]. It is currently [string] and should be [IP address] (Schema:UserManagement)"
"(2) Info: Empty value in 29 records (47.54%) in optional field [EventSubType] (Schema:UserManagement)"
"(2) Info: Empty value in 44 records (72.13%) in optional field [ActorUserId] (Schema:UserManagement)"
"(2) Info: Empty value in 54 records (88.52%) in optional field [GroupIdType] (Schema:UserManagement)"
"(2) Info: Empty value in 54 records (88.52%) in optional field [GroupId] (Schema:UserManagement)"
"(2) Info: Empty value in 54 records (88.52%) in optional field [GroupNameType] (Schema:UserManagement)"
"(2) Info: Empty value in 54 records (88.52%) in optional field [GroupName] (Schema:UserManagement)"
"(2) Info: Empty value in 54 records (88.52%) in optional field [GroupOriginalType] (Schema:UserManagement)"
"(2) Info: Empty value in 54 records (88.52%) in optional field [GroupType] (Schema:UserManagement)"
"(2) Info: Empty value in 59 records (96.72%) in optional field [PreviousPropertyValue] (Schema:UserManagement)"
"(2) Info: Empty value in 7 records (11.48%) in optional field [NewPropertyValue] (Schema:UserManagement)"
"(2) Info: Empty value in 8 records (13.11%) in optional field [TargetUserType] (Schema:UserManagement)"
"(2) Info: Empty value in 8 records (13.11%) in optional field [TargetUsername] (Schema:UserManagement)"
"(2) Info: Empty value in 57 records (64.04%) in optional field [EventSubType] (Schema:UserManagement)"
"(2) Info: Empty value in 72 records (80.9%) in optional field [ActorUserId] (Schema:UserManagement)"
"(2) Info: Empty value in 73 records (82.02%) in optional field [NewPropertyValue] (Schema:UserManagement)"
"(2) Info: Empty value in 73 records (82.02%) in optional field [PreviousPropertyValue] (Schema:UserManagement)"
"(2) Info: Empty value in 8 records (8.99%) in optional field [TargetUserType] (Schema:UserManagement)"
"(2) Info: Empty value in 8 records (8.99%) in optional field [TargetUsername] (Schema:UserManagement)"
"(2) Info: Empty value in 82 records (92.13%) in optional field [GroupIdType] (Schema:UserManagement)"
"(2) Info: Empty value in 82 records (92.13%) in optional field [GroupId] (Schema:UserManagement)"
"(2) Info: Empty value in 82 records (92.13%) in optional field [GroupNameType] (Schema:UserManagement)"
"(2) Info: Empty value in 82 records (92.13%) in optional field [GroupName] (Schema:UserManagement)"
"(2) Info: Empty value in 82 records (92.13%) in optional field [GroupOriginalType] (Schema:UserManagement)"
"(2) Info: Empty value in 82 records (92.13%) in optional field [GroupType] (Schema:UserManagement)"
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"(1) Warning: Missing recommended field [SrcDomain]"
"(1) Warning: Missing recommended field [SrcHostname]"
"(1) Warning: Missing recommended field [Src]"
"(2) Info: Missing optional alias [Rule] aliasing non-existent column [RuleName]"
"(2) Info: Missing optional field [ActingAppId]"
"(2) Info: Missing optional field [ActingAppType]"
"(2) Info: Missing optional field [ActiveAppName]"
Expand All @@ -30,6 +31,8 @@
"(2) Info: Missing optional field [EventProductVersion]"
"(2) Info: Missing optional field [EventReportUrl]"
"(2) Info: Missing optional field [HttpUserAgent]"
"(2) Info: Missing optional field [RuleName]"
"(2) Info: Missing optional field [RuleNumber]"
"(2) Info: Missing optional field [SrcDeviceType]"
"(2) Info: Missing optional field [SrcDvcId]"
"(2) Info: Missing optional field [SrcDvcScopeId]"
Expand All @@ -42,6 +45,17 @@
"(2) Info: Missing optional field [SrcGeoRegion]"
"(2) Info: Missing optional field [TargetOriginalUserType]"
"(2) Info: Missing optional field [TargetUserId]"
"(2) Info: Missing optional field [ThreatCategory]"
"(2) Info: Missing optional field [ThreatConfidence]"
"(2) Info: Missing optional field [ThreatField]"
"(2) Info: Missing optional field [ThreatFirstReportedTime]"
"(2) Info: Missing optional field [ThreatId]"
"(2) Info: Missing optional field [ThreatIsActive]"
"(2) Info: Missing optional field [ThreatLastReportedTime]"
"(2) Info: Missing optional field [ThreatName]"
"(2) Info: Missing optional field [ThreatOriginalConfidence]"
"(2) Info: Missing optional field [ThreatOriginalRiskLevel]"
"(2) Info: Missing optional field [ThreatRiskLevel]"
"(2) Info: Missing recommended alias [Hostname] aliasing non-existent column [DvcHostname]"
"(2) Info: extra unnormalized column [TimeGenerated]"
"(2) Info: extra unnormalized column [Type]"
Loading

0 comments on commit 70ca645

Please sign in to comment.