HelSec Azure AD write-up: Phishing on Steroids with Azure AD Consent Extractor

Here is short summary of the Presentation slides and demo of the Azure AD Consent Extractor @HelSec

  1. Attackers sends OWA upgrade link
  2. Victim clicks the link and accepts the upgrade
  3. Victim is redirected back to OWA when hitting the attacking server
  4. Victim receives ”OWA upgrade complete” message to email
  5. Meanwhile the attacking server is enjoying its new privileges on the user account

See the attack in action

If you want to know more about the consent attack, you can read my previous blog post from 2018

This version is the updated version to the one I did in 2018


Azure AD – Add Custom claims for WS-Federation applications

Disclaimer: The information in this weblog is provided “AS IS” with no warranties and confers no rights.

Most guides using Azure AD as IDP focus at OAuth and OAuth2/w OIDC flows for API access, and for enterprise SSO SAML. Not much endorsement for WS-Federation, and that’s understandable because the two previous options cover pretty much every scenario you would ideally have. But what if you have a app that is using explicitly WS-Federation? For example Microsoft OWIN based application?

There aren’t good support articles on using WS-Federation and custom claims in Azure AD when Azure AD is IDP, but WS-Federation is definitely supported when Azure AD is acting as IDP .

The only article I found covering custom claims and mentioning WS-Federation was the one I’ve used to write my previous article on preview of custom claims (how to get sAMAccountName into JWT tokens)

Since Azure AD App’s are largely protocol agnostic I figured that maybe the claims mappings are somewhat ambiguous also, just as long you understand how custom claims, and federations work

Guide to testing

The order here is important. While SAML endpoint is enabled by default in any Azure AD App, any specific settings, especially one’s for configuring Service Provider aren’t directly available in the ”non-SAML” app you create – Unless you play around with the App Registration Manifest. But there are other features that require spawning app initially as SAML app (For example using custom token sign-in cert, using token encryption and so on)

  • Configure new SAML federation at Azure AD
  • Add the custom claims for the federation
  • Set Single-Sign On mode to disabled
    • If you’re planning to use this in production, you have get the Metadata from SAML federation settings, I will do some further investigation later to update this blog
  • For metadata replace the metadata URL with tenant and AppID details

Test the federation.

I have handy NodeJS Express App I use pretty much for testing and debugging any authorization related stuff, with very simple purpose of catching different inbound calls.

About the code… The code itself is epitome of laziness, so I am too embarrassed to share it :)…

  • Invoke the call
    • Use AppID or any Identifier you’ve defined in the manifest
    • If you have multiple reply URL’s define the ’wreply’ param
  • Confirm the emitted claims
    • In this particular case its user.displayname +(join) user.dnsdomain
Typical WS-Federation body

There are many questions and details that I could add here, but since I am just fooling around with a feature, I am not devoting any more time until there is actual production need for such scenario.

Deploy: Native Exchange ActiveSync with Conditional Access and Intune while blocking legacy auth?

I’ve seen many companies struggle with EAS (Exchange ActiveSync) configuration, in relation how to adapt strong authentication and trusted devices approach for native mail clients. Thus I’d like to present three possible scenarios for EAS handling with Conditional Access/Intune mostly

Update: Microsoft will be initially deprecating basic auth for EAS, which some of the options presented below do rely. Efforts for Supporting non-modern auth activesync methods will be in vain once the deprecation is in effect

The options

  1. Allow EAS go unchecked (not recommended)
  2. Allow compliant (enrolled) native clients
  3. Use only Outlook App / Don’t allow native clients (Using Approved Client App option in Conditional Access)
  4. Mix of 2 and 3 with different policies
  • Option 1. Not recommended (even without Intune)
  • Option 2. Recommend to most who are unsure whether they can transition from Native mail clients to using Outlook app (Option 3), which gives the best control, if you’re considering having Outlook as managed application
  • Its also worth mentioning, that IOS native mail client has supported modern authentication for a good while. Meaning, that If it’s you’re only client for Native Mail, you don’t need necessarily a separate policies for EAS
  • For org’s without Conditional Access and Intune, there is less flexible, but similar option available to scenario 2 – Which I’ve addressed in another blog post (So no reason really for option 1

Before configuration guide, lets address these two strange sentences

  • ”Apply only to supported platforms”
  • ”Exchange ActiveSync currently does not support all the other conditions”

”Apply only to supported platforms”


The heading ”Apply only to supported platforms” is super confusing. From a security point of view I’d think that unsupported platforms would go past Conditional Access? (as they aren’t other clients, which we handle in another block policy)

It boils down to this:

”if you have chosen to block clients that aren’t supported by Intune, use the Apply policy only to supported platforms option”

See, when the device isn’t supported by Intune (thus unable to ever get the Compliant status for ActiveSync access) it won’t get past Conditional Access.

Unsupported clients (Linux and such) checked against what-if tool, indicate that they wouldn’t be then blocked. But all the guides, including the MS one rely on using the following policy option ’  Apply policy only to supported platforms’


Exchange ActiveSync currently does not support all the other conditions


The supported conditions for Native Mail Apps Are

  • In Users / Groups selection of specific users/groups, or all users (include and exclude both seem to apply)
  • In Cloud Apps only Exchange Online is selected
  • In Conditions: Apply only to supported platforms
  • In Conditions – Client Apps only ActiveSync is selected (and in scope of this blog, and other recommendations it’s recommended to narrow it down to ’Apply policy only to supported platforms’
  • In Access Controls only ’ Require device to be marked as compliant’ is the only supported condition

You may have varying mileage with other conditions, but I’d recommend sticking with recommendations in MS articles

Policy examples

  • Exclude Exchange Online from other policies before configuring specific policies for it:
  • In my example I haven’t specified mobile platform specific policies for ActiveSync, since the configuration options in ActiveSync are very limited. I don’t see thus much (or any value) of separating for example IOS and Android into their respective policies, unless you wan’t to define Block Policy for mobile platform (in this case bare in mind, that the platform selection is based often on User-Agents, meaning that if you really need to block mobile platform, ensure that the allowed mobile platforms are narrowed down also in protocol, apps and in Intune policies
  • There is many ways to deal with service accounts with the following policies. I will be providing another post on how to deal with service accounts in Conditional Access, to keep this post tidy 🙂
    • Any way as a single mention is that, when you want to bypass certain account or action remember to narrow the bypass conditions so that for example the IP based bypass for a single service account is possible only for one application (meaning that Service account even in ”trusted location” won’t have any more access than the single app – unless specified otherwise.

EXO (Modern auth and browser clients)

EXO – Activesync (Compliant only)

General – Block ’Other Clients’

Note! you could possibly also use one of the built in baseline rules, as it doesn’t block EAS. I am opting for non-baseline policy because I may want to exclude some directory roles (service accounts) to another policy. The Policy also lists that it blocks the Native Android Mail Client, which I supported is still to some extent supported platform, and I want to maintain it in separate policy

Expected behaviour

  1. Newly added devices will be quarantined in EXO
  2. Client will receive mail prompting to enroll the company portal app
  3. After enrollment phone will stay in the quarantine, while the compliance information is propagating
  4. On success
    1. CA device info will display ”join type = Azure AD Registered”
    2. CA Policy for ’require compliant device’ result = Success
    3. Exchange display DeviceAccessState = Allowed, DeviceAccessStateReason = ExternallyManaged

Below is short the process shortly

There is also a baseline policy, which is recommended unless you need more exclude conditions (such as native Android Mail Clients)

Intune Configuration

Users devices show as compliant in both Azure AD, and Intune
’Compliant status’ in Azure AD
Ensure that all used platforms have a compliance policy
Ensure devices with no compliance policy assigned are handled as ’Not Compliant’

Keywords for troubleshooting

EXO powershell Module

”DeviceAccessState : Quarantined”
”DeviceAccessStateReason : ExternalEnrollment”

During the enrollment the devices will stay in quarantine, until the enrollment is complete (device gets registered ID in AAD, and Azure AD displays Success for Conditional Access 

Once successful the states and reasons should be as following

”DeviceAccesState : Allowed”
”DeviceAccessStateReason : ExternallyManaged”

Company Portal App Android

”Company Access Setup is Incomplete”

Email account Activation”

with Android devices even after successful enrollment and Conditional Access working as supposed (and with DeviceAccessState in EXO) – I suppose this is some bug for the enrollment not being able to display the status correctly (tested on Android 7xx and 8xx)


LINK to MS article regarding blocking legacy auth


Azure AD Directories and B2B user decision matrix – One-slider

Click for larger version

Ever pondered on how to decide about B2B Account Types? One thing is for sure, If you’re enterprise org, you’re better of having multiple partner account types, because it’s not one size fits all type scenario

  • The matrix makes clear separation between collaboration only, and administrative tasks performing partners
    • This is based on multiple recommendations, but is based mostly on the following Azure Subscription recommendation from Azure Secure DevOps Kit. (Obviously if the account is also homed in Azure AD and you’ve setup B2B conditional access policy for guests, you might consider yourself covered to some extent…)
  • Where authentication happens is important part on the picture, and is the main deciding factor on users home directory

Other considerations

  • Licensing is separate discussion… Anyway key takeaway is, that the 1:5 ratio licensing works in the background = If you assign license to guest user its one license gone, and doesn’t benefit from the B2B-Licensing
  • The picture doesn’t consider SSO between the host tenant and its IDP, as it basically wouldn’t add anything to the picture (unless you’d ”multiplex” multiple claims provider against single AD FS, and then via claims pipeline transformations emit claims for the guest type users in you’re tenant)
  • More detailed explanation of all the scenarios (minus the flowchart) can be found here Properties of an Azure Active Directory B2B collaboration user

Please don’t hesitate to comment or send feedback, if you notice any errors or wrong assumptions in the flowchart


If you want to check B2B deep diver on user types and authn/authz, then check: https://securecloud.blog/2019/05/06/deep-diver-azure-ad-b2b/

Click for bigger picture

Deep Diver: Azure AD B2B

In this blog I focus on enterprise collaboration access scenarios, and demonstrate some peculiar insights Azure AD and AAD B2B hold in terms of issuing tokens

The Big Picture (click picture for larger version)

Click the picture for larger image

Disclaimer: The article focuses on delegated app permissions, thus you won’t see examples of App Identity & Client Credentials Flow. Neither should you assume that direct app permissions behave the same way as the scenarios demonstrated in the below paragraphs. The blog assumes previous understanding of Azure AD B2B (if you feel, that more is needed, read this excellent article describing the basics)

Tokens & Claims and resource access

Three stages of access?

Before we delve into B2B access, it’s important to understand how the resource access generally works in v1.0 endpoints with user identity driven scenarios

Click the picture for larger image


UserType and Source have ”loose” correlation. Meaning you can always change the UserType. Source cannot be changed for existing account (not including the local federation), unless you delete the account, and do a specific invitation and on-boarding flow. By loose I mean, that invited user always correlates to non-native directory (but can be changed)

There is also userType OTP, which isn’t yet in the official documentation

B2B Specific general, tokens & claims articles:

MS provides only two very specific articles on these concepts when related to claims and tokens. I believe the reason is the generally excellent documentation for Azure AD Authz/authn scenarios, which is highly applicable

Under the hood?

Did you know, that you can make basically any global Azure AD tenant issue a Access Token for you’re account?… The token is worthless… Unless it held proper permissions scopes on the Client, and app specific ”acl-like” permissions for the requested application, like we demonstrated in the access stages part

What separates AAD B2B token from AAD token is that seperate IDP value is written to the B2B Token, since the final issuer is the destination directory, where the B2B user is collaborating, and not the users home directory

Lets take example from Teams

  • Flow differences
    • The local directory token is fetched against multi-tenant endpoint [common]
    • Guest token is fetched against the guest directory (issuer in our examples)

Guest token

    "aud": "1fec8e78-bce4-4aaf-ab1b-5451cc387264",
    "iss": "https://sts.windows.net/46d2c4e6-a732-4fb4-b9f8-374af03f3f58/",
    "iat": 1557116305,
    "nbf": 1557116305,
    "exp": 1557120205,
    "acct": 1,
    "acr": "1",
    "aio": "AUQAu/8LAAAACFsh87mJ7wZTvQe5/qq5SnS+9srK3tO5sbt5leCu0sm5Rjfx41a9x7OQpn7HbrglieuT+bsL7db6hAEIvRb/XA==",
    "altsecid": "5::100320003B090681",
    "amr": [
    "appid": "1fec8e78-bce4-4aaf-ab1b-5451cc387264",
    "appidacr": "0",
    "email": "jose@ff00.info",
        "idp": "https://sts.windows.net/7fde6064-17a0-4c0e-87d6-19883001bd0d/",
    "ipaddr": "",
    "name": "jose santa",
    "oid": "e648ddcb-2ea0-4a02-9a2e-ff491494846c",
    "puid": "1003200046F07AB7",
    "scp": "Contacts.ReadWrite.Shared Files.ReadWrite.All Notes.ReadWrite.All Sites.ReadWrite.All",
    "sub": "DYE_FXLPCgd1yPksPNFXov8b41jgZsedrc_W8t4bcMA",
    "tid": "46d2c4e6-a732-4fb4-b9f8-374af03f3f58",
    "unique_name": "jose@ff00.info",
    "uti": "rdex3UDBd0yBZXI5XfVEAA",
    "ver": "1.0"

Local token

    "aud": "1fec8e78-bce4-4aaf-ab1b-5451cc387264",
    "iss": "https://sts.windows.net/7fde6064-17a0-4c0e-87d6-19883001bd0d/",
    "iat": 1557116092,
    "nbf": 1557116092,
    "exp": 1557119992,
    "acct": 0,
    "acr": "1",
    "aio": "AVQAq/8LAAAAjpEyijYGeGtKYtJ2cqQfvZpmcc5AtM+g/REMI506RwnVm6GanjOcuGmG2iv97UygfkTI/ngALSC5pEZBlmJg1xpCgujBXkajEbKmYpjlWZA=",
    "amr": [
    "appid": "1fec8e78-bce4-4aaf-ab1b-5451cc387264",
    "appidacr": "0",
    "family_name": "santa",
    "given_name": "jose",
    "ipaddr": "",
    "name": "jose santa",
    "oid": "2995f48b-8c49-4cf9-aabc-21aef5661e15",
    "onprem_sid": "S-1-5-21-621967805-835074083-177589206-1153",
    "puid": "100320003B090681",
    "scp": "Contacts.ReadWrite.Shared Files.ReadWrite.All Notes.ReadWrite.All Sites.ReadWrite.All",
    "sub": "27ASPxuGbUTB8DlgO_kAFeoZkAUbZBkah5JhvFN5nDc",
    "tid": "7fde6064-17a0-4c0e-87d6-19883001bd0d",
    "unique_name": "jose@ff00.info",
    "upn": "jose@ff00.info",
    "uti": "AEIFj-kI00-InbpiPzlBAA",
    "ver": "1.0"

Stranger questions in a Strange Land:

  • What happens when B2B users UPN changes?
    • Answer:According to my testing, the user mapping isn’t done based on UPN, but other immutable-like ID (There are bunch of those in the token claims) – Thus If the UPN changes, the mapping will still work, but it will reflect the initial UPN of the user
  • Can I do access control on group based role claims emitted from guest tenant?
    • answer: I haven’t tested this yet, but I would speculate that only the roles of the destination tenant are available, not roles from the IDP tenant (for the guest user) – Maybe there is ”exposed groups/roles” -like feature in the roadmap, that allows a scoping a select set of group-values to flow cross-tenant?
  • Which claims I shouldnt excpect to flow cross tenant in SAML federations
  • How Google and OTP authenticated users differ from other B2B sources?
    • Answer: Both require tenant context for sign-in requests, meaning common endpoints, such portal.azure.com myapps.microsoft.com eg. wont work without the destination tenant appended in the URL
  • Can I prevent my users collaborating on another tenants?
    • Answer: You can deny external guest accounts collaborating on you’re directory, but you can’t deny you’re users collaborating on other tenants (Unless you allow very few apps, that don’t support B2B collaboration on conditional access for the users, and deny all other apps)
    • Short answer: Inbound collaboration is controllable, outbound isn’t
  • Does the MFA performed in guests host tenant satisfy the MFA requirement on the destination tenant
    • Answer: No, and for good reasons. You cant simply know, in what way the guest tenant user has satisfied the MFA requirement
  • I am developing Azure AD App where I need to control groups and App Roles in Azure AD related authorizations. Which App type should I use: single, or multi-tenant?
    • Answer: With single tenant app using guest users all app roles and group permissions are on you’re control. You can also apply local conditional access policy to the application and its b2b users, which you can’t do in multi-tenant apps for B2B users
    • More: With multi-tenant app you don’t need to worry about having B2B collaboration accounts on you’re directory, but you need to build the authorization and roles directly in the app, if want retain similar control.
    • Even more: There are many scenarios where it makes sense to develop app using both app types. The multi-tenant app can act as initial staging proxy, to invoke the invitation API, enabling complete self-service on-boarding for example select group of users
  • Can we use B2B users in Azure AD Domain Services
    • Answer:

Ending words

If you felt that my article didn’t cover enough, or felt vague in some areas check these excellent articles from MS.

I plan also to update the article on continuous basis, so I will try to post any updates on the article on future as well.

B2B User Types – Properties of an Azure Active Directory B2B collaboration user

B2B High Level – What is guest user access in Azure Active Directory B2B?

UserType OTP – Email one-time passcode authentication (preview)

Br, Joosua