Cloud Watcher is an Open Source script that scans your subscription and compares it to a baseline, this helps companies reduce the time to detect breaches to their cloud resources.
- Azure Account
- Azure Automation Service with runas service principal
- Storage Account
Azure has an ever growing number of resources and features, making it impossible for us to cover all of them, we currently monitor the following actions and resources:
- RBAC Changes to subscriptions
- Classic Administrator changes to subscriptions
- Azure Resource Provider changes to subscription
- Resource creation or deletion
- Change of Group membership (just first degree, we do not support nested groups)
- SQL Firewall changes
- SQL Server AAD Admin changes
- AKV Access Policies Changes
- AKV Firewall changes
-
Create Azure Automation Account with runas account
-
Give the service principal created reader access to the subscriptions you want to monitor.
-
Go to Azure Active Directory > Enterprise Applications and select the application created as the runas account. (you might have to change the filter to all applications and search for the name of your application)
-
Copy the object ID shown in the application page.
-
Get the Directory Readers Role ID running 'Get-AzureADDirectoryRole'
-
Run the following commands replacing with the app's object Id. and the role ID with the 'Directory readers' role ID.
$roleID = '<Role ID>'
$appObjID = '<APP ObjectID>'
Connect-AzureAD
Add-AzureADDirectoryRoleMember -ObjectId $roleID -RefObjectId $appObjID
Before setting this up, please read the "Recommended Use" section since we have some security recommendations as on where to set up this storage account.
-
Create a storage account.
-
Create a container to hold your baseline
-
In the Azure portal, go to the Azure Automation Account you created in the first section.
-
Go to Variables (under the Share Resources section)
-
Create a variable named "accountName" with the storage account name as the value.
-
Create a variable named "blobName" with a name for the baseline file (we use "baseline.json") as the value.
-
Create a variable named "containerName" with the storage account container name as the value.
-
Create a variable named "RunType" This value is used to tell the script if you are running in monitoring mode or Baselining mode. enter "monitoring" or "baseline" as the value depending on which mode you want to run.
-
Create a variable named "accountKey" with the storage account SAS key as the value Remember to set this value as encrypted!
In the Azure Automation Resource, go to modules, and add the following modules:
-
Az.KeyVault
-
Az.Resources
-
Az.Sql
-
Az.Storage
-
Az.Accounts
Now that we have set up the script to run.
-
In the Azure Automation account, go to runbooks.
-
In the search field type "CloudWatcher"
-
Click Import
-
Enter the name for your Runbook
-
Click on it and click the edit button.
-
Once the editor is open, click the test pane and run the test to make sure it is working properly. Note: The fist time you run it you should set the run type as baseline to have a baseline in the storage account.
-
If the run is successful, go back to the edit pane and click on publish: Your Runbook should now be published and it should allow you to add it to schedules.
For security reasons we recommend running the automation account, and hosting the storage account in a different subscription than the subscription being hosted. This prevents attackers that get access to your subscription to stop or modify the baseline.
At Keytos we wanted to ensure the security of our CloudWatcher deployment. To do this we use 3 different subscriptions, and they all point at each other with CloudWatchers.
To simplify it I am just going to show one of the CloudWatchers in the diagram.
The Idea is that you have the subscription that you want to monitor (Subscription A). Then in a different subscription (Subscription B) that ideally does not share any of the same administrator identities with the subscription you want to monitor, you create the CloudWatcher Automation Account. Then in another Subscription (Subscription C) (At Keytos we do it in another Tenant) you have a storage account with the baseline. The token given to the CloudWatcher in Subscription B only has read access to the baseline blob, meaning that a compromise of that account does not allow to make changes to the baseline.