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!

The Offensive Security Certified Expert (OSCE)

while True:
    try_harder()

tl;dr: 2 out of 3 big Offsec certs. Worth taking it just for the exam.

The Course

I read a lot of reviews before deciding I was ready to take the course. Like most of the other reviewers, I was already familiar with the concepts required for getting through most of the modules. Similar to the OSCP, their is very little direction given to you during the course and exam.

Cracking the Perimeter (CTP) is meant to be an extension to Pentesting with Kali Linux (PWK), and for good reason. It is much more focused on exploit development and dives deep into the less explored facets of penetration testing. A strong familiarity with x86 assembly (all examples are in Intel syntax) and the inner-workings of the Portable Executable (PE) format will go a long way, especially during the exploitation development and antivirus avoidance portions of the course.

In order to register for the course, you need to pass the “filter” hosted at fc4.me. Put simply: if you can not pass the filter, it is best you spend some time learning the preliminary knowledge elsewhere so you don’t waste your time (and hard-earned cash) on the course. The available options are:

Option Price (USD)
CTP v.1.0 + 60 days CTP Lab access + certification 1,500
CTP v.1.0 + 30 days CTP Lab access + certification 1,200
CTP Lab access – extension of 60 days 600
CTP Lab access – extension of 30 days 350
OSCE – Certification retake 100

At the suggestion of other reviewers, I purchased the 30 day option, which was only a couple hundred more than I paid for the OSCP (though that was 60 days). 30 days was more than enough to complete the course. By the 20th day I was ready to take the exam (I actually scheduled it for a date that was before my lab time expired). Even though it was much shorter than the OSCP, the modules are packed with material from real-life scenarios meant to evoke a sense of critical thinking. They do a great job of showing you what happened, how they got there, and what they did to get around it.

That being said, the course/exam require a lot of self-teaching and don’t hold your hand very much. Most of the modules have you re-enact the scenario that was written into the course. The scenarios are a bit dated, but the same principles (most importantly the ones that help you think in a different way) still apply today. The course is definitely centered around exploit development, but it is surrounded by the Web Application and Network Infrastructure modules. The module names (which give you a good idea of what’s included in each one) can be found in the syllabus, available here.

The Exam

This time around, the exam is a 48 hour endeavor with an additional 24 hours (total of 72 hours) to turn in your report. It was certainly the most difficult exam I have ever taken. At first look, the exam is deceivingly simple. There are 90 points possible, with a required 70 points to pass. 4 questions (30 points x 2 questions, 15 points x 2 questions), 48 hours, and anything you want to use is fair game. Documentation is a must, and can make a big difference when you need a few extra points to push you over the edge.

Side note: It was never mentioned in the course or on the forum if documentation is required for the exercises. Since it was required for the OSCP, I made sure to document every step in the course and on the exam. I don’t know if the course documentation made a difference, but it was helpful nonetheless.

All of the questions appear to be very straightforward and it was hard to imagine the whole process taking all that time. About 7 hours in, I had finished both of the 15 point questions. I was feeling good…

That feeling did not last. One thing Offsec is very good at is pure, unadulterated deception. The other two took me for quite a ride. One was related to exploit development, the other to web applications. The only advice I can give is that you do need external knowledge to complete the exam objectives. It also pays off quite nicely to automate as much as you possibly can. Research on creative attack methodologies is crucial. The course knowledge will get you part of the way there, but it’s up to you to finish the job. Suffice it to say I finished with what I was confident would pass. I went to sleep early after the exam and looked at my results with fresh eyes in the morning.

One very important note about documentation. They give you an analysis environment for developing exploits and the like. Since that is where a large part of the exam takes place, you need to do your documentation prior to disconnecting from the VPN. If you forget to document a step during the exam that takes place in the analysis environment, it will be absent from your documentation. Take notes and screenshots of everything.

I had a quick scare regarding some missing documentation (hence the above note), then found it in my screenshots folder. I finished the documentation around noon and sent it in. I got an email back stating that I had officially submitted my exam docs and that I should expect to hear something in the next three business days. Well, one business day later and I got my congratulations email.

Conclusion

I learned as much as I did during the exam as I did during the course. It was a surreal experience that I will never forget. One day, maybe I’ll get my OSEE. One day…

My Journey Through the Offensive Security Certified Professional (OSCP)

TL;DR: I passed. Thinking about going for it? Do it, you won’t regret it.

Decision Time

Let’s face it. There are a lot of certifications out there. Before I took the OSCP (and the accompanying Pentesting with Kali Linux course), I spent most of my time researching the “right” course to bust my resume out of the shell it was contained in. I figured there had to be some magical letters that could separate me from the rest of the pack. I had recently taken the GPEN, so GIAC was out unless I wanted to take the GXPN, but ~$6000 is a lot to blow on training. I wanted practical, no hand holding. I wanted in-depth and outright awesome. I wanted the most bang for my buck, and I had been using Backtrack since BT3 – so the OSCP seemed like a solid fit.

Signing up

I signed up for 60 days of lab time with the course materials and exam included for ~$1000. There is a negligible difference in price for time, it’s a lifetime cert, completely hands-on, includes the course material, free software, free SAINT license, a custom VM, 10 hours of video, AND great support.

The Course

First of all, I had to dedicate some serious time to this thing. In order to take the OSCP exam, you have to take the PWK course and be able to prove that you took it. What does that mean? It means you can take the exam at any time after you have purchased the course, but you won’t pass unless you can show that you actually took the course. The only real requirement is that you document nearly all of the exercises. And there are a lot. My final documentation (including the exam) was 238 pages.

The actual course material that contains the exercises is a PDF doc (no bookmarks) that is ~400 pages (369 IIRC). It contains 16 modules, 14 of which contain exercises that require documentation. You can read the syllabus on their website, but it covers all the standard things you might encounter on a pentest, while also traversing some unknown territory for a lot of people. It dabbles in exploit development, AV evasion, along with a myriad of other tips and tricks that should help you on the job. In the beginning, there is a fair amount of hand-holding to help you set up your environment, which does not require documentation. It dives right in and follows common pentesting methodology, filling in the gaps with common use cases for the included tools. The actual course had some great material in it, and I ended up picking up a few things that I wouldn’t have learned otherwise.

As the course progresses, it becomes noticeably about being independent and figuring things out for yourself. Several exercises point you in a generic direction and force you to think on your feet for a solution. Once you traverse the exploit development module, it feels sort of downhill in difficulty (which may simply be a product of the challenge of exploit dev). During the course, they have you practice on the lab network, which gives you some strong hints as to what you should do when you eventually invest all of your time in the labs.

SIDE TRACK: something that irked me a bit. When you purchase the course, you choose a Saturday to receive all of the material, and they don’t send you the PDF until then. Since you have to document all of the exercises, it forces you to “waste” valuable lab time by going through each and every module…

The lab network consists of some well configured lab machines that represent a real network fairly accurately. They span the entirety of a pentester’s toolbox and do a great job of forcing you to perform each step of the process carefully. I’m not going too reveal too much about the labs (since it would violate the agreement), but you can’t reach all of the boxes without pivoting over dual-homed machines into different networks. That being said, OffSec recommends you are able to compromise most of the machines in the “Student” network (with the exception of the (in)famously challenging ones) to consider yourself relatively prepared for the exam. I got around to most of them, but still ran out of time with 5 or 6 left.

The support for the course is quick to respond and very good about resolving issues. It’s a simple Freenode where you can go in and ping the admin. Any time I needed someone, I got help within a few minutes. A few times, I couldn’t connect to my debugging environment (they give you a Windows 7 box with some labs on it). The support team was quick to reset my box and I was able to connect again. I only had one incident where the support team led me astray and that was when I finally caved and asked for some help on a box. I had located a remote-file inclusion on a small web app and was having trouble exploiting it. Every once in a while, the exploit would succeed and I would get a shell only to have it die when commands were run, after which I couldn’t browse to that box anymore. I could browse on others, so I was convinced that it was that specific machine having issues. I reverted the box several times and it kept having the same issue. The admin told me that I “should look for another vector” if that’s the only thing I tried, and to use a different payload because the one I was using was unreliable. After looking around for other vectors and using other payloads for a couple hours, I decided to give it a rest and come back to it later. I returned to the box the next day with an open mind and decided to try my RFI one more time. It worked fine, totally stable. Not a huge deal, but if the solution is correct and I’m telling you I can’t connect to any part of the box, potentially the problem is on your end.

The Exam

To keep it short, the exam was actually easier than the lab machines in my opinion. You’re given 48 hours total to compromise a small subset of machines with some restrictions on specific tool usage and turn in a report. More specifically, you have 23 hours and 45 minutes in the exam network, then 24 hours to turn in the report. The machines themselves are, again, very well designed. The network is stable and reflects the training environment well. Each target is given a point value and breaks down specific goals into smaller point values (partial points for local vs. root access, sufficient documentation, etc.) Every machine has a proof file that must be cat’d/type’d in order to prove access. I put way more effort into documenting my process for the exam machines than the lab machines, considering the former was the difference between passing and failing. You have the option of turning in a lab pentest report along with your exam report for extra points. I included my course documentation in the lab report and kept the exam report separate. I finished 80 points worth of the machines in ~9.5 hours (you need 70/100 to pass), and was left with plenty of time for documentation. In fact, I hadn’t started my lab report until two nights before my exam (the documentation was ready though, just needed to be organized). I started my exam on a Saturday morning at 9 AM, and turned in everything (including my KeepNote files) on Sunday at 3 PM.

Conclusion

I had a great time on this course, and wouldn’t trade the experience for anything. I highly recommend taking it if you’re on the fence. After turning in my documentation, I received a confirmation email ~7 hours later. I then got a congratulations email on Tuesday morning, only 1 full business day later! Feel free to leave your comments or questions below.

Implementing pattern_create and pattern_offset in Python

Like many projects, the last script I wrote was born from frustration and misery. I was navigating the exploitation module of the OSCP course when I got to using Metasploit’s pattern_create and pattern_offset scripts. I’d used them before, and knew I was about to experience the same frustration of copying endless lines of unique strings from a terminal to an entirely separate Windows VM all over again.

Sure, VM Tools works, but when I’m in exploitation mode, I don’t want to be flipping back and forth between VMs, copying strings with my mouse like a prehistoric animal. I don’t want to recite the “address” that EIP is trying to execute 50 times in my head just to forget it by the time I remember where pattern_offset is even located on my box!

So first I re-implemented Phillips321’s to work as a function, so that inserting a unique pattern of arbitrary length was as easy as:

import pattern_tools
junk = pattern_tools.pattern_create(1000)

Where junk contains Aa0Aa1Aa2Aa3Aa4A...Bg8Bg9Bh0Bh1Bh2B

I went on to replicate pattern_offset. An offset can be located using:

import pattern_tools
print pattern_tools.pattern_offset('AccessViolationAddressHere')

An example:

import pattern_tools
print pattern_tools.pattern_offset('69413269')
[*] Exact match at offset 247

In case you’re the type that likes to prefix your addresses with 0x, it supports that as well. You can download pattern_tools from my github. Feel free to do a pull request if you see an error, and leave a comment below if it helped you!