-
Notifications
You must be signed in to change notification settings - Fork 120
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature/234: Added check to verify exchange operation enabled for audit.
- Loading branch information
1 parent
6af6ce5
commit 943c2ef
Showing
5 changed files
with
169 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
Function Get-HawkUserExchangeSearchQuery { | ||
<# | ||
.SYNOPSIS | ||
This will export SearchQueryInitiatedExchange operations from the Unified Audit Log (UAL). Must be connected to Exchange Online | ||
using the Connect-EXO or Connect-ExchangeOnline module. M365 E5 or G5 license is required for this function to work. | ||
This telemetry will ONLY be availabe if Advanced Auditing is enabled for the M365 user. | ||
.DESCRIPTION | ||
This function queries for searches performed in Exchange, providing visibility into what users are searching for and potential | ||
indications of insider threats or data exploration during incidents. | ||
.PARAMETER UserPrincipalName | ||
Specific user(s) to be investigated | ||
.EXAMPLE | ||
Get-HawkUserExchangeSearchQuery -UserPrincipalName [email protected] | ||
Returns search queries from Unified Audit Log (UAL) that correspond to the UserPrincipalName that is provided | ||
.OUTPUTS | ||
[email protected] /json | ||
[email protected]/json | ||
.LINK | ||
https://www.microsoft.com/security/blog/2020/12/21/advice-for-incident-responders-on-recovery-from-systemic-identity-compromises/ | ||
.NOTES | ||
"Operation Properties" and "Folders" will return "System.Object" as they are nested JSON within the AuditData field. | ||
You will need to conduct individual log pull and review via PowerShell or other SIEM to determine values | ||
for those fields. | ||
#> | ||
[CmdletBinding()] | ||
param( | ||
[Parameter(Mandatory=$true)] | ||
[array]$UserPrincipalName | ||
) | ||
|
||
BEGIN { | ||
# Check if Hawk object exists and is fully initialized | ||
if (Test-HawkGlobalObject) { | ||
Initialize-HawkGlobalObject | ||
} | ||
Out-LogFile "Starting Unified Audit Log (UAL) search for 'SearchQueryInitiatedExchange'" -Action | ||
Out-LogFile "Please be patient, this can take a while..." -Information | ||
Test-EXOConnection | ||
}#End Begin | ||
|
||
PROCESS { | ||
|
||
#Verify UPN input | ||
[array]$UserArray = Test-UserObject -ToTest $UserPrincipalName | ||
|
||
foreach($UserObject in $UserArray) { | ||
[string]$User = $UserObject.UserPrincipalName | ||
|
||
# Verify that user has operation enabled for auditing. Otherwise, move onto next user. | ||
if (Test-OperationEnabled -User $User -Operation 'SearchQueryInitiated') { | ||
Out-LogFile "Operation 'SearchQueryInitiated' verified enabled for $User." -Information | ||
try { | ||
#Retrieve all audit data for mailitems accessed | ||
$SearchCommand = "Search-UnifiedAuditLog -Operations 'SearchQueryInitiatedExchange' -UserIds $User" | ||
$ExchangeSearches = Get-AllUnifiedAuditLogEntry -UnifiedSearch $SearchCommand | ||
|
||
if ($ExchangeSearches.Count -gt 0){ | ||
|
||
#Define output directory path for user | ||
$UserFolder = Join-Path -Path $Hawk.FilePath -ChildPath $User | ||
|
||
#Create user directory if it doesn't already exist | ||
if (-not (Test-Path -Path $UserFolder)) { | ||
New-Item -Path $UserFolder -ItemType Directory -Force | Out-Null | ||
} | ||
|
||
#Compress raw data into more simple view | ||
$ExchangeSearchesSimple = $ExchangeSearches | Get-SimpleUnifiedAuditLog | ||
|
||
#Export both raw and simplistic views to specified user's folder | ||
$ExchangeSearches | Select-Object -ExpandProperty AuditData | Convertfrom-Json | Out-MultipleFileType -FilePrefix "ExchangeSearchQueries_$User" -User $User -csv -json | ||
$ExchangeSearchesSimple | Out-MultipleFileType -FilePrefix "Simple_ExchangeSearchQueries_$User" -User $User -csv -json | ||
} else { | ||
Out-LogFile "Get-HawkUserExchangeSearchQuery completed successfully" -Information | ||
Out-LogFile "No items found for $User." -Information | ||
} | ||
} catch { | ||
Out-LogFile "Error processing Exchange Search Queries for $User : $_" -isError | ||
Write-Error -ErrorRecord $_ -ErrorAction Continue | ||
} | ||
} else { | ||
Out-LogFile "Operation 'SearchQueryInitiated' is not enabled for $User." -Information | ||
Out-LogFile "No data recorded for $User." -Information | ||
} | ||
} | ||
|
||
}#End Process | ||
|
||
END{ | ||
Out-Logfile "Completed exporting Search Query logs" -Information | ||
}#End End | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<# | ||
.SYNOPSIS | ||
Test if a user has a specific operation enabled for auditing | ||
.DESCRIPTION | ||
Test if a user has a specific operation enabled for auditing | ||
.EXAMPLE | ||
[bool]$result = Test-OperationEnabled -User [email protected] -Operation 'SearchQueryInitiated' | ||
.PARAMETER User | ||
Specific user under investigation | ||
.PARAMETER Operation | ||
Operation to be verified enabled for auditing | ||
.EXAMPLE | ||
Test-OperationEnabled -User [email protected] -Operation 'SearchQueryInitiated' | ||
.OUTPUTS | ||
System.Boolean | ||
Output is a boolean result returned to the calling external function | ||
.NOTES | ||
This function is internal and to be called from another Hawk user-enabled function. Return value is boolean, and | ||
it is intended to be used in an if-else check verifying an operation is enabled for auditing under a given user. | ||
#> | ||
Function Test-OperationEnabled { | ||
|
||
[CmdletBinding()] | ||
[OutputType([bool])] | ||
param( | ||
[Parameter(Mandatory=$true)] | ||
[string]$User, | ||
[Parameter(Mandatory=$true)] | ||
[string]$Operation | ||
) | ||
|
||
# Verify the provided User has the specified Operation enabled | ||
$TestResult = Get-Mailbox -Identity $User | Where-Object -Property AuditOwner -eq $Operation | ||
|
||
if ($null -eq $TestResult) { | ||
return $false | ||
} else { | ||
return $true | ||
} | ||
} |