Not Your Grandfather’s Empire I’ve wanted to put this blog together since returning home from DEFCON. Anytime we ran into someone who recognized our swag, they mentioned how much they loved Empire back in the day and didn’t realize it was being actively maintained. This made me reflect on all [...]
Earlier this year, we discovered that Outlook is now employing a sandbox for screening emails on all accounts, not just enterprise accounts or those protected by Microsoft Advanced Threat Protection (ATP). However, the sandbox allowed payloads to execute outbound connections back to a Command and Control (C2) server. In this post, we will walk through how we were able to leverage these connections to enumerate the sandbox and generate a highly targeted evasion code that continues to work today.
Disclaimer: This issue was disclosed to Microsoft, and while some of it has been corrected, not all of the issues have been addressed. Microsoft stated that they may correct these issues in a future product release, but, currently do not have planned remediation efforts.
LaunchingthePayload
While conducting an assessment for a client earlier this year, we stumbled across some unexpected behaviors while ops testing a payload. We experienced an unexpected callback to our C2 server while sending a malicious file to an Outlook account (that we controlled).
After a brief moment of panic, thinking we had accidentally sent a malicious file to an innocent person, and some research we found that the IP address from the host was owned by Microsoft. This piqued our interested even more, and thus we dove deeper into enumerating the target. The info showed that while the host was a Windows 10 machine, our payload was running in a high integrity process. Since our malicious macro contained no organic privilege escalation capability, it shouldn’t ever call back from a high integrity process. On top of that, the callback only lasted a couple minutes before it terminated.
Stumbling onto the Sandbox
All of this led us to suspect that maybe we had encountered an anti-malware sandbox filter, but we were unable to find any documentation from Microsoft that they were employing sandboxes outside of its ATP products; which our test account was not employing. Next, we tried to send another email with our payload attached to see if the callback was just an anomaly… and NOPE! we got another callback. We were sure this was some kind of sandbox and began trying to implement other more common sandbox evasion techniques, such as requiring user input, looking for generic file names, or executing on file close. However, each technique was thwarted and the sandbox still detonated the payload. At the end of the night, we were stumped, but at least we had a list of callbacks.
At this point in the investigation, we hadn’t set up any redirection; which left every payload calling back to the same domain/IP address. This meant that Outlook did not flag our efforts as malicious just yet (to our surprise). Some of you may have already noted that if we are getting connections back, we could possibly use them to enumerate the sandbox and look for any identifying features that would allow the payload to evade Microsoft’s detection; and yes, that is exactly what we tried next!
Playing in the Sandbox
Being lazy engineers, the first attempt at enumerating the sandbox was to write a quick and dirty batch file that:
Detonated
Created a .txt file
Attempted to copy itself back to the sever
Apparently straight copying of files out of the sandbox was a bridge too far; as the payload connection was immediately severed as soon as it tried to copy the file.
Instead, we modified the second stage of Powershell Empire to gather a little bit of additional information:
The code in the red box was all that had to be added for our successful enumeration. Empire already does some basic enumeration as part of the default second stage; checking for the computer name and current users name, what version of Powershell is running and a few other things. We just utilized a couple of additional WMI objects (Win32_ComputerSystemProduct, Win32_ComputerSystem and Win32_LogicalDisk) to gather some additional information on the host. This allowed us to get the vendor, system identification number, the number of cores and size of the hard drive. We chose these because “hardware” is often constrained to abnormal numbers for VMs to limit resource utilization and sometimes the vendor is listed as the virtualization software or the software uses a unique identification number. However, in this case the only abnormal field returned was the number of cores being one.
Evasion Development
Upon further investigation, we determined that the sandbox changed IP addresses, domain names, and usernames for each instance (or at least cycled through a list). Yet, the sandbox spawns an identifying number and disk size that always remain constant. So despite the fact that these values were not initially indicative of a VM the fact that they are always the same allows for us to easily identify the sandbox. We made these modifications to our macro and were able to successfully evade the sandbox.
Wrap-up
Prior to us filing a vulnerability report to Microsoft, we were no longer able to generate callbacks with intentionally caught payloads. However, we don’t believe it was through an intentional fix action on Microsoft’s part, so this data leak may re-appear in the future. It is important to note that the identifying number and disk size continue to work for evasion and Microsoft has reported that they have verified the issue. Unfortunately, we believe Microsoft has stated they will address it no earlier than the next release of the sandbox product – if at all.