danielbohannon / Invoke-Obfuscation

PowerShell Obfuscator
Apache License 2.0
3.59k stars 759 forks source link

String TOKEN obfuscation issue on 'ConfirmImpact' ParameterValidationAttribute #19

Closed cobbr closed 6 years ago

cobbr commented 7 years ago

Problem

Currently, ConfirmImpact is a member of the $ParameterValidationAttributesToTreatAsScriptBlock group. When the ConfirmImpact attribute is assigned to a ScriptBlock, execution fails. There are no errors during obfuscation, only during execution.

I discovered this issue obfuscating the Invoke-EventVwrBypass module in Empire.

Example

PS> cat .\Invoke-Example.ps1
function Invoke-Example {

    [CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Medium')]
    Param ([String] $Example)
    Write-Host $Example
}
PS > Invoke-Obfuscation -ScriptPath .\Invoke-Example.ps1 -Command 'Token\All\1,Out Invoke-ObfuscatedExample.ps1' -Quiet

Outputting ObfuscatedCommand to stdout and exiting since -Command was specified and -NoExit was not specified:

function I`NVOkE`-e`xa`Mple {

    [CmdletBinding(suPPORTssHoUlDpROCESS = ${t`RUE}, cOnfirmimpact = {"{1}{2}{0}"-f 'ium','M','ed'})]
    Param ([String] ${EX`AMP`Le})
    &("{2}{0}{3}{1}"-f 'te','ost','Wri','-H') ${eXA`mPle}
}
PS> Import-Module .\Invoke-ObfuscatedExample.ps1
PS> INVOkE-exaMple -Example example
Cannot convert the ""{1}{2}{0}"-f 'ium','M','ed'" value of type "System.Management.Automation.ScriptBlock" to type
"System.Management.Automation.ConfirmImpact".
At line:1 char:1
+ INVOkE-exaMple -Example example
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : ConvertToFinalInvalidCastException

Solution

I was able to fix this by first removing ConfirmImpact from the list of $ParameterValidationAttributesToTreatAsScriptBlock variable. Second, I included ConfirmImpact along with ParameterSetName as a parameter binding that should be only obfuscated with ticks.

If(($SubString.Contains('parametersetname') -OR $SubString.Contains('confirmimpact')) -AND !$SubString.Contains('defaultparametersetname') -AND $SubString.Contains('='))
{
    # For strings in ParameterSetName parameter binding (but not DefaultParameterSetName) then we will only obfuscate with tick marks.
    # Otherwise we may get errors depending on the version of PowerShell being run.
    $ObfuscatedToken = $Token.Content
    $TokenForTicks = [System.Management.Automation.PSParser]::Tokenize($ObfuscatedToken,[ref]$null)
    $ObfuscatedToken = '"' + (Out-ObfuscatedWithTicks $ObfuscatedToken $TokenForTicks[0]) + '"'
}

Technically, ConfirmImpact could be obfuscated using simple concatenation as well, but not reordering with the format operator.

Also, this may be related to #2 , although I've observed that HelpMessage does not suffer from the same error.

cobbr commented 6 years ago

Fixed: 950785e5f846fb0e8d3be8484d2ba466c2340469