mirror of
https://github.com/wietze/Invoke-ArgFuscator
synced 2026-06-08 18:17:29 +00:00
Implementing FilePathTransformer, URLTransformer, Regex modifiers
Also updating CharacterInsertion and Sed
This commit is contained in:
@@ -4,6 +4,9 @@ using module "Modifiers\CharacterInsertion.psm1"
|
||||
using module "Modifiers\RandomCase.psm1"
|
||||
using module "Modifiers\OptionCharSubstitution.psm1"
|
||||
using module "Modifiers\Sed.psm1"
|
||||
using module "Modifiers\FilePathTransformer.psm1"
|
||||
using module "Modifiers\UrlTransformer.psm1"
|
||||
using module "Modifiers\Regex.psm1"
|
||||
|
||||
param (
|
||||
[Parameter(Mandatory = $true)][string]$InputFile,
|
||||
@@ -27,7 +30,7 @@ function Parse-Json {
|
||||
|
||||
|
||||
foreach ($modifier_params in $JSONData.modifiers.PSObject.Properties) {
|
||||
$ModifierName = $modifier_params.Name;
|
||||
$ModifierName = $modifier_params.Name -replace "^(?i)regex$","RegularExpression"; # Regex is a reserved name, hence this rename for the Modifier class
|
||||
$Modifier = ($ModifierName -as [type])
|
||||
|
||||
if ($null -eq $Modifier) {
|
||||
@@ -64,7 +67,7 @@ function Parse-Json {
|
||||
|
||||
# Show final result
|
||||
$Output = $tokens[0]
|
||||
if($Tokens.length -gt 0){
|
||||
if($Tokens.Count -gt 1){
|
||||
ForEach ($Index in (1..($Tokens.Count - 1))) {
|
||||
$Output = -join ($Output, $(if (($Tokens[$Index - 1].Type -eq "argument" -or $Tokens[$Index - 1].Type -eq "value") -and ($Tokens[$Index - 1].TokenContent[-1] -eq "=")) { "" } else { " " }), ($Tokens[$Index].ToString()))
|
||||
}
|
||||
|
||||
@@ -4,28 +4,34 @@ using module "..\Types\Token.psm1"
|
||||
class CharacterInsertion : Modifier {
|
||||
[float]$Probability;
|
||||
[char[]]$Characters;
|
||||
[int]$Offset;
|
||||
|
||||
CharacterInsertion([Token[]]$InputCommandTokens, [string[]]$ExcludedTypes, [float]$Probability, [string[]]$Characters) : base($InputCommandTokens, $ExcludedTypes) {
|
||||
CharacterInsertion([Token[]]$InputCommandTokens, [string[]]$ExcludedTypes, [float]$Probability, [string[]]$Characters, [int]$Offset) : base($InputCommandTokens, $ExcludedTypes) {
|
||||
$this.Probability = $Probability;
|
||||
$this.Characters = $Characters;
|
||||
$this.Offset = $Offset;
|
||||
}
|
||||
|
||||
[void]GenerateOutput(){
|
||||
foreach($Token in $this.InputCommandTokens){
|
||||
$NewTokenContent = [System.Collections.ArrayList]@();
|
||||
foreach($Char in $Token.TokenContent){
|
||||
$NewTokenContent.Add($Char);
|
||||
$i = 0;
|
||||
if(!$this.ExcludedTypes.Contains($Token.Type) -and [Modifier]::CoinFlip($this.Probability)){
|
||||
do {
|
||||
$chosen = [Modifier]::ChooseRandom($this.Characters)
|
||||
$NewTokenContent.Add($chosen);
|
||||
$i++;
|
||||
} while ([Modifier]::CoinFlip($this.Probability * [Math]::Pow(0.9, $i)));
|
||||
}
|
||||
}
|
||||
[void]GenerateOutput() {
|
||||
foreach ($Token in $this.InputCommandTokens) {
|
||||
if (!$this.ExcludedTypes.Contains($Token.Type)) {
|
||||
$NewTokenContent = [System.Collections.ArrayList]@();
|
||||
$Token.TokenContent | Select-Object -First $this.Offset | ForEach-Object { $NewTokenContent.Add($_) }
|
||||
|
||||
$Token.TokenContent = $NewTokenContent;
|
||||
foreach ($Char in ($Token.TokenContent | Select-Object -Skip $this.Offset)) {
|
||||
$NewTokenContent.Add($Char);
|
||||
$i = 0;
|
||||
if ([Modifier]::CoinFlip($this.Probability)) {
|
||||
do {
|
||||
$chosen = [Modifier]::ChooseRandom($this.Characters)
|
||||
$NewTokenContent.Add($chosen);
|
||||
$i++;
|
||||
} while ([Modifier]::CoinFlip($this.Probability * [Math]::Pow(0.9, $i)));
|
||||
}
|
||||
}
|
||||
|
||||
$Token.TokenContent = $NewTokenContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
using module "..\Types\Modifier.psm1"
|
||||
using module "..\Types\Token.psm1"
|
||||
|
||||
class FilePathTransformer : Modifier {
|
||||
[float]$Probability;
|
||||
[boolean]$PathTraversal;
|
||||
[boolean]$SubstituteSlashes;
|
||||
[boolean]$ExtraSlashes;
|
||||
$keywords = @("debug", "system32", "compile", "winsxs", "temp", "update")
|
||||
|
||||
FilePathTransformer([Token[]]$InputCommandTokens, [string[]]$ExcludedTypes, [float]$Probability, [boolean]$PathTraversal, [boolean]$SubstituteSlashes, [boolean]$ExtraSlashes) : base($InputCommandTokens, $ExcludedTypes) {
|
||||
$this.Probability = $Probability;
|
||||
$this.PathTraversal = $PathTraversal;
|
||||
$this.SubstituteSlashes = $SubstituteSlashes;
|
||||
$this.ExtraSlashes = $ExtraSlashes;
|
||||
}
|
||||
|
||||
[void]GenerateOutput() {
|
||||
foreach ($Token in $this.InputCommandTokens) {
|
||||
$NewTokenContent = $Token.ToString();
|
||||
|
||||
if (!$this.ExcludedTypes.Contains($Token.Type)) {
|
||||
# Path Traversal
|
||||
if ($this.PathTraversal) {
|
||||
$NewTokenContent = [regex]::replace($NewTokenContent, "([^\\/])([\\/])([^\\/])", {
|
||||
$slash = $args[0].groups[2].value;
|
||||
if ([Modifier]::CoinFlip($this.Probability)) {
|
||||
$subpath = $slash + [Modifier]::ChooseRandom($this.Keywords) + $slash + ".." + $slash;
|
||||
return $args[0].groups[1].value + $subpath + $args[0].groups[3].value;
|
||||
}
|
||||
return $args[0].groups[0].value;
|
||||
});
|
||||
}
|
||||
|
||||
# Substitute slashes
|
||||
if ($this.SubstituteSlashes) {
|
||||
$NewTokenContent = [regex]::replace($NewTokenContent, "[/\\]", {
|
||||
if ([Modifier]::CoinFlip($this.Probability)) {
|
||||
if ($args[0].value -eq "/") {
|
||||
return "\\"
|
||||
}
|
||||
return "/"
|
||||
}
|
||||
return $args[0].value;
|
||||
});
|
||||
}
|
||||
|
||||
# Extra slashes
|
||||
if ($this.ExtraSlashes) {
|
||||
$NewTokenContent = [regex]::replace($NewTokenContent, "([^\\/])([\\/])([^\\/])", {
|
||||
$slash = $args[0].groups[2].value;
|
||||
if ([Modifier]::CoinFlip($this.Probability)) {
|
||||
$extra_slashes = $slash * [Modifier]::ChooseRandom($(2, 3, 4));
|
||||
return $args[0].groups[1].value + $extra_slashes + $args[0].groups[3].value;
|
||||
}
|
||||
return $args[0].groups[0].value;
|
||||
});
|
||||
}
|
||||
$Token.TokenContent = $NewTokenContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,3 @@ class OptionCharSubstitution : Modifier {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
using module "..\Types\Modifier.psm1"
|
||||
using module "..\Types\Token.psm1"
|
||||
|
||||
# 'Regex' is taken, hence 'RegularExpression'
|
||||
class RegularExpression : Modifier {
|
||||
[float]$Probability;
|
||||
[string]$RegexMatch;
|
||||
[string]$RegexReplace;
|
||||
|
||||
RegularExpression([Token[]]$InputCommandTokens, [string[]]$ExcludedTypes, [float]$Probability, [string]$RegexMatch, [string]$RegexReplace, [boolean]$CaseSensitive) : base($InputCommandTokens, $ExcludedTypes) {
|
||||
$this.Probability = $Probability;
|
||||
$this.RegexMatch = $RegexMatch;
|
||||
if(!$CaseSensitive){
|
||||
$this.RegexMatch = "(?i)"+ $this.RegexMatch;
|
||||
}
|
||||
$this.RegexReplace = $RegexReplace;
|
||||
}
|
||||
|
||||
[void]GenerateOutput() {
|
||||
foreach ($Token in $this.InputCommandTokens) {
|
||||
$NewTokenContent = $Token.ToString();
|
||||
|
||||
if (!$this.ExcludedTypes.Contains($Token.Type) -and [Modifier]::CoinFlip($this.Probability)) {
|
||||
$this.RegexReplace = [regex]::replace($this.RegexReplace, "\`$(\d+)\[(\d+):(\d+(?:-x?(?:\d+)?)?)\]", {
|
||||
[int]$rIndex = $args[0].groups[1].value
|
||||
[int]$start = $args[0].groups[2].value
|
||||
[string]$end = $args[0].groups[3].value
|
||||
if($NewTokenContent -match $this.RegexMatch){
|
||||
$match = $Matches[$rIndex]
|
||||
if($end.IndexOf('-') -ge 0){
|
||||
$ids = $end.split('-')
|
||||
if($ids[1] -eq ''){$ids[1] = $match.length;}
|
||||
[int]$end = Get-Random -Minimum ([int]($ids[0])) -Maximum ([int]($ids[1]));
|
||||
}
|
||||
return $match.substring($start, $end);
|
||||
}
|
||||
return $args[0].value;
|
||||
});
|
||||
|
||||
$this.RegexMatch = $this.RegexMatch -replace "`$RANDOM",(-join((65..90) + (97..122)|Get-Random -Count (Get-Random -minimum 1 -Maximum 20)|ForEach-Object {[char]$_}))
|
||||
|
||||
$NewTokenContent = [regex]::replace($NewTokenContent, $this.RegexMatch, $this.RegexReplace)
|
||||
$Token.TokenContent = $NewTokenContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -25,9 +25,9 @@ class Sed : Modifier {
|
||||
while ($Instance -ge 0) {
|
||||
$Replacement = [Modifier]::ChooseRandom($Match.Replace);
|
||||
if ([Modifier]::CoinFlip($this.Probability)) {
|
||||
$NewTokenContent = $NewTokenContent.Substring(0, $instance) + $Replacement + $NewTOkenContent.substring($instance + $match.Find.length);
|
||||
$NewTokenContent = $NewTokenContent.Substring(0, $instance) + $Replacement + $NewTokenContent.substring($instance + $match.Find.length);
|
||||
}
|
||||
$instance = $NewTokenContent.IndexOf($Match.Find, $instance + $Replacement.Length);
|
||||
$instance = $NewTokenContent.IndexOf($Match.Find, [math]::Min($instance + $Replacement.Length, $NewTokenContent.Length));
|
||||
}
|
||||
}
|
||||
$Token.TokenContent = $NewTokenContent.ToCharArray()
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
using module "..\Types\Modifier.psm1"
|
||||
using module "..\Types\Token.psm1"
|
||||
|
||||
class UrlTransformer : Modifier {
|
||||
[float]$Probability;
|
||||
[boolean]$LeaveOutProtocol;
|
||||
[boolean]$LeaveOutDoubleSlashes;
|
||||
[boolean]$SubstituteSlashes;
|
||||
[boolean]$IpToHex;
|
||||
[boolean]$PathTraversal;
|
||||
$keywords = @("debug", "system32", "compile", "winsxs", "temp", "update")
|
||||
|
||||
UrlTransformer([Token[]]$InputCommandTokens, [string[]]$ExcludedTypes, [float]$Probability, [boolean]$LeaveOutProtocol, [boolean]$LeaveOutDoubleSlashes, [boolean]$SubstituteSlashes, [boolean]$IpToHex, [boolean]$PathTraversal) : base($InputCommandTokens, $ExcludedTypes) {
|
||||
$this.Probability = $Probability;
|
||||
$this.LeaveOutProtocol = $LeaveOutProtocol;
|
||||
$this.SubstituteSlashes = $SubstituteSlashes;
|
||||
$this.IpToHex = $IpToHex;
|
||||
$this.PathTraversal = $PathTraversal;
|
||||
}
|
||||
|
||||
[void]GenerateOutput() {
|
||||
foreach ($Token in $this.InputCommandTokens) {
|
||||
$NewTokenContent = $Token.ToString();
|
||||
|
||||
if (!$this.ExcludedTypes.Contains($Token.Type)) {
|
||||
# Leave out protocol
|
||||
if ($this.LeaveOutProtocol -and [Modifier]::CoinFlip($this.Probability)) {
|
||||
$NewTokenContent = [regex]::replace($NewTokenContent, "\w+:\/\/", "://");
|
||||
}
|
||||
|
||||
# Path Traversal
|
||||
if ($this.PathTraversal) {
|
||||
[int]$i = 0;
|
||||
do {
|
||||
$NewTokenContent = [regex]::replace($NewTokenContent, "([^/])([/])([^/])", {
|
||||
$slash = $args[0].groups[2].value;
|
||||
if ([Modifier]::CoinFlip($this.Probability)) {
|
||||
$subpath = $slash + [Modifier]::ChooseRandom($this.Keywords) + $slash + ".." + $slash;
|
||||
return $args[0].groups[1].value + $subpath + $args[0].groups[3].value;
|
||||
}
|
||||
return $args[0].groups[0].value;
|
||||
});
|
||||
$i++;
|
||||
} while ([Modifier]::CoinFlip($this.Probability * [Math]::Pow(0.9, $i)));
|
||||
}
|
||||
|
||||
# Change double slashes
|
||||
if ($this.LeaveOutDoubleSlashes -and [Modifier]::CoinFlip($this.Probability)) {
|
||||
$NewTokenContent = [regex]::replace($NewTokenContent, "\:\/\/", ":/");
|
||||
}
|
||||
|
||||
# Substitute slashes
|
||||
if ($this.SubstituteSlashes) {
|
||||
$NewTokenContent = [regex]::replace($NewTokenContent, "\/+", {
|
||||
if ([Modifier]::CoinFlip($this.Probability)) {
|
||||
return "\" * $args[0].value.length;
|
||||
}
|
||||
return $args[0].value;
|
||||
});
|
||||
}
|
||||
|
||||
# IP Transform
|
||||
if ($this.IpToHex -and [Modifier]::CoinFlip($this.Probability)) {
|
||||
$NewTokenContent = [regex]::replace($NewTokenContent, "(?:[0-9]{1,3}\.){3}[0-9]{1,3}", {
|
||||
$ints = $args[0].value.split('.');
|
||||
[array]::reverse($ints);
|
||||
[int]$decimal = 0;
|
||||
$ints | foreach { $i = 0 } { $decimal += ([int]$_ * [Math]::Pow(256, $i++)) };
|
||||
|
||||
if ([Modifier]::CoinFlip(0.5)) {
|
||||
return $decimal;
|
||||
}
|
||||
else {
|
||||
return '0x{0:x}'-f $decimal;
|
||||
}
|
||||
})
|
||||
}
|
||||
$Token.TokenContent = $NewTokenContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -13,8 +13,8 @@ class SedStatement {
|
||||
|
||||
[int32]StringIndex([string]$Content){
|
||||
if($this.CaseInsensitive){
|
||||
return $Content.ToUpper().IndexOf($This.Find.ToUpper());
|
||||
return $Content.ToUpper().IndexOf($this.Find.ToUpper());
|
||||
}
|
||||
return $Content.IndexOf($This.Find);
|
||||
return $Content.IndexOf($this.Find);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user