5 min read

AitM detection with Sentinel via custom CSS

AitM detection with Sentinel via custom CSS
Photo by Growtika / Unsplash

Introduction

You are probably wondering, what has CSS to do with detecting AitM sites. In this blog post, we will go over how we can use a custom CSS template in Microsoft Entra ID Company Branding, to trigger a logic that detects when a user visited a Microsoft login page via an AitM site. The idea of this detection was not initially my idea, so the credit for it goes to the projects I will refer to throughout the blog. I re-used the logic of these projects to build a Logic App that creates Microsoft Sentinel incidents when a suspected AitM connection is detected.

Disclaimer, I did not test this project out in production environments yet while writing this post. So make sure you test it yourself if you are interested in implementing it ;).

How it works

Looking at the clarion project, we can see that HuskyHacks uses Python Flask to host an API. This API gets called by adding the url() parameter in CSS, which serves as the trigger for the detection logic. This detection logic checks what the 'referer' field contains in the HTTP header that is received. This 'referer' field contains the absolute partial address from which a resource has been requested (meaning, the domain where the user was on when the url() parameter was called in CSS).

The thought process behind all of this is that if we see a Microsoft login page being called for an account of one of our users where the 'referer' field is not 'login.microsoftonline.com', we expect that the user was on an AitM site. This is because you would expect that the Microsoft login page is only displayed at the 'login.microsoftonline.com' site.

Using a Logic App

Since this is an awesome way to detect connections to AitM sites without having to rely on Microsoft detection logic or Threat Intelligence sources, I wanted to create a simple Logic App that creates an incident in Microsoft Sentinel when this occurs. After all, the only thing we need is the custom CSS and a GET REST API endpoint to build this detection. For me, the logic solution to build this was an Azure Logic App.

Below you can find an example of a Logic App I created, which simply creates a Microsoft Sentinel incident and adds the domain from the 'referer' field to a watchlist.

The Logic App creates a Sentinel incident, and adds the phishing domain that was detected in the HTTP header to the description of the incident:

This domain can then be used by the SOC team to hunt for the end-user which connected to the AitM site, by hunting networking events like MDE DeviceNetworkEvents or Firewall / Proxy logs.

Custom CSS

As you probably know, Microsoft allows you to give your personal touch to the Microsoft login screen via the Company Branding blade in Entra ID. This feature also allows you to add a custom CSS file, where we can use a predefined set of selectors. By using the .ext-footer selector we can add an invisible background image to the footer of the login page, and use the url() parameter in CSS to try and trigger the Logic App we just created. Below you find the CSS file I used to trigger the Logic App.

.ext-footer {
    background-image: url(<logicapp-url>);
    background-size: 0 0;
}

Once you have this CSS file, you need to upload the file in the portal by going to Company branding > Default sign-in > Edit > Layout > Custom CSS.

After allowing Microsoft to implement the custom CSS file, you can go to login.microsoftonline.com (or an AitM site) and see the custom CSS you have added in the HTML code after you put in a UPN of your tenant:

If everything works fine, the Logic App should have triggered and logged the 'referer' field in the HTTP header:

Automatic correlation with network events

To take this setup one step further, I added the functionality to add the AitM domain to a watchlist in Sentinel. This can be used for TI sharing or other automations, but most importantly for automatic correlation with network events. If we create an analytic rule that checks the watchlist regularly and correlates the AitM domain with the networking data we have at our SIEM, we can create a new incident in Microsoft Sentinel which already includes the user that visited the malicious site. This is a much more smart detection than just creating a Sentinel incident and having to hunt for the impacted user yourself. It is also an advantage for automatic password reset automations, as this user entity is needed for such logic which is not present by default in the simple Sentinel incident. Below you can find an example of a very simple KQL query that could be used to correlate the watchlist with the MDE DeviceNetworkEvents. The caveat here is that to make this work, you will have to ingest the MDE DeviceNetworkEvents in Sentinel which might be costly to do.

let watchlist =_GetWatchlist('aitm-domains')
| where LastUpdatedTimeUTC > ago(10m)
| extend ExtractedDomain = extract("(?:https?:\\/\\/)?(?:www\\.)?([a-zA-Z0-9.-]+)(?:\\/||$)", 1, SearchKey);
let networkEvents = DeviceNetworkEvents
| where TimeGenerated > ago(10m)
| extend ExtractedDomain = extract("(?:https?:\\/\\/)?(?:www\\.)?([a-zA-Z0-9.-]+)(?:\\/||$)", 1, RemoteUrl);
watchlist
| join kind=leftouter networkEvents on ExtractedDomain

Challenges

No UPN present in the request

One of the challenges in this project is that the UPN of the user who visited the AitM site is not present in the request. To do this, we would need some sort of scripting language such as JavaScript to take the inputted UPN out of the HTML and send it along with the trigger. Unfortunately, only custom CSS is supported in the Company Branding blade in Entra ID, meaning I have not found a way yet to make this possible. If you have any ideas, please let me know in the comments.

Security of the Logic App

In the above example, I used a simple Logic App which is publicly available and uses simple SAS tokens in the URL as authentication. This is not ideal, since the URL can be found in plain text in the CSS when an UPN of the tenant is inputted. Even though the impact of exploitation of this is low (as long as only Sentinel Incidents are created), it might not be an ideal solution for a production environment.

Changing the login page

The CIPP project released a cool feature in their V5 version of the project where they changed the background image of the login page by using the .ext-sign-in-box class in the custom CSS. By doing this, the login page changes for the end user when they connect via an AitM site, letting them know not to enter their password. Since we already created a Sentinel incident giving us the possibility to force automatic password resets, I did not build this feature in the Logic App. Although, it might be a fun thing to do, extending the project further.

https://github.com/KelvinTegelaar/CIPP/releases/tag/v5.0.0