rapid7 / rex-powershell

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

Add and use a method to obfuscate string literals #31

Closed zeroSteiner closed 3 years ago

zeroSteiner commented 3 years ago

This adds and uses a method that can obfuscate powershell string literals. In the case of our current protections bypass stub (which is a combination of an AMSI bypass and a Script Block Loggin bypass), it is being detected as a malicious script. These changes alone aren't enough to fix that but put us in a position to add additional entropy to strings that are otherwise contributing to this classification. I also added a generic option to prepend a Powershell stub that can be used in the future to add custom logic. This currently isn't leveraged but will be necessary for future work on the Metasploit side of things.

Testing

For now, things are still identified as malicious so the target Windows system must have Defender disabled, specifically the Real Time Protections setting.

Example

New obfuscated string literal which changes (default threshold is 0.15).

>> Rex::Powershell::Obfu.scate_string_literal('ScriptBlockLogging')
=> "(('Scrip{2}B'+'loc'+'{'+'0}Log'+'gi{1}g')-f'k','n','t')"
>> Rex::Powershell::Obfu.scate_string_literal('ScriptBlockLogging')
=> "(('Sc'+'{0}i'+'p{1}B{2}o'+'ckLo'+'gging')-f'r','t','l')"
>> Rex::Powershell::Obfu.scate_string_literal('ScriptBlockLogging', threshold: 0)
=> "'ScriptBlockLogging'"
>> Rex::Powershell::Obfu.scate_string_literal('ScriptBlockLogging', threshold: 1)
=> "((''+'{'+'6'+'}'+'{'+'9'+'}'+'{'+'1'+'}'+'{'+'1'+'3'+'}'+'{'+'0'+'}'+'{'+'3'+'}'+'{'+'5'+'}'+'{'+'8'+'}'+'{'+'1'+'1'+'}'+'{'+'9'+'}'+'{'+'7'+'}'+'{'+'2'+'}'+'{'+'1'+'1'+'}'+'{'+'1'+'5'+'}'+'{'+'1'+'5'+'}'+'{'+'1'+'3'+'}'+'{'+'4'+'}'+'{'+'1'+'5'+'}'+'')-f'p','r','L','t','n','B','S','k','l','c','o','i','g')"
>> Rex::Powershell::Obfu.scate_string_literal('ScriptBlockLogging', threshold: 0.5)
=> "((''+'{0}c{4'+'}'+'i{'+'3}{'+'7}'+'{5'+'}'+'{'+'8'+'}'+'oc'+'{'+'6'+'}{2}'+'ogg'+'i{'+'1'+'}g'+'')-f'S','n','L','p','r','B','k','t','l')"
>> 
zeroSteiner commented 3 years ago

It looks like the gem failed to release for this because there was a unit test failure that I wasn't aware of. I'll look into and see if I can get it fixed. Thanks for testing and landing this @timwr! May have to hold on for a bit until I can get it resolved.

zeroSteiner commented 3 years ago

Figured out why the tests failed and proposed a solution to fix them in #32.