www.secureworks.com Open in urlscan Pro
2620:1ec:bdf::45  Public Scan

Submitted URL: https://click.cloudseclist.com/CL0/https:%2F%2Fwww.secureworks.com%2Fresearch%2Ftampering-with-conditional-access-policies-usin...
Effective URL: https://www.secureworks.com/research/tampering-with-conditional-access-policies-using-azure-ad-graph-api
Submission: On May 28 via manual from IN — Scanned from DE

Form analysis 0 forms found in the DOM

Text Content

Skip to main content
NEW REPORT State of the Threat: A Year in Review
 * Experiencing a Breach?
 * Contact Us
 * Support
 * Login
 * Blog
 * English



 * Products
 * Services
 * Why Secureworks
 * Partners
 * Resources

Request Demo
Close
Close
0 Results Found
 * Products
 * Products, Services & Solutions
 * Insights
 * About
 * Contact
 * Other

Back To Results
 * 


 * Threat Intelligence Research
 * Tampering with Conditional Access Policies Using Azure AD Graph API

Threat Analysis



TAMPERING WITH CONDITIONAL ACCESS POLICIES USING AZURE AD GRAPH API

Tuesday, May 23, 2023 By: Secureworks Counter Threat Unit
 * 
 * 
 * 
 * 


SUMMARY

Azure Active Directory (Azure AD) is Microsoft's cloud-based identity and access
management service, and it supports multiple authentication methods. The premium
version of Azure AD also supports Conditional Access policies (CAPs) that grant
or block access based on defined criteria, such as device compliance or user
location. Azure AD stores the settings for the authentication methods and CAPs.
CAPs can be modified via the Azure AD portal, PowerShell, and API calls.

In May 2022, Secureworks® Counter Threat Unit™ (CTU) researchers investigated
which APIs allow editing of CAP settings and identified three: the legacy Azure
AD Graph (also known as AADGraph), Microsoft Graph, and an undocumented Azure
IAM API. AADGraph was the only API that allowed modification of all CAP
settings, including the metadata. This capability lets administrators tamper
with all CAP settings, including the creation and modification timestamps.
Modifications made using AADGraph are not properly logged, endangering integrity
and non-repudiation of Azure AD policies.

CTU™ researchers shared these findings with Microsoft on May 26, 2022. Microsoft
confirmed the findings a month later but stated that it is expected behavior. On
May 11, 2023, Microsoft notified CTU researchers of planned changes to improve
audit logs and restrict CAP updates via AADGraph.


AZURE AD CAPS

Azure AD CAPs allow organizations to grant or block access to services protected
by Azure AD. They can also be used for session monitoring and limiting a session
lifetime. CAPs are enforced during the Azure AD authentication process. Azure AD
uses the following common signals to make a policy decision:

 * User or group membership
 * IP location information
 * Device
 * Application


Only users with specific roles can access CAPs in the Azure AD portal (see Table
1).

Access type Azure AD role Read Global Administrator
Global Reader
Security Administrator
Conditional Access Administrator
Security Reader Modify Global Administrator
Security Administrator
Conditional Access Administrator

Table 1. Azure AD roles required to access CAPs.

Figure 1 shows an example CAP that requires all users to perform multi-factor
authentication (MFA). The policy is not enabled in this example; it is set to
Report-only mode. This mode allows organizations to assess the impact of the CAP
before enforcing it.


Figure 1. Sample CAP. (Source: Secureworks)

The Azure AD portal displays the name, state, and creation and modification
timestamps (see Figure 2).


Figure 2. List of CAPs. (Source: Secureworks)

The Azure AD portal reflects changes whenever the CAP is modified (see Figure
3).


Figure 3. Modified CAP. (Source: Secureworks)

Azure AD audit logs captures CAP creation and modification events (see Figure
4).


Figure 4. Azure AD audit logs listing CAP creation events (highlighted in red
(bottom)) and CAP modification events (highlighted in green (top)). (Source:
Secureworks)

Both the 'Add conditional access policy' and 'Update conditional access policy'
events include details of the modified properties (see Figure 5). This feature
provides a full audit trail and includes modified settings.


Figure 5. Audit log details for the 'Update conditional access policy' event.
(Source: Secureworks)


MODIFYING CONDITIONAL ACCESS WITH API CALLS

The Azure AD portal is a graphical user interface (GUI) that allows
administrators to create and maintain CAPs via a browser. GUIs can perform
ad-hoc tasks but not automation and programmatic access. To address those needs,
Microsoft provides three APIs that can interact with CAPs:

 * Azure AD IAM
 * MS Graph
 * Azure AD Graph (AADGraph)



AZURE AD IAM API

The Azure AD portal uses an undocumented Azure AD IAM API to create, view, and
edit CAPs. The API is available at https ://main . iam . ad . ext . azure .
com/api/Policies/Policies. Because the Azure AD portal uses Azure AD IAM APIs,
access requires the permissions listed in Table 1. The API returns a list of
CAPs as a JSON object (see Figure 6).


Figure 6. Azure AD IAM API response. (Source: Secureworks)

When the API opens a CAP for editing, it returns the CAP details as a JSON
object (see Figure 7). This returned JSON object has many fields, which
correspond to the CAP settings available in the Azure AD portal. The response
also includes creation and modification timestamps.


Figure 7. Response returned by the Azure AD IAM API call. (Source: Secureworks)

Modifying a CAP sends a JSON object to https: //main . iam . ad . ext . azure .
com/api/Policies/ConvertPolicyMsGraph as an HTTP POST request. Figure 8 shows a
JSON object where the CAP state was changed from Off to Report-only. Only the
modified data and not the metadata is sent to Azure AD.


Figure 8. Azure AD IAM API CAP modification request. (Source: Secureworks)


MS GRAPH API

MS Graph API support for conditional access is well-documented, Microsoft also
published examples for creating and editing CAPs. Table 2 lists the required
permissions to access CAPs via MS Graph API.

Access type Permissions Modify (all three required) Policy.Read.All
Policy.ReadWrite.ConditionalAccess Application.Read.All Read Policy.Read.All

Table 2. MS Graph API permissions required for CAPs.

Users or applications with these permissions can list CAPs by calling the API at
https: //graph . Microsoft . com/v1.0/identity/conditionalAccess/policies. The
API returns all CAPs and details as a JSON object (see Figure 9).


Figure 9. MS Graph API response. (Source: Secureworks)

Creating or modifying a CAP uses the same API endpoint:

 * Creating a CAP makes an HTTP POST with a JSON object (see Figure 10).
   
   
   Figure 10. Creating Conditional Access policies via MS Graph API. (Source:
   Secureworks)

 * Modifying a CAP makes an HTTP PATCH request with a JSON object.


Only the modified data is sent to Azure AD. The metadata is not included.


AZURE AD GRAPH API (AADGRAPH)

Microsoft has attempted to deprecate the AADGraph API for years. As of this
publication, its retirement is scheduled to occur sometime after June 30, 2023.
Microsoft has removed public AADGraph API documentation to discourage its use.

CAPs can be accessed using the AADGraph API at https: //graph . windows .
net/<tenant>/policies?api-version=<api version>, where <tenant> is the Azure AD
tenant and <api version> is the desired AADGraph API version. Using 1.6 as the
API version returns some Azure AD policies that the user can access if they have
appropriate permissions, but CAPs are not listed. However, using 1.61-internal
as the version returns all Azure AD policies, including CAPs, regardless of the
user's permissions. As a result, any user of the tenant can list CAPs and bypass
the role requirements.

The API returns all policies as JSON objects. Figure 11 shows a CAP policy
(indicated by the policyType of 18).


Figure 11. AADGraph API response. (Source: Secureworks)

The CAP settings and metadata are stored in the policyDetail attribute as a JSON
object (see Figure 12). Administrators with permissions to modify CAPs can edit
this attribute, enabling them to tamper with the CAP conditions and metadata.


Figure 12. CAP settings in policyDetail attribute. (Source: Secureworks)

Updating an existing CAP with the AADGraph API involves an HTTP PATCH request to
https: //graph . windows .
net/<tenant>/policies/<objectid>?api-version=1.61-internal, where <objectid> is
the object ID of the CAP to be modified. The content of the request is a JSON
object that only includes the policyDetail attribute (see Figure 13).


Figure 13. Updating CAP using the AADGraph API. (Source: Secureworks)


TAMPERING WITH CONDITIONAL ACCESS POLICIES

CTU researchers used the AADInternals toolkit to tamper with CAPs.
Administrators or threat actors can leverage the AADGraph API to make changes
that are not properly logged.

 1. We retrieved the current policyDetail value of the example CAP:
    1. Acquired an access token for an administrator with permissions to modify
       CAPs
    2. Saved the example CAP to a variable
    3. Extracted the policyDetail value and copy the data to the clipboard (see
       Figure 14)
       
       
       Figure 14. Getting current CAP policyDetail using AADInternals. (Source:
       Secureworks)

 2. We pasted the policyDetail value into a text editor and reformatted the JSON
    for readability (see Figure 15). We then emptied the ModifiedDateTime
    attribute (see line 4) and changed the State attribute from Reporting to
    Disabled. The modified JSON was flattened and copied to the clipboard.
    
    
    Figure 15. Modified CAP policyDetail. (Source: Secureworks)

 3. We used the modified policyDetail from the clipboard to update the CAP (see
    Figure 16).
    
    
    Figure 16. Updating the CAP policyDetail attribute via AADInternals.
    (Source: Secureworks)
    
    The Azure AD portal updated the modifications within a minute (see Figure
    17).
    
    
    Figure 17. Modified CAP in Azure AD portal. (Source: Secureworks)

When CAPs are updated via the AADGraph API, the 'Update conditional access
policy' event is not generated in the audit logs (see Figure 18). As a result,
there is an incomplete audit trail on what modifications were made.


Figure 18. CAP modification via AADGraph does not create the Update conditional
access event. (Source: Secureworks)

Threat actors with administrator permissions can leverage this omission to
obscure CAPs. For instance, the PowerShell script in Figure 19 removes the
timestamps and display names of all CAPs.


Figure 19. PowerShell scipt to remove CAP display name and timestamps. (Source:
Secureworks)

After running the script, CAPs are fully functional. However, the Azure AD
portal cannot open or edit them (see Figure 20).


Figure 20. Azure AD portal after removing CAP display names and timestamps.
(Source: Secureworks)

Administrators can still delete CAPs and make duplicates to view existing CAP
settings. If organizations keep audit logs for a longer period of time, they may
be able to restore CAP names and timestamps based on historical audit log data.


COMMUNICATION WITH MICROSOFT

CTU researchers reported the metadata editing and logging issues to the
Microsoft Security Response Center (MSRC) on May 20, 2022. These issues were
reported as tampering and elevation of privilege, as administrators are also
able to modify the metadata. The MSRC responded on June 26:

We confirm the following behaviors when a Conditional Access Policy is modified
via Azure AD Graph APIs (or PowerShell modules based on AAD Graph APIs):

Only Core Directory service Audit Log item is present in the Audit Logs, while
the corresponding Conditional Access service Audit Log item is missing.

Details of the changed properties and values are not present in the Core
Directory service Audit Log item.

Modified Date information of the edited policy object is not updated on the
Conditional Access Azure Portal page.

We analyzed the scenario, and established that:

There is no escalation of privileges: only users with the required permissions
are allowed to access or modify policy objects.

Investigations of malicious Conditional Access Policies are not affected due to
relevant information present in the sign-in logs.

Date, Activity, Target, and Actor information of policy changes are present in
the Activity Logs, allowing admins to audit who changed a policy and when.

On August 23, 2022, CTU researchers notified the MSRC that all users can read
conditional access. This issue was reported as elevation of privilege, as any
user can read CAPs without administrator permissions. The MSRC responded on
February 2, 2023:

There are several known experiences where an authenticated and authorized user
is able to read specific data pertaining to an Azure AD configuration such as an
authentication policy or other similar configurations.

These cases are by design: the user is authorized, the data is read-only and
doesn't contain any specific user information.

While reading data such as an authentication policy is not perceived as a
security breach, we do have optimizations in Azure AD to allow other data or
configurations to only be read or changed based on admin roles with specific
edit / create/ delete rights for security purposes.

On May 11, 2023, the MSRC informed the CTU research team of planned changes to
address these issues:

 1. Improve audit logs to reflect the type of policy being updated when CA
    policies are updated through AAD Graph.
 2. We will prevent admins from using AAD Graph to make updates to CA policies.


In addition to these improvements, AAD Graph is set to be retired.


CONCLUSION

Administrators can use the AADGraph API to change CAPs. The API does not
properly log changes, and the lack of an audit trail breaks integrity and
non-repudiation of CAPs. As a result, organizations cannot trust CAP information
shown in the Azure AD portal or in directory audit logs. In addition, any tenant
user can view CAPs without administrator permissions. This ability allows
low-privileged threat actors to identify gaps in CAPs or target them for future
modification. Third-party tools such as ROADTools and TSxAzureADExport exploit
this ability.

CTU researchers recommend that organizations store Azure AD audit logs in the
Log Analytics workspace or in other storage solutions such as Secureworks
Taegis™ XDR. Organizations can detect CAP modifications via the AADGraph API by
monitoring audit logs for an 'Update policy' event that does not have a
corresponding 'Update conditional access policy' event within two seconds.


APPENDIX

The following script can restore the names and modification dates of CAPs that
have been created or modified using the Azure AD portal or the MS Graph API:

# Read legit CAP events from the audit log
$CAPEvents=Get-AADIntAzureAuditLog -Export                    `
            | Where-Object activityDisplayName -in            `
                "Add conditional access policy",              `
                "Update conditional access policy"            `
            | Select-Object "activityDateTime" -ExpandProperty "targetResources" `
            | Select-Object "id","displayName","activityDateTime"
 
# Loop through the events to get the first (latest) update
$CAPInfos=@{}
foreach($CAPEvent in $CAPEvents)
{
    if(!$CAPInfos.ContainsKey($CAPEvent.id))
    {
        $CAPInfos[$CAPEvent.id] = [pscustomobject]@{
                "displayName"      = $CAPEvent.displayName
                "modifiedDateTime" = $CAPEvent.activityDateTime
            }
    }
}
 
# Read current CAPs
$CAPs = Get-AADIntConditionalAccessPolicies
 
# Loop through CAPs
foreach($CAP in $CAPs)
{
    # Create the return value
    $retVal = [pscustomobject][ordered]@{
        "id"      = $CAP.objectId
        "isEmpty" = [string]::IsNullOrWhiteSpace($CAP.displayName)
        "success" = $null
        "name"    = $CAP.displayName
    }
 
    # Check whether the displayName is empty
    if($retVal.isEmpty)
    {
        # Check whether we found the old information
        if($CAPInfo = $CAPInfos[$retVal.id])
        {
            # Get policyDetails and fix Modified Date
            $policyDetail = $CAP.policyDetail[0] | ConvertFrom-Json 
            try
            {
                $policyDetail.ModifiedDateTime = $CAPInfo.modifiedDateTime
            }
            catch{}
 
            $newPolicyDetail = $policyDetail | ConvertTo-Json -Depth 10 -Compress
 
            # Replace name with the old displayName
            $retVal.name = $CAPInfo.displayName
            try
            {
                Set-AADIntAzureADPolicyDetails  -ObjectId     $retVal.id       `
                                                -PolicyDetail $newPolicyDetail `
                                                -DisplayName  $retVal.name     `
                                                | Out-Null
 
                $retVal.success = $true
            }
            catch
            {
                # Failed
                $retVal.success = $false
                $retVal.name = $CAP.displayName
            }
        }
    }
    # Return
    $retVal
} 



The following KQL query can be used to identify 'Update policy' events that do
not have a corresponding 'Update conditional access policy' event within two
seconds:

AuditLogs 
| where OperationName == "Update policy"
| mv-expand TargetResources
| where TargetResources.displayName != "Default Policy"
| mv-expand InitiatedBy
| project PolicyName = TargetResources.displayName, PolicyId = tostring(TargetResources.id), UserPrincipalName = InitiatedBy.user.userPrincipalName, UserId = tostring(InitiatedBy.user.id), OperationName, Time = bin(TimeGenerated, 2s), TimeGenerated, CorrelationId
|join kind=leftanti (AuditLogs
        | where OperationName == "Update conditional access policy"
        | mv-expand TargetResources
        | mv-expand InitiatedBy
        | project PolicyId = tostring(TargetResources.id), UserId = tostring(InitiatedBy.user.id), Time = bin(TimeGenerated, 2s)) on PolicyId,UserId,Time
| order by TimeGenerated




STAY INFORMED

Get the latest in cybersecurity news, trends, and research 
SEND ME UPDATES


NOW TRENDING...


 * 2022 State of the Threat Report
 * XDR vs. SIEM: A Cybersecurity Leader’s Guide
 * Modernize Your Security Operation Center with XDR
 * MDR Done Right
 * EDR, XDR, MDR: Filtering Out the Alphabet Soup of Cybersecurity

Secureworks Taegis™ 

Security Analytics +
Human Intelligence
Delivers Better
Security Outcomes







About Taegis


LATEST REPORT


Reports
2022 State of the Threat Report
Enjoyed what you read? Share it!
 * 
 * 
 * 
 * 





RELATED CONTENT

Reports


THREAT INTELLIGENCE EXECUTIVE REPORT 2023 VOL. 2

Blog


CHINESE CYBERESPIONAGE GROUP BRONZE SILHOUETTE TARGETS U.S. GOVERNMENT AND
DEFENSE ORGANIZATIONS

Secureworks Counter Threat Unit
Threat Analysis


THE GROWING THREAT FROM INFOSTEALERS

Secureworks Counter Threat Unit
Reports


THREAT INTELLIGENCE EXECUTIVE REPORT 2023 VOL. 2

Blog


CHINESE CYBERESPIONAGE GROUP BRONZE SILHOUETTE TARGETS U.S. GOVERNMENT AND
DEFENSE ORGANIZATIONS

Secureworks Counter Threat Unit


GET THE LATEST UPDATES AND NEWS FROM SECUREWORKS.

Subscribe Now



PRODUCTS

 * DETECTION & RESPONSE
   
   * XDR
   * MDR
   * Threat Hunting
   * Log Management
   * MITRE ATT&CK Coverage

 * ENDPOINT SECURITY
   
   * EDR
   * NGAV

 * NETWORK SECURITY
   
   * IDPS

 * VULNERABILITY MANAGEMENT
   
   * Vulnerability Risk Prioritization


SERVICES

 * ASSESS & PLAN
   
   * Threat Hunting Assessment
   * Vulnerability Assessment
   * Ransomware Readiness Assessment

 * BATTLE TEST & EXERCISE
   
   * Application Security Testing
   * Adversary Exercises
   * Penetration Testing

 * INCIDENT RESPONSE
   
   * About Emergency Incident Response
   * Emergency Breach Hotline


WHY SECUREWORKS

 * Why Secureworks
 * Corporate Overview
 * Corporate Responsibility
 * Careers
 * Investor Relations


RESOURCES

 * Blog
 * Resource Library
 * Case Studies
 * Data Sheets
 * Industry Reports
 * In the News
 * Knowledge Center Library
 * Live Events
 * Threat Resource Library
 * Threat Profiles
 * White Papers
 * Webinars
 * Podcasts
 * Videos
 * Cybersecurity Glossary


GET IN TOUCH

 * Experiencing a Breach?
 * Contact
 * Support
 * Login

©2023 Secureworks, Inc.

 * Privacy Policy
 * Supply Chain Transparency
 * Terms & Conditions
 * Accessibility Statement
 * Unsubscribe
 * Cookie Settings








By clicking “Accept All Cookies”, you agree to the storing of cookies on your
device to enhance site navigation, analyze site usage, and assist in our
marketing efforts.

Accept All Cookies
Reject All
Cookies Settings


PRIVACY PREFERENCE CENTER

When you visit any website, it may store or retrieve information on your
browser, mostly in the form of cookies. This information might be about you,
your preferences or your device and is mostly used to make the site work as you
expect it to. The information does not usually directly identify you, but it can
give you a more personalized web experience. Because we respect your right to
privacy, you can choose not to allow some types of cookies. Click on the
different category headings to find out more and change our default settings.
However, blocking some types of cookies may impact your experience of the site
and the services we are able to offer.
Allow All


MANAGE CONSENT PREFERENCES

PERFORMANCE COOKIES

Performance Cookies

These cookies allow us to count visits and traffic sources so we can measure and
improve the performance of our site. They help us to know which pages are the
most and least popular and see how visitors move around the site.    All
information these cookies collect is aggregated and therefore anonymous. If you
do not allow these cookies we will not know when you have visited our site, and
will not be able to monitor its performance.

TARGETING COOKIES

Targeting Cookies

These cookies may be set through our site by our advertising partners. They may
be used by those companies to build a profile of your interests and show you
relevant adverts on other sites.    They do not store directly personal
information, but are based on uniquely identifying your browser and internet
device. If you do not allow these cookies, you will experience less targeted
advertising.

FUNCTIONAL COOKIES

Functional Cookies

These cookies enable the website to provide enhanced functionality and
personalisation. They may be set by us or by third party providers whose
services we have added to our pages.    If you do not allow these cookies then
some or all of these services may not function properly.

STRICTLY NECESSARY COOKIES

Always Active

These cookies are necessary for the website to function and cannot be switched
off in our systems. They are usually only set in response to actions made by you
which amount to a request for services, such as setting your privacy
preferences, logging in or filling in forms.    You can set your browser to
block or alert you about these cookies, but some parts of the site will not then
work. These cookies do not store any personally identifiable information.

Back Button


COOKIE LIST



Search Icon
Filter Icon

Clear
checkbox label label
Apply Cancel
Consent Leg.Interest
checkbox label label
checkbox label label
checkbox label label

Reject All Confirm My Choices