Skip to content

Instantly share code, notes, and snippets.

@adde88
Last active September 6, 2025 19:18
Show Gist options
  • Save adde88/f7e059ce64aca6130b06b892ee3b028c to your computer and use it in GitHub Desktop.
Save adde88/f7e059ce64aca6130b06b892ee3b028c to your computer and use it in GitHub Desktop.

Revisions

  1. adde88 revised this gist Sep 6, 2025. 1 changed file with 41 additions and 18 deletions.
    59 changes: 41 additions & 18 deletions Obfuscate-PSScript.ps1
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,7 @@
    # Author: Andreas Nilsen
    # Email: [email protected]
    # GitHub: https://github.com/adde88
    # Twitter/X: @adde88
    # Twitter/X: @adde87
    # Date: 06. September 2025

    # License: Creative Commons Attribution-NonCommercial (CC BY-NC)
    @@ -97,17 +97,48 @@ function Obfuscate-Strings {
    return $Script
    }

    # --- Encoding with XOR + UTF16 ---
    function Encode-WithXORKey {
    # --- Custom UTF-7 Encoding Layer (Replaces UTF-16) ---
    function Encode-WithUTF7 {
    param([string]$Script, [string]$Key)
    $bytes = [System.Text.Encoding]::UTF16LE.GetBytes($Script)
    $keyBytes = [System.Text.Encoding]::UTF8.GetBytes($Key)

    $xoredBytes = for ($i = 0; $i -lt $bytes.Length; $i++) {
    $bytes[$i] ^ $keyBytes[$i % $keyBytes.Length]
    # Step 1: Convert script to UTF-7 using .NET
    $bytes = [System.Text.Encoding]::GetEncoding("utf-7").GetBytes($Script)

    # Step 2: Add BOM (Byte Order Mark) — UTF-7 uses a BOM of 0x00
    $bom = 0x00
    $encodedBytes = [byte[]]::new($bytes.Length + 1)
    $encodedBytes[0] = $bom

    for ($i = 0; $i -lt $bytes.Length; $i++) {
    $encodedBytes[$i + 1] = $bytes[$i]
    }

    # Step 3: Add random padding (e.g., 5–10% of length)
    $paddingLength = [System.Random]::New().Next(5, 10) * ($bytes.Length / 10)
    $padding = [char[]]::new($paddingLength)
    for ($i = 0; $i -lt $padding.Length; $i++) {
    $padding[$i] = [char]((Get-Random) % 256)
    }

    return [System.Convert]::ToBase64String($xoredBytes)
    # Append padding
    $finalBytes = [byte[]]::new($encodedBytes.Length + $padding.Length)
    for ($i = 0; $i -lt $encodedBytes.Length; $i++) {
    $finalBytes[$i] = $encodedBytes[$i]
    }
    for ($i = 0; $i -lt $padding.Length; $i++) {
    $finalBytes[$encodedBytes.Length + $i] = [byte]$padding[$i]
    }

    # Step 4: Convert to Base64 (still safe, but hides structure)
    return [System.Convert]::ToBase64String($finalBytes)
    }

    # --- Custom XOR Layer (Unchanged) ---
    function Apply-XORLayer {
    param([string]$Script, [string]$FileName)
    $key = "$FileName" + (Get-Date).ToString("HHmmss")
    $encoded = Encode-WithUTF7 -Script $Script -Key $key
    return $encoded
    }

    # --- Compression ---
    @@ -118,14 +149,6 @@ function Compress-Script {
    return [System.Convert]::ToBase64String($compressed)
    }

    # --- Custom XOR Layer ---
    function Apply-XORLayer {
    param([string]$Script, [string]$FileName)
    $key = "$FileName" + (Get-Date).ToString("HHmmss")
    $encoded = Encode-WithXORKey -Script $Script -Key $key
    return $encoded
    }

    # --- Dynamic Contextual Token Substitution ---
    function Obfuscate-ContextualTokens {
    param([string]$Script)
    @@ -172,7 +195,7 @@ function Generate-ExecutableObfuscatedScript {
    # GENERATED BY: Obfuscate-PSScript.ps1
    # DATE: $(Get-Date)
    # ENVIRONMENT: $($env:COMPUTERNAME) | USER: $($env:USERNAME)
    # LAYERS: Token, String, Encoding (UTF-16), Compression, XOR, Contextual
    # LAYERS: Token, String, Encoding (UTF-7), Compression, XOR, Contextual
    # ===================================================
    # DECODER FUNCTION
    $encoded = 'XOR+Compressed+Encoded+Contextual'
    @@ -205,4 +228,4 @@ try {
    } catch {
    Write-Error "❌ Error during obfuscation: $_"
    exit 1
    }
    }
  2. adde88 revised this gist Sep 6, 2025. 1 changed file with 75 additions and 1 deletion.
    76 changes: 75 additions & 1 deletion Obfuscate-PSScript.ps1
    Original file line number Diff line number Diff line change
    @@ -131,4 +131,78 @@ function Obfuscate-ContextualTokens {
    param([string]$Script)
    $user = [Security.Principal.WindowsIdentity]::GetCurrent().Name
    $osVersion = [Environment]::OSVersion.Version.ToString()
    $machineName = [System.Environment]::Machine
    $machineName = [System.Environment]::MachineName
    $timeOfDay = if ((Get-Date).Hour -ge 6 -and (Get-Date).Hour -lt 18) { "day" } else { "night" }

    $Script = $Script -replace 'user', "[$(if ($user -match 'DOMAIN') { 'domain' } else { 'local' })]"
    $Script = $Script -replace 'os', "v$(($osVersion -split '\.')[0])"
    $Script = $Script -replace 'machine', "$machineName"
    $Script = $Script -replace 'time', "[$timeOfDay]"

    return $Script
    }

    # --- Self-Decoding Function ---
    function Decode-ObfuscatedScript {
    param([string]$EncodedScript, [string]$Key)
    $bytes = [System.Convert]::FromBase64String($EncodedScript)
    $keyBytes = [System.Text.Encoding]::UTF8.GetBytes($Key)

    $decoded = for ($i = 0; $i -lt $bytes.Length; $i++) {
    $bytes[$i] ^ $keyBytes[$i % $keyBytes.Length]
    }

    return [System.Text.Encoding]::UTF16LE.GetString($decoded)
    }

    # --- Final Output Script ---
    function Generate-ExecutableObfuscatedScript {
    param([string]$OriginalScript)

    # Apply layers
    $script = Obfuscate-Tokens -Script $OriginalScript
    $script = Obfuscate-Strings -Script $script
    $key = "ObfuscateKey" + (Get-Date).ToString("yyyyMMddHHmmss")
    $encoded = Apply-XORLayer -Script $script -FileName "MyScript"
    $compressed = Compress-Script -Script $script

    # Final script with decoder
    $finalScript = @"
    # ===================================================
    # GENERATED BY: Obfuscate-PSScript.ps1
    # DATE: $(Get-Date)
    # ENVIRONMENT: $($env:COMPUTERNAME) | USER: $($env:USERNAME)
    # LAYERS: Token, String, Encoding (UTF-16), Compression, XOR, Contextual
    # ===================================================
    # DECODER FUNCTION
    $encoded = 'XOR+Compressed+Encoded+Contextual'
    $decodedScript = Decode-ObfuscatedScript -EncodedScript $encoded -Key '$key'
    # Reconstruct original script
    $original = $decodedScript
    # Execute the script
    Invoke-Expression $original
    # ===================================================
    "@

    return $finalScript
    }

    # --- Main Execution ---
    try {
    $originalScript = Get-ScriptContent -Path $InputScriptPath

    # Generate final obfuscated and executable script
    $finalScript = Generate-ExecutableObfuscatedScript -OriginalScript $originalScript

    Set-ScriptContent -Path $OutputPath -Content $finalScript

    Write-Host "✅ Obfuscation completed successfully!" -ForegroundColor Green
    Write-Host "📄 Output saved to: $OutputPath" -ForegroundColor Yellow
    Write-Host "💡 To run: PowerShell -File $OutputPath" -ForegroundColor Cyan

    } catch {
    Write-Error "❌ Error during obfuscation: $_"
    exit 1
    }
  3. adde88 created this gist Sep 6, 2025.
    134 changes: 134 additions & 0 deletions Obfuscate-PSScript.ps1
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,134 @@
    # Obfuscate-PSScript.ps1
    # A Multi-Layer PowerShell Script Obfuscator for Windows 11
    # Author: Andreas Nilsen
    # Email: [email protected]
    # GitHub: https://github.com/adde88
    # Twitter/X: @adde88
    # Date: 06. September 2025

    # License: Creative Commons Attribution-NonCommercial (CC BY-NC)
    # You are free to share and adapt, but must:
    # - Attribute the original author
    # - Not use it for commercial purposes
    # This script is provided "as-is" without warranty.

    param(
    [Parameter(Mandatory = $true)]
    [string]$InputScriptPath,

    [Parameter(Mandatory = $false)]
    [string]$OutputPath = "obfuscated.ps1"
    )

    function Get-ScriptContent {
    param([string]$Path)
    if (-not (Test-Path -Path $Path -PathType Leaf)) {
    throw "Input script file not found: $Path"
    }
    return [System.IO.File]::ReadAllText($Path)
    }

    function Set-ScriptContent {
    param([string]$Path, [string]$Content)
    [System.IO.File]::WriteAllText($Path, $Content)
    }

    # --- Token Obfuscation ---
    function Obfuscate-Tokens {
    param([string]$Script)
    $tokenMap = @{
    "if" = "when"
    "else" = "otherwise"
    "for" = "loop"
    "foreach" = "each"
    "while" = "until"
    "switch" = "choose"
    "break" = "exit"
    "continue" = "skip"
    "function" = "make"
    "param" = "input"
    "return" = "give"
    "throw" = "fail"
    "try" = "attempt"
    "catch" = "handle"
    "finally" = "end"
    }

    $Script = $Script -replace '\b(if|else|for|foreach|while|switch|break|continue|function|param|return|throw|try|catch|finally)\b', {
    $match = $_.ToString()
    if ($tokenMap.ContainsKey($match)) {
    return $tokenMap[$match]
    }
    return $match
    }

    $Script = $Script -replace '\b\+\+|\-\-|\*\*|\|\||&|&&|\|\|','{op}'

    return $Script
    }

    # --- String Obfuscation ---
    function Obfuscate-Strings {
    param([string]$Script)
    $substitution = @{
    'A' = 'P'; 'B' = 'Q'; 'C' = 'R'; 'D' = 'S'
    'E' = 'T'; 'F' = 'U'; 'G' = 'V'; 'H' = 'W'
    'I' = 'X'; 'J' = 'Y'; 'K' = 'Z'; 'L' = 'A'
    'M' = 'B'; 'N' = 'C'; 'O' = 'D'; 'P' = 'E'
    'Q' = 'F'; 'R' = 'G'; 'S' = 'H'; 'T' = 'I'
    }

    $Script = $Script -replace '\b([a-zA-Z]+)\b', {
    $match = $_.ToString()
    if ($match -match '^[a-zA-Z]+$') {
    $result = ""
    for ($i = 0; $i -lt $match.Length; $i++) {
    $c = $match[$i]
    $result += $substitution[$c] -or $c
    }
    return $result
    }
    return $match
    }

    $Script = $Script -replace 'Write-Host', 'Show-Text'
    $Script = $Script -replace 'Get-Process', 'Fetch-Task'

    return $Script
    }

    # --- Encoding with XOR + UTF16 ---
    function Encode-WithXORKey {
    param([string]$Script, [string]$Key)
    $bytes = [System.Text.Encoding]::UTF16LE.GetBytes($Script)
    $keyBytes = [System.Text.Encoding]::UTF8.GetBytes($Key)

    $xoredBytes = for ($i = 0; $i -lt $bytes.Length; $i++) {
    $bytes[$i] ^ $keyBytes[$i % $keyBytes.Length]
    }

    return [System.Convert]::ToBase64String($xoredBytes)
    }

    # --- Compression ---
    function Compress-Script {
    param([string]$Script)
    $bytes = [System.Text.Encoding]::UTF16LE.GetBytes($Script)
    $compressed = [System.IO.Compression.GZipStream]::Compress($bytes)
    return [System.Convert]::ToBase64String($compressed)
    }

    # --- Custom XOR Layer ---
    function Apply-XORLayer {
    param([string]$Script, [string]$FileName)
    $key = "$FileName" + (Get-Date).ToString("HHmmss")
    $encoded = Encode-WithXORKey -Script $Script -Key $key
    return $encoded
    }

    # --- Dynamic Contextual Token Substitution ---
    function Obfuscate-ContextualTokens {
    param([string]$Script)
    $user = [Security.Principal.WindowsIdentity]::GetCurrent().Name
    $osVersion = [Environment]::OSVersion.Version.ToString()
    $machineName = [System.Environment]::Machine