danielbohannon / Invoke-Obfuscation

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

Error on ParameterValidationAttribute 'OutputType' #12

Closed cobbr closed 7 years ago

cobbr commented 7 years ago

Problem

Errors obfuscating the ParameterValidationAttribute 'OutputType'. The problem only arises when OutputType uses a TypeNameString instead of a TypeLiteral as described here.

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

This error specifically was found while attempting to obfuscate PowerUp.ps1 and Invoke-Kerberoast.ps1.

Steps to reproduce

PS> Invoke-Obfuscation -ScriptPath 'https://raw.githubusercontent.com/EmpireProject/Empire/2.0_beta/data/module_source/privesc/PowerUp.ps1' -Command 'Token\All\1' -Quiet
Exception calling "Create" with "1" argument(s): "At line:675 char:17                                                                         
+ ... [OutputType(("{4}{5}{0}{3}{1}{2}"-f'eCo','oll','er','ntr','ServicePro ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Attribute argument must be a constant or a script block.
At line:826 char:17
+ ... [OutputType(("{4}{2}{9}{5}{8}{1}{0}{7}{6}{3}" -f '.Serv','s','r','ont ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Attribute argument must be a constant or a script block."
At /opt/Invoke-Obfuscation/Out-ObfuscatedTokenCommand.ps1:137 char:13
+             $ScriptString = Out-ObfuscatedTokenCommand ([ScriptBlock] ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ParseException

Exception calling "Create" with "1" argument(s): "At line:675 char:17
+ ... [OutputType(("{4}{5}{0}{3}{1}{2}"-f'eCo','oll','er','ntr','ServicePro ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Attribute argument must be a constant or a script block.
At line:826 char:17
+ ... [OutputType(("{4}{2}{9}{5}{8}{1}{0}{7}{6}{3}" -f '.Serv','s','r','ont ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Attribute argument must be a constant or a script block."
At /opt/Invoke-Obfuscation/Out-ObfuscatedTokenCommand.ps1:137 char:13
+             $ScriptString = Out-ObfuscatedTokenCommand ([ScriptBlock] ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ParseException

Exception calling "Create" with "1" argument(s): "At line:675 char:17
+ ... [OutputType(("{4}{5}{0}{3}{1}{2}"-f'eCo','oll','er','ntr','ServicePro ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Attribute argument must be a constant or a script block.
At line:826 char:17
+ ... [OutputType(("{4}{2}{9}{5}{8}{1}{0}{7}{6}{3}" -f '.Serv','s','r','ont ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Attribute argument must be a constant or a script block."
At /opt/Invoke-Obfuscation/Out-ObfuscatedTokenCommand.ps1:137 char:13
+             $ScriptString = Out-ObfuscatedTokenCommand ([ScriptBlock] ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ParseException

Exception calling "Create" with "1" argument(s): "At line:675 char:17
+ ... [OutputType(("{4}{5}{0}{3}{1}{2}"-f'eCo','oll','er','ntr','ServicePro ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Attribute argument must be a constant or a script block.
At line:826 char:17
+ ... [OutputType(("{4}{2}{9}{5}{8}{1}{0}{7}{6}{3}" -f '.Serv','s','r','ont ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Attribute argument must be a constant or a script block."
At /opt/Invoke-Obfuscation/Out-ObfuscatedTokenCommand.ps1:137 char:13
+             $ScriptString = Out-ObfuscatedTokenCommand ([ScriptBlock] ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ParseException

Exception calling "Create" with "1" argument(s): "At line:675 char:17
+ ... [OutputType(("{4}{5}{0}{3}{1}{2}"-f'eCo','oll','er','ntr','ServicePro ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Attribute argument must be a constant or a script block.
At line:826 char:17
+ ... [OutputType(("{4}{2}{9}{5}{8}{1}{0}{7}{6}{3}" -f '.Serv','s','r','ont ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Attribute argument must be a constant or a script block."
At /opt/Invoke-Obfuscation/Out-ObfuscatedTokenCommand.ps1:137 char:13
+             $ScriptString = Out-ObfuscatedTokenCommand ([ScriptBlock] ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ParseException

Solution

I was able to get rid of the error messages by adding OutputType to the $ParameterValidationAttributesToTreatStringAsScriptblock array.

# The below Parameter Binding Validation Attributes cannot have their string values formatted with the -f format operator unless treated as a scriptblock.
# When we find strings following these Parameter Binding Validation Attributes then if we are using a -f format operator we will treat the result as a scriptblock.
# Source: https://technet.microsoft.com/en-us/library/hh847743.aspx
$ParameterValidationAttributesToTreatStringAsScriptblock  = @()
$ParameterValidationAttributesToTreatStringAsScriptblock += 'alias'
$ParameterValidationAttributesToTreatStringAsScriptblock += 'allownull'
$ParameterValidationAttributesToTreatStringAsScriptblock += 'allowemptystring'
$ParameterValidationAttributesToTreatStringAsScriptblock += 'allowemptycollection'
$ParameterValidationAttributesToTreatStringAsScriptblock += 'validatecount'
$ParameterValidationAttributesToTreatStringAsScriptblock += 'validatelength'
$ParameterValidationAttributesToTreatStringAsScriptblock += 'validatepattern'
$ParameterValidationAttributesToTreatStringAsScriptblock += 'validaterange'
$ParameterValidationAttributesToTreatStringAsScriptblock += 'validatescript'
$ParameterValidationAttributesToTreatStringAsScriptblock += 'validateset'
$ParameterValidationAttributesToTreatStringAsScriptblock += 'validatenotnull'
$ParameterValidationAttributesToTreatStringAsScriptblock += 'validatenotnullorempty'

$ParameterValidationAttributesToTreatStringAsScriptblock += 'helpmessage'
$ParameterValidationAttributesToTreatStringAsScriptblock += 'confirmimpact'
$ParameterValidationAttributesToTreatStringAsScriptblock += 'outputtype'
danielbohannon commented 7 years ago

Thanks, cobbr! Detailed issue report (and resolution) as always. Just pushed the fix in 63e694fa6ae3cab1a16ceb8ef0a968601bc1b808.

dmchell commented 6 years ago

This or a similar issue seems to have reoccurred...

At line:1244 char:56
+ ... sMessageAttribute(("{3}{0}{1}{2}" -f'ShouldPro','c','ess','PS'), '')]
+                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Attribute argument must be a constant or a script block.
Not all parse errors were reported.  Correct the reported errors and try again."
At Z:\tools\Infrastructure\RedTeam\Invoke-Obfuscation\Out-ObfuscatedTokenCommand.ps1:137 char:13
+             $ScriptString = Out-ObfuscatedTokenCommand ([ScriptBlock] ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ParseException

Above occurs when obfuscating powerup