10 tips to improve your administrative accounts posture in Azure AD


General Introduction

As I speak to more and more customers about the matter, I notice that a lot of companies have a questionable security posture regarding their administrative accounts. For example, many admins are using their “daily-runner” account as privileged administrators for their tenants, or synchronizing their domain admins to privileged roles in Azure AD. In general, a lot of admin accounts aren’t getting the care they deserve.

Losing privileged access is a big deal and it’s happening more and more often. Clearly, attackers love targeting privileged accounts because they give them quick and broad access to a company’s important assets, leaving a lot of defences behind.

I decided to write this article to highlight some of the controls that should be implemented in our tenants to improve our admin accounts posture, as privileged access management should be one of our top security priorities. These points have been aggregated after a lot of discussions with colleagues and experts on the topic and with the help of best practices from Microsoft Docs.


The 10 tips list

As a best practice, administrator accounts should be: 

  1. Separate from your daily-runner account. Collaboration tasks should not be done from the administrative accounts. While it’s of course not convenient, admins should get used to handling multiple accounts for different permission levels.
  2. Cloud-only. Your Azure AD administrator accounts should be different to your on-premises admins, and should not be synchronized from the on-premises Active Directory. This is because if one’s identity gets breached, the attackers would have easy access to both Azure AD and AD.
  3. Mailbox-less. The easy way to implement this is by not assigning admins licenses. You should enable a forward from your admin account to your daily driver account, or a dedicated mailbox/distribution list assigned to an unprivileged user. 
  4. Using phishing-resistant authentication methods. FIDO2 keys should be your primary way of accessing your admin accounts. If FIDO2 keys or similar methods are unavailable to you, you should have at least MFA active on your account with number matching and additional details active. Ideally, you should also restrict access to your resources to only allow access from known devices.
  5. Reviewed periodically. Periodically analyse the list of admins, and remove excessive permissions. There are a lot of cool tools that can help you out with this, or you can script your own.
    Microsoft suggests analysing these roles first, then moving to the other administrative accounts: Global Administrator, Privileged Role Administrator (they are a click away from being Global Admins), Exchange Administrator, and SharePoint Administrator. Remove guest admins where applicable.
  6. Protected by Identity Protection. Identity Protection automatically scans your sign-ins and blocks the user if anything strange is going on. You can also configure it to force the user to do a self-service password reset.
  7. PIM-enabled. You should have administrative privileges only when you require them. Having admin privileges active on an account 24/7 without a specific reason is not the best idea. Moreover, whenever you enable your PIM roles, you get an email, to keep everything under control.
  8. Backed up by one or two emergency accounts. If bad things happen, you should still be able to access your tenant. Emergency access administrators help you with that. You should also consider activating a rule to alert you when this admin gets used. Here is a cool guide to create passwordless emergency admins with FIDO2 Keys: https://janbakker.tech/break-glass-accounts-and-azure-ad-security-defaults/
  9. Logged constantly. Configure logging for your tenant by exporting the Azure AD logs to a Log Analytics workspace. Alerts should be configured for risky actions (like modifying a conditional access policy). Also, check if you have enabled the Unified Audit Logs: https://azvise.com/2021/10/26/office-365-enable-unified-audit-logs/
  10. Protected with Conditional Access Policies. This is a very broad topic, but make sure that at least the following apply. Those policies can be created quickly using Conditional Access policies templates: Require phishing-resistant multifactor authentication for admins, Securing security info registration, block legacy authentication, require multifactor authentication for Azure management, Require compliant or hybrid Azure AD joined device for admins, Block access for unknown or unsupported device platform, No persistent browser session. Of course, before activating this policies, be really careful to test things out and exclude the emergency account(s).

Additional points:

  • Use precise Administrative roles. Of course, using highly privileged accounts it’s convenient, as you have only to activate one role to manage everything. But if you assign people the correct permissions they need for their daily job, a lot of headaches can be prevented. Check out this documentation page to ease the pain of finding the right role to assign:
    https://learn.microsoft.com/en-us/azure/active-directory/roles/delegate-by-task
  • Consider Privileged Access Workstations. Having PAWs for Admin roles can help a lot with your security posture. PAWs can be configured on Azure AD with device filtering rules in Conditional Access Policies. For example the CAP may require: When all admins, except for the emergency access administrator, access all apps, block access unless they are using specified devices, filtered by device ID.
    These PAWs should be AAD joined, and are usually for Global Admins and Privileged Role Administrators. Also, having Bitlocker on at least this machines is a must.
    Spoofing device IDs with Powershell is sadly possible at the moment, but it’s kinda hard and not one of the first things that attackers will do. As always, a lot of this depends on your security risk acceptance level.
    If you want to drill down on PAWs, this article might be useful: https://learn.microsoft.com/en-us/security/privileged-access-workstations/privileged-access-devices
  • If you have an on-premises AD, you should really look into improving your AD security, as your AAD security and your AD security are tightly correlated. A tiering model for Active Directory is really useful to better manage your forests, and implementing Defender for Identity gives you a whole new level of analysis and reaction on what’s going on. This won’t be discussed here, but there are plenty of resources to get started with this. Also, again, don’t sync your on-prem administrators to Azure AD. You should have some level of filtering from on-prem to Azure AD, such as filtering by OU or by AD attributes.
  • Also not discussed here, as Azure permissions are a whole topic by themselves, but you should really be analyzing Azure privileged permissions and keeping everything under control.


Link to Microsoft docs, and additional reads:

Securing privileged access

Ensure separate user accounts and mail forwarding for Global Administrator accounts

Enterprise access model

Token Protection

Get all users of an Azure AD Group and add them to another one – Powershell

The following script will get all the members of an Azure AD group and add them to another group. You’ll just need to know the name of the two groups to make it work.

In the code shown below, the source group will be called Group1Name and the destination one Group2Name.

# Replace Group1Name with the name of your source group and Group2Name with the name of the destination one. Everything else will be done automatically

$Group1 = "Group1Name"
$Group2 = "Group2Name"


$group1ObjectID = Get-AzureADGroup -Filter "Displayname eq '$group1'" | Select objectid -ExpandProperty ObjectID
$group2ObjectID = Get-AzureADGroup -Filter "Displayname eq '$group2'" | Select objectid -ExpandProperty ObjectID

$membersGroup1 = Get-AzureADGroupMember -ObjectId $group1ObjectID -All $true

foreach($member in $membersGroup1)
{
    $currentuser = Get-AzureADUser -ObjectId $member.ObjectId | select objectid
    Add-AzureADGroupMember -ObjectId $group2ObjectID -RefObjectId $currentuser.objectid

}
Get-AzureADGroupMember -ObjectId $group2ObjectID -All $true

Enable Unified Audit Logs – Office 365

Unified Audit Log is one of the essential features for tracking down every action done across the tenant.

The logs are kept for 90 days by default, but you can extend them using special addons.

If you want to check whether the logging is enabled on your tenant, connect to Exchange Online with PowerShell. Once connected, you can check the status.

Install-Module ExchangeOnlineManagement
Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName yourupn@domain.com
Get-AdminAuditLogConfig | FL UnifiedAuditLogIngestionEnabled

If you get “True” as a result, the logging is enabled. If you get “False”, follow the steps below to enable it:

PowerShell way:

Using the PS tab, you opened before to check the Audit Log status, send the following command:

Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $true

You might be asked to run “Enable-OrganizationCustomization” before relaunching the command. You must wait 30 to 60 minutes after sending “Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $true” to see it enabled in the portal.

Portal way:

Go to https://compliance.microsoft.com/, then click on “Audit” on the left pane. When you get to the page, click on “Start recording user and admin activity“, then check the status after 30-60 minutes. If it fails, try with PowerShell.

Disconnect a user session in Azure Virtual Desktop (AVD) – PowerShell

Prerequisites: The Microsoft.RDInfra.RDPowerShell module, the Az PS module

First, install the RDInfra module:

Install-Module -Name Microsoft.RDInfra.RDPowerShell; Import-Module -Name Microsoft.RDInfra.RDPowerShell

Then proceed by installing the Az module and logging in:

Connect-AzAccount

Once you are logged in you can run the following script to disconnect a specific user session:

Get-RdsUserSession -TenantName "tenantname.onmicrosoft.com" -HostPoolName "HostPoolName" | where { $_.UserPrincipalName -eq "azvise\demouser" } | Invoke-RdsUserSessionLogoff -NoUserPrompt

Password Hash Synchronization won’t update any user password

If AD Sync won’t update any user password across a domain follow these steps:

  • Open Microsoft Azure Active Directory Connect
  • Click Configure
  • Click Troubleshoot
  • Click Launch
  • In PowerShell type 2 (Enter ‘2’ – Troubleshoot Password Hash Synchronization)
  • Type 1 (Enter ‘1’ – Password Hash Synchronization does NOT work at all)

Usually, the output on your local AD Connector is:

Last successful attempt to synchronize passwords from this directory partition started at: [long time ago]

If this is the case proceed as follows:

  • Open Synchronization Service Manager
  • Click on Connectors
  • Click on your local connector (ex. domain.com)
  • Right-click, then open properties
  • Under Connect to Active Directory Forest insert the password for the user and click ok
  • Run an initial Sync in PowerShell: Start-ADSyncSyncCycle -PolicyType Initial