8000 Bugfix/210 bugip stack api key flow needs improvement for better user experience new by dcodev1702 · Pull Request #243 · T0pCyber/hawk · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Bugfix/210 bugip stack api key flow needs improvement for better user experience new #243

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

Open
wants to merge 56 commits into
base: Development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
6deb0c6
Added a very valuable comment :)
Jan 18, 2025
21773ac
Better comment, aye, aye sir!
Jan 18, 2025
288597d
Added logic for checking ipstack.com API Key with some error handling.
Jan 19, 2025
e1f7352
Added logic for checking ipstack.com API Key with some error handling.
Jan 19, 2025
63f79dc
Resolved merge conflict.
Jan 19, 2025
f9340ec
added -EnableGeoIPLocation command line switch and IPSTACK API logic …
Jan 19, 2025
75de877
added help .PARAMETERS for EnableGeoIPLocation for 2 files to pass pe…
Jan 19, 2025
54cd832
added additional information for help parameters for EnableGeoIPLocation
Jan 19, 2025
599f733
Enhanced comments for deeper understanding and minor refactoring of u…
Jan 19, 2025
1cfbc10
Add internal helper function to rest hawk environment.
jonnybottles Jan 20, 2025
33bc25a
Add internal helper function to rest hawk environment.
jonnybottles Jan 20, 2025
2fb3c96
Delete Hawk/internal/functions/Reset-HawkEnvironment.ps1
jonnybottles Jan 20, 2025
06ffb5b
accepted and resolved merge conflicts from development branch into th…
Feb 2, 2025
8fb8725
Merge branch 'bugfix/210-bugip-stack-api-key-flow-needs-improvement-f…
Feb 2, 2025
c0c3a6b
Initial commit on new workstation
Feb 7, 2025
3bea42a
Validated use cases for EnableGeoIPLocation for interactive and non-i…
Feb 7, 2025
7c9b2b8
Fixed cosmetic output in Hawk Configuration Summary - 'Enable Geo IP …
Feb 7, 2025
7726dfe
Added checks for any 1 of 3 CmdLets were called to validate the use o…
Feb 7, 2025
b7acab5
Fleshing out logic for API Access Key if absored from file or provide…
Feb 7, 2025
bb91e8f
Still narrowing down the bug. Additional checks for malformed and bad…
Feb 7, 2025
595fd23
Still narrowing down the bug. Additional checks for malformed and bad…
Feb 7, 2025
26dfdbc
If key exists on disk and user chooses to use it, we will validate it…
Feb 7, 2025
2cd6c07
cosmetics
Feb 7, 2025
e9dd6b8
cosmetics
Feb 7, 2025
c0c89c2
Prepping for all the AI's
Feb 23, 2025
d05dcc0
moved IP Stack API Key check to a better / sane location && FIXED GET…
Feb 24, 2025
d0cac86
Get-IPGeolocation - Line: 59 :: ConvertTo-Json -Depth 10
Feb 24, 2025
f27d393
Removed Global variable for
Feb 24, 2025
4c1f2f7
Inserted a while loop to select Y/N to use existing AccessKey
Feb 24, 2025
3ef29a2
Updated output
Feb 24, 2025
a04911a
cosmetic / removed START-USERINVESTIGATION output
Feb 24, 2025
0af959b
Added do/while loop to repeatedly prompt the user for a valid IP Stac…
Feb 24, 2025
fcf286f
modified Read-HawkAppData and more importantly restructured the logic…
Feb 24, 2025
0ffebc4
Fixed issue with the API Key not correctly writing itself to Hawk.jso…
Feb 24, 2025
f3183d7
cleaning up commented out code / variables.
Feb 24, 2025
7ca6f48
Specifically looked for value of .access_key to determine which branc…
Feb 24, 2025
770b816
Cosmetic mod to Add-HawkAppData method.
Feb 24, 2025
70b2775
If access key on file is invalid, set access key to null so user is p…
Feb 25, 2025
4bb3b09
Coded USE CASE: Invalid/Expired key exists on disk, check key, comes …
Feb 25, 2025
6316120
Updated comment section of Get-IPGeolocation.ps1
Feb 25, 2025
6c129af
added documentation and comments throughout code.
Feb 25, 2025
d798ad0
Validated Y/N input when user is asked if they want to save REST API …
Feb 25, 2025
f5daaad
Validated Y/N input when user is asked if they want to save REST API …
Feb 25, 2025
690f0db
cosmetics / minor refactoring
Feb 26, 2025
fc580b9
comments / corrections
Feb 26, 2025
cefb42b
updated changelog.md and Hawk.psd1 to reflect version 4.0.1
Mar 2, 2025
cd474b6
Need to add Hawk GeoIPLocation Automation logic.
Mar 2, 2025
b89f0c4
added logic to support to get Geo IP data in non-interactive mode
Mar 3, 2025
4c0ce3d
valided the log telemetry still get proceeded in non-interactive mode…
Mar 3, 2025
b3dc3a1
added GeoIPNonInteractive variable to Hawk Global Object to help dete…
Mar 3, 2025
191561a
Logic for non-interacive use case added to Hawk ISO version 4.0.1
Mar 3, 2025
0ac07c4
Changed Get-IPGeolocation to Get-IPGeoLocation
Mar 3, 2025
e27ffa1
renaming files
Mar 3, 2025
47a1239
added Get-IPGeoLocation.ps1
Mar 3, 2025
a59ea1e
Modified changelog.md
Mar 3, 2025
0d61d17
Changed AccessKey Parameter from False to True
Mar 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10000
2 changes: 1 addition & 1 deletion Hawk/Hawk.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
RootModule = 'Hawk.psm1'

# Version number of this module.
ModuleVersion = '4.0'
ModuleVersion = '4.0.1'

# ID used to uniquely identify this module
GUID = '1f6b6b91-79c4-4edf-83a1-66d2dc8c3d85'
Expand Down
7 changes: 6 additions & 1 deletion Hawk/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
- Updated Change Log URI.
- Removed improperly formatted JSON from Get-HawkTenantAdminInboxRuleHistory, Get-HawkTenantAdminInboxRuleRemoval, Get-HawkTenantRBACChange, Get-HawkUserAdminAudit, Search-HawkTenantEXOAuditLog

## 4.0 (2025-2-XX)
## 4.0 (2025-2-23)

- Implemented UTC timestamps to avoid using local timestamps
- Implemented PROMPT tag to display to screen when prompting user
Expand All @@ -106,3 +106,8 @@
- Implemented check to verify that an Exchange operation is enabled for auditing before attempting to pull logs
- Added log pull of user Send activity to the User Investigation (Get-HawkUserMailSendActivity)
- Added log pull of user SharePoint Search activity to the User Investigation (Get-HawkUserSharePointSearchQuery)

## 4.0.1 (2025-3-0X)
- Fixed bug in Get-IPGeolocation where API Keys from ipstack.com were not validated
- Fixed bug in Get-IPGeolocation where API Keys were not validated to meet basic sanity checks/requirements
- Added commandline agrument '-EnableGeoIPLocation' to Start-HawkUserInvestigation providing the ability to skip interactive prompts when conducting investigations.
2 changes: 2 additions & 0 deletions Hawk/debug.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Import-Module "C:\Users\Lorenzo\hawk\Hawk\Hawk.psd1"
Start-HawkUserInvestigation -UserPrincipalName irelandl@semperhunt.onmicrosoft.com -DaysToLookBack 60 -FilePath C:\Temp
16 changes: 8 additions & 8 deletions Hawk/functions/Tenant/Get-HawkTenantRiskyServicePrincipals.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ Function Get-HawkTenantRiskyServicePrincipals {
Send-AIEvent -Event "CmdRun"

# Check for required license
$licenseCheck = Test-EntraWorkloadIDPremium
if (-not $licenseCheck.HasLicense) {
Out-LogFile "Entra Workload ID Premium license not found" -isWarning
Out-LogFile "No Entra Workload ID Premium capable licenses found." -Information
Out-LogFile "Required licenses: AAD_PREMIUM_P2, ENTERPRISEPREMIUM, SPE_E5, IDENTITY_THREAT_PROTECTION" -Information
Out-LogFile "The service principal risk detection requires one of these licenses to function" -Information
return
}
# $licenseCheck = Test-EntraWorkloadIDPremium
# if (-not $licenseCheck.HasLicense) {
# Out-LogFile "Entra Workload ID Premium license not found" -isWarning
# Out-LogFile "No Entra Workload ID Premium capable licenses found." -Information
# Out-LogFile "Required licenses: AAD_PREMIUM_P2, ENTERPRISEPREMIUM, SPE_E5, IDENTITY_THREAT_PROTECTION" -Information
# Out-LogFile "The service principal risk detection requires one of these licenses to function" -Information
# return
# }

Out-LogFile "Retrieving risky service principals from Microsoft Entra ID" -Action

Expand Down
4 changes: 1 addition & 3 deletions Hawk/functions/Tenant/Start-HawkTenantInvestigation.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@
Out-LogFile "Running Get-HawkTenantRBACChange" -action
Get-HawkTenantRBACChange
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove trailing whitespace.

if ($PSCmdlet.ShouldProcess("Entra ID Audit Log", "Get Entra ID audit logs")) {
Out-LogFile "Running Get-HawkTenantEntraIDAuditLog" -action
Get-HawkTenantEntraIDAuditLog
Expand Down Expand Up @@ -247,6 +247,4 @@
$investigationEndTime = Get-Date
Write-HawkInvestigationSummary -StartTime $investigationStartTime -EndTime $investigationEndTime -InvestigationType 'Tenant'
}


}
29 changes: 17 additions & 12 deletions Hawk/functions/User/Get-HawkUserUALSignInLog.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
Single UPN of a user, comma seperated list of UPNs, or array of objects that contain UPNs.
.PARAMETER ResolveIPLocations
Resolved IP Locations

If this option is specified, it will attempt to resolve IP locations (GeoIP) using ipstack.com API (API Key Required)
.OUTPUTS

File: Converted_Authentication_Logs.csv
Expand Down Expand Up @@ -100,26 +102,31 @@
}


# Add IP Geo Location information to the data
if ($ResolveIPLocations) {
Out-File "Resolving IP Locations"
# Add Geo IP location information to the data
if ($PSBoundParameters.ContainsKey('ResolveIPLocations')) {
Out-LogFile "Attemping to resolve IP Locations" -Information
# Setup our counter
$i = 0

# Loop thru each connection and get the location
# Conduct IPStack API Key validation (once) so the API Key can be passed to Get-IPGeolocation
# Get-IPStackAPIKey either returns a valid API key or null
$AccessKey = Get-IPStackAPIKey

# Loop thru each connection and get the Geo IP location
while ($i -lt $ExpandedUserLogonLogs.Count) {

if ([bool]($i % 25)) { }
Else {
Write-Progress -Activity "Looking Up Ip Address Locations" -CurrentOperation $i -PercentComplete (($i / $ExpandedUserLogonLogs.count) * 100)
else {
Write-Progress -Activity "Looking Up IP Address Locations" -CurrentOperation $i -PercentComplete (($i / $ExpandedUserLogonLogs.count) * 100)
}

# Get the location information for this IP address
if($ExpandedUserLogonLogs.item($i).clientip){
$Location = Get-IPGeolocation -ipaddress $ExpandedUserLogonLogs.item($i).clientip
# Need to perform access key value only once instead of for each IP address
if($ExpandedUserLogonLogs.item($i).clientip -and ([string]::IsNullOrEmpty($AccessKey) -eq $false)) {
$Location = Get-IPGeoLocation -IPAddress $ExpandedUserLogonLogs.item($i).clientip -AccessKey $AccessKey
}
else {
$Location = "IP Address Null"
$Location = "Lack valid REST API key or IP address was not found"
}

# Combine the connection object and the location object so that we have a single output ready
Expand All @@ -129,7 +136,7 @@
$i++
}

Write-Progress -Completed -Activity "Looking Up Ip Address Locations" -Status " "
Write-Progress -Completed -Activity "Looking Up IP Address Locations" -Status " "
}
else {
Out-LogFile "ResolveIPLocations not specified" -Information
Expand All @@ -144,6 +151,4 @@

}
}


}
52 changes: 44 additions & 8 deletions Hawk/functions/User/Start-HawkUserInvestigation.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@
.PARAMETER WhatIf
Shows what would happen if the command runs. The command is not executed.
Use this parameter to understand which investigation steps would be performed without actually collecting data.

.PARAMETER EnableGeoIPLocation
Switch to enable resolving IP addresses to geographic locations in the investigation.
This option requires an active internet connection and may increase the time needed to complete the investigation.
Providing this parameter automatically enables non-interactive mode.

REQUIRED: An API key from ipstack.com is required to use this feature.

.OUTPUTS
Creates multiple CSV and JSON files containing investigation results.
Expand Down Expand Up @@ -97,12 +104,12 @@
param (
[Parameter(Mandatory = $true)]
[array]$UserPrincipalName,

[DateTime]$StartDate,
[DateTime]$EndDate,
[int]$DaysToLookBack,
[string]$FilePath,
[switch]$SkipUpdate
[switch]$SkipUpdate,
[switch]$EnableGeoIPLocation
)

begin {
Expand All @@ -125,9 +132,17 @@
}

try {
Initialize-HawkGlobalObject -StartDate $StartDate -EndDate $EndDate `
-DaysToLookBack $DaysToLookBack -FilePath $FilePath `
-SkipUpdate:$SkipUpdate -NonInteractive:$NonInteractive
# Call Initialize-HawkGlobalObject in case of non-interactive mode
if ($PSBoundParameters.ContainsKey('EnableGeoIPLocation')) {
Initialize-HawkGlobalObject -StartDate $StartDate -EndDate $EndDate `
-DaysToLookBack $DaysToLookBack -FilePath $FilePath `
-SkipUpdate:$SkipUpdate -NonInteractive:$NonInteractive -EnableGeoIPLocation:$EnableGeoIPLocation
} else {
# Call Initialize-HawkGlobalObject in case of interactive mode for EnableGeoIPLocation
Initialize-HawkGlobalObject -StartDate $StartDate -EndDate $EndDate `
-DaysToLookBack $DaysToLookBack -FilePath $FilePath `
-SkipUpdate:$SkipUpdate -NonInteractive:$NonInteractive
}
}
catch {
Stop-PSFFunction -Message "Failed to initialize Hawk: $_" -EnableException $true
Expand All @@ -138,8 +153,18 @@
process {
if (Test-PSFFunctionInterrupt) { return }

# Be sure to remove comments after testing!
#if ($PSBoundParameters.ContainsKey('EnableGeoIPLocation')) {
# Initialize-HawkGlobalObject -EnableGeoIPLocation
# Out-LogFile "START-HAWKUSERINVESTIGATION -> Calling Initialize-HawkGlobalObject with EnableGeoIPLocation" -Information
#} else {
# Initialize-HawkGlobalObject
# Out-LogFile "START-HAWKUSERINVESTIGATION -> Calling Initialize-HawkGlobalObject without EnableGeoIPLocation" -Information
#}

# Check if Hawk object exists and is fully initialized
if (Test-HawkGlobalObject) {
#Out-LogFile "START-USERINVESTIGATION::Test-HawkGlobalOjbect evaluated to TRUE!" -Information
Initialize-HawkGlobalObject
}
$investigationStartTime = Get-Date
Expand All @@ -156,6 +181,7 @@
foreach ($Object in $UserArray) {
[string]$User = $Object.UserPrincipalName

<#
if ($PSCmdlet.ShouldProcess("Running Get-HawkUserConfiguration for $User")) {
Out-LogFile "Running Get-HawkUserConfiguration" -Action
Get-HawkUserConfiguration -User $User
Expand All @@ -180,12 +206,21 @@
Out-LogFile "Running Get-HawkUserEntraIDSignInLog" -Action
Get-HawkUserEntraIDSignInLog -UserPrincipalName $User
}

#>
if ($PSCmdlet.ShouldProcess("Running Get-HawkUserUALSignInLog for $User")) {
Out-LogFile "Running Get-HawkUserUALSignInLog" -Action
Get-HawkUserUALSignInLog -User $User -ResolveIPLocations
# Two different use cases (interactive and non-interactive) have to be considered here
# $Hawk.EnableGeoIPLocation is to account for interactive mode
# $PSBoundParameters.ContainsKey('EnableGeoIPLocation') is to account for non-interactive mode
if ($Hawk.EnableGeoIPLocation -or $PSBoundParameters.ContainsKey('EnableGeoIPLocation')) {
Out-LogFile "Running Get-HawkUserUALSignInLog and resolving IP locations" -Action
Get-HawkUserUALSignInLog -User $User -ResolveIPLocations
} else {
Out-LogFile "Running Get-HawkUserUALSignInLog without resolving IP locations" -Action
Get-HawkUserUALSignInLog -User $User
}
}

<#
if ($PSCmdlet.ShouldProcess("Running Get-HawkUserMailboxAuditing for $User")) {
Out-LogFile "Running Get-HawkUserMailboxAuditing" -Action
Get-HawkUserMailboxAuditing -User $User
Expand Down Expand Up @@ -224,6 +259,7 @@
Out-LogFile "Running Get-HawkUserMobileDevice" -Action
Get-HawkUserMobileDevice -User $User
}
#>

}
}
Expand Down
4 changes: 2 additions & 2 deletions Hawk/internal/functions/Add-HawkAppData.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ Function Add-HawkAppData {
[string]$Value
)

Out-LogFile ("Adding " + $value + " to " + $Name + " in HawkAppData") -Action
Out-LogFile ("Adding `"$Value`" to `"$Name`" in HawkAppData") -Action

# Test if our HawkAppData variable exists
if ([bool](get-variable HawkAppData -ErrorAction SilentlyContinue)) {
$global:HawkAppData | Add-Member -MemberType NoteProperty -Name $Name -Value $Value
$global:HawkAppData | Add-Member -MemberType NoteProperty -Name $Name -Value $Value -Force
}
else {
$global:HawkAppData = New-Object -TypeName PSObject
Expand Down
88 changes: 88 additions & 0 deletions Hawk/internal/functions/Get-IPGeoLocation.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<#
.SYNOPSIS
Get-IPGeoLocation is called by Get-HawkUserUALSignInLog to resolve IP addresses to geolocation data.
An IP address and IP Stack API Key is passed to the function, as it returns a PSCustomObject with the geolocation data.

.DESCRIPTION
Get the Geographic Location of an IP address using the ipstack.com REST API
.PARAMETER IPAddress
IP address to look up for its geographic location
.PARAMETER AccessKey
Access key for ipstack.com's REST API
.EXAMPLE
Get-IPGeoLocation -IPAddress 8.8.8.8 -AccessKey e904134b5cbb91f752a79f3ba9cbe59a
Gets all IP GeoLocation data of IPs that recieved
.NOTES
General notes
#>
function Get-IPGeoLocation {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string]$IPAddress,

[Parameter(Mandatory = $true)]
[string]$AccessKey
)

begin {}

process {
try {

if ($IPAddress -eq "<null>") {
Write-Verbose "Null IP Provided: $IPAddress"
return [PSCustomObject]@{
IP = $IPAddress
CountryName = "NULL IP"
RegionName = "Unknown"
RegionCode = "Unknown"
ContinentName = "Unknown"
City = "Unknown"
KnownMicrosoftIP = "Unknown"
}
}

# Check cache
if ($Global:IPLocationCache.ip -contains $IPAddress) {
Write-Verbose "IP Cache Hit: $IPAddress"
return ($Global:IPLocationCache | Where-Object { $_.ip -eq $IPAddress })
}

# Make API calls to IP Stack to look up IP addresses
$resource = "http://api.ipstack.com/$($IPAddress)?access_key=$AccessKey"
$geoip = Invoke-RestMethod -Method Get -URI $resource -ErrorAction Stop
$geoip | ConvertTo-Json -Depth 10

# Create result object
Write-Output "`n"
$isMSFTIP = Test-MicrosoftIP -IPToTest $geoip.ip -Type $geoip.type
$result = [PSCustomObject]@{
IP = $geoip.ip
CountryName = $geoip.country_name
ContinentName = $geoip.continent_name
RegionName = $geoip.region_name
RegionCode = $geoip.region_code
City = $geoip.city
KnownMicrosoftIP = $isMSFTIP
}

# Update cache
[array]$Global:IPLocationCache += $result

return $result
}
catch {
Out-LogFile "Failed to retrieve location for IP $IPAddress : $_" -isError
return [PSCustomObject]@{
IP = $IPAddress
CountryName = "Failed to Resolve"
RegionName = "Unknown"
RegionCode = "Unknown"
ContinentName = "Unknown"
City = "Unknown"
KnownMicrosoftIP = "Unknown"
}
}
}
}
Loading
0