Files
snake-in-a-briefcase/Invoke-Stealth/Invoke-Stealth.ps1
2025-08-07 20:40:38 +07:00

121 lines
9.8 KiB
PowerShell

#================================#
# Invoke-Stealth by @JoelGMSec #
# https://darkbyte.net #
#================================#
# Variables
$ErrorActionPreference = "SilentlyContinue"
$InvokePath = $args[0]
$Paramt = $args[1]
$Technique = $args[2]
$NoBanner = $args[3]
# Banner
function Show-Banner {
Write-Host
Write-host " ___ _ ____ _ _ _ _ " -ForegroundColor Blue
Write-host " |_ _|_ _ __ _ ___ | | _ ___ / ___|| |_ ___ __ _| | |_| |__ " -ForegroundColor Blue
Write-host " | || '_ \ \ / / _ \| |/ / _ \____\___ \| __/ _ \/ _' | | __| '_ \ " -ForegroundColor Blue
Write-host " | || | | \ V / (_) | < __/_____|__) | || __/ (_| | | |_| | | | " -ForegroundColor Blue
Write-host " |___|_| |_|\_/ \___/|_|\_\___| |____/ \__\___|\__,_|_|\__|_| |_| " -ForegroundColor Blue
Write-host
Write-host " ------------------------- by @JoelGMSec ------------------------- " -ForegroundColor Green
Write-host }
# Help
function Show-Help {
Write-host ; Write-Host " Info: " -ForegroundColor Yellow -NoNewLine ; Write-Host " This tool helps you to automate the obfuscation process of"
Write-Host " any script written in PowerShell with different techniques"
Write-Host ; Write-Host " Usage: " -ForegroundColor Yellow -NoNewLine ; Write-Host ".\Invoke-Stealth.ps1 script.ps1 -technique Chameleon" -ForegroundColor Blue
Write-Host " - You can use as single or separated by commas -" ; Write-Host ; Write-Host " Techniques: " -ForegroundColor Yellow
Write-Host " · " -NoNewLine ; Write-Host "Chameleon: "-ForegroundColor Green -NoNewLine ; Write-Host "Substitute strings and concatenate variables"
Write-Host " · " -NoNewLine ; Write-Host "BetterXencrypt: "-ForegroundColor Green -NoNewLine ; Write-Host "Compresses and encrypts with random iterations"
Write-Host " · " -NoNewLine ; Write-Host "PyFuscation: "-ForegroundColor Green -NoNewLine ; Write-Host "Obfuscate functions, variables and parameters"
Write-Host " · " -NoNewLine ; Write-Host "ReverseB64: "-ForegroundColor Green -NoNewLine ; Write-Host "Encode with base64 and reverse it to avoid detections"
Write-Host " · " -NoNewLine ; Write-Host "PSObfuscation: "-ForegroundColor Green -NoNewLine ; Write-Host "Convert content to bytes and compress with Gzip"
Write-Host " · " -NoNewLine ; Write-Host "All: "-ForegroundColor Green -NoNewLine ; Write-Host "Sequentially executes all techniques described above"
Write-Host ; Write-Host " Warning: " -ForegroundColor Red -NoNewLine ; Write-Host "The output script will exponentially multiply the original size"
Write-Host " " -NoNewLine ; Write-Host " Chameleon & PyFuscation need dependencies to work properly" ; Write-Host }
if($NoBanner -notlike '*-nobanner') { Show-Banner } ; if($InvokePath -like '*-h*') { Show-Help ; break }
if(!$Technique) { Show-Help ; Write-Host "[!] Error: Not enough parameters!" -ForegroundColor Red ; Write-Host ; break }
# Checks
$CheckPath = Get-ChildItem $pwd\Resources ; $RandomNumber = Get-Random (10..25)
if ($CheckPath){ $local = "True" ; Get-ChildItem -Path $pwd -Recurse | Unblock-File }
if (($InvokePath -notlike "*/*") -and ($InvokePath -notlike "*\*")){ $InvokePath = "`"$pwd/$($args[0])`"" }
# Functions
function Test-Command { Param ($command)
$oldPreference = $ErrorActionPreference ; $ErrorActionPreference = 'stop'
try { if(Get-Command $command){RETURN $true }}
Catch { RETURN $false } ; Finally { $ErrorActionPreference=$oldPreference }}
function Load-Chameleon {
$TestChameleon = Test-Command python3 ; if ($TestChameleon -in 'True'){
Write-Host "[+] Loading Chameleon and doing some obfuscation.. " -ForegroundColor Blue -NoNewline
$Chameleon = python3 ./Resources/Chameleon/chameleon.py -a $InvokePath -o $InvokePath 2>&1> $null
Write-Host "[OK]" -ForegroundColor Green ; Write-Host ; del function_mapping.json -ErrorAction SilentlyContinue }}
function Load-BetterXencrypt {
if($NoBanner -like '*-nobanner') { Write-Host } else {
if($Technique -in 'All') { Write-Host "[!] Avoid mixing BetterXencrypt with another techniques.. " -ForegroundColor Red -NoNewline }
else { Write-Host "[+] Loading BetterXencrypt and doing some encryption with random iterations.. " -ForegroundColor Blue -NoNewline
if ($local){ Import-Module $pwd\Resources\BetterXencrypt\BetterXencrypt.ps1 -Force } else {
(New-object System.net.webclient).DownloadFile("https://raw.githubusercontent.com/JoelGMSec/Invoke-Stealth/main/Resources/BetterXencrypt/BetterXencrypt.ps1","$pwd/BetterXencrypt.ps1")
Import-Module $pwd\BetterXencrypt.ps1 -Force } ; Invoke-BetterXencrypt -InFile $InvokePath -OutFile $InvokePath -Iterations $RandomNumber 2>&1> $null }
Write-Host "[OK]" -ForegroundColor Green ; Write-Host ; del BetterXencrypt.ps1 -ErrorAction SilentlyContinue }}
function Load-PyFuscation {
$TestPyFuscation = Test-Command python3 ; if ($TestPyFuscation -in 'True'){
if($Technique -like '*Chameleon*' -or '*all*') { $some = 'more' } else { $some = 'some' }
Write-Host "[+] Loading PyFuscation and doing $some obfuscation.. " -ForegroundColor Blue -NoNewline
$PyExecution = python3 ./Resources/PyFuscation/PyFuscation.py -fvp --ps $InvokePath 2> $null ; if($PyExecution) {
$PyFuscation = "$pwd/Resources/PyFuscation/tmp/script.ps1" ; Clear-Content $InvokePath ; Add-Content $InvokePath $(Get-Content $PyFuscation -ErrorAction SilentlyContinue)}
Write-Host "[OK]" -ForegroundColor Green ; Write-Host ; del "$pwd/Resources/PyFuscation/tmp" -R -Force -ErrorAction SilentlyContinue }}
function Rev64-Encoder {
Write-Host "[+] Encoding with base64 and reverse it to avoid detections.. " -ForegroundColor Blue -NoNewline
$base64 = [Convert]::ToBase64String([IO.File]::ReadAllBytes($InvokePath)) -replace "=","" ; $b64 = "`"$base64`""
$base64rev = $b64.ToCharArray() ; [array]::Reverse($base64rev) ; $best64 = -join $base64rev | Out-File $InvokePath
$content = Get-Content $InvokePath ; Clear-Content $InvokePath ; Add-Content $InvokePath '$best64code = ' -NoNewline ; Add-Content $InvokePath "$content ;"
Add-Content $InvokePath '$base64 = $best64code.ToCharArray() ; [array]::Reverse($base64) ; $Stripped = -join $base64 ;'
Add-Content $InvokePath '$Padded = switch ($Stripped.Length % 4) { 0 { $Stripped }; 1 { $Stripped.Substring(0, $Stripped.Length - 1) }; 2 { $Stripped + ("=" * 2) }; 3 { $Stripped + "=" }} ;'
$RandomCode = '$LoadCode = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Padded)) ;' ; Add-Content $InvokePath $RandomCode
$RandomSTR = "Invoke-Expression"; $RandomSTR2Parts = @(); $currentIndex = 0; while ($currentIndex -lt $RandomSTR.Length) {
$remainingLength = $RandomSTR.Length - $currentIndex; $chunkSize = Get-Random -Minimum 1 -Maximum ([System.Math]::Min(3, $remainingLength) + 1);
$chunk = $RandomSTR.Substring($currentIndex, $chunkSize); $randomCasedChunk = ($chunk.ToCharArray() | ForEach-Object {
if (Get-Random -Maximum 2) {$_.ToString().ToLower()} else {$_.ToString().ToUpper()}}) -join '';
$RandomSTR2Parts += $randomCasedChunk; $currentIndex += $chunkSize } ; $RandomSTR = $RandomSTR2Parts -join ""
$RandomSTR64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($RandomSTR)) -replace "=",""
$RandomSTR64 = $RandomSTR64.ToCharArray(); [array]::Reverse($RandomSTR64); $RandomSTR64 = -join $RandomSTR64
Add-Content $InvokePath "`$RandomSTR64 = '$RandomSTR64'.ToCharArray() ; [array]::Reverse(`$RandomSTR64) ; `$iexbase64 = -join `$RandomSTR64 ;"
Add-Content $InvokePath "`$iexbase64 = switch (`$iexbase64.Length % 4) { 0 { `$iexbase64 }; 1 { `$iexbase64.Substring(0, `$iexbase64.Length - 1) }; 2 { `$iexbase64 + '=' * 2 }; 3 { `$iexbase64 + '=' } } ;"
Add-Content $InvokePath "`$iexcmd = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(`$iexbase64)) ;"
$aliasName = -join ((48..57)+(97..122)+(65..90) | Get-Random -Count 4 | ForEach-Object {[char]$_})
$aliasNameB64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($aliasName)) -replace "=",""
$aliasNameB64 = $aliasNameB64.ToCharArray(); [array]::Reverse($aliasNameB64); $aliasNameB64 = -join $aliasNameB64
Add-Content $InvokePath "`$aliasSTR64 = '$aliasNameB64'.ToCharArray() ; [array]::Reverse(`$aliasSTR64) ; `$aliasbase = -join `$aliasSTR64 ;"
Add-Content $InvokePath "`$aliasbase = switch (`$aliasbase.Length % 4) { 0 { `$aliasbase }; 1 { `$aliasbase.Substring(0, `$aliasbase.Length - 1) }; 2 { `$aliasbase + '=' * 2 }; 3 { `$aliasbase + '=' } } ;"
Add-Content $InvokePath "`$aliasFinal = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(`$aliasbase)) ;"
$RandomCode = '$null = New-Alias -Name $aliasFinal -Value $iexcmd -Force ; & $aliasFinal $LoadCode ;'
$RandomCode = ($RandomCode -split "" | %{if(@(0..1) | Get-Random){$_.ToUpper()}else{$_.ToLower()}}) -join "" ; Add-Content $InvokePath $RandomCode
Write-Host "[OK]" -ForegroundColor Green ; Write-Host }
function Load-PSObfuscation {
Write-Host "[+] Loading PSObfuscation and randomizing script.. " -ForegroundColor Blue -NoNewline
if ($local){ Import-Module $pwd\Resources\PSObfuscation\Invoke-PSObfuscation.ps1 -Force } else {
Invoke-Expression (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/JoelGMSec/Invoke-Stealth/master/Resources/PSObfuscation/Invoke-PSObfuscation.ps1')}
$PSobfuscation = Invoke-PSObfuscation -Path $InvokePath -Comments -Variables -OutFile $InvokePath
Write-Host "[OK]" -ForegroundColor Green ; Write-Host }
# Main
if($Technique -like '*Chameleon*') { Load-Chameleon }
if($Technique -like '*BetterXencrypt*') { Load-BetterXencrypt }
if($Technique -like '*PyFuscation*') { Load-PyFuscation }
if($Technique -like '*ReverseB64*') { Rev64-Encoder }
if($Technique -like '*PSObfuscation*') { Load-PSObfuscation }
if($Technique -in 'All') { Load-Chameleon ; Load-BetterXencrypt ; Load-PyFuscation ; Rev64-Encoder ; Load-PSObfuscation }
if($NoBanner -notlike '*-nobanner') { Write-Host "[+] Done! " -ForegroundColor Green ; Write-Host }