diff --git a/Hawk/Hawk.psd1 b/Hawk/Hawk.psd1 index 1589cd3..4b7bac5 100644 --- a/Hawk/Hawk.psd1 +++ b/Hawk/Hawk.psd1 @@ -83,6 +83,7 @@ 'Get-HawkTenantEntraIDAdmin', 'Get-HawkTenantEXOAdmin', 'Get-HawkTenantMailItemsAccessed', + 'Get-HawkUserMailItemsAccessed', 'Get-HawkTenantAppAndSPNCredentialDetail', 'Get-HawkTenantEntraIDUser', 'Get-HawkTenantDomainActivity', diff --git a/Hawk/changelog.md b/Hawk/changelog.md index 2f2aee0..3030106 100644 --- a/Hawk/changelog.md +++ b/Hawk/changelog.md @@ -95,4 +95,5 @@ - Implemented PROMPT tag to display to screen when prompting user - Added functionality to expand detect M365 license type to determine max log retention time - Added ability to expand search up to 365 days +- Added search of mail items accessed to the User Investigation (Get-HawkUserMailItemsAccessed) diff --git a/Hawk/functions/User/Get-HawkUserMailItemsAccessed.ps1 b/Hawk/functions/User/Get-HawkUserMailItemsAccessed.ps1 new file mode 100644 index 0000000..3054fd5 --- /dev/null +++ b/Hawk/functions/User/Get-HawkUserMailItemsAccessed.ps1 @@ -0,0 +1,89 @@ +Function Get-HawkUserMailItemsAccessed { +<# +.SYNOPSIS + This will export MailboxItemsAccessed 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 + Recent attacker activities have illuminated the use of the Graph API to read user mailbox contents. This will export + logs that will be present if the attacker is using the Graph API for such actions. Note: NOT all graph API actions against + a mailbox are malicious. Review the results of this function and look for suspicious access of mailbox items associated + with a specific user. +.PARAMETER UserPrincipalName + Specific user(s) to be investigated +.EXAMPLE + Get-HawkUserMailItemsAccessed -UserPrincipalName bsmith@contoso.com + Gets MailItemsAccessed from Unified Audit Log (UAL) that corresponds to the User ID that is provided +.OUTPUTS + MailItemsAccessed_bsmith@contoso.com.csv /json + Simple_MailItemsAccessed.csv/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 'MailItemsAccessed'" -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 + try { + #Retrieve all audit data for mailitems accessed + $SearchCommand = "Search-UnifiedAuditLog -Operations 'MailItemsAccessed' -UserIds $User" + $MailboxItemsAccessed = Get-AllUnifiedAuditLogEntry -UnifiedSearch $SearchCommand + + if ($MailboxItemsAccessed.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 + $MailboxItemsAccessedSimple = $MailboxItemsAccessed | Get-SimpleUnifiedAuditLog + + #Export both raw and simplistic views to specified user's folder + $MailboxItemsAccessed | Select-Object -ExpandProperty AuditData | Convertfrom-Json | Out-MultipleFileType -FilePrefix "MailItemsAccessed_$User" -User $User -csv -json + $MailboxItemsAccessedSimple | Out-MultipleFileType -FilePrefix "Simple_MailItemsAccessed_$User" -User $User -csv -json + } else { + Out-LogFile "Get-HawkUserMailItemsAccesed completed successfully" -Information + Out-LogFile "No items found for $User." -Information + } + } catch { + Out-LogFile "Error processing mail items accessed for $User : $_" -isError + Write-Error -ErrorRecord $_ -ErrorAction Continue + } + } + + }#End Process + + END{ + Out-Logfile "Completed exporting MailItemsAccessed logs" -Information + }#End End + +} \ No newline at end of file diff --git a/Hawk/functions/User/Start-HawkUserInvestigation.ps1 b/Hawk/functions/User/Start-HawkUserInvestigation.ps1 index d295c90..c62e8f4 100644 --- a/Hawk/functions/User/Start-HawkUserInvestigation.ps1 +++ b/Hawk/functions/User/Start-HawkUserInvestigation.ps1 @@ -112,6 +112,11 @@ Out-LogFile "Running Get-HawkUserMessageTrace" -Action Get-HawkUserMessageTrace -User $User } + + if ($PSCmdlet.ShouldProcess("Running Get-HawkUserMailItemsAccessed for $User")) { + Out-LogFile "Running Get-HawkUserMailItemsAccessed" -Action + Get-HawkUserMailItemsAccessed -UserPrincipalName $User + } if ($PSCmdlet.ShouldProcess("Running Get-HawkUserMobileDevice for $User")) { Out-LogFile "Running Get-HawkUserMobileDevice" -Action