danielbohannon / Invoke-Obfuscation

PowerShell Obfuscator
Apache License 2.0
3.62k stars 763 forks source link

Out-ObfuscatedCommandArgumentTokenLevel3 should treat filter names like function names #4

Closed cobbr closed 7 years ago

cobbr commented 7 years ago

Problem

The Out-ObfuscatedCommandArgumentTokenLevel3 treats function names as special CommandArgument tokens that can't be concatenated. I believe that filters should be treated the same way.

I discovered this issue while attempting to obfuscate modules in the Empire project.

This error specifically was found while attempting to obfuscate powerview.ps1

Steps to reproduce

PS> git clone https://github.com/danielbohannon/Invoke-Obfuscation.git
PS> wget https://github.com/adaptivethreat/Empire/raw/master/data/module_source/situational_awareness/network/powerview.ps1
PS> Import-Module .\Invoke-Obfuscation\Invoke-Obfuscation.psm1

[*] Validating necessary commands are loaded into current PowerShell session.

[*] Function Loaded :: Out-ObfuscatedTokenCommand
[*] Function Loaded :: Out-ObfuscatedStringCommand
[*] Function Loaded :: Out-EncodedAsciiCommand
[*] Function Loaded :: Out-EncodedHexCommand
[*] Function Loaded :: Out-EncodedOctalCommand
[*] Function Loaded :: Out-EncodedBinaryCommand
[*] Function Loaded :: Out-SecureStringCommand
[*] Function Loaded :: Out-EncodedBXORCommand
[*] Function Loaded :: Out-PowerShellLauncher
[*] Function Loaded :: Invoke-Obfuscation

[*] All modules loaded and ready to run Invoke-Obfuscation

PS> Out-ObfuscatedTokenCommand -Path .\powerview.ps1 | Out-File out
Obfuscating powerview.ps1

[*] Obfuscating 747 Comment tokens.
[*]             600 Comment tokens remaining to obfuscate.
[*]             500 Comment tokens remaining to obfuscate.
[*]             400 Comment tokens remaining to obfuscate.
[*]             300 Comment tokens remaining to obfuscate.
[*]             200 Comment tokens remaining to obfuscate.
[*]             100 Comment tokens remaining to obfuscate.

[*] Obfuscating 1990 String tokens.
[*]             1800 String tokens remaining to obfuscate.
[*]             1700 String tokens remaining to obfuscate.
[*]             1600 String tokens remaining to obfuscate.
[*]             1500 String tokens remaining to obfuscate.
[*]             1400 String tokens remaining to obfuscate.
[*]             1300 String tokens remaining to obfuscate.
[*]             1200 String tokens remaining to obfuscate.
[*]             1100 String tokens remaining to obfuscate.
[*]             1000 String tokens remaining to obfuscate.
[*]              900 String tokens remaining to obfuscate.
[*]              800 String tokens remaining to obfuscate.
[*]              700 String tokens remaining to obfuscate.
[*]              600 String tokens remaining to obfuscate.
[*]              500 String tokens remaining to obfuscate.
[*]              400 String tokens remaining to obfuscate.
[*]              300 String tokens remaining to obfuscate.
[*]              200 String tokens remaining to obfuscate.
[*]              100 String tokens remaining to obfuscate.

[*] Obfuscating 531 Argument tokens.
[*]             400 Argument tokens remaining to obfuscate.
[*]             300 Argument tokens remaining to obfuscate.
[*]             200 Argument tokens remaining to obfuscate.
[*]             100 Argument tokens remaining to obfuscate.
Exception calling "Create" with "1" argument(s): "At line:445 char:7
+ filter ("{0}{2}{1}{3}{4}"-f 'E','t-','xpor','PowerViewCS','V') {
+       ~
Missing name after filter keyword.
(errors continue)

The error message makes it pretty clear that there is a problem with the obfuscated filter name.

The powerview.ps1 file makes use of filters extensively.

Solution

It seems that the issue is that filter names should be treated as a special case, just like function names.

The following code:

# Function name declarations are CommandArgument tokens that cannot be obfuscated with concatenations.
# For these we will obfuscated them with ticks because this changes the string from AMSI's perspective but not the final functionality.
If($ScriptString.SubString(0,$Token.Start-1).Trim().ToLower().EndsWith('function'))
{
    $ScriptString = Out-ObfuscatedWithTicks $ScriptString $Token
    Return $ScriptString
}

becomes:

# Function name declarations are CommandArgument tokens that cannot be obfuscated with concatenations.
# For these we will obfuscated them with ticks because this changes the string from AMSI's perspective but not the final functionality.
# This is also true of the 'filter' keyword
If($ScriptString.SubString(0,$Token.Start-1).Trim().ToLower().EndsWith('function') -or $ScriptString.SubString(0,$Token.Start-1).Trim().ToLower().EndsWith('filter'))
{
    $ScriptString = Out-ObfuscatedWithTicks $ScriptString $Token
    Return $ScriptString
}

This fixed the issue for me.

danielbohannon commented 7 years ago

Issue fixed in d419d0b4a0592c0cd48d7a22d462477f4b976970 release.