Jacob Krasnov | Anthony Rose

At DEF CON this year BC Security had the pleasure of teaching a Workshop on Windows Antimalware Scan Interface (AMSI) Bypasses and Sandbox Evasions (We have posted the materials on our GitHub ). Like any class that involves the liberal use of Virtual Machines (VM) we had several technical issues that the students ran into, but one was particularly strange to us. Most of the scripts that we had written to intentionally get flagged by AMSI were running completely undetected. Initially, we thought either the students had forgotten to re-enable Defender or that the command we had given them to do so was failing. However, we verified the re-enable command was working properly in our own VM and that the scripts were getting flagged. Students then re-ran the enable command and verified that Defender was indeed on. However, no one was getting flags which were very strange. We moved on due to the class being under a time constraint.

After DEF CON was over (and we finally had some free time), we wanted to figure out why some of our students were having issues with the scripts being flagged. We decided to use Matt Graeber’s AMSI bypass as our control script (The workshop slides show how to obfuscate it past AMSI). We booted up the laptop, ran the script, and it wasn’t flagged!

$ReF=[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils^' ); $REF.GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$True);

Typically the keywords amsiInitFailed and System.Management.Automation.AmsiUtils would cause a trigger and be flagged.

Bare Metal Machine

During the workshop, we passed out three scripts that were supposed to be flagged on every computer. Only one of those scripts was being consistently flagged while the others weren’t. We tested that one to see if our machine was now exhibiting the same problems our students encountered. That script was indeed flagged and the fact that AMSI bypass wasn’t, indicates that the problem is with AMSI and Defender’s malware signatures and not that they are completely disabled.

Bare Metal Machine

We knew our test VM was flagging Graeber’s bypass during the workshop, so we tried it again there. Success! We finally received a flag from AMSI on the Bypass.

Virtual Machine

At this point you may have noticed the difference between the bare metal machine and the VM. When using our VM for obfuscation testing we set the VM to host only and disable cloud integration for Defender. The VM’s Defender had its signatures last updated on August 4, while the bare metal had the latest updates from August 12 and 13. We took a snapshot of our VM with the August 4 updates then updated Defender’s signatures to test our theory. Instantly the Graeber bypass was no longer being flagged. Now we were sure that an update between August 5 and 8 had broken AMSI, but we wanted to know just how screwed up the definitions had gotten.

We are big fans of Powershell Empire and decided to test the defective signatures against it. We first tested an unobfuscated Base64 encoded payload.

Virtual Machine

As expected, the August 4 signatures flagged it as malicious. However…the new definitions did not.

Bare Metal Machine

With some light obfuscation the initial Powershell Empire payload will make it past AMSI, however with the August 4 definitions a different Windows Defender event provider will flag the “Invoke-Empire” string (presumably by scanning for strings in memory) and kill the process. It identifies the malicious process as Powershell Empire:

Virtual Machine

On top of the failure by AMSI to identify the malicious payload the August 12/13 definitions don’t flag the string in memory either.

Bare Metal Machine

Defender can be a little hit or miss on identifying the Invoke-Empire string but Invoke-Mimikatz is pretty much a sure way to get caught. The August 4 definitions still finds Invoke-Mimikatz in memory and then kills the process and the beacon.

The August 12/13 definitions do not identify Mimikatz and allows it to run to completion.

So, what does this mean?

Powershell Empire is pretty much invisible to Defender with the August 12/13 definitions. Which would have been great if we were on an assessment and not teaching a workshop when it happened.

Eventually we were able to pin down the bad update as sometime between the evening of August 4 and morning of August 5. We notified Microsoft about the issues and they have corrected the issue as of August 16, but for a little over a week Powershell Empire was great again (it’s still pretty awesome but that’s a topic for a future article).