Skip to content

Commit

Permalink
Merge pull request #237 from T0pCyber/feature/154-dc-1-extend-log-ret…
Browse files Browse the repository at this point in the history
…rieval-period

Feature/154 dc 1 extend log retrieval period
  • Loading branch information
T0pCyber authored Jan 12, 2025
2 parents 71bdea2 + cdaf7be commit 470acce
Show file tree
Hide file tree
Showing 48 changed files with 1,024 additions and 443 deletions.
4 changes: 4 additions & 0 deletions Hawk/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,7 @@
## 3.X.X (2025-X-XX)

- Implemented UTC timestamps to avoid using local timestamps
- 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

227 changes: 120 additions & 107 deletions Hawk/functions/General/Update-HawkModule.ps1
Original file line number Diff line number Diff line change
@@ -1,109 +1,122 @@
Function Update-HawkModule {
<#
.SYNOPSIS
Hawk upgrade check
.DESCRIPTION
Hawk upgrade check
.PARAMETER ElevatedUpdate
Update Module
.EXAMPLE
Update-HawkModule
Checks for update to Hawk Module on PowerShell Gallery
.NOTES
General notes
#>
param
(
[switch]$ElevatedUpdate
)
<#
.SYNOPSIS
Hawk upgrade check.
.DESCRIPTION
Hawk upgrade check. Checks the PowerShell Gallery for newer versions of the Hawk module and handles the update process, including elevation of privileges if needed.
.PARAMETER ElevatedUpdate
Switch parameter indicating the function is running in an elevated context.
.PARAMETER WhatIf
Shows what would happen if the command runs. The command is not run.
.PARAMETER Confirm
Prompts you for confirmation before running the command.
.EXAMPLE
Update-HawkModule
Checks for update to Hawk Module on PowerShell Gallery.
.NOTES
Requires elevation to Administrator rights to perform the update.
#>
[CmdletBinding(SupportsShouldProcess)]
param
(
[switch]$ElevatedUpdate
)

# If ElevatedUpdate is true then we are running from a forced elevation and we just need to run without prompting
if ($ElevatedUpdate) {
# Set upgrade to true
$Upgrade = $true
}
else {

# See if we can do an upgrade check
if ($null -eq (Get-Command Find-Module)) { }

# If we can then look for an updated version of the module
else {
Out-LogFile "Checking for latest version online" -Action
$onlineversion = Find-Module -name Hawk -erroraction silentlycontinue
$Localversion = (Get-Module Hawk | Sort-Object -Property Version -Descending)[0]
Out-LogFile ("Found Version " + $onlineversion.version + " Online") -Information

# If ElevatedUpdate is true then we are running from a forced elevation and we just need to run without prompting
if ($ElevatedUpdate) {
# Set upgrade to true
$Upgrade = $true
}
else {

# See if we can do an upgrade check
if ($null -eq (Get-Command Find-Module)) { }

# If we can then look for an updated version of the module
else {
Write-Output "Checking for latest version online"
$onlineversion = Find-Module -name Hawk -erroraction silentlycontinue
$Localversion = (Get-Module Hawk | Sort-Object -Property Version -Descending)[0]
Write-Output ("Found Version " + $onlineversion.version + " Online")

if ($null -eq $onlineversion){
Write-Output "[ERROR] - Unable to check Hawk version in Gallery"
}
elseif (([version]$onlineversion.version) -gt ([version]$localversion.version)) {
Write-Output "New version of Hawk module found online"
Write-Output ("Local Version: " + $localversion.version + " Online Version: " + $onlineversion.version)

# Prompt the user to upgrade or not
$title = "Upgrade version"
$message = "A Newer version of the Hawk Module has been found Online. `nUpgrade to latest version?"
$Yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Stops the function and provides directions for upgrading."
$No = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Continues running current function"
$options = [System.Management.Automation.Host.ChoiceDescription[]]($Yes, $No)
$result = $host.ui.PromptForChoice($title, $message, $options, 0)

# Check to see what the user choose
switch ($result) {
0 { $Upgrade = $true; Send-AIEvent -Event Upgrade -Properties @{"Upgrade" = "True" }
}
1 { $Upgrade = $false; Send-AIEvent -Event Upgrade -Properties @{"Upgrade" = "False" }
}
}
}
# If the versions match then we don't need to upgrade
else {
Write-Output "Latest Version Installed"
}
}
}

# If we determined that we want to do an upgrade make the needed checks and do it
if ($Upgrade) {
# Determine if we have an elevated powershell prompt
If (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
# Update the module
Write-Output "Downloading Updated Hawk Module"
Update-Module Hawk -Force
Write-Output "Update Finished"
Start-Sleep 3

# If Elevated update then this prompt was created by the Update-HawkModule function and we can close it out otherwise leave it up
if ($ElevatedUpdate) { exit }

# If we didn't elevate then we are running in the admin prompt and we need to import the new hawk module
else {
Write-Output "Starting new PowerShell Window with the updated Hawk Module loaded"

# We can't load a new copy of the same module from inside the module so we have to start a new window
Start-Process powershell.exe -ArgumentList "-noexit -Command Import-Module Hawk -force" -Verb RunAs
Write-Warning "Updated Hawk Module loaded in New PowerShell Window. `nPlease Close this Window."
break
}

}
# If we are not running as admin we need to start an admin prompt
else {
# Relaunch as an elevated process:
Write-Output "Starting Elevated Prompt"
Start-Process powershell.exe -ArgumentList "-noexit -Command Import-Module Hawk;Update-HawkModule -ElevatedUpdate" -Verb RunAs -Wait

Write-Output "Starting new PowerShell Window with the updated Hawk Module loaded"

# We can't load a new copy of the same module from inside the module so we have to start a new window
Start-Process powershell.exe -ArgumentList "-noexit -Command Import-Module Hawk -force"
Write-Warning "Updated Hawk Module loaded in New PowerShell Window. `nPlease Close this Window."
break
}
}
# Since upgrade is false we log and continue
else {
Write-Output "Skipping Upgrade"
}
}
if ($null -eq $onlineversion){
Out-LogFile "[ERROR] - Unable to check Hawk version in Gallery" -isError
}
elseif (([version]$onlineversion.version) -gt ([version]$localversion.version)) {
Out-LogFile "New version of Hawk module found online" -Information
Out-LogFile ("Local Version: " + $localversion.version + " Online Version: " + $onlineversion.version) -Information

# Prompt the user to upgrade or not
$title = "Upgrade version"
$message = "A Newer version of the Hawk Module has been found Online. `nUpgrade to latest version?"
$Yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Stops the function and provides directions for upgrading."
$No = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Continues running current function"
$options = [System.Management.Automation.Host.ChoiceDescription[]]($Yes, $No)
$result = $host.ui.PromptForChoice($title, $message, $options, 0)

# Check to see what the user choose
switch ($result) {
0 { $Upgrade = $true; Send-AIEvent -Event Upgrade -Properties @{"Upgrade" = "True" }
}
1 { $Upgrade = $false; Send-AIEvent -Event Upgrade -Properties @{"Upgrade" = "False" }
}
}
}
# If the versions match then we don't need to upgrade
else {
Out-LogFile "Latest Version Installed" -Information
}
}
}

# If we determined that we want to do an upgrade make the needed checks and do it
if ($Upgrade) {
# Determine if we have an elevated powershell prompt
If (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
# Update the module
if ($PSCmdlet.ShouldProcess("Hawk Module", "Update module")) {
Out-LogFile "Downloading Updated Hawk Module" -Action
Update-Module Hawk -Force
Out-LogFile "Update Finished" -Action
Start-Sleep 3

# If Elevated update then this prompt was created by the Update-HawkModule function and we can close it out otherwise leave it up
if ($ElevatedUpdate) { exit }

# If we didn't elevate then we are running in the admin prompt and we need to import the new hawk module
else {
Out-LogFile "Starting new PowerShell Window with the updated Hawk Module loaded" -Action

# We can't load a new copy of the same module from inside the module so we have to start a new window
Start-Process powershell.exe -ArgumentList "-noexit -Command Import-Module Hawk -force" -Verb RunAs
Out-LogFile "Updated Hawk Module loaded in New PowerShell Window. Please Close this Window." -Notice
break
}
}
}
# If we are not running as admin we need to start an admin prompt
else {
# Relaunch as an elevated process:
Out-LogFile "Starting Elevated Prompt" -Action
Start-Process powershell.exe -ArgumentList "-noexit -Command Import-Module Hawk;Update-HawkModule -ElevatedUpdate" -Verb RunAs -Wait

Out-LogFile "Starting new PowerShell Window with the updated Hawk Module loaded" -Action

# We can't load a new copy of the same module from inside the module so we have to start a new window
Start-Process powershell.exe -ArgumentList "-noexit -Command Import-Module Hawk -force"
Out-LogFile "Updated Hawk Module loaded in New PowerShell Window. Please Close this Window." -Notice
break
}
}
# Since upgrade is false we log and continue
else {
Out-LogFile "Skipping Upgrade" -Action
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ Function Get-HawkTenantAdminEmailForwardingChange {
[CmdletBinding()]
param()

# Check if Hawk object exists and is fully initialized
if (Test-HawkGlobalObject) {
Initialize-HawkGlobalObject
}

# Test the Exchange Online connection to ensure the environment is ready for operations.
Test-EXOConnection
# Log the execution of the function for audit and telemetry purposes.
Expand Down Expand Up @@ -199,8 +204,9 @@ Search-UnifiedAuditLog -RecordType ExchangeAdmin -Operations @(
}
else {
# Log a message if no forwarding changes are found in the logs.
Out-LogFile "No forwarding changes found in filtered results" -Information
Out-LogFile "Retrieved $($AllMailboxChanges.Count) total operations, but none involved forwarding changes" -Information
Out-LogFile "Get-HawkTenantAdminEmailForwardingChange completed successfully" -Information
Out-LogFile "No forwarding changes found in filtered results" -action
Out-LogFile "Retrieved $($AllMailboxChanges.Count) total operations, but none involved forwarding changes" -action
}
}
catch {
Expand Down
12 changes: 9 additions & 3 deletions Hawk/functions/Tenant/Get-HawkTenantAdminInboxRuleCreation.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ Function Get-HawkTenantAdminInboxRuleCreation {
[CmdletBinding()]
param()

# Check if Hawk object exists and is fully initialized
if (Test-HawkGlobalObject) {
Initialize-HawkGlobalObject
}

Test-EXOConnection
Send-AIEvent -Event "CmdRun"

Expand Down Expand Up @@ -85,8 +90,8 @@ Function Get-HawkTenantAdminInboxRuleCreation {
foreach ($rule in $SuspiciousRules) {
$reasons = @()
if (Test-SuspiciousInboxRule -Rule $rule -Reasons ([ref]$reasons)) {
Out-LogFile "Found suspicious rule creation: '$($rule.Param_Name)' created by $($rule.UserId) at $($rule.CreationTime)" -Notice
Out-LogFile "Reasons for investigation: $($reasons -join '; ')" -Notice
Out-LogFile "Found suspicious rule creation: '$($rule.Param_Name)'" -Notice

}
}
}
Expand All @@ -96,7 +101,8 @@ Function Get-HawkTenantAdminInboxRuleCreation {
}
}
else {
Out-LogFile "No admin inbox rule creation events found in audit logs" -Information
Out-LogFile "Get-HawkTenantAdminInboxRuleCreation completed successfully" -Information
Out-LogFile "No admin inbox rule creation events found in audit logs" -Action
}
}
catch {
Expand Down
17 changes: 12 additions & 5 deletions Hawk/functions/Tenant/Get-HawkTenantAdminInboxRuleModification.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ Function Get-HawkTenantAdminInboxRuleModification {
[CmdletBinding()]
param()

# Check if Hawk object exists and is fully initialized
if (Test-HawkGlobalObject) {
Initialize-HawkGlobalObject
}


Test-EXOConnection
Send-AIEvent -Event "CmdRun"

Expand Down Expand Up @@ -80,16 +86,16 @@ Function Get-HawkTenantAdminInboxRuleModification {

if ($SuspiciousModifications) {
Out-LogFile "Found suspicious rule modifications requiring investigation" -Notice

Out-LogFile "Writing suspicious rule modification data" -Action
$SuspiciousModifications | Out-MultipleFileType -FilePrefix "_Investigate_Admin_Inbox_Rules_Modification" -csv -json -Notice

# Log details about why each modification was flagged
foreach ($rule in $SuspiciousModifications) {
$reasons = @()
if (Test-SuspiciousInboxRule -Rule $rule -Reasons ([ref]$reasons)) {
Out-LogFile "Found suspicious rule modification: '$($rule.Param_Name)' modified by $($rule.UserId) at $($rule.CreationTime)" -Notice
Out-LogFile "Reasons for investigation: $($reasons -join '; ')" -Notice
# Just enhance the log message but keep all data processing the same
Out-LogFile "Found suspicious rule modification: Operation=$($rule.Operation) User=$($rule.UserId)" -Notice
}
}
}
Expand All @@ -99,7 +105,8 @@ Function Get-HawkTenantAdminInboxRuleModification {
}
}
else {
Out-LogFile "No inbox rule modifications found in audit logs" -Information
Out-LogFile "Get-HawkTenantAdminInboxRuleModification completed successfully" -Information
Out-LogFile "No inbox rule modifications found in audit logs" -action
}
}
catch {
Expand Down
12 changes: 9 additions & 3 deletions Hawk/functions/Tenant/Get-HawkTenantAdminInboxRuleRemoval.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ Function Get-HawkTenantAdminInboxRuleRemoval {
[CmdletBinding()]
param()

# Check if Hawk object exists and is fully initialized
if (Test-HawkGlobalObject) {
Initialize-HawkGlobalObject
}

Test-EXOConnection
Send-AIEvent -Event "CmdRun"

Expand Down Expand Up @@ -88,8 +93,8 @@ Function Get-HawkTenantAdminInboxRuleRemoval {
foreach ($rule in $SuspiciousRemovals) {
$reasons = @()
if (Test-SuspiciousInboxRule -Rule $rule -Reasons ([ref]$reasons)) {
Out-LogFile "Found suspicious rule removal: '$($rule.Param_Name)' removed by $($rule.UserId) at $($rule.CreationTime)" -Notice
Out-LogFile "Reasons for investigation: $($reasons -join '; ')" -Notice
Out-LogFile "Found suspicious rule removal: '$($rule.Param_Name)'" -Notice

}
}
}
Expand All @@ -99,7 +104,8 @@ Function Get-HawkTenantAdminInboxRuleRemoval {
}
}
else {
Out-LogFile "No inbox rule removals found in audit logs" -Information
Out-LogFile "Get-HawkTenantAdminInboxRuleRemoval completed successfully" -Information
Out-LogFile "No inbox rule removals found in audit logs" -action
}
}
catch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ Function Get-HawkTenantAdminMailboxPermissionChange {
[CmdletBinding()]
param()

# Check if Hawk object exists and is fully initialized
if (Test-HawkGlobalObject) {
Initialize-HawkGlobalObject
}


Test-EXOConnection
Send-AIEvent -Event "CmdRun"

Expand Down Expand Up @@ -98,7 +104,8 @@ Function Get-HawkTenantAdminMailboxPermissionChange {
}
}
else {
Out-LogFile "No mailbox permission changes found in audit logs" -Information
Out-LogFile "Get-HawkTenantAdminMailBoxPermissionChange completed successfully" -Information
Out-LogFile "No mailbox permission changes found in audit logs" -action
}
}
catch {
Expand Down
Loading

0 comments on commit 470acce

Please sign in to comment.