From f1504b502593a94e047cc296d5f8ed3e97987870 Mon Sep 17 00:00:00 2001 From: Cam Murray Date: Thu, 30 May 2024 11:30:23 +1000 Subject: [PATCH 1/6] Update README.md --- README.md | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d7a1bd0..855130a 100644 --- a/README.md +++ b/README.md @@ -14,5 +14,47 @@ The following API methods are pulled, flattened, and stored in to Azure Table St Whilst the code here could be adjusted to suit any means, it is intended to run in an Azure Function App. -1. Create a new Azure Function App. Use the default options, and do not set up deployment at this stage unless you want to fork this repository. -2. \ No newline at end of file +### Create the function app + +When creating the Azure Function App in Azure, use the following options +* **Function App Name**: a descriptive name for your function app, and it must be unique across the azure service. As this is not HTTP triggered, the name shouldn't matter. +* **Runtime stack**: .NET +* **Version**: 8 (LTS), isolated worker model +* **Region**: Any region of your choice + +![image](https://github.com/cammurray/ASTSync/assets/26195772/cec9948f-b56b-49ca-aaa4-bbddebd9ccaa) + +Do not specify any other options at this stage, and press Review + Create, followed by create. + +Wait for deployment to complete, and then proceed to setting the deployment method below. + +#### Set the deployment method + +In the "Deployment Center" for the Azure Function App (Accessible under the Deployment Menu), populate the deployment options: +* **Source** Manual Deployment - External Git +* **Repository** Is this one here: https://github.com/cammurray/ASTSync +* **Branch** main +* **Repository Type** Public + +Click Save when populated + +image + +#### Set up the Authentication to Graph API + +There are two ways to perform authentication: +* a secure method which uses a managed identity provisioned by the Function App, however requires some PowerShell +* or by using an Azure AD Application where you manage the Client ID & Secret yourself. This is needed if the Function App is in an Azure Subscription that is not associated to the same Entra directory as M365. + +##### (Option 1) Recommended - Managed Identity + +First, turn on the managed identity in your azure function app by going to Settings -> Identity and turning on the system assigned managed identity for this function app + +image + + +#### Deploy the code + +Once the deployment method has been set, you should be able to click the "Sync" button. This downloads the latest version and compiles it. Confirm the redeployment. + +![image](https://github.com/cammurray/ASTSync/assets/26195772/70516189-0e0c-4b5c-88a1-97ce1665f72f) From b0966fc2c96493dd12d52c32e38013e5d4b22b46 Mon Sep 17 00:00:00 2001 From: Cam Murray Date: Thu, 30 May 2024 12:22:12 +1000 Subject: [PATCH 2/6] Update README.md --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index 855130a..f8103fa 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,31 @@ First, turn on the managed identity in your azure function app by going to Setti image +When this option saves, you should be given a Object (principal) ID, you must save this + +![image](https://github.com/cammurray/ASTSync/assets/26195772/fa130b73-db26-4cbf-b97c-8205ccf9cde7) + +For the next steps, you will need PowerShell. Due to AzureAD module compatability, this cannot be ran from a Mac or an ARM processor. Needs to be run on Windows/x86. + +The following script will find the Function App Security Principal, and grant it AttackSimulation.Read.All and User.Read.All scopes to Microsoft Graph. + +Copy and paste the following in to a PowerShell prompt: + +` +$PrincipalID=Read-Host "Enter the Object ID of the Function App Managed Service Principal" +Install-Module AzureAD -Scope CurrentUser +Connect-AzureAD +$MSI = (Get-AzureADServicePrincipal -Filter "ObjectId eq '00000003-0000-0000-c000-000000000000'") +$GraphServicePrincipal = Get-AzureADServicePrincipal -Filter "appId eq '$GraphAppId'" + +$AppRole = $GraphServicePrincipal.AppRoles | Where-Object {$_.Value -eq "AttackSimulation.Read.All" -and $_.AllowedMemberTypes -contains "Application"} +New-AzureAdServiceAppRoleAssignment -ObjectId $MSI.ObjectId -PrincipalId $MSI.ObjectId -ResourceId $GraphServicePrincipal.ObjectId -Id $AppRole.Id + +$AppRole = $GraphServicePrincipal.AppRoles | Where-Object {$_.Value -eq "User.Read.All" -and $_.AllowedMemberTypes -contains "Application"} +New-AzureAdServiceAppRoleAssignment -ObjectId $MSI.ObjectId -PrincipalId $MSI.ObjectId -ResourceId $GraphServicePrincipal.ObjectId -Id $AppRole.Id +` + +#### (Option 2) Not Recommended - Azure AD Application (COMING SOON). #### Deploy the code From 6a183a86756f3e4382ef51ba452cb0f3f97c7f12 Mon Sep 17 00:00:00 2001 From: Cam Murray Date: Thu, 30 May 2024 12:22:50 +1000 Subject: [PATCH 3/6] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f8103fa..848346e 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ The following API methods are pulled, flattened, and stored in to Azure Table St * graph.microsoft.com/beta/security/attackSimulation/simulations/{id}/reports/simulationUsers -> SimulationsUsers (stores a row for every user in the simulation) and SimulationUserEvents Table (stores all events, such as click/report, etc.) * graph.microsoft.com/beta/security/attackSimulation/payloads -> Payloads * graph.microsoft.com/beta/security/attackSimulation/training -> Trainings +* graph.microsoft.com/beta/users -> Users (Only performed for users that have had a simulation ran against them) ## Installation From 1f969cd3307597135cf6129e2d9ca8700114d25f Mon Sep 17 00:00:00 2001 From: Cam Murray Date: Thu, 30 May 2024 12:24:35 +1000 Subject: [PATCH 4/6] Update README.md --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 848346e..7b6803f 100644 --- a/README.md +++ b/README.md @@ -63,19 +63,25 @@ The following script will find the Function App Security Principal, and grant it Copy and paste the following in to a PowerShell prompt: -` +``` $PrincipalID=Read-Host "Enter the Object ID of the Function App Managed Service Principal" + +# Install AAD Module and Connect Install-Module AzureAD -Scope CurrentUser Connect-AzureAD + +# Find the Managed Service Identity and Graph Service Principal $MSI = (Get-AzureADServicePrincipal -Filter "ObjectId eq '00000003-0000-0000-c000-000000000000'") $GraphServicePrincipal = Get-AzureADServicePrincipal -Filter "appId eq '$GraphAppId'" +# Add AttackSimulation.Read.All permission $AppRole = $GraphServicePrincipal.AppRoles | Where-Object {$_.Value -eq "AttackSimulation.Read.All" -and $_.AllowedMemberTypes -contains "Application"} New-AzureAdServiceAppRoleAssignment -ObjectId $MSI.ObjectId -PrincipalId $MSI.ObjectId -ResourceId $GraphServicePrincipal.ObjectId -Id $AppRole.Id +# Add User.Read.All permission $AppRole = $GraphServicePrincipal.AppRoles | Where-Object {$_.Value -eq "User.Read.All" -and $_.AllowedMemberTypes -contains "Application"} New-AzureAdServiceAppRoleAssignment -ObjectId $MSI.ObjectId -PrincipalId $MSI.ObjectId -ResourceId $GraphServicePrincipal.ObjectId -Id $AppRole.Id -` +``` #### (Option 2) Not Recommended - Azure AD Application (COMING SOON). From 3baec58e364da031519b885409f8ae04d37c3fd3 Mon Sep 17 00:00:00 2001 From: Cam Murray Date: Thu, 30 May 2024 12:39:12 +1000 Subject: [PATCH 5/6] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7b6803f..24181dd 100644 --- a/README.md +++ b/README.md @@ -71,8 +71,8 @@ Install-Module AzureAD -Scope CurrentUser Connect-AzureAD # Find the Managed Service Identity and Graph Service Principal -$MSI = (Get-AzureADServicePrincipal -Filter "ObjectId eq '00000003-0000-0000-c000-000000000000'") -$GraphServicePrincipal = Get-AzureADServicePrincipal -Filter "appId eq '$GraphAppId'" +$MSI = (Get-AzureADServicePrincipal -Filter "ObjectId eq '$PrincipalID'") +$GraphServicePrincipal = Get-AzureADServicePrincipal -Filter "appId eq '00000003-0000-0000-c000-000000000000'" # Add AttackSimulation.Read.All permission $AppRole = $GraphServicePrincipal.AppRoles | Where-Object {$_.Value -eq "AttackSimulation.Read.All" -and $_.AllowedMemberTypes -contains "Application"} From 947e84bbbe7776932f8ebe58968d94bb7445cd02 Mon Sep 17 00:00:00 2001 From: Cam Murray Date: Thu, 30 May 2024 12:52:46 +1000 Subject: [PATCH 6/6] Update README.md --- README.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 24181dd..29c69b2 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,16 @@ The following API methods are pulled, flattened, and stored in to Azure Table St * graph.microsoft.com/beta/security/attackSimulation/training -> Trainings * graph.microsoft.com/beta/users -> Users (Only performed for users that have had a simulation ran against them) +## What happens when we sync? + +The function app by default runs every hour. If you want to change this, you will need to fork the code and use your fork for deployment. Be wary of hitting any Graph limitations. + +On the initial sync, we will pull down every simulation, simulation user, and event. This will take some time to complete. Be patient. + +On the iterative sync windows, we will only pull simulations that are in a running state, or completed within the past 7 days. + +User details are pulled as well in to the Users table to enable better reporting, but this can be disabled by setting the "SyncEntra" environment variable to false. + ## Installation Whilst the code here could be adjusted to suit any means, it is intended to run in an Azure Function App. @@ -34,12 +44,13 @@ Wait for deployment to complete, and then proceed to setting the deployment meth In the "Deployment Center" for the Azure Function App (Accessible under the Deployment Menu), populate the deployment options: * **Source** Manual Deployment - External Git * **Repository** Is this one here: https://github.com/cammurray/ASTSync -* **Branch** main +* **Branch** master * **Repository Type** Public Click Save when populated -image +image + #### Set up the Authentication to Graph API @@ -90,3 +101,9 @@ New-AzureAdServiceAppRoleAssignment -ObjectId $MSI.ObjectId -PrincipalId $MSI.Ob Once the deployment method has been set, you should be able to click the "Sync" button. This downloads the latest version and compiles it. Confirm the redeployment. ![image](https://github.com/cammurray/ASTSync/assets/26195772/70516189-0e0c-4b5c-88a1-97ce1665f72f) + +After clicking sync, monitor the deployment on the logs page, the "Status" should change when complete. The deployment will take several minutes. + +### Connecting to the Azure Table + +