Azure AD Application Proxy – SSO and Authorization notes from the field

This blog attempts to capture some of the Single Sign-On and Authorization scenarios I’ve dealt with during my extensive tenure with Azure AD Application proxy deployments.

To keep this blog short there is no description of what Azure AD Application Proxy is generally. More information can be found here

  • AAD SSO Column in the table indicates whether Single Sign-On setting on Azure AD Enterprise Application is enabled or disabled
  • Native Clients in the following table assumes scenario where browser-like features (web view etc) are only used to perform subset of functions, such as authenticating user to Azure AD. All other calls are authorized to Azure AD Application via the usage of Access Tokens passed in Authorization Header
    • For example: The native app may not use cookies to hold session persistence, but rather refresh token stored in the device
    • Some native clients rely completely on running browser inside the app, or open external browser (payment views etc). In these scenarios the application may support similar option as described in the second column (2 Browser)


Back-end Protocol
AAD SSO1 Native Client 2 Browser
SAML – WS/FED (SSO)*Enabled:SAML / or Disabled*No – At least when the most common binding: (Redirect -> POST) is used
Yes 1.Further reading 2.Source
Header Based Authentication against back-end APIDisabledYes With Azure API management using JWT_Bearer Grant Yes With Azure API management using JWT_Bearer Grant (Note this solution is not for rendering browser views. To render browser view from API response additional client side rendering is required
OAuth2 / OIDC Disabled No, unless the application is using web-view that maintains the session to Azure AD (source) Yes – While existing Azure AD session is maintained within browser. Fetch/XHR, or redirect based client can make requests to the back-end app, which can then validate tokens in Authorization Bearer scenario (source)
Header Based Authentication using PingAccessEnabled:Header-BasedNot tested – Probably? (Refer to the documentation) Not tested – Probably? (Refer to the documentation)
Windows integrated Authentication / SPNEGO * * Enabled:Windows Integrated Authentication
Yes – Kerberos Constrained Delegation by the App Proxy Agent is transparent to the client
Yes – Kerberos Constrained Delegation by the App Proxy Agent is transparent to the client
Basic / NTLM Authentication  * * * Disabled No – Authorization header is reserved for Bearer Tokens, which App Proxy Consumes Yes – While existing Azure AD session is maintained within browser, Basic Authentication can be used. NTLM can be used as well, applies also to WIA scenario when WIA fallbacks to NTLM
SOAP API (U/P)Disabled
Yes – When credentials are passed as part of body, and authorization header contains the Bearer Token
Yes – When credentials are passed as part of body, and authorization header contains the Bearer Token
Client CertificateNANo No

Clarifications

  • * Existing IDP Session
    • You could also have specified another Azure AD application separate from the App Proxy Enterprise Application. The SSO works regardless of the SSO setting, when the application uses sames IDP which the user has existing session on.
  • * * About SPNEGO [Source]
    • ”If you configure a connector machine for SPNEGO, make sure that all other connectors in that Connector group are also configured with SPNEGO. Applications expecting standard KCD should be routed through other connectors that are not configured for SPNEGO ”
  • * * * Compound Authorization (in some cases Double authentication)
    • First Authorization: Azure AD Consumes the Authorization header
      • While Sending additional Bearer token in other than Authorization header, or in body payload
      • Or While Sending additional Credentials in other than Authorization header, or in body payload
      • Sequentially (after) challenged by the back-end app running in browser session

Good to know

  • Native API clients using AAD Pre-authentication
    • With Native Clients Forwarding JWT tokens to back-end service doesn’t work unless the Native client is calling Azure AD App Proxy from webview like representation or pure browser
  • Only user identities can passed through application having Azure AD pre-authentication enabled
    • For example Application identity (Client Credentials Flow) doesn’t work with Azure AD App Proxy Applications, unless Compound Authorization is used
    • Apps can still work in chain (On-Behalf-of-Flow for example) as long as the identity being delegated is user identity
  • If you have Windows Authentication enabled in the Application, ensure the deployment scenario supports Kerberos Constrained Delegation, and the Azure AD App Proxy agent can act as delegating party to the SPN.
  • While Mutual TLS authentication isn’t supported features such as require device compliance from and other Client recognizing options are available when combined with Conditional Access.
  • There are also other scenarios which I may cover in another blog post
    • Using a mix of pre-authenticated and pass-trough Azure AD Applications
    • Linked applications
    • Password-based

Further reading

https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/application-proxy-configure-single-sign-on-with-kcd

https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/application-proxy-configure-for-claims-aware-applications

If you find any discrepancies (errors etc) with the information on the table just dm me at @santasalojoosua, or post question to this blog, and I shall correct it /explain it.

Demonstration – Illicit consent grant attack in Azure AD / Office 365

Disclaimer: All information contained within this post is common knowledge, given you grasp basic concepts of AAD default behavior,  OAuth2 Authorizations and how Javascript works in browsers.


There is new demo available here done for HelSec 12.2019

https://securecloud.blog/2019/12/17/helsec-azure-ad-write-up-phishing-on-steroids-with-azure-ad-consent-extractor/


How does it work?

Attacker creates multi-tenant app, and adds non-admin requiring API permissions for the desired API’s.  Attacker then delivers the link to end user, which after clicking the link only has to consent (Approve) the API permissions for the attacker.

Attacker has then access to user mail, this happens because attacker exfiltrates in the background the Access Token and uses it against the Exchange Online API

Down below I describe why it might be hard for the user to discern good app from the bad app.

Why it works?

Multi-tenants app by default have access to end users data, unless your Azure AD Admin have disabled the particular defaults that enable this behavior.

Exfil.jpg

Graph API + Other API’s

PoC

  • Create multi-tenant Azure AD Web-App/API + Azure Web App that delivers the JS. client side code to browser from Node.JS Web App
  • I am using minified ADAL.JS as <script src in the code. Other than that, I’ve just added few custom functions to the code, and studied wide variety of existing Vanilla ADAL JS Apps in GitHub
  • Figure out a way to deliver the link to the victim/victims in other AAD / Office 365 tenants
  • I’ve opted to forge existing Microsoft Newsletter with link to malicious Azure Web App to
  • When user clicks the link consent dialog is prompted.

JSA.PNG

  • Consent – This as any other dialog, you would get prompted for when consent framework kicks in (This is where the confidence part happens)

Newsletter.PNG

The process is same for benign apps, so there is superficially nothing to separate the good app from the bad (except caution, which is often unheeded, if you consider how often an mobile application presenting similar dialog is approved for multiple permissions in mobile phone)

  • User is redirected to the malicious app with seemingly benign OIDC-Flow (response_type=id_token)… no mention here of the OAuth2 Implicit Grant Flow (yet)

Redir

  • Hidden iFrame executes the OAuth2 Implicit Grant Flow, and gains Access Token to resource

Tokens

  • AJAX HTTP is used to post the Access Token as Payload to external exfil service
    • In case you wonder, that I’d left the function key there :)… Just try

JAX

  • User is redirected to the original link requested in the mail

OH.PNG

<- Users timeline stops here


– >Perpetrators timeline begins here

  • Token is copied by the malicious actor from Azure Functions where it was posted

Exfil

JWTIO

  • A Separate Powershell session running in some dark corner of the world is now searching users mail content for several keywords, and playing with the Access Token for the next 3600 seconds

Passwords

See it live:

Evil side:

User side

Microsoft References

https://docs.microsoft.com/en-us/office365/securitycompliance/detect-and-remediate-illicit-consent-grants 

https://blogs.technet.microsoft.com/office365security/defending-against-illicit-consent-grants/

Microsoft has issued multiple items in Secure Score controls about the scenario

Stay tuned for PT2 (How to defend against it)