Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ASIM Authentication schema parser with its sample and test data for SentinelOne #8665

Merged
900 changes: 900 additions & 0 deletions .script/tests/KqlvalidationsTests/CustomTables/SentinelOne_CL.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
Parser:
vakohl marked this conversation as resolved.
Show resolved Hide resolved
Title: ASIM Authentication parser for SentinelOne
Version: '0.1.0'
LastUpdated: Jul 24 2023
jayeshprajapaticrest marked this conversation as resolved.
Show resolved Hide resolved
Product:
Name: SentinelOne
Normalization:
Schema: Authentication
Version: '0.1.3'
References:
- Title: ASIM Authentication Schema
Link: https://aka.ms/ASimAuthenticationDoc
- Title: ASIM
Link: https:/aka.ms/AboutASIM
- Title: SentinelOne Documentation
Link: https://<SOneInstanceDomain>.sentinelone.net/api-doc/overview
Description: |
This ASIM parser supports normalizing SentinelOne logs to the ASIM Authentication normalized schema. SentinelOne events are captured through SentinelOne data connector which ingests SentinelOne server objects such as Threats, Agents, Applications, Activities, Policies, Groups, and more events into Microsoft Sentinel through the REST API.
ParserName: ASimAuthenticationSentinelOne
EquivalentBuiltInParser: _ASim_Authentication_SentinelOne
ParserParams:
- Name: disabled
Type: bool
Default: false
ParserQuery: |
let EventResultDetailsLookup = datatable (comments_s: string, EventResultDetails: string)
[
"invalid 2FA code", "Incorrect password",
"IP/User mismatch", "No such user or password",
"invalid password", "Incorrect password",
"user temporarily locked 2FA attempt", "User locked",
"no active site", "Other"
];
let EventFieldsLookup = datatable (
activityType_d: real,
vakohl marked this conversation as resolved.
Show resolved Hide resolved
jayeshprajapaticrest marked this conversation as resolved.
Show resolved Hide resolved
EventType: string,
EventResult: string,
EventOriginalResultDetails: string
)
[
27, "Logon", "Success", "User Logged In",
33, "Logoff", "Success", "User Logged Out",
133, "Logon", "Failure", "Existing User Login Failure",
134, "Logon", "Failure", "Unknown User Login",
vakohl marked this conversation as resolved.
Show resolved Hide resolved
139, "Logon", "Failure", "User Failed to Start an Unrestricted Session",
vakohl marked this conversation as resolved.
Show resolved Hide resolved
3629, "Logon", "Success", "Login Using Saved 2FA Recovery Code"
];
let EventTypeLookup = datatable (alertInfo_eventType_s: string, EventType: string)
[
"WINLOGONATTEMPT", "Logon",
"WINLOGOFFATTEMPT", "Logoff"
];
let EventSubTypeLookup = datatable (alertInfo_loginType_s: string, EventSubType: string)
jayeshprajapaticrest marked this conversation as resolved.
Show resolved Hide resolved
[
"BATCH","System",
"CACHED_INTERACTIVE", "Interactive",
"CACHED_REMOTE_INTERACTIVE", "RemoteInteractive",
"CACHED_UNLOCK", "System",
"INTERACTIVE", "Interactive",
"NETWORK_CLEAR_TEXT", "Remote",
"NETWORK_CREDENTIALS", "Remote",
"NETWORK", "Remote",
"REMOTE_INTERACTIVE", "RemoteInteractive",
"SERVICE", "Service",
"SYSTEM", "System",
"UNLOCK", "System"
];
let DeviceTypeLookup = datatable (agentDetectionInfo_machineType_s: string, SrcDeviceType: string)
[
"desktop", "Computer",
"server", "Computer",
"laptop", "Computer",
"kubernetes node", "Other",
"unknown", "Other"
];
let TargetUserTypesList = dynamic(["Regular", "Machine", "Admin", "System", "Application", "Service Principal", "Service", "Anonymous"]);
let parser = (disabled: bool=false) {
let alldata = SentinelOne_CL
| where not(disabled);
let activitydata = alldata
| where event_name_s == "Activities."
and activityType_d in (27, 33, 133, 134, 139, 3629)
| parse-kv DataFields_s as (ipAddress: string, username: string, userScope: string, accountName: string, fullScopeDetails: string, fullScopeDetailsPath: string, role: string, scopeLevel: string, source: string, sourceType: string) with (pair_delimiter=",", kv_delimiter=":", quote='"')
jayeshprajapaticrest marked this conversation as resolved.
Show resolved Hide resolved
| lookup EventFieldsLookup on activityType_d
| lookup EventResultDetailsLookup on comments_s
| extend
SrcIpAddr = iff(ipAddress == "null", "", ipAddress),
EventOriginalType = tostring(toint(activityType_d)),
TargetUsername = username,
TargetUserScope = userScope,
AdditionalFields = bag_pack(
"accountName", accountName,
vakohl marked this conversation as resolved.
Show resolved Hide resolved
"fullScopeDetails", fullScopeDetails,
"fullScopeDetailsPath", fullScopeDetailsPath,
"scopeLevel", scopeLevel,
"source", source,
"sourceType", sourceType
),
TargetOriginalUserType = role,
TargetUserType = case(
role in (TargetUserTypesList), role,
role == "null", "",
"Other"
)
| project-rename
EventStartTime = createdAt_t,
TargetUserId = userId_s,
EventOriginalUid = activityUuid_g,
EventMessage = primaryDescription_s;
let alertdata = alldata
| where event_name_s == "Alerts."
vakohl marked this conversation as resolved.
Show resolved Hide resolved
and alertInfo_eventType_s in ("WINLOGONATTEMPT", "WINLOGOFFATTEMPT")
| lookup EventTypeLookup on alertInfo_eventType_s
| lookup EventSubTypeLookup on alertInfo_loginType_s
jayeshprajapaticrest marked this conversation as resolved.
Show resolved Hide resolved
| lookup DeviceTypeLookup on agentDetectionInfo_machineType_s
| invoke _ASIM_ResolveDvcFQDN('agentDetectionInfo_name_s')
| invoke _ASIM_ResolveSrcFQDN('alertInfo_loginAccountDomain_s')
| extend
EventResult = iff(alertInfo_loginIsSuccessful_s == "true", "Success", "Failure"),
EventSeverity = iff(ruleInfo_severity_s == "Critical", "High", ruleInfo_severity_s)
jayeshprajapaticrest marked this conversation as resolved.
Show resolved Hide resolved
| project-rename
EventStartTime = alertInfo_createdAt_t,
SrcIpAddr = alertInfo_srcMachineIp_s,
ActingAppName = sourceProcessInfo_name_s,
jayeshprajapaticrest marked this conversation as resolved.
Show resolved Hide resolved
DvcId = agentDetectionInfo_uuid_g,
jayeshprajapaticrest marked this conversation as resolved.
Show resolved Hide resolved
DvcOs = agentDetectionInfo_osName_s,
jayeshprajapaticrest marked this conversation as resolved.
Show resolved Hide resolved
DvcOsVersion = agentDetectionInfo_osRevision_s,
EventOriginalSeverity = ruleInfo_severity_s,
EventOriginalType = alertInfo_eventType_s,
EventOriginalSubType = alertInfo_loginType_s,
RuleName = ruleInfo_name_s,
TargetUserId = alertInfo_loginAccountSid_s,
TargetUsername = alertInfo_loginsUserName_s
| extend
Rule = RuleName,
ActingAppType = iff(isnotempty(ActingAppName), "Process", ""),
DvcIdType = iff(isnotempty(DvcId), "Other", ""),
TargetUserType = _ASIM_GetUserType(TargetUsername, TargetUserId);
union activitydata, alertdata
| extend
EventCount = int(1),
EventProduct = "SentinelOne",
jayeshprajapaticrest marked this conversation as resolved.
Show resolved Hide resolved
EventSchemaVersion = "0.1.3",
EventVendor = "SentinelOne",
EventSchema = "Authentication"
| extend
Dvc = coalesce(DvcHostname, EventProduct),
EventEndTime = EventStartTime,
EventUid = _ItemId,
User = TargetUsername,
TargetHostname = SrcHostname,
TargetDomain = SrcDomain,
TargetDomainType = SrcDomainType,
TargetFQDN = SrcFQDN,
TargetUserIdType = iff(isnotempty(TargetUserId), "Other", ""),
TargetUsernameType = _ASIM_GetUsernameType(TargetUsername)
| extend
IpAddr = SrcIpAddr,
Src = SrcIpAddr
| project-away
*_b,
*_d,
*_g,
*_s,
*_t,
ipAddress,
username,
accountName,
fullScopeDetails,
fullScopeDetailsPath,
role,
scopeLevel,
source,
sourceType,
userScope,
Computer,
MG,
ManagementGroupName,
RawData,
SourceSystem,
TenantId,
_ItemId,
_ResourceId
};
parser(disabled=disabled)
197 changes: 197 additions & 0 deletions Parsers/ASimAuthentication/Parsers/vimAuthenticationSentinelOne.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
Parser:
jayeshprajapaticrest marked this conversation as resolved.
Show resolved Hide resolved
Title: ASIM Authentication parser for SentinelOne
Version: '0.1.0'
LastUpdated: Jul 25 2023
Product:
Name: SentinelOne
Normalization:
Schema: Authentication
Version: '0.1.3'
References:
- Title: ASIM Authentication Schema
Link: https://aka.ms/ASimAuthenticationDoc
- Title: ASIM
Link: https:/aka.ms/AboutASIM
- Title: SentinelOne Documentation
Link: https://<SOneInstanceDomain>.sentinelone.net/api-doc/overview
Description: |
This ASIM parser supports normalizing SentinelOne logs to the ASIM Authentication normalized schema. SentinelOne events are captured through SentinelOne data connector which ingests SentinelOne server objects such as Threats, Agents, Applications, Activities, Policies, Groups, and more events into Microsoft Sentinel through the REST API.
ParserName: vimAuthenticationSentinelOne
EquivalentBuiltInParser: _Im_Authentication_SentinelOne
ParserParams:
- Name: disabled
Type: bool
Default: false
- Name: starttime
Type: datetime
Default: datetime(null)
- Name: endtime
Type: datetime
Default: datetime(null)
- Name: targetusername_has
Type: string
Default: '*'
ParserQuery: |
let EventResultDetailsLookup = datatable (comments_s: string, EventResultDetails: string)
[
"invalid 2FA code", "Incorrect password",
"IP/User mismatch", "No such user or password",
"invalid password", "Incorrect password",
"user temporarily locked 2FA attempt", "User locked",
"no active site", "Other"
];
let EventFieldsLookup = datatable (
activityType_d: real,
EventType: string,
EventResult: string,
EventOriginalResultDetails: string
)
[
27, "Logon", "Success", "User Logged In",
33, "Logoff", "Success", "User Logged Out",
133, "Logon", "Failure", "Existing User Login Failure",
134, "Logon", "Failure", "Unknown User Login",
139, "Logon", "Failure", "User Failed to Start an Unrestricted Session",
3629, "Logon", "Success", "Login Using Saved 2FA Recovery Code"
];
let EventTypeLookup = datatable (alertInfo_eventType_s: string, EventType: string)
[
"WINLOGONATTEMPT", "Logon",
"WINLOGOFFATTEMPT", "Logoff"
];
let EventSubTypeLookup = datatable (alertInfo_loginType_s: string, EventSubType: string)
[
"BATCH","System",
"CACHED_INTERACTIVE", "Interactive",
"CACHED_REMOTE_INTERACTIVE", "RemoteInteractive",
"CACHED_UNLOCK", "System",
"INTERACTIVE", "Interactive",
"NETWORK_CLEAR_TEXT", "Remote",
"NETWORK_CREDENTIALS", "Remote",
"NETWORK", "Remote",
"REMOTE_INTERACTIVE", "RemoteInteractive",
"SERVICE", "Service",
"SYSTEM", "System",
"UNLOCK", "System"
];
let DeviceTypeLookup = datatable (agentDetectionInfo_machineType_s: string, SrcDeviceType: string)
[
"desktop", "Computer",
"server", "Computer",
"laptop", "Computer",
"kubernetes node", "Other",
"unknown", "Other"
];
let TargetUserTypesList = dynamic(["Regular", "Machine", "Admin", "System", "Application", "Service Principal", "Service", "Anonymous"]);
let parser = (disabled: bool = false, starttime: datetime=datetime(null), endtime: datetime=datetime(null), targetusername_has: string='*') {
let alldata = SentinelOne_CL
| where not(disabled)
and (isnull(starttime) or TimeGenerated >= starttime) and (isnull(endtime) or TimeGenerated <= endtime);
let activitydata = alldata
| where event_name_s == "Activities."
and activityType_d in (27, 33, 133, 134, 139, 3629)
| parse-kv DataFields_s as (ipAddress: string, username: string, userScope: string, accountName: string, fullScopeDetails: string, fullScopeDetailsPath: string, role: string, scopeLevel: string, source: string, sourceType: string) with (pair_delimiter=",", kv_delimiter=":", quote='"')
| where targetusername_has == "*" or username has targetusername_has
| lookup EventFieldsLookup on activityType_d
| lookup EventResultDetailsLookup on comments_s
| extend
SrcIpAddr = iff(ipAddress == "null", "", ipAddress),
EventOriginalType = tostring(toint(activityType_d)),
TargetUsername = username,
TargetUserScope = userScope,
AdditionalFields = bag_pack(
"accountName", accountName,
"fullScopeDetails", fullScopeDetails,
"fullScopeDetailsPath", fullScopeDetailsPath,
"scopeLevel", scopeLevel,
"source", source,
"sourceType", sourceType
),
TargetOriginalUserType = role,
TargetUserType = case(
role in (TargetUserTypesList), role,
role == "null", "",
"Other"
)
| project-rename
EventStartTime = createdAt_t,
TargetUserId = userId_s,
EventOriginalUid = activityUuid_g,
EventMessage = primaryDescription_s;
let alertdata = alldata
| where event_name_s == "Alerts."
and alertInfo_eventType_s in ("WINLOGONATTEMPT", "WINLOGOFFATTEMPT")
and targetusername_has == "*" or alertInfo_loginsUserName_s has targetusername_has
| lookup EventTypeLookup on alertInfo_eventType_s
| lookup EventSubTypeLookup on alertInfo_loginType_s
| lookup DeviceTypeLookup on agentDetectionInfo_machineType_s
| invoke _ASIM_ResolveDvcFQDN('agentDetectionInfo_name_s')
| invoke _ASIM_ResolveSrcFQDN('alertInfo_loginAccountDomain_s')
| extend
EventResult = iff(alertInfo_loginIsSuccessful_s == "true", "Success", "Failure"),
EventSeverity = iff(ruleInfo_severity_s == "Critical", "High", ruleInfo_severity_s)
| project-rename
EventStartTime = alertInfo_createdAt_t,
SrcIpAddr = alertInfo_srcMachineIp_s,
ActingAppName = sourceProcessInfo_name_s,
DvcId = agentDetectionInfo_uuid_g,
DvcOs = agentDetectionInfo_osName_s,
DvcOsVersion = agentDetectionInfo_osRevision_s,
EventOriginalSeverity = ruleInfo_severity_s,
EventOriginalType = alertInfo_eventType_s,
EventOriginalSubType = alertInfo_loginType_s,
RuleName = ruleInfo_name_s,
TargetUserId = alertInfo_loginAccountSid_s,
TargetUsername = alertInfo_loginsUserName_s
| extend
Rule = RuleName,
ActingAppType = iff(isnotempty(ActingAppName), "Process", ""),
DvcIdType = iff(isnotempty(DvcId), "Other", ""),
TargetUserType = _ASIM_GetUserType(TargetUsername, TargetUserId);
union activitydata, alertdata
| extend
EventCount = int(1),
EventProduct = "SentinelOne",
EventSchemaVersion = "0.1.3",
EventVendor = "SentinelOne",
EventSchema = "Authentication"
| extend
Dvc = coalesce(DvcHostname, EventProduct),
EventEndTime = EventStartTime,
EventUid = _ItemId,
User = TargetUsername,
TargetHostname = SrcHostname,
TargetDomain = SrcDomain,
TargetDomainType = SrcDomainType,
TargetFQDN = SrcFQDN,
TargetUserIdType = iff(isnotempty(TargetUserId), "Other", ""),
TargetUsernameType = _ASIM_GetUsernameType(TargetUsername)
| extend
IpAddr = SrcIpAddr,
Src = SrcIpAddr
| project-away
*_b,
*_d,
*_g,
*_s,
*_t,
ipAddress,
username,
accountName,
fullScopeDetails,
fullScopeDetailsPath,
role,
scopeLevel,
source,
sourceType,
userScope,
Computer,
MG,
ManagementGroupName,
RawData,
SourceSystem,
TenantId,
_ItemId,
_ResourceId
};
parser(disabled=disabled, starttime=starttime, endtime=endtime, targetusername_has=targetusername_has)
Loading