As a Security Analyst, one challenge of auditing mailbox permissions is identifying whether the given access should be granted. It is very simple to pick out the major outliers, like “Everyone” or “NT Authority/Authenticated Users“, but determining if an individual user account should have access can be nearly impossible in very large enterprise environments.
Most users can understand the difference between mailbox permissions, mailbox folder permissions, mailbox message processing rules, and delegated mailbox access after describing the function of each. However asking thousands to review these different permission sets can be exceptionally difficult.
Most of these permission pulls can be obtained with a handful of clicks. The two exceptions are:
- Auditing Exchange Mailbox Folder Permissions
- Depending how many folders the user has, it can be time consuming to perform this review
- Auditing Exchange Mailbox Permissions
- The most concise way to obtain this information is to query the mailbox directly using the ExchangeOnline module in powershell
To help resolve this issue, I created a pseudo-web app powered by Microsoft Power Automate and Azure Automation Runbooks. This app simplifies the process so users can 1-click and have their live mailbox permissions (or whatever other Azure back end data) sent to them in an email.
This blog will show you how I resolved this problem by:
- Creating a new AAD Service Account (user account)
- Creating a new management role based on the “View-Only Recipients” role, but has permission to only user “Get-Mailbox” and “Get-MailboxPermission” cmdlets
- Creating Automation Credentials and using them in a Runbook
- Updating and loading new modules into Azure Automation
- Creating a PowerShell Runbook with a variable to query ExchangeOnline for mailbox and mailboxfolder permissions
- Creating a Flow that queries the ExchangeOnline modules for the permissions associated with the account running the flow (this is where the variable from the step comes into play), then subsequently emails those permissions to the requestor
- Publishing this web app for all users
Create a new AAD Service Account (user account)
Follow these steps to create a new Service Account that will be performing these actions against the ExchangeOnline environment:
- Visit https://aad.portal.azure.com and select “Add a user”.
2. Name your Account, then select Create. For this demonstration I will create “Mailbox_Automation”.
At this point be sure the new account has valid credentials. Those steps will be shown.
Create a new management role
The simplest way to get this Runbook operational would be to add its credentials to Exchange Admins ,but those permissions are way too permissive for this purpose. Rather, we are going to create a new management role and role group that only have permissions to run the Get-Mailbox, Get-MailboxPermission, Get-MailboxFolderPermission, and Get-MailboxFolderStatistics cmdlets.
Run the following PowerShell commands using an account with permissions, then create management roles and assign the account to the management role groups.
Connect-ExchangeOnline
New-ManagementRole -Name "View Mailbox Permissions" -Parent "View-Only Recipients" -EnabledCmdlets "Get-MailboxPermission","Get-Mailbox","Get-MailboxFolderPermission","Get-MailboxFolderStatistics"
Run the following commands to assign the account you created to the RoleGroup above.
New-RoleGroup -Name "Audit Permissions" -Roles "View Mailbox Permissions"
Get-RoleGroup -Identity "Audit Permissions" | Add-RoleGroupMember -Member “Mailbox_Automation”
Confirm that this worked by visiting https://outlook.office365.com/ecp, and selecting admin roles under permissions.
Then select Audit Permissions.
Automation
Now we will create the Automation Account, Credentials, and Runbook that will perform the queries against ExchangeOnline.
Visit https://portal.azure.com and search for automation accounts.
Select Create
I will name my Automation Account ExchangeOnline-PowerShell for this demonstration. The most important option on this screen is selecting Yes to Create Azure Run As account. This is what allows you to connect to your runbook to Azure. It is important to note that this account will have contributor permissions to the entire subscription the account was created in. More information regarding restricting this accounts permissions can be found at https://docs.microsoft.com/en-us/azure/automation/manage-runas-account.
Once the new Automation Account is created, add a credential by selecting Credentials, then Add a credential.
This is where the credentials for the account created in the first step are added. The credentials in this blade will be made available to all Runbooks in this Automation Account. Note that you have already limited what cmdlts this account can use.
Record the name of this credential as it will be referenced in the Runbook Powershell script.
Now we will install the modules needed to perform the ExchangeOnline queries. From the Automation Account, select Modules gallery, then search for and select ExchangeOnlineManagement.
Select the Import option, then OK. It will take a few minutes to import the module. The import status can be checked by selecting the “Modules” blade.
Create Runbook
Under your Automation Account, select Runbooks, then Create a runbook.
Now give your runbook a name, description, and type (for my example, I have a PowerShell script).
Here is a simple PowerShell script that will use the credential we created earlier by calling the Get-AutomationPSCredential cmdlet.
Be sure to change the Automation credential to the name of the credential you created earlier (in my case the credentials are named Mailbox_Automation@echopoint.net).
To test your script, select Test pane.
Then give it a test run with an account in your environment. I tested the account KingGeorge and am getting no errors.
If you are not getting any errors, publish your Runbook by selecting Publish then Yes.
GO WITH THE FLOW*
*This step may require you to have a flow license (or trial).
Visit https://us.flow.microsoft.com/en-us/ from an account that has privileges to create flows in your environment.
Select My flows, New flow, then Instant cloud flow.
Select Manually trigger a flow, then Create.
Select Yes/No, and provide a description of “Do you want to run a mailbox permissions query”.
Select New Step, then search for the term Create job.
Select the appropriate Subscription, Resource Group, Automation Account, and Runbook for the job. Be sure to select Yes to Wait for Job, then give a Runbook Parameter name of User name. Note: The User name Parameter takes the username of the identity performing the execution of the flow, and passes it as the $Name parameter into the Runbook script.
Select New Step then search for get job output. Next, select Premium and then Get job output from the available options.
Select the appropriate Subscription, Resource Group, and Automation Account, and then select Job ID for Job ID.
Next, initialize a variable for the User email in the Dynamic content. This makes the requestor’s email address available for the next step. In this example, I am using the variable name of Email_Address. Note that I tried to send email directly to the User email variable, but it is output in Base64.
Now, add a final step to email the output of the data to the requesting user by selecting New Step, Mail, and Send an email notification (V3).
- Select To and choose the Email_Address variable you created
- Create a subject and message body of your choice
- Select the advanced options selector at the bottom
- select attachment and choose Content
- provide an appropriate filename ending in .txt.
- select attachment and choose Content
Now we should rename the flow to something friendly and share the flow to other users.
I will change the name by selecting My flows, hitting the three dots next to the flow name, then selecting Details.
Select Edit on the Details box, and then provide an appropriate Flow name and Description. Next, select Save.
Now your flow is much easier to locate!
I will change the permissions by selecting Edit under Run only users.
Select All User, and then Save.
Publish the flow to App Launcher
The final step is publishing the flow to the App Launcher.
Microsoft does a good job describing the steps to publish a custom tile here. Note that the URL of the website is the URL of the flow.
You can find the app by selecting the App Launcher, then All apps.
Now lets test this!!!
I have logged into the email account for President George Washington via the Outlook WebApp.
Select the App Launcher, then All apps.
My new app is published here, and I select it.
Select Run.
Select Yes, then Run flow.
Within a few minutes, you should receive an email with all of the account permissions. You can modify the script to pull additional attributes. If you do this, be sure to make the necessary modifications to the Management Role to allow use of the cmdlets.
In this example, General Washington has an email permissions problem, where King George not only has explicit (Reviewer) access to the folder “Plans for the Revolution”, but also has access to the full mailbox.
In Conclusion
While I am sure there are many other ways to format this report (e.g., populate a dashboard), and initiate the Flow (e.g., Webhooks, complete an online form, etc.), this is a great starting point to help others understand the capabilities of certain features in Azure, and provide a unique tool to help correlate multiple data points to one location.
I would also like to give a special thanks to Mark Hawver for helping me navigate the permissions gremlins I came cross when standing up the Runbook and Management Role.