
Ofuscador PowerShell
Seu objetivo é transformar código para dificultar análises e assinaturas estáticas, útil em laboratórios e em testes autorizados de Red Team/Pentesting.
Suporta 6 níveis de ofuscação mais uma arquitetura de transformações/pipelines que permite empilhar técnicas como tokenização de strings, criptografia leve de literais, mascaramento de números, morfismo de identificadores, "jitter" de formato, cosméticos de fluxo de controle, injeção de código morto, perfis de fragmentação e perfis determinísticos.
⚠️ Uso responsável: esta ferramenta é destinada apenas para pesquisa e testes autorizados. Não use para fins maliciosos.```powershell
./psobf -h
██████╗ ███████╗ ██████╗ ██████╗ ███████╗
██╔══██╗██╔════╝██╔═══██╗██╔══██╗██╔════╝
██████╔╝███████╗██║ ██║██████╔╝█████╗
██╔═══╝ ╚════██║██║ ██║██╔══██╗██╔══╝
██║ ███████║╚██████╔╝██████╔╝██║
╚═╝ ╚══════╝ ╚═════╝ ╚═════╝ ╚═╝
Omar Salazar
v.2.0.0
Usage: psobf -i -o -level <1|2|3|4|5|6> [options]
Obfuscation Levels: 1 - Char join encoding 2 - Base64 encoding 3 - Base64 encoding (alternate) 4 - GZip + Base64 compression 5 - Script fragmentation 6 - AES-256 CTR encryption (NEW in 2.0.0)
Transform Pipeline Options (use with -pipeline): iden - Identifier morphing (use with -iden obf) strenc - String encryption (use with -strenc xor|rc4) stringdict - String tokenization (use with -stringdict N) numenc - Number encoding fmt - Format jitter (use with -fmt jitter) cf - Control flow obfuscation (use with -cf-opaque, -cf-shuffle) dead - Dead code injection (use with -deadcode N) hexenc - Hex string encoding (NEW) alias - Cmdlet alias substitution (NEW) unicode - Unicode character encoding (NEW) antidebug - Anti-debugging/VM detection (NEW) iexobf - Invoke-Expression obfuscation (NEW)
Examples:
psobf -i script.ps1 -o out.ps1 -level 2
psobf -i script.ps1 -o out.ps1 -level 6 -profile heavy
psobf -i script.ps1 -o out.ps1 -level 4 -pipeline "iden,alias,hexenc,antidebug,iexobf" -iden obf
psobf -i script.ps1 -o out.ps1 -level 4 -pipeline "strenc" -strenc rc4 -strkey 0011223344556677
## Recursos
<h1 align="center">
<img src="https://assets.kitploit.com/production/public/readmes/6598/11956ab9f65e8dc1b0460652042c601f70d28bb67e9fd6f0a89813ed5369997f.gif" alt="psobf" width="700px"></a>
<br>
</h1>
<h1 align="center">
<img src="https://raw.githubusercontent.com/taurusomar/psobf/HEAD/static/poc2.gif" alt="psobf" width="700px"></a>
<br>
</h1>
---
## Instalação```bash
go install github.com/TaurusOmar/psobf/v2/cmd/[email protected]
psobf -i input.ps1 -o out.ps1 -level 1..6 [options] psobf -h # full help
## Funcionalidades
<h1 align="center">
<img src="https://assets.kitploit.com/production/public/readmes/6598/11956ab9f65e8dc1b0460652042c601f70d28bb67e9fd6f0a89813ed5369997f.gif" alt="psobf" width="700px"></a>
<br>
</h1>
<h1 align="center">
<img src="https://raw.githubusercontent.com/taurusomar/psobf/HEAD/static/poc2.gif" alt="psobf" width="700px"></a>
<br>
</h1>
---
## Instalação```bash
go install github.com/TaurusOmar/psobf/cmd/[email protected]
psobf -i input.ps1 -o out.ps1 -level 1..6 [options] psobf -h # full help
---
## Referência completa de flags
| Flag | Tipo / Valores | Padrão | Descrição | Exemplo | | |
| ------------- | ---------------- | ----------: | ----------------------------------------- | ------------------------------------------------------------ | ------------------------------- | ---------------------- |
| `-i` | string | — | PS1 de entrada (use `-stdin` para ler a partir do pipe) | `-i script.ps1` | | |
| `-o` | string | `obfuscated.ps1` | Saída (use `-stdout` para escrever na STDOUT) | `-o out.ps1` | | |
| `-level` | 1..6 | 1 | Empacotador final (ver Níveis) | `-level 4` | | |
| `-noexec` | bool | false | Emitir apenas o payload (sem `Invoke-Expression`) | `-noexec` | | |
| `-stdin` | bool | false | Ler PS da STDIN | `-stdin` | | |
| `-stdout` | bool | false | Escrever resultado na STDOUT | `-stdout` | | |
| `-seed` | int64 | random | Aleatoriedade reproduzível | `-seed 42` | | |
| `-q` | bool | false | Silencioso (sem banner) | `-q` | | |
| `-pipeline` | csv | — | Transformações a aplicar em ordem | `-pipeline "iden,strenc,stringdict,numenc,fmt,cf,dead,frag"` | | |
| `-iden` | `keep`/`obf` | `keep` | Morfagem de identificadores (variáveis e funções) | `-iden obf` | | |
| `-strenc` | `off`/`xor`/`rc4`| `off` | Criptografia de literais de string | `-strenc rc4` | | |
| `-strkey` | hex | — | Chave para `-strenc` | `-strkey 0011223344556677` | | |
| `-stringdict` | 0..100 | 0 | Tokenizar strings longas; % de chance por literal | `-stringdict 40` | | |
| `-numenc` | bool | false | Codificar números como expressões PS aritméticas | `-numenc` | | |
| `-fmt` | `off`/`jitter` | `off` | Randomizar espaçamento/quebras de linha | `-fmt jitter` | | |
| `-cf-opaque` | bool | false | Envolver em `if(1 -eq 1){...}` | `-cf-opaque` | | |
| `-cf-shuffle` | bool | false | Reordenar **blocos de função** | `-cf-shuffle` | | |
| `-deadcode` | 0..100 | 0 | Probabilidade de injetar código morto | `-deadcode 20` | | |
| `-frag` | \`profile=tight | medium | loose\` | — | Perfil de fragmentação (nível 5) | `-frag profile=medium` |
| `-minfrag` | int | 10 | Tamanho mínimo do fragmento (nível 5) | `-minfrag 8` | | |
| `-maxfrag` | int | 20 | Tamanho máximo do fragmento (nível 5) | `-maxfrag 16` | | |
| `-profile` | \`light | balanced | heavy\` | — | Predefinições para pipeline/semente/etc. | `-profile heavy` |
| `-fuzz` | int | 0 | Produzir N variantes (sementes diferentes)| `-fuzz 5` | | |
| `-poly` | int | 0 | Variantes polimórficas por transformação | `-poly 3` | | |
> O **pipeline** é executado **antes** do empacotamento final **`-level`**.
---
## Script de entrada de exemplo (seguro)
Para manter os exemplos inofensivos, usaremos:```powershell
Write-Host "Hello, World!"
$answer = 42
function Greet($name) { Write-Host ("Hi, " + $name) }
Greet "Ada"
A seguir, são mostrados os formatos das saídas (trechos). Os payloads reais podem variar.
psobf -i sample.ps1 -o out.ps1 -level 1
**Saída (trecho):**```powershell
$obfuscated = $([char[]](87,114,105,116,101,45,72,111,115,116,32,34,72,101,108,108,111,44,32,87,111,114,108,100,33,34,10,36,97,110,115,119,101,114,32,61,32,52,50,10,102,117,110,99,116,105,111,110,32,71,114,101,101,116,40,36,110,97,109,101,41,32,123,32,87,114,105,116,101,45,72,111,115,116,32,40,34,72,105,44,32,34,32,43,32,36,110,97,109,101,41,32,125,10,71,114,101,101,116,32,34,65,100,97,34,10) -join ''); Invoke-Expression $obfuscated
psobf -i sample.ps1 -o out.ps1 -level 2
**Saída (trecho):**```powershell
$obfuscated = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String('V3JpdGUtSG9zdCAiSGVsbG8sIFdvcmxkISIKJGFuc3dlciA9IDQyCmZ1bmN0aW9uIEdyZWV0KCRuYW1lKSB7IFdyaXRlLUhvc3QgKCJIaSwgIiArICRuYW1lKSB9CkdyZWV0ICJBZGEiCg==')); Invoke-Expression $obfuscated
psobf -i sample.ps1 -o out.ps1 -level 3
**Saída (trecho):**```powershell
$e = [Convert]::FromBase64String('V3JpdGUtSG9zdCAiSGVsbG8sIFdvcmxkISIKJGFuc3dlciA9IDQyCmZ1bmN0aW9uIEdyZWV0KCRuYW1lKSB7IFdyaXRlLUhvc3QgKCJIaSwgIiArICRuYW1lKSB9CkdyZWV0ICJBZGEiCg=='); $obfuscated = [Text.Encoding]::UTF8.GetString($e); Invoke-Expression $obfuscated
psobf -i sample.ps1 -o out.ps1 -level 4
**Saída (trecho):**```powershell
$compressed = 'H4sIAAAAAAAA/wovyixJ1fXILy5RUPJIzcnJ11EIzy/KSVFU4lJJzCsuTy1SsFUwMeJKK81LLsnMz1NwL0pNLdFQyUvMTdVUqFZA0q+h5JGpo6CkoK0Ala3lAitWUHJMSVTiAgQAAP//m+Ey2GoAAAA='; $bytes = [Convert]::FromBase64String($compressed); $ms = New-Object IO.MemoryStream(,$bytes); $gz = New-Object IO.Compression.GzipStream($ms,[IO.Compression.CompressionMode]::Decompress); $sr = New-Object IO.StreamReader($gz); $obfuscated = $sr.ReadToEnd(); Invoke-Expression $obfuscated
psobf -i sample.ps1 -o out.ps1 -level 5
**Saída (trecho):**```powershell
$fragments = @('Write-Host "Hello',', World!"
$','answer = 42','
function G','reet($name)',' { Write-Ho','st ("Hi, " ','+ $name) }
','Greet "Ada"','
'); $script = $fragments -join ''; Invoke-Expression $script
psobf -i sample.ps1 -o out.ps1 -level 6
**Saída (trecho):**```powershell
$k=[Convert]::FromBase64String('...base64key...');$iv=[Convert]::FromBase64String('...base64iv...');$e=[Convert]::FromBase64String('...base64ciphertext...');$a=New-Object Security.Cryptography.AesManaged;$a.Key=$k;$a.IV=$iv;$d=$a.CreateDecryptor();$bytes=$d.TransformFinalBlock($e,0,$e.Length);$dec=[Text.Encoding]::UTF8.GetString($bytes);Invoke-Expression $dec
Use
-noexecpara inspecionar payloads sem executar.
-iden)__$.Comando```bash psobf -i sample.ps1 -o out.ps1 -level 4 -pipeline "iden" -iden obf -seed 11
**Saída (trecho)**```powershell
$WguE = 42
function QhZy($Chx){ Write-Host ("Hi, " + $Chx) }
QhZy "Ada"
-strenc xor|rc4)Encripta apenas literais de cadeias de caracteres (sem adulteração de API). Desencripta just-in-time em tempo de execução. Flags: -strenc xor|rc4, -strkey .
Comando```bash psobf -i sample.ps1 -o out.ps1 -level 4 -pipeline "strenc" -strenc xor -strkey a1b2c3d4 -seed 42
**Saída (trecho)**```powershell
$b=[Convert]::FromBase64String('EwAB...'); for($i=0;$i -lt $b.Length;$i++){$b[$i]=$b[$i] -bxor 0xA1}; [Text.Encoding]::UTF8.GetString($b)
Comando```bash psobf -i sample.ps1 -o out.ps1 -level 2 -pipeline "strenc" -strenc rc4 -strkey 0011223344556677 -seed 7
**Saída (trecho)**```powershell
function __decGWREVT($k,[byte[]]$d){ $s=0..255; $j=0; for($i=0;$i -lt 256;$i++){ $j=($j+$s[$i]+$k[$i%$k.Length])%256; $t=$s[$i];$s[$i]=$s[$j];$s[$j]=$t } $i=0;$j=0; for($x=0;$x -lt $d.Length;$x++){ $i=($i+1)%256;$j=($j+$s[$i])%256; $t=$s[$i];$s[$i]=$s[$j];$s[$j]=$t; $d[$x]=$d[$x] -bxor $s[($s[$i]+$s[$j])%256] } [Text.Encoding]::UTF8.GetString($d) }
...
( __decGWREVT ([byte[]](0..(8-1)|%{[Convert]::ToByte('0011223344556677'.Substring($_*2,2),16)})) ([Convert]::FromBase64String('m7m7...')) )
-stringdict)Tokeniza strings longas em um array $D e as reconstrói em tempo de execução. Reduz assinaturas repetitivas.
Flag: -stringdict <0..100>
Comando```bash psobf -i sample.ps1 -o out.ps1 -level 3 -pipeline "stringdict" -stringdict 40 -seed 1
**Saída (trecho)**```powershell
$D=@('Hello',', World','!','Hi, ', 'Ada');
Write-Host ($D[0]+$D[1]+$D[2])
function Greet($name){ Write-Host ($D[3] + $name) }
Greet $D[4]
-numenc)Substitui números comuns por expressões aritméticas/bit a bit equivalentes (fora de strings).
Comando```bash psobf -i sample.ps1 -o out.ps1 -level 2 -pipeline "numenc" -numenc -seed 1337
**Saída (trecho)**```powershell
$answer = ((0x2A -bxor 0x00)+0)
Atenção: Redirecionamentos como 2>&1 devem permanecer idênticos. Se seu código-fonte tiver redirecionamentos sem aspas e você estiver enfrentando problemas, desabilite -numenc ou encapsule esses redirecionamentos em strings no código-fonte.
-fmt)Randomiza espaçamentos e novas linhas.
Comando```bash psobf -i sample.ps1 -o out.ps1 -level 2 -pipeline "fmt" -fmt jitter -seed 20
**Saída (trecho)**```powershell
Write-Host "Hello, World!"
$answer=42
function Greet($name) { Write-Host ("Hi, "+$name) }
Greet "Ada"
-cf-opaque, -cf-shuffle)-cf-opaque: envolve todo o script em um ramo que nunca é falso.-cf-shuffle: reordena blocos de funções (não instruções individuais). Você notará mudanças apenas se seu script definir funções.```bash
psobf -i sample.ps1 -o out.ps1 -level 4 -pipeline "cf" -cf-opaque -cf-shuffle -seed 77**Saída (trecho)**```powershell
if(1 -eq 1){
function Greet($name){ Write-Host ("Hi, " + $name) }
Write-Host "Hello, World!"
$answer = 42
Greet "Ada"
}
-deadcode)Injeta funções no-op, loops de 0 iterações, strings inofensivas, etc. Controlado por probabilidade. Flag: -deadcode <0..100> (probabilidade de injeção de snippet).
Comando```bash psobf -i sample.ps1 -o out.ps1 -level 4 -pipeline "dead" -deadcode 25 -seed 5
**Saída (trecho)**```powershell
function __dummyzQJxJk { return }
for($i=0;$i -lt 0;$i++){Start-Sleep -Milliseconds 0}
$x='canary';$y=$x+$x|Out-Null
Write-Host "Hello, World!"
...
-frag, -minfrag, -maxfrag)Afeta apenas o nível 5 (fragmentos de string + junção em tempo de execução).
Perfis:
profile=tight → pequenos fragmentos (≈6–10)profile=medium → fragmentos médios (≈10–18)profile=loose → fragmentos maiores (≈14–28)Ou ajuste com -minfrag / -maxfrag.
Comandos```bash
psobf -i sample.ps1 -o out.ps1 -level 5 -frag profile=loose -seed 9
psobf -i sample.ps1 -o out.ps1 -level 5 -minfrag 8 -maxfrag 16 -seed 9
**Saída (trecho)**```powershell
$fragments=@('Write-Host "Hello,',' World!"',"`n", '$answer = 42',"`n",'function Greet($','name){ Write-Host ("Hi, "+$name)}',"`n",'Greet "Ada"');
$script=$fragments -join ''; Invoke-Expression $script
hexenc)Codifica literais de string como hexadecimal.```bash psobf -i sample.ps1 -o out.ps1 -level 2 -pipeline "hexenc" -seed 42
**Saída (trecho):**```powershell
[Text.Encoding]:https://raw.githubusercontent.com/taurusomar/psobf/HEAD/:UTF8.GetString(%5BConvert%5D::FromHexString(%2748656C6C6F%27))
alias)Substitui os cmdlets do PowerShell por seus alias curtos.```bash psobf -i sample.ps1 -o out.ps1 -level 2 -pipeline "alias" -seed 42
**Saída (trecho):**```powershell
# Write-Host → echo/write/outright
# Get-ChildItem → dir/ls/gci
# ForEach-Object → foreach/%
unicode)Converte caracteres de string para o formato [char]0xNNNN.```bash
psobf -i sample.ps1 -o out.ps1 -level 2 -pipeline "unicode" -seed 42
**Resultado (trecho):**```powershell
"H[char]0x0065[char]0x006C[char]0x006Co"
antidebug)Injeta trechos de detecção de sandbox/VM/debugger.```bash psobf -i sample.ps1 -o out.ps1 -level 4 -pipeline "antidebug" -seed 42
**Saída (trecho):**```powershell
if($env:COMPUTERNAME -match '^(SANDBOX|MALWARE|VIRUS)'){ exit }
if((Get-WmiObject Win32_ComputerSystem).Model -match '^(VirtualBox|VMware)'){ exit }
# ... original script ...
iexobf)Substitui Invoke-Expression por formas alternativas.```bash
psobf -i sample.ps1 -o out.ps1 -level 2 -pipeline "iexobf" -seed 42
**Saída (trecho):**```powershell
# Invoke-Expression → IEX or .
. $code # instead of Invoke-Expression $code
Predefinições são pontos de partida convenientes. Qualquer flag explícita que você passar substitui a predefinição. Qualquer flag que você passar explicitamente tem precedência sobre o perfil.
-seed N → saída determinística para uma configuração dada.-seed → aleatoriedade com semente criptográfica.-fuzz N → produzir N variantes (out.ps1.v1.ps1, out.ps1.v2.ps1, …), ótimo para testes de diversidade.Exemplo```bash psobf -i sample.ps1 -o out.ps1 -level 4 -profile heavy -fuzz 3
## STDIN/STDOUT e `-noexec`
* **Pipe de entrada / saída** ```bash
cat sample.ps1 | psobf -stdin -stdout -level 2 > out.ps1
O objetivo é diversificar artefatos e reduzir assinaturas estáveis para pesquisa em ambientes autorizados.
2. **Máxima diversidade (formato + fragmentação + código morto)**```bash
psobf -i sample.ps1 -o out.ps1 -level 5 \
-pipeline "fmt,frag,dead" -fmt jitter -frag profile=loose -deadcode 15 \
-fuzz 5
4. **Reduzir IOCs estáticos (números + dicionário)**```bash
psobf -i sample.ps1 -o out.ps1 -level 2 -pipeline "numenc,stringdict" -numenc -stringdict 35 -seed 9
---
## Melhores práticas e notas defensivas
* Rotacione **`-strkey`** e **`-seed`** por compilação.
* Prefira combinar camadas: `-strenc` + `-stringdict` + `-fmt jitter` + fragmentação.
* Use `-fuzz` para gerar famílias de variantes para teste de detecção.
* Mantenha uma linha de base limpa e benigna e verifique a equivalência funcional em sandbox antes e depois das transformações.
* Se seu script depende de sintaxe PS delicada (ex.: redirecionamentos), mantenha-os dentro de aspas ou desabilite `-numenc`.
---
## Diagrama de arquitetura```
┌──────────────┐
│ input.ps1 │
└──────┬───────┘
│ read (-i / -stdin)
▼
┌──────────────┐
│ Pipeline │ order you choose
│ iden │ rename vars/funcs
│ strenc │ XOR/RC4 literals
│ stringdict │ tokenize + rejoin
│ numenc │ numeric masking
│ fmt │ whitespace jitter
│ cf │ opaque/shuffle
│ dead │ harmless noise
└──────┬───────┘
│ mutated script
▼
┌──────────────┐
│ Level 1..5 │ final packing
└──────┬───────┘
│ + Invoke-Expression (unless -noexec)
▼
┌──────────────┐
│ out.ps1 │
└──────────────┘
psobf -i sample.ps1 -o out.ps1 -level 2 -seed 123
psobf -i sample.ps1 -o out.ps1 -level 4 -pipeline "strenc" -strenc rc4 -strkey 0011223344556677
psobf -i sample.ps1 -o out.ps1 -level 3 -pipeline "stringdict,numenc" -stringdict 40 -numenc
psobf -i sample.ps1 -o out.ps1 -level 5
-pipeline "iden,strenc,stringdict,numenc,fmt,cf,dead,frag"
-iden obf -strenc xor -strkey a1b2c3d4 -stringdict 35 -numenc
-fmt jitter -cf-opaque -deadcode 15 -frag profile=medium -seed 777
psobf -i sample.ps1 -o out.ps1 -level 6 -profile heavy -seed 999
psobf -i sample.ps1 -o out.ps1 -level 4 -pipeline "antidebug,alias,hexenc" -seed 42
psobf -i sample.ps1 -o out.ps1 -level 6
-pipeline "iden,alias,hexenc,unicode,antidebug,iexobf,strenc"
-iden obf -strenc rc4 -strkey 0011223344556677 -seed 42
psobf -i sample.ps1 -o payload.txt -level 4 -noexec
---
## Legal
Este projeto é destinado apenas para fins **educacionais** e **testes autorizados**. Você é o único responsável pelo seu uso. Os autores e colaboradores não assumem nenhuma responsabilidade por danos diretos ou indiretos.