
Uma coleção de técnicas, exemplos e um pouco de teoria para ofuscar manualmente scripts PowerShell visando evasão de AV, compilada para fins educacionais. O conteúdo deste repositório é o resultado de pesquisa pessoal, incluindo leitura de materiais online e tentativas de tentativa e erro em laboratórios e testes de penetração.
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.
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:
#!/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.
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:

Você também pode identificar gatilhos manualmente executando um script trecho por trecho.
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:

Agora considere a seguinte versão ofuscada:

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:

Agora considere esta versão:

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.

⚡ 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.
#!/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>