From 2a0ea1c6280eb08918c77a13931cc5debf55a902 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 8 Jan 2025 13:19:07 +0100 Subject: [PATCH] addedbreach searches --- .../Entrypoints/Invoke-ExecBreachSearch.ps1 | 23 ++++++++++++ .../Entrypoints/Invoke-ListBreachesTenant.ps1 | 20 ++++------- .../Public/HIBP/Get-BreachInfo.ps1 | 12 +++++++ .../Public/HIBP/Get-HIBPRequest.ps1 | 21 +++++++---- .../Public/HIBP/New-BreachTenantSearch.ps1 | 36 +++++++++++++++++++ 5 files changed, 92 insertions(+), 20 deletions(-) create mode 100644 Modules/CIPPCore/Public/Entrypoints/Invoke-ExecBreachSearch.ps1 create mode 100644 Modules/CippExtensions/Public/HIBP/Get-BreachInfo.ps1 create mode 100644 Modules/CippExtensions/Public/HIBP/New-BreachTenantSearch.ps1 diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecBreachSearch.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecBreachSearch.ps1 new file mode 100644 index 000000000000..5babb8345a72 --- /dev/null +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecBreachSearch.ps1 @@ -0,0 +1,23 @@ +using namespace System.Net + +Function Invoke-ExecBreachSearch { + <# + .FUNCTIONALITY + Entrypoint + .ROLE + CIPP.Core.Read + #> + [CmdletBinding()] + param($Request, $TriggerMetadata) + + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $TenantFilter = $Request.query.TenantFilter + #Move to background job + New-BreachTenantSearch -TenantFilter $TenantFilter + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = @{ Results = "Executing Search for $TenantFilter" } + }) + +} diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBreachesTenant.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBreachesTenant.ps1 index 61dd7a122404..d30bec6dffef 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBreachesTenant.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBreachesTenant.ps1 @@ -10,20 +10,14 @@ Function Invoke-ListBreachesTenant { [CmdletBinding()] param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - $users = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users?`$select=UserPrincipalName,mail" -tenantid $Request.query.TenantFilter - $usersResults = foreach ($user in $users) { - $Results = Get-HIBPRequest "breachedaccount/$($user.UserPrincipalName)?truncateResponse=true" - if ($null -eq $Results) { - $Results = 'No breaches found.' - } - [PSCustomObject]@{ - user = $user.UserPrincipalName - breaches = $Results - } + $TenantFilter = $Request.query.TenantFilter + $Table = Get-CIPPTable -TableName UserBreaches + if ($TenantFilter -ne 'AllTenants') { + $filter = "PartitionKey eq '$TenantFilter'" + } else { + $filter = $null } - + $usersResults = (Get-CIPPAzDataTableEntity @Table -Filter $filter).breaches | ConvertFrom-Json # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ diff --git a/Modules/CippExtensions/Public/HIBP/Get-BreachInfo.ps1 b/Modules/CippExtensions/Public/HIBP/Get-BreachInfo.ps1 new file mode 100644 index 000000000000..9e1ff4fd8481 --- /dev/null +++ b/Modules/CippExtensions/Public/HIBP/Get-BreachInfo.ps1 @@ -0,0 +1,12 @@ +function Get-BreachInfo { + [CmdletBinding()] + param( + [Parameter()] + $TenantFilter + ) + $Data = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/domains' -tenantid $TenantFilter | ForEach-Object { + $uri = 'https://geoipdb.azurewebsites.net/api/Breach?func=domain&domain=limenetworks.nl' + Invoke-RestMethod -Uri $uri + } + return $Data +} diff --git a/Modules/CippExtensions/Public/HIBP/Get-HIBPRequest.ps1 b/Modules/CippExtensions/Public/HIBP/Get-HIBPRequest.ps1 index 2f6de9d51e1d..1de419c98064 100644 --- a/Modules/CippExtensions/Public/HIBP/Get-HIBPRequest.ps1 +++ b/Modules/CippExtensions/Public/HIBP/Get-HIBPRequest.ps1 @@ -1,17 +1,24 @@ function Get-HIBPRequest { [CmdletBinding()] - param ( - [Parameter()]$endpoint - + param( + [Parameter()] + $endpoint ) $uri = "https://haveibeenpwned.com/api/v3/$endpoint" try { - Invoke-RestMethod -Uri $uri -Headers (Get-HIBPAuth) + return Invoke-RestMethod -Uri $uri -Headers (Get-HIBPAuth) } catch { - #If the error is a 404, it means no breach has been found. Return an empty object. - if ($_.Exception.Response.StatusCode -eq 404) { + if ($_.Exception.Response -and $_.Exception.Response.StatusCode -eq 404) { return @() + } elseif ($_.Exception.Response -and $_.Exception.Response.StatusCode -eq 429) { + Write-Host 'Rate limited hit for hibp.' + return @{ + Wait = ($_.Exception.Response.headers | Where-Object -Property key -EQ 'Retry-After').value + 'rate-limit' = $true + } + } else { + throw "Failed to connect to HIBP: $($_.Exception.Message)" } - throw "Failed to connect to HIBP: $($_.Exception.Message)" } + throw "Failed to connect to HIBP after $maxRetries retries." } diff --git a/Modules/CippExtensions/Public/HIBP/New-BreachTenantSearch.ps1 b/Modules/CippExtensions/Public/HIBP/New-BreachTenantSearch.ps1 new file mode 100644 index 000000000000..a7b40ab26b8d --- /dev/null +++ b/Modules/CippExtensions/Public/HIBP/New-BreachTenantSearch.ps1 @@ -0,0 +1,36 @@ +function New-BreachTenantSearch { + [CmdletBinding()] + param ( + [Parameter()]$TenantFilter, + [Parameter()][switch]$Force + ) + + $Table = Get-CIPPTable -TableName UserBreaches + $LatestBreach = Get-BreachInfo -TenantFilter $TenantFilter + + $usersResults = foreach ($domain in $LatestBreach) { + $ExistingBreaches = Get-CIPPAzDataTableEntity @Table -Filter "RowKey eq '$TenantFilter'" + if ($null -eq $domain.result) { + Write-Host "No breaches found for domain $($domain.domain)" + continue + } + $SumOfBreaches = ($LatestBreach | Measure-Object -Sum -Property found).sum + if ($ExistingBreaches.sum -eq $SumOfBreaches -and $Force.IsPresent -eq $false) { + Write-Host "No new breaches found for tenant $TenantFilter" + continue + } + + @{ + RowKey = $domain.domain + PartitionKey = $TenantFilter + breaches = "$($LatestBreach.Result | ConvertTo-Json)" + sum = $SumOfBreaches + } + } + + #Add user breaches to table + if ($usersResults) { + $entity = Add-CIPPAzDataTableEntity @Table -Entity $usersResults -Force + Write-Host "Added $($usersResults.Count) breaches to table for tenant $TenantFilter" + } +}