Decrypting Modern McAfee ePolicy Orchestrator Credentials

Back in 2011, a community-submitted module was pulled into the Metasploit Framework that was able to decrypt the passwords in files such as db.properties, containing the necessary credentials to connect to the database driving ePO. The module details the existence of a static key, used in conjunction with AES-128-ECB, that provides crypto services for strings in the ePO installation. It does not, however, tell us how we can find it ourselves.

During a recent pentest, a co-worker tried this module against the latest version (ePO 5.3.0 as of writing) to no avail. With access to the database, one could reset or add a user in order to modify agent configurations, enabling distributed compromise on an enterprise scale. This post details the added “crypto” code, where the original author found the static key, and how the credentials can still be decrypted today.

The Key

The following configuration defines some of the directives used in the all-important db.properties file (my installation used Windows authentication). By default, this file is located at C:\Program Files (x86)\McAfee\ePolicy Orchestrator\Server\conf\orion\db.properties

db.database.name=ePO_WIN-VICTIM
db.jdbc.driver=jtds
db.param.ssl=request
db.param.USENTLMV2=true
db.instance.name=EPOSERVER
db.user.domain=WIN-VICTIM
db.user.name=Victim
db.port=49327
db.pool.exhausted.action=grow
db.server.name=WIN-VICTIM
db.user.passwd.encrypted.ex2=uo/giUYBfzl9DZwU08iSiA\=\=

I noticed that changing the password to something else using the standard authentication configuration tool located at https://win-victim:8443/core/config-auth and back again did not alter the ciphertext in any way. This meant that, while the key now changes among installations, it is still static per-install.

Following the Trail

After a long tour of the filesystem, I determined that our JAR of choice was orion-core-common.jar, located by default at C:\Program Files (x86)\McAfee\ePolicy Orchestrator\Server\lib\orion-core-common.jar. After searching around the JAR for a while, I wound up at the createConfig function located in the DatabaseUtil class as part of the com.mcafee.orion.core.db.base package. This function is called whenever the password is changed.

Database Util Class Location
Location of the DatabaseUtil class

Below is the relevant part of the code:

createConfig Function
createConfig Function

The Obfuscate Call

Note the single call to MfsPassword.obfuscate (Seems the McAfee developers also noted the real nature of the “encryption”), passing in a single object and version of encryption to use. By following the call, we notice an interesting getKeyStuff function.

Obfuscate Function
obfuscate Function

Following the getKeyStuff function, we note the number of versions available.

getKeyStuff Function
getKeyStuff Function

Perhaps version 1 of this function contains the static key mentioned in the Metasploit module? Let’s take a look at the MfsPassword class definition.

MfsPassword Class Definition
MfsPassword Class Definition

Well, they were right, the key was hardcoded. This is version 1 code, though. Surely version 2 would be much more secure? Let’s take a look at getDefaultKeyStuff.

getDefaultKeyStuff Obtaining a Value from the Registry
getDefaultKeyStuff Obtaining a Value from the Registry

Seems like it’s building a string from obfuscation.v2.key.registry.key and obfuscation.v2.key.registry.value. After a quick search, it lead me to C:\Program Files (x86)\McAfee\ePolicy Orchestrator\Server\conf\orion\orion.properties

orion.properties Contents
orion.properties Contents

That looks like a promising location, lets see what it does with that value.

getDefaultKeyStuff Part 2
getDefaultKeyStuff reading the value and decoding it

So, it looks like it just base64 decodes the value and (not pictured) returns right after. Let’s see if this value fits as a possible AES-128-EBC key.

InstallKey Location
InstallKey Location
$ echo l/urC4YpU+5/KthxgBspnA==|base64 -D|hexdump
0000000 97 fb ab 0b 86 29 53 ee 7f 2a d8 71 80 1b 29 9c

16 bytes would fit as a drop in. Let’s take our encrypted password from db.properties and drop into a new file that can be consumed by openssl. Then we’ll try to use the key we found in the registry to decrypt using AES-128-EBC.

$ echo uo/giUYBfzl9DZwU08iSiA==|base64 -D>in.key
$ openssl enc -d -aes-128-ecb -in in.key -K $(echo l/urC4YpU+5/KthxgBspnA==|base64 -D|xxd -p)
testing

Summary

It turns out that the key is now in the registry, which (in my installation) can be found at HKLM/SOFTWARE/Wow6432Node/Network Associates/ePolicy Orchestrator/Secured/InstallKey. Drop the encrypted contents to disk, and decrypt them using openssl like so:

$ echo uo/giUYBfzl9DZwU08iSiA==|base64 -D>in.key
$ openssl enc -d -aes-128-ecb -in in.key -K $(echo l/urC4YpU+5/KthxgBspnA==|base64 -D|xxd -p)
testing

This post will be updated when I (hopefully) get a PR into Metasploit. Happy hunting!

Leave a Reply

Your email address will not be published. Required fields are marked *