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

Exchange Security Insights On-Premise -ExchangeAdminAuditLogs() - parser issue #11664

Closed
itsjusthaif opened this issue Jan 15, 2025 · 5 comments
Assignees
Labels
Parser Parser specialty review needed

Comments

@itsjusthaif
Copy link

itsjusthaif commented Jan 15, 2025

Describe the bug
KQL function doesn't seem to work as intended and results in a kql function parameter error. Please see below images and scenarios for ideas.

To Reproduce
Steps to reproduce the behavior:

  1. Go to Sentinel Content Hub and install the Exchange On-Prem content pack
  2. Once installed go to LogAnalytics in Sentinel and run the parser ExchangeAdminAuditLogs()
  3. See the error union: must have at least one operand that can be evaluated successfully when running with 'Fuzzy' mode

Expected behavior
Should parse the underlying events and generate the output.

Screenshots
Table Data Ingestion:
Image

Watchlist were deployed:
Image

Error showcase:
Image

KQL Function Code:
let CmdletCheck = externaldata (Cmdlet:string, UserOriented:string, RestrictToParameter:string, Parameters:string)[h"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/CmdletWatchlist.csv"]with(format="csv",ignoreFirstRecord=true); let SensitiveCmdlets = CmdletCheck | project tostring(Cmdlet) ; let Check = (T:(*)) { let fuzzyWatchlist = datatable(displayName:string, userPrincipalName:string, sAMAccountName:string, objectSID:string, objectGUID:guid, canonicalName:string, comment:string) [ "NONE","NONE","NONE","NONE","00000001-0000-1000-0000-100000000000","NONE","NONE"]; let Watchlist = union isfuzzy=true withsource=TableName _GetWatchlist('ExchangeVIP'), fuzzyWatchlist | where objectGUID != "00000001-0000-1000-0000-100000000000" | project-away TableName; let SearchUserDisplayName = T | join Watchlist on $left.TargetObject == $right.displayName | project TargetObject,SearchKey; let SearchUserUPN = T | join Watchlist on $left.TargetObject == $right.userPrincipalName | project TargetObject,SearchKey; let SearchUserCanonicalName = T | join Watchlist on $left.TargetObject == $right.canonicalName | project TargetObject,SearchKey; let SearchUserSAMAccountName = T | join Watchlist on $left.TargetObject == $right.sAMAccountName | project TargetObject,SearchKey; let SearchUserObjectSID = T | join Watchlist on $left.TargetObject == $right.objectSID | project TargetObject,SearchKey; let SearchUserObjectGUID = T | join (Watchlist | extend objectGuidString = tostring(objectGUID)) on $left.TargetObject == $right.objectGuidString | project TargetObject,SearchKey; let SearchUserDistinguishedName = T | join Watchlist on $left.TargetObject == $right.distinguishedName | project TargetObject,SearchKey; union isfuzzy=true withsource=TableName SearchUserDisplayName, SearchUserUPN, SearchUserCanonicalName, SearchUserSAMAccountName, SearchUserObjectSID, SearchUserObjectGUID, SearchUserDistinguishedName }; let Env = ExchangeConfiguration(SpecificSectionList="ESIEnvironment") | extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN) | project DomainFQDN_, ESIEnvironment; let EventList = Event | where EventLog == 'MSExchange Management' | where EventID in (1,6) // 1 = Success, 6 = Failure | parse ParameterXml with '<Param>' CmdletName '</Param><Param>' CmdletParameters '</Param><Param>' Caller '</Param><Param>' * | extend TargetObject = iif( CmdletParameters has "-Identity ", split(split(CmdletParameters,'-Identity ')[1],'"')[1], iif( CmdletParameters has "-Name ", split(split(CmdletParameters,'-Name ')[1],'"')[1], "")); let MSExchange_Management = (){ EventList | extend Status = case( EventID == 1, 'Success', 'Failure') | join kind=leftouter (EventList | project TargetObject | invoke Check()) on TargetObject | extend IsVIP = iif(SearchKey == "", false, true) | join kind=leftouter ( MESCheckVIP() ) on SearchKey | extend CmdletNameJoin = tolower(CmdletName) | join kind=leftouter ( CmdletCheck | extend CmdletNameJoin = tolower(Cmdlet) ) on CmdletNameJoin | extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'') | join kind=leftouter ( Env ) on $left.DomainEnv == $right.DomainFQDN_ | extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat("Unknown-",DomainEnv)) | extend IsSenstiveCmdlet = iif( isnotempty(CmdletNameJoin1) , true, false) | extend IsRestrictedCmdLet = iif(IsSenstiveCmdlet == true, iif( RestrictToParameter == "Yes", true, false), dynamic(null)) | extend RestrictedParameters = iif(IsSenstiveCmdlet == true, split(tolower(Parameters),';'), dynamic(null)) | extend ExtractedParameters = iif(IsSenstiveCmdlet == true,extract_all(@"\B(-\w+)", tolower(CmdletParameters)), dynamic(null)) | extend IsSenstiveCmdletParameters = iif(IsSenstiveCmdlet == true,iif( array_length(set_difference(ExtractedParameters,RestrictedParameters)) == array_length(ExtractedParameters), false, true ) , false) | extend IsSensitive = iif( ( IsSenstiveCmdlet == true and IsRestrictedCmdLet == false ) or (IsSenstiveCmdlet == true and IsRestrictedCmdLet == true and IsSenstiveCmdletParameters == true ), true, false ) | project TimeGenerated,Computer,Status,Caller,TargetObject,IsVIP,canonicalName,displayName,distinguishedName,objectGUID,objectSID,sAMAccountName,userPrincipalName,CmdletName,CmdletParameters,IsSenstiveCmdlet,IsRestrictedCmdLet,ExtractedParameters,RestrictedParameters,IsSenstiveCmdletParameters,IsSensitive,UserOriented, ESIEnvironment }; MSExchange_Management

Desktop (please complete the following information):

  • OS: Windows 11
  • Browser: Edge
  • Version:

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version 131.0.2903.112 (Official build) (64-bit)

Additional context
Item was deployed straight from content hub and no modifications were made.

@v-sudkharat v-sudkharat added the Parser Parser specialty review needed label Jan 15, 2025
@v-sudkharat
Copy link
Contributor

Hi @itsjusthaif, Thanks for flagging this issue, we will investigate this issue and get back to you with some updates. Thanks!

@v-sudkharat
Copy link
Contributor

Hi @itsjusthaif, We checked this issue with concern team, below is the response from team:
The Exchange Security Insights On-Premises Collector data connector is mandatory for this ExchangeAdminAuditLogs() parser in addition to the "MSExchange Management" table in workspace.
The ExchangeAdminAuditLogs() Parser call's the other parser which is - Parser for ExchangeConfiguration,
After configuration of the Exchange Security Insights On-Premises Collector check for the table searching it by ESIAPIExchange* or ESIExchange* is get created into the workspace.

Once the above-mentioned step is done kindly run the parser and let us know if still get the issue.

Thanks!

@v-sudkharat
Copy link
Contributor

Hi @itsjusthaif, Did you get a chance to check on above suggestions. Waiting for your response. Thanks!

@v-sudkharat
Copy link
Contributor

Hi @itsjusthaif, Gentle Reminder: We are waiting for your response on this issue. If you still need to keep this issue active, please respond to it in the next 2 days. If we don't receive a response by 29-01-2024 date, we will be closing this issue.
Thanks!

@v-sudkharat
Copy link
Contributor

Hi @itsjusthaif, since we have not received a response in the last 5 days, we are closing your issue as per our standard operating procedures. If you still need support for this issue, feel free to re-open at any time. Thank you for your co-operation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Parser Parser specialty review needed
Projects
None yet
Development

No branches or pull requests

3 participants