La cobertura previa de Elastic Security Labs sobre REF6598 documentó un conjunto de intrusiones cuya cadena de herramientas de Windows aterrizó mediante abuso de plugins de Obsidian, escaló mediante un cargador PE en memoria (PHANTOMPULL) y terminó con un RAT (PHANTOMPULSE). Esa publicación se centraba en la entrega. Esta publicación analiza la etapa final: PHANTOMPULSE, un implante que incluye tres técnicas de inyección de procesos, resuelve su C2 mediante entradas de transacciones de Ethereum/Base/Optimism y evita el UAC mediante la técnica de schuac pública. El análisis pone a la luz un canal C2 de blockchain que puede ser sometido, una primitiva unificada de punto de interrupción de hardware que desactiva AMSI / WLDP / ETW y las huellas digitales generalizadas de desarrollo asistido por IA en las cadenas de depuración del implante.
Conclusiones clave
- PHANTOMPULSE implementa tres técnicas de inyección adaptadas de recientes PoCs de seguridad ofensiva pública.
- AMSI, WLDP y ETW se evitan mediante una única primitiva HWBP compartida
- El resolver C2 de blockchain no tiene verificación del remitente, lo que permite a un defensor anular la URL C2 de cada implante publicando una sola transacción
- Indicadores estables de desarrollo asistido por IA presentes en el binario
Una nota sobre el desarrollo asistido por IA
PHANTOMPULSE muestra fuertes huellas dactilares de la asistencia de codificación de IA, visibles a lo largo de las cadenas de depuración.
Las señales más claras:
- Numeración estructurada de pasos en registros operativos:
[STEP 1] Staged mode — payload downloaded from C2 at runtime,[STEP 1/3] Scheduled Task (DotNetSvcUpdateTask, logon + every 3 min),[STEP 2/3] Boot Task (DotNetSvcCoreTask, INTERACTIVE_TOKEN + BootTrigger),[UNINSTALL 4/6] Removing persist_loader DLL + registry PE data...,[REPAIR] Reinstalling boot task (INTERACTIVE_TOKEN).... - Trazado de funciones ENTER/DONE:
"[HEIS] encrypt_text_only ENTER"/"[HEIS] encrypt_text_only DONE","KeylogResolveAPIs: ENTER". El estilo de diagnóstico de los LLMs se emplea por defecto al generar nuevas funciones. - Diagnóstico verboso:
"FindHostProcessEx: scan stats: total=%lu sessSkip=%lu openFail=%lu native=%lu wow64=%lu mapReject=%lu dbgReject=%lu sess=%lu","ManualMap: thread hijacked and resumed — DLL injection via thread hijack complete". Salida autoexplicativa, inusualmente habladora para malware. - Guiones en Em en cuerdas de Do:
"elevate: FAIL — no deployed DLL path",">>> .elevate: NOT proxy — spawning trusted host to handle elevation".
Cadena de ejecución
MainEntryLogic es la función de orquestación que ejecuta la secuencia completa de inicialización antes de entrar en el bucle C2:
start
└─ WinMain
└─ MainEntryLogic
1. DynInit // Bootstrap API resolution
2. ElevationStateCheck // ".elevate" marker detection, routes by token elevation state
3. SingleInstanceCheck // XOR-decrypted mutex, exit if already running
4. EvasionInit // Direct syscalls + ETW HWBP
5. SyscallResolverInit // CPUID + hash-based kernel32 resolution
6. SleepMaskInit // Sleep obfuscation setup
7. ComputeMachineID // DJB2(module name) ^ volume serial
8. IsRunningHollowed // Process hollowing self-check
9. CollectSysInfo // CPU, GPU, RAM, OS, AV, apps
10. FilelessPersist // Drop stub DLL, registry artifact
11. InstallPersistence // Three scheduled tasks via COM ITaskService
12. C2Loop_Init → C2Loop_Main
Al inicio, el implante DJB2 hace hash del nombre de usuario y de la computadora y busca cada uno en una tabla precomputada. Una coincidencia sale del proceso. Forzar la tabla contra listas públicas anti-sandbox recuperó 20 de las 61 entradas: WDAGUtilityAccount (Windows Defender Application Guard), varios nombres de VM por defecto DESKTOP-XXXXXXX y las personalidades de Joe Sandbox (abby, patex, george, john, lisa, frank, RDhJ0CNFevzX).
Evasión de la defensa
Llamadas directas a sistemas y envoltorios de API
PHANTOMPULSE resuelve funciones ntdll recorriendo PEB→Ldr con hashes DJB2, extrae Números de Servicio del Sistema (SSNs) del prólogo de cada función NT y crea stubs privados de llamadas de sistema. Estos muñones están envueltos en ayudantes de nivel superior que se emplean en el resto del implante:
NtCreateFile_WrapNtWriteFile_WrapNtClose_WrapNtCreateSection_WrapNtMapViewOfSection_WrapNtProtectVirtualMemory_WrapNtWriteVirtualMemory_Wrap
El resto del implante llama a estos envoltorios en lugar de exportaciones kernel32/ntdll , anulando los ganchos de ntdll en modo usuario (reemplazos de IAC, desvíos en línea o parches de trampolín) que los productos EDR inyectan en la superficie documentada de la API.
Una única función auxiliar enruta cada escritura de disco a través de NtCreateFile + NtWriteFile directamente, con errores de borrado y reintento al acceder a la escritura.
Ofuscación de cadenas y configuración
PHANTOMPULSE emplea cuatro capas XOR para diferentes artefactos:
| ¿Qué | Clave | Donde vive la llave |
|---|---|---|
| URL de reservación C2, mutex, nombres de archivo de ruta de caída | 16 bytes: F7 7C 8E 40 DF C1 7B E5 E7 4D 86 79 D5 B3 53 41 | Incrustado en .rdata |
| Nombres host de proveedores de blockchain (UTF-16 LE) | 8 bytes: 5A 3C 7E 1D 9F 2B 4E 8A | Incrustado en .rdata |
| Nombre de elevación COM, carga útil de archivo de registro de teclas | 0xE95CA237, calculado en tiempo de ejecución para mantener la constante fuera de .rdata | Calculado, no almacenado |
URL C2 extraída de una transacción blockchain input | La dirección del monedero resolver en sí misma | Reutilizado desde la clave de búsqueda pública |
AMSI, WLDP y ETW se desvían mediante puntos de interrupción por hardware
PHANTOMPULSE desactiva AMSI, la comprobación de code-trust de la Política de Bloqueo de Windows, y la telemetría ETW mediante una única primitiva compartida: un punto de interrupción de hardware plantado en cada entrada de API, interceptado por un manejador de excepciones vectorizado que falsifica el valor de retorno sin parche en línea.
| Slot | API de destino | Retorno suplantado (RAX) |
|---|---|---|
| DR0 | WldpQueryDynamicCodeTrust | 0 (S_OK) |
| DR1 | AmsiScanBuffer | 0x80070057 (E_INVALIDARG) |
| DR2 | EtwEventWrite | 0 (STATUS_SUCCESS) |
El mecanismo, paso a paso:
- El implante resuelve la API objetivo. AMSI y WLDP pasan por
LoadLibraryA+ búsqueda de exportación basada en hash; ETW emplea un paseo PEB→Ldr ya que ntdll ya está cargado. - El descriptor HWBP (dirección de la API objetivo, modo, valor de retorno suplantado) se escribe en una de las cuatro ranuras de 40 bytes en una tabla global de ranuras.
- Un hilo auxiliar suspende el hilo destino, llama a
NtGetContextThread/NtSetContextThreadpara escribir DR0–DR3 + DR7 y luego continúa. (Si el manejador de excepciones vectorizado del implante ya está instalado, se eleva unSTATUS_BREAKPOINTen proceso en su lugar, permitiendo que el VEH lea la tabla de ranuras y programe los DRs sin un hilo auxiliar.) - Cuando se llama a la API protegida, la CPU eleva
Debug Exceptionen la primera instrucción de la función. - El manejador vectorizado de excepciones del implante intercepta el
Debug Exception, recorre su tabla de 4 ranuras para encontrar la dirección de disparo y modifica el contexto del hilo:CONTEXT.Raxse establece al valor de retorno suplantado por ranuraCONTEXT.Ripse redirige a un thunk "skip" prealmacenado que regresa al llamador. - El manejador responde
EXCEPTION_CONTINUE_EXECUTION. El llamante ve el RAX suplantado como si la API se ejecutó.
El despachador sirve dos rutas. Un manejador (VEH_Dispatcher) procesa tanto las llamadas de RaiseException(STATUS_BREAKPOINT) propias del implante (usadas para iniciar y reprogramar los registros de DR desde la tabla de ranuras) como las excepciones STATUS_SINGLE_STEP que se activan cuando se llama a una API protegida. El código de excepción controla la rama: STATUS_BREAKPOINT activa la programación de DR STATUS_SINGLE_STEP activa la suplantación.
El manejador tampoco está registrado directamente. AddVectoredExceptionHandler recibe un pequeño golpe JMP asignado en tiempo de ejecución en una página de MEM_PRIVATE nueva (VirtualAlloc + VirtualProtect a PAGE_EXECUTE_READ). El thunk es un salto indirecto JMP [RIP-relative] (código de operación de 6 bytes FF 25 00 00 00 00) seguido en línea por la dirección del despachador. Como nunca se escriben bytes en AmsiScanBuffer, WldpQueryDynamicCodeTrust EtwEventWrite, la detección basada en firma que escanea parches de prólogo pasa esto por alto por completo.
Variante de construcción: subsistemas activos y latentes
Existen varios subsistemas en el binario como código o cadenas, pero no están activos en esta versión. Esta es una versión simplificada de una base de código más grande.
- Desconexión NTDLL: Las cadenas de depuración de un subsistema que se desengancha están en
.rdata(UnhookNtdll: ntdll base = %p,applied %d relocation fixups to .text), pero nada las referencia. Muerto en esta variante. - Cargador de blob PE residente en el registro: las versiones anteriores almacenaban el PE de la siguiente etapa dentro del registro. Esta compilación no, pero la rutina de desinstalación sigue limpiando el blob del registro heredado.
- Persistencia del secuestro COM: nunca se instaló con esta versión. La lógica de limpieza para ello permanece en la rutina de desinstalación.
- Persistencia del monitor de impresión: mismo patrón que el secuestro COM; Ruta de instalación ausente, ruta de desinstalación conservada.
Los tres últimos (cargador de blob del registro, secuestro COM, monitor de impresión) muestran el patrón contrario: lógica de limpieza sin lógica de instalación, mantenida para compatibilidad con despliegues anteriores.
| Característica | Construcción de cargas útiles | Evidencia |
|---|---|---|
| Llamadas directas al sistema (extracción del SSN) | Activo | Extracción del SSN + generación de stub confirmada |
| Bypass HWBP AMSI / WLDP / ETW | Activo | DR0/DR1/DR2 mediante primitiva de hilo auxiliar compartido |
| Inyección de procesos de tres vías | Activo | PhantomInject, DbgNexum, ManualMap son todas funcionales |
| Resolución C2 de la cadena de bloques | Activo | Se consultan tres proveedores de Blockscout |
| Desenganche NTDLL | Código muerto | Cadenas presentes, cero referencias de código |
| Cifrado HEIS | Deshabilitado | Cifrado/descifrado de código stubbed |
| Registry-resident PE blob loader | Solo legado | Solo se limpia durante la desinstalación |
| Persistencia del secuestro de COM | Solo legado | Limpiado durante la desinstalación, nunca instalado |
| Persistencia del monitor de impresión | Solo legado | Limpiado durante la desinstalación, nunca instalado |
| Cuerdas señuelo | Activo | 4 cadenas señuelo sin referencia en .rdata |
Mando y control
Resolución C2 de la cadena de bloques
PHANTOMPULSE descentraliza la búsqueda de C2 a través de tres proveedores de Blockscout:
eth.blockscout[.]com(Ethereum L1)base.blockscout[.]com(Base L2)optimism.blockscout[.]com(Optimismo L2)
La dirección de la billetera 0xc117688c530b660e15085bF3A2B664117d8672aA está descifrada por XOR desde el almacenamiento con una clave de 16 bytes. Para cada proveedor, el implante emite un HTTPS GET (puerto 443, errores de certificado SSL ignorados), extrae el campo input de la última transacción, la decodifica en hexadecimal, descifra por XOR usando los bytes de dirección del monedero como clave y valida que el resultado comienza con http. En caso de fallo total, vuelve a la URL codificada https://panel.fefea22134[.]net.
El resolver no verifica al remitente de la transacción. Solo comprueba que el último input decodificado empiece con http. Cualquiera puede enviar una transacción a esa cartera con su propia URL codificada en XOR bajo los bytes de la cartera, y cada instancia PHANTOMPULSE de esa campaña que haga encuestas después se resuelve a esa URL. Para los defensores de red, esto es un sumidero viable a costa de una sola transacción.
Puntos finales y latido cardíaco
Cinco rutas API se construyen en tiempo de ejecución, cifradas de nuevo en memoria con una clave por sesión:
| Camino | Método | Tipo de contenido | Objetivo |
|---|---|---|---|
/v1/telemetry/report | PUBLICACIÓN | application/json | Latido cardíaco con telemetría del sistema completo |
/v1/telemetry/tasks/<machine_id> | GET | Obtención de comandos | |
/v1/telemetry/upload/ | PUBLICACIÓN | image/bmp | Captura de pantalla / subida de archivo |
/v1/telemetry/result | PUBLICACIÓN | application/json | Entrega de resultados por mando |
/v1/telemetry/keylog/ | PUBLICACIÓN | text/plain | Carga de datos de keylog |
El latido envía un perfil completo del sistema como JSON:
{
"machine_id": "<uint32>",
"status": "online",
"cpu": "<model>",
"gpu": "<description>",
"ram_mb": "<uint32>",
"os": "<version>",
"username": "<user>",
"computer_name": "<name>",
"cores": "<uint32>",
"screen_w": "<int>",
"screen_h": "<int>",
"privilege": "<user|admin|admin_nouac|system>",
"build": "payloads",
"public_ip": "<ip>",
"av_list": ["<av1>", "<av2>"],
"apps": ["<app1>", "<app2>"],
"last_cmd": "<cmd>",
"last_cmd_result": "<result>"
}
Se analizan dos campos de respuesta: "status":"deleted" activa la desinstalación completa; "ip":"<value>" llena la caché de IP pública, pero solo si el descubrimiento local (ipif[.]org / icanhazip[.]com/ checkip.amazonaws[.]com) Aún no lo llenó.
Cadencia y resiliencia de bucles
- Sueño: aleatorio uniforme en [20, 40] segundos
- Auto-curación: se ejecuta en la iteración 2, luego cada décima iteración
- Tic de monitorización de salud: primera llamada después de que el implante se active, luego cada quinta iteración después. Llena una estructura local de información del sistema (CPU%, RAM, versión del SO, tiempo de funcionamiento, nombre de la computadora).
- Umbral de fallo: 10 fallos consecutivos de latidos cardíacos desencadenan un resetear automático para recuperación SSL/TLS atascada
- Re-resolución: en caso de fallo, se ejecuta la re-resolución de blockchain; si la URL resuelta cambia, el contador de fallos se resetear
- IP pública:
api4.ipify[.]org→ipv4.icanhazip[.]com→checkip.amazonaws[.]com - Comprobación de conectividad: sondas
microsoft[.]com,google[.]com,cloudflare[.]comgithub[.]com
Despacho de mando
El despachador de comandos enruta los comandos mediante hash DJB2. Ocho comandos en total:
| Hash | Mandar | Comportamiento |
|---|---|---|
0x04CF1142 | inject | Inyecta shellcode/DLL/EXE. Rutas por tipo: código de shell→ PhantomInject; DLL → ManualMap; EXE → DbgNexum. Los bypass HWBP de AMSI y WLDP se instalan en la primera llamada de inject (el ETW HWBP ya está en funcionamiento desde EvasionInit). |
0x7C95D91A | drop | Suelta el archivo en el disco y ejecuta. Soporta DLL, EXE, shellcode (inyección APC) y cargas útiles MSI. |
0x9A37F083 | screenshot | Captura GDI, escalado a 960px de ancho, subido como BMP. |
0x08DEDEF0 | keylog | Inicia o detiene el keylogger en línea. |
0x4EE251FF | uninstall | Limpieza y terminación en 6 pasos. |
0x65CCC50B | elevate | Bypass UAC mediante la técnica schuac (IElevatedFactoryServer::ServerCreateElevatedObject(CLSID_TaskScheduler)); registra una tarea elevada transitoria que relanza el implante. |
0xB3B5B880 | downgrade | SYSTEM → transición administrativa elevada. |
0x20CE3BC8 | (resetear automático) | Auto-terminación en cascada: NtTerminateProcess(-1, 0) llamada syscall directa primero; si eso no se resuelve, vuelve a ExitProcess(0). La persistencia resetear el implante en el siguiente tick de tarea programada. Operativamente equivalente a un resetear suave. |
El octavo manejador no tiene ningún registro de depuración que lo nombre. Se autotermina; La tarea programada reactiva el implante en el siguiente tick. La ausencia de andamiaje al estilo LLM (cadenas de depuración) hace que este sea uno de los pocos manejadores en el binario que parece ser agregado por el autor humano en lugar de generado por LLM.
Técnicas de inyección
PHANTOMPULSE incluye tres técnicas de inyección, una por tipo de carga útil. El comando inject C2 enruta shellcode a PhantomInject, DLLs a ManualMapy EXEs a DbgNexum.
Los bypass de punto de interrupción hardware AMSI/WLDP se instalan en la primera llamada inject , antes de que se ejecute cualquier inyector.
| Tipo de carga | Inyector | Estrategia |
|---|---|---|
| Shellcode | PhantomInject | Módulos entrando dbghelp.dll a través de SEC_IMAGE |
| EXE | DbgNexum | Debug-API máquina de estados |
| DLL | ManualMap | Mapeo manual completo de PE |
PhantomInject: módulo pisoteando dbghelp.dll
El pisoteamiento de módulos evita MEM_PRIVATE asignación mapeando una DLL legítima de Windows como SEC_IMAGE y sobrscribiendo .text:
-
Adquiere
SeDebugPrivilege(medianteOpenProcessToken/LookupPrivilegeValueW/AdjustTokenPrivileges), luego recorre la instantánea del proceso para uno de los siete candidatos a proceso host (coincidencia insensible a mayúsculas y minúsculas). Probado en orden de prioridad:sihost.exe,taskhostw.exe,backgroundTaskHost.exe,RuntimeBroker.exe,dllhost.exe,ctfmon.exe,explorer.exe. -
Abre
dbghelp.dllvíaNtOpenFile, creaSEC_IMAGEsección, y se mapea al objetivo medianteNtMapViewOfSection -
Analiza la copia local para
.textRVA y tamaño, y luego la libera -
Selecciona y suspende un hilo, captura el contexto
-
Construye un trampolín de 82 bytes de salvar, callar, restaurar
-
Escribe shellcode + trampolín en
.textde la DLL mapeada -
Invierte la protección a
PAGE_EXECUTE_READ -
Reapunta RIP al trampolín y reanuda el hilo
Para un escáner de memoria, el resultado parece un hilo ejecutar dentro de dbghelp.dlllegítimo, una región de imagen respaldada por archivo con la ruta de archivo correcta, nombre de sección y hash de primera página.
DbgNexum: API de depuración como controlador de ejecución
DbgNexum gestiona las cargas útiles EXE. En lugar de escribir código ejecutable en el destino desde el principio, emplea la API de depuración de Windows para ejecutar una excepción a la vez: una cadena ROP cuyos gadgets son APIs completas de Windows en el destino.
La técnica no es original de PHANTOMPULSE. Es una versión literal de dis0rder0x00/DbgNexum, una prueba de concepto pública publicada en GitHub el 04-01-2026. El operador mantenía el nombre de la técnica publicado ("DbgNexum") en las cadenas de depuración del implante sin cambios, y la máquina de estados interna es una coincidencia 1:1: la misma API de cebo, nombre de sección, cadena de gadgets y constantes. PHANTOMPULSE envuelve el núcleo x64 elevado con andamiaje operativo que el PoC no tiene: selección de proceso host (FindHostProcessEx), un respaldo que genera un nuevo SysWOW64\cmd.exe / rundll32.exe / notepad.exe, un bootstrap personalizado para carga de PE (para que pueda transportar EXE completos en lugar de shellcode en bruto) y una variante separada de arquitectura cruzada WoW64.
Para cargas útiles nativas x64, el implante pre-prepara el PE, el stub de arranque y la configuración del trampolín dentro de una sección de mapeo de archivos nombrada. El nombre de la sección es la cadena literal de dos bytes "MZ", el implante se conecta con DebugActiveProcess y crea un hilo remoto en FileTimeToSystemTime con un punto de interrupción hardware en DR0.
Cuando el cebo alcanza el punto de interrupción, una máquina de estados impulsa el objetivo a través de esta cadena de API:
- Redirigir
RIPaDbgBreakPoint+1con la bandera de trampa activada; la excepción resultante de un solo paso conecta el resto de la cadena. LocalAlloc(LMEM_ZEROINIT, 3), asigna el búfer de nombre de 3 bytes.memcpy(buf, kernel32_base, 2), copia"MZ"desde el encabezado DOS dekernel32.dllal búfer.memset(stack+40, 0, 8): cero un slot de stack arg.OpenFileMappingA(0x1F, FALSE, "MZ"), abre la sección preparada con acceso completo al mapeo de secciones.MapViewOfFile(...), mapearla en el objetivo.- Redirígete
RIPamapped_base + 0x400, el stub bootstrap. Esta es la única etapa registrada directamente:DbgNexumLoop64: stage 6 -> stub at %llx, base=%llx. (El PoC redirige amapped_base + 0para el shellcode en bruto; PHANTOMPULSE agrega el desplazamiento+0x400para aterrizar en su cargador PE personalizado.)
Cada transición intercepta el siguiente evento de depuración, restaura RSP, elimina la bandera de trampa, modifica RIP y el argumento se registra (RCX, RDX, R8, R9) para la siguiente llamada y continúa con el depurador. DR0 se reutiliza como punto de interrupción de hardware para ejecutar en cada dirección de retorno almacenada, por lo que no se necesitan parches en línea ni WriteProcessMemory contra el objetivo. Desde la perspectiva del núcleo, lo único que ocurría era un hilo dentro de kernel32.dll llamando a LocalAlloc, OpenFileMappingAy MapViewOfFile.
El camino de cross-architecture (PE32 desde un implante de 64 bits) es una variante solo PHANTOMPULSE que el PoC público no tiene. Toma un atajo: el implante recorre la PEB.Ldr del objetivo mediante NtReadVirtualMemory (usando ProcessWow64Information para elegir el diseño PEB de 32 o 64 bits) para encontrar una DLL con un punto de entrada llamable, y luego pre-mapea una sección que contiene un cargador de 32 bits y un trampolín en ambos procesos mediante NtCreateSection + NtMapViewOfSection. La redirección consta de solo dos etapas: cebo en RtlExitUserThread, luego un DbgBreakPointsaltos de un solo paso mediado RIP al trampolín. No hay cadena de API en este camino porque la sección ya está mapeada en ambos lados, así que no se necesitan OpenFileMappingAMapViewOfFile .
La selección de hosts cross-arch pasa por FindHostProcessEx, que excluye procesos críticos del sistema (csrss.exe, lsass.exe, smss.exe, winlogon.exe, services.exe, wininit.exe, svchost.exe, MsMpEng.exe) y vuelve a generar un nuevo SysWOW64\cmd.exe / rundll32.exe / notepad.exe si no se encuentra ningún host utilizable de WoW64.
ManualMap: mapador PE completo
ManualMap gestiona cargas útiles DLL con una implementación completa de mapeo manual de PE:
-
Valida la firma MZ/PE; rechaza PE32 en la ruta de host x64 (registro de depuración:
"PE32 DLL in x64 host is impossible") -
Asigna
SizeOfImageen el objetivo medianteNtAllocateVirtualMemory -
Copia cabeceras y secciones a un búfer de estacionamiento local
-
Aplica reubicaciones de base (
IMAGE_REL_BASED_DIR64,IMAGE_REL_BASED_HIGHLOW) -
Resuelve importaciones mediante
LoadLibraryA+GetProcAddress -
Borra cabeceras PE (ceros
SizeOfHeadersbytes) -
Escribe la imagen por etapas en la asignación remota
-
Protección de memoria por sección de conjuntos
-
Construye un trampolín de 137 bytes en una asignación remota separada de 0x2000 bytes (configurada a
PAGE_EXECUTE_READ):
El resumen completo del shellcode del trampolín contiene los bytes completos.
10. Secuestra un hilo mediante suspend / get-context / set-context
Escalada de privilegios
El comando elevate es un bypass UAC mediante la técnicaschuac (IElevatedFactoryServer::ServerCreateElevatedObject(CLSID_TaskScheduler)), publicada como número UACME #129 por zcgonvh, actualmente bajo el ID 74.
Mecanismo
MaintenanceUI.dllEl CMaintenanceUIVirtualFactory de 's (CLSID {A6BFEA43-501F-456F-A845-983D3AD7B8F0}) está registrado con una clave de registro Elevation , por lo que el sistema operativo entrega a los llamantes no administradores una instancia elevada. Su interfaz IElevatedFactoryServer expone ServerCreateElevatedObject(rclsid, riid, ppv), que el servidor elevado emplea para instanciar cualquier otro CLSID bajo su contexto elevado. PHANTOMPULSE lo alimenta CLSID_TaskScheduler, recibe un ITaskServiceelevado , y emplea ese servicio para registrar una tarea HighestAvailable-RunLevel que resetear el implante.
El mando elevate C2
Dentro ProcessCommands, el manejador de elevación:
- Construye la acción de tarea. El comando está
<system_dir>\rundll32.execon argumentos\"<deployed_dll>\",DllRegisterServer. El identificador de usuarioCOMPUTERNAME\USERNAMEdeGetEnvironmentVariableW. ! [Llamada de comando de elevación][/assets/imágenes/blockchain-c2-phantompulse-rat-sinkhole/image17.png] - Escribe el marcador de
.elevatecomo un solo byte ("1",0x31), no como parámetros codificados. La escritura pasa porNtCreateFile+NtWriteFilepara saltar los ganchos en modo usuario. El marcador es solo una señal de presencia; Los parámetros de elevación viajan dentro de la definición de tarea que el implante está a punto de registrar. - Descifra por XOR el Moniker de Elevación COM en tiempo de ejecución, 66 bytes de
.rdatase xredan contra0xE95CA237semilla , que decodifica aElevation:Administrator!new:{A6BFEA43-501F-456F-A845-983D3AD7B8F0}. - Llama
CoGetObject(moniker, &BIND_OPTS3{dwClassContext=CLSCTX_LOCAL_SERVER}, IID_IElevatedFactoryServer, &factory)para obtener unIElevatedFactoryServer*elevado, luegofactory->ServerCreateElevatedObject(CLSID_TaskScheduler, IID_ITaskService, &elevatedTaskService)para obtener unITaskService*elevado que herede esa elevación. - Registra una tarea transitoria
DotNetSvcElevateTaskenHighestAvailableRunLevel con la acción rundll32 arriba. - Elimina cualquier tarea persistente no elevada preexistente para que la persistencia antigua de baja IL no pueda acelerar el resetear elevado.
- Llama
ITaskService::Runa la tarea transitoria y la elimina inmediatamente después. Libera el mutex de instancia única y sale del implante de IL medio.
Reintento de respaldo mediante proxy rundll32
Si falla la cadena CoGetObject / RegisterTask , se activa un camino de respaldo. Un camino de inicio separado genera un rundll32.exe "<deployed_dll>",DllRegisterServer nuevo directamente a través de CreateProcessW, con reintentos (">>> .elevate redirect attempt %d"). Dentro de ese rundll32, el implante detecta isProxy=1, elevated=0 y vuelve a intentar la secuencia de schuac con tres variantes de registro (ELEVATED+INTERACTIVE+user, ELEVATED+INTERACTIVE, INTERACTIVE). En caso de éxito, la tarea elevada se activa y el relanzamiento elevado toman el control. Al agotar, el proxy registra ">>> Phase 1: all registration methods failed, cleaning marker" y sale.
Relanzamiento elevado de rundll32
Cuando la tarea transitoria se activa, svchost.exe (Schedule) se lanza rundll32.exe "<deployed_dll>",DllRegisterServer bajo un token de alta IL nuevo. La exportación DllRegisterServer del implante se realiza como entrada; al arrancar ve el marcador de .elevate y un token de alta inversión y enruta hacia la ruta elevada:
- Lee y elimina el marcador de
.elevate. - Reinstala la persistencia bajo contexto elevado, incluyendo la tarea de arranque
DotNetSvcCoreTaskbajo\Microsoft\Windows\NetFramework\, registrada conINTERACTIVE_TOKEN+BootTrigger, lo que requiere que el administrador se registre. - Continúa con la operación normal del implante como un servicio de alta IL.
Enrutamiento por estado de marcador
En cada startup, MainEntryLogic llama a GetFileAttributesW en el camino .elevate . Si vuelve INVALID_FILE_ATTRIBUTES, el implante se salta toda la lógica de elevación y arranca normalmente. Si el marcador existe, el implante recopila dos hechos más: si el proceso actual es un proxy de rundll32.exe/regsvr32.exe , y si el token está elevado, entonces rutas sobre la combinación:
| Marcador | Proxy | Elevado | Qué sucede |
|---|---|---|---|
| ausente | N/A | N/A | Arranque normal, sin enrutamiento especial |
| Presente | No | No | Invoca proxy rundll32 para volver a intentar la cadena de Schuac, y luego sal |
| Presente | Sí | No | reintentar a Schuac dentro del rundll32; Al agotar, eliminar marcador y salida |
| Presente | * | Sí | marcador de eliminación, reinstala la persistencia con la tarea de arranque, continúa con alta IL |
El contenido del archivo de marcadores nunca se lee, su sola presencia impulsa el enrutamiento.
Exploring Windows UAC Bypasses de Elastic Security Labs cubre directamente los patrones de detección para la clase IElevatedFactoryServer de bypass.
Persistencia
Tres tareas programadas
PHANTOMPULSE instala tres tareas programadas a través de la interfaz COM ITaskService , cada una ejecutando rundll32.exe "<stub_dll>",DllRegisterServer:
| Tarea | Disparador | Intervalo | RunLevel |
|---|---|---|---|
DotNetSvcUpdateTask | Inicio de sesión del usuario + Tiempo | 3 min | Estándar |
DotNetSvcCoreTask | Arranque + Tiempo | 15 min | Más AltoDisponible + Oculto |
DotNetSvcUserTask | Inicio de sesión de usuario | En el inicio de sesión | Estándar |
La tarea de arranque está bajo \Microsoft\Windows\NetFramework\ para integrar con tareas legítimas de mantenimiento de .NET. Su cuerpo completo en XML está incrustado en .rdata, no se construye en tiempo de ejecución. Las firmas en este blob literal son duraderas en todas las builds.
La instalación prueba múltiples variantes de RegisterTask de respaldo por tarea, combinando tipos de inicio de sesión INTERACTIVE_TOKEN y S4U con diferentes formatos de identificadores de usuario (COMPUTER\User, SID, nombre de usuario corto). El orden exacto de los intentos depende del contexto de privilegio del implante (SISTEMA, administrador o usuario estándar); los fallos pasan a la siguiente variante hasta que uno tiene éxito.
Caída de DLL de esbozo
El agente desplegado vive cifrado y comprimido dentro de la propia .rdatadel EXE. FilelessPersist lo descifra bajo demanda y escribe el resultado en disco mediante (NtCreateFile + NtWriteFile).
El descifrado consta de dos etapas:
- Decodifica XOR un blob contra una clave giratoria de 16 bytes en (
decoded[i] = blob[i] ^ key[i & 0xF], condecoded[0] = 0x1Ecomo primer byte codificado en fija que activa el encabezado de bloque LZNT1). RtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, ...)en el búfer decodificado, que es una DLL (svcagent.dll).
Rutas de caída en orden de prioridad, fallando por errores de acceso:
%ProgramData%\AssetMon\svcagent.dll(primaria)%APPDATA%\AssetMon\svcagent.dll%TEMP%\svcagent.dll- Una copia redundante
%ProgramData%"sleeper" en un camino separado
Los analistas pueden reproducir la DLL desplegada sin conexión leyendo las dos regiones anteriores del EXE, aplicando el bucle XOR y enviando el resultado a RtlDecompressBuffer (o a cualquier implementación de LZNT1), como se ve en la captura de pantalla de CyberChef a continuación.
Migración de carga lateral DLL
Un bloque dentro de SetupRegistryPE (registrado con los prefijos de cadena de depuración MigrateSideload / MigrateLegacySideloads ) enumera los procesos en ejecución y sus directorios ejecutables, buscando diagcore.dll. Cuando se encuentra, sobreescribir el archivo con el stub actual a través de CopyFileW.
Autorreparación
La auto-reparación se ejecuta en iteraciones 2 del bucle C2 y cada décima iteración posterior, bloqueada con una bandera de diferido-persistencia que queda limpia. El orden de comprobación:
- Primero comprobación de persistencia del registro.
CheckRegistryPersistenceCorre en la parte superior de la manzana. Si informa de que está mal, el implante vuelve a ejecutar inmediatamenteFilelessPersist(vuelve a descifrar y volver a colocar el DLL del stub) yInstallPersistence(vuelve a registrar los disparos de tarea). - Verificación de tareas.
SelfHealCheckTasksluego verifica las tres tareas de persistencia (DotNetSvcUpdateTask,DotNetSvcCoreTask,DotNetSvcUserTask) y reinstala las que falten. La comprobación de tareas de arranque está bloqueada en contexto SYSTEM o admin; Los que no tienen privilegios se lo saltan. - Actualización del inventario AV.
DetectInstalledAVse ejecuta al final para actualizar la lista de productos antivirus visible por el operador.
La barrera de privilegios es importante para el desahucio. Desde un contexto no elevado, la comprobación de la tarea de arranque se oye, por lo que la tarea de arranque no se inspecciona durante la limpieza. La expulsión total requiere eliminar las tres tareas más el artefacto del registro en una sola ventana desde un contexto elevado.
Más allá de la auto-curación basada en iteraciones, el implante lleva un mecanismo de persistencia diferida activado por una sola bandera. En las trayectorias de éxito de latido en C2Loop_Main, una vez que el contador de éxito de latidos supera a uno con la bandera colocada, el implante se repite FilelessPersist + InstallPersistence y elimina la bandera. Esto le da a PHANTOMPULSE un segundo camino de persistencia-reparación que se activa en un disparador diferente al de la auto-curación basada en iteraciones.
Colección
Keylogger en línea con monitorización en portapapeles
El keylogger funciona en línea en el bucle C2 sin hilo dedicado. Resuelve APIs de user32.dll en tiempo de ejecución:
| API | Objetivo |
|---|---|
GetAsyncKeyState | Estado clave de las encuestas |
GetForegroundWindow | Detección activa de ventanas |
GetWindowTextA | Captura de título de ventana |
MapVirtualKeyA / ToUnicode | Traducción de claves |
GetClipboardSequenceNumber | Detección de cambios en la tabla |
OpenClipboard / GetClipboardData | Lectura en portapapeles (CF_UNICODETEXT) |
El archivo de registro está cifrado por XOR con la semilla 0xE95CA237 . Las subidas solo envían el delta para evitar la retransmisión.
Captura de pantalla
Las capturas de pantalla emplean APIs GDI resueltas por hash. Si el ancho del escritorio supera 960 px, la imagen se reduce antes de subirla. El BMP en bruto está integrado en memoria y se sube con Content-Type: image/bmp. Activado bajo demanda por el comando screenshot C2 (hash 0x9A37F083).
Reconocimiento de sistemas
Datos de reconocimiento que recopila el implante:
| Datos | Fuente |
|---|---|
| CPU | Registro: ProcessorNameString |
| GPU | Adaptador de pantalla del registro DriverDesc (filtra "Microsoft Basic") |
| RAM | GlobalMemoryStatusEx |
| OS | RtlGetVersion con mapeo de compilación a versión (Win7 a Win11, Server 2008 a Server 2025) |
| Nombre de usuario | GetUserNameW con respaldo a LookupAccountSidW desde explorer.exe token |
| Privilegio | Tipo de elevación de la ficha: user, admin, admin_nouac, system |
| AV | DetectInstalledAV compara procesos en ejecución con una lista fija de ~25–30 nombres de proveedores de antivirus |
| Aplicaciones | DetectInstalledApps Consulta una lista seleccionada de 19 nombres de aplicaciones dirigidas |
| Estado del firewall | Las lecturas SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\{Domain,Standard,Public}Profile para registrar el estado habilitado por perfil |
| Servicios | Recuento de servicios en funcionamiento mediante enumeración de servicios |
| ID de máquina | DJB2(nombre del módulo) ^ volumen serial |
| IP pública | Cadena HTTPS multi-API |
La lista de detección AV es inusualmente amplia, abarcando productos estándar occidentales para consumidores como Defender, Norton, McAfee, Avast, AVG, Avira, Bitdefender, ESET, F-Secure, G Data, Kaspersky, Panda, Sophos, Trend Micro, VIPRE, Webroot, ZoneAlarm, Comodo, junto con proveedores EDR (CrowdStrike, SentinelOne, Cylance, Malwarebytes, HitmanPro). El implante también realiza sondeos para AhnLab V3 (surcoreano), Qihoo 360 / 360 Total Security y Tencent QQPC (chino), y K7 Computing (indio). La inclusión de la AV asiática es poco común entre los ladrones de mercancías dirigidos a Occidente y es coherente con un implante diseñado para víctimas en múltiples mercados regionales.
El implante también busca una lista seleccionada de 19 aplicaciones de alto valor por nombre y señala coincidencias en el latido (App detection: found %d apps):
| Categoría | Objetivos |
|---|---|
| Billeteras de criptomonedas | ledger, trezor, bitcoin-core, electrum, exodus, atomic, guarda |
| Mensajeros | telegram, discord, signal, viber, slack, whatsapp |
| Clientes de correo | thunderbird, outlook |
| Aplicación 2FA | authy |
| Transferencia de archivos / SSH | filezilla, winscp |
| Juegos | steam |
La función de detección (DetectInstalledApps) no escanea el registro ni enumera procesos. Expande tres raíces de variables de entorno (%LOCALAPPDATA%, %APPDATA%, %ProgramFiles(x86)%), concatena un sufijo de ruta relativa UTF-16 codificado de forma fija por aplicación (por ejemplo, \Telegram Desktop\, \Authy Desktop\, \Ledger Live\, \@trezor\trezor-suite\, \Steam\steam.exe), y llama a GetFileAttributesW en cada camino. Un retorno sin error significa que la app está instalada y el nombre se registra en el buffer de resultados de latido.
PHANTOMPULSE en sí no extrae datos de ninguno de estos. La lista es reconocimiento de objetivos para tareas posteriores. El operador ve en el instante qué aplicaciones de alto valor tiene una víctima determinada y decide qué carga útil especializada enviar a continuación mediante inject o drop.
No se identificó ninguna funcionalidad de cartera, navegador, mensajería o robo de credenciales en la muestra analizada; La lista de puntería es puramente una comprobación de presencia que alimenta el árbol de decisiones del operador.
Desinstalar
Una limpieza en 6 pasos, activada por el comando uninstall , por "status":"deleted" en una respuesta de latido o por una bandera de apagada en el registro:
| Paso | Acción |
|---|---|
| 1/6 | Escribe la bandera de apagada en HKCU + HKLM, procesa el anfitrión de apagar |
| 2/6 | Elimina todas las tareas 3 programadas mediante COM + CreateProcessW de respaldo |
| 3/6 | Eliminar registro heredado: valor NTLoad, COM secuestra claves, imprimir teclas del monitor |
| 4/6 | Eliminar DLLs de stub, registros de durmiente, blob de PE de registro, directorios de ProgramData |
| 5/6 | Eliminar la ruta de instalación y la ruta propia desde el disco |
| 6/6 | Terminar healthmon.exe residual y cualquier instancia rundll32.exe que aloje svcagent.dll |
El paso 3 revela las técnicas heredadas de persistencia: lógica de limpieza para secuestros de COM y teclas de monitor de impresión que esta compilación nunca instala.
Atribución
Las elecciones de técnica, segmentación e infraestructura de PHANTOMPULSE se alinean con los clústeres de intrusiones cripto-targeting alineados con la RPDC que incluyen Lazarus, BlueNoroff, UNC5342 (Contagious Interview) y APT38. Múltiples dimensiones independientes coinciden con los reportes recientes sobre esos grupos.
Señales alineadas con la información de la RPDC:
- El C2 resuelto por blockchain mediante campos de
inputde transacción coincide con el patrón de dead-drop-resolver que Mandiant atribui a UNC5342 (Entrevista Contagiosa) en DPRK adopta EtherHiding. Las especificaciones de PHANTOMPULSE (XOR por byte de cartera, Blockscout multi-cadena) no son una huella 1:1, pero la clase de técnica ahora está etiquetada con DPRK. - El conjunto de enumeración de carteras criptográficas de escritorio (
ledger,trezor,bitcoin-core,electrum,exodus,atomic,guarda) se ajusta estrechamente a la lista de segmentación RustDoor / Koi Stealer para macOS de la Unidad 42, que está atribuida a la RPDC. - Los implantes multiplataforma de Windows + macOS para el mismo perfil de víctima (la publicación anterior REF6598 documentó un hermano macOS con C2 a
0x666[.]infoy un respaldo de Telegram at[.]me/ax03bot) es una firma BlueNoroff. - La segmentación por Telegram y mensajería es específicamente una especialidad de BlueNoroff según la cobertura de Arctic Wolf BlueNoroff.
Búsqueda de nuevos dominios C2 a través de la firma de texto plano conocido de la cartera resolver
El esquema XOR empleado por el resolver blockchain filtra una firma estable de 2 bytes que los defensores pueden buscar contra toda la cadena, no solo contra una cartera.
Se combinan dos hechos: cada URL C2 comienza con ht (de http:// o https://), y la clave XOR es la dirección ASCII de la cartera textualmente, por lo que sus dos primeros bytes clave son siempre los caracteres literales 0 y x. Hacer XOR ht contra 0x produce \x58 \x0c. Cada campo de input cifrado producido por un resolvedor tipo PHANTOMPULSE, en cualquier cadena firmado por cualquier monedero relacionado, comienza con los cuatro caracteres hexadecimales 580c.
Esto convierte la búsqueda de monitorizar una cartera en barrier la cadena en busca de la firma. Los datos públicos de transacciones de Ethereum, Base y Optimism pueden consultar a través de BigQuery, Dune o nodos de archivo completos. Una consulta contra el conjunto público de datos de transacciones de Ethereum para valores de input que comienzan por 0x580c, con alcance a una ventana reciente de marca de tiempo de bloque, pone a la luz monederos resolvedores previamente desconocidos usados por la misma base de código. Cada coincidencia se valida decodificando con la dirección ASCII de la cartera del emisor como clave: una URL C2 real comienza con http tras la decodificación. La siguiente receta de CyberChef puede usar para descifrar la URL de C2.
SELECT
block_timestamp AS block_time,
from_address AS `from`,
to_address AS `to`,
input AS data
FROM `bigquery-public-data.crypto_ethereum.transactions`
WHERE block_timestamp >= '2026-04-01 00:00:00'
AND input LIKE '0x580c%'
ORDER BY block_timestamp DESC
LIMIT 10000;
CyberChef puede descifrar los datos de entrada para revelar el dominio, como se muestra en la captura de pantalla a continuación.
Conclusión
PHANTOMPULSE está diseñado a partir de componentes publicados: pisoteamiento de módulos, máquinas de estados de depuración API, mapeo manual, bypass AMSI/WLDP/ETW con punto de interrupción por hardware, persistencia de tareas programadas y C2 de blockchain. La combinación y el endurecimiento que lo une apuntan a una base de código madura en desarrollo activo. Las señales duraderas son de carácter conductual y están cubiertas por las protecciones conductuales de Elastic para REF6598.
PHANTOMPULSE y MITRE ATT&CK
Elastic usa el framework MITRE ATT&CK para documentar tácticas, técnicas y procedimientos comunes que las amenazas persistentes avanzadas emplean contra las redes empresariales.
Táctica
Las tácticas representan el porqué de una técnica o subtécnica. Es el objetivo táctico del adversario: la razón para realizar una acción.
- Acceso inicial
- Ejecución
- Persistencia
- Escalada de privilegios
- Evasión de defensa
- Acceso a credenciales
- Descubrimiento
- Colección
- Comando y control
- Exfiltración
Técnicas
Las técnicas representan cómo un adversario logra un objetivo táctico mediante la realización de una acción.
- Phishing: Spearphishing a través de un servicio
- Intérprete de comandos y scripting: PowerShell
- Inyección de proceso
- Inyección de procesos: Inyección DLL
- Ejecución de Proxy Binario del Sistema: msiexec
- Ejecución de proxy binario del sistema: Rundll32
- Tarea/Trabajo programado: Tarea programada
- Ejecución de arranque o inicio automático de sesión
- Modificar el registro
- Debilitar defensas: deshabilitar o modificar herramientas
- Eliminación de indicadores: Eliminación de archivos
- Detección de información del sistema
- Descubrimiento del Propietario del Sistema/Usuario
- Descubrimiento de procesos
- Descubrimiento de software: Descubrimiento de software de seguridad
- Captura de entrada: registro de teclas
- Datos del portapapeles
- Captura de pantalla
- Exfiltración a través del canal C2
- Protocolo de Capa de Aplicación: Protocolos Sitio web
- Servicio sitio web
- Canal encriptado
- Información o archivos ofuscados
- Desofuscar/decodificar archivos o información
- Manipulación de tokens de acceso
- Mecanismo de control de elevación de abuso: omitir el control de cuentas de usuario
- API nativa
- Evasión de virtualización/sandbox: evasión basada en el tiempo
- Flujo de ejecución de secuestro: carga lateral de DLL
- Carga de código reflectante
Remediación
YARA
Elastic Security creó reglas YARA para identificar esta actividad.
Observaciones
| Observable | Tipo | Nombre | Referencia |
|---|---|---|---|
33dacf9f854f636216e5062ca252df8e5bed652efd78b86512f5b868b11ee70f | SHA-256 | RATONA PULSO FANTASMA | Final payload |
70bbb38b70fd836d66e8166ec27be9aa8535b3876596fc80c45e3de4ce327980 | SHA-256 | syncobs.exe | Cargador PHANTOMPULL |
def66275fa3baffb16e6e4ae0297861d9790ae7161fbc271a2ba05d121f13c70 | SHA-256 | Haz la baliza | GTESTIC_WIN registro |
panel.fefea22134[.]net | dominio | Panel C2 | PHANTOMPULSE con respaldo codificado directamente |
fea22134[.]net | dominio | C2 domain | Cifrado en binario |
195.3.222[.]251 | IPv4-ADDR | Servidor de etapas | Entrega PowerShell/cargador |
0xc117688c530b660e15085bF3A2B664117d8672aA | Cartera de criptomonedas | Cartera Blockchain C2 | ETH/Base/Optimismo |
0x38796B8479fDAE0A72e5E7e326c87a637D0Cbc0E | Cartera de criptomonedas | Cartera de financiación | Financiación de la resolución C2 |
eth.blockscout[.]com | dominio | Proveedor de blockchain | Resolución de URL C2 |
base.blockscout[.]com | dominio | Proveedor de blockchain | Resolución de URL C2 |
optimism.blockscout[.]com | dominio | Proveedor de blockchain | Resolución de URL C2 |
hVNBUORXNiFLhYYh | mutex | Instancia única | Descifrado por XOR |
svcagent.dll | Nombre del archivo | DLL de esbozo | Carga útil de persistencia |
AssetMon | Directorio | Directorio de DLL de incompleto | %ProgramData% o%APPDATA% |
healthmon.exe | Nombre del archivo | Dropper | Nombre original del ejecutable |
diagcore.dll | Nombre del archivo | DLL de carga lateral heredada | Migrado por MigrateSideload |
.elevate | Nombre del archivo | Marcador de elevación | Rutas para el relanzamiento elevado |
DotNetSvcUpdateTask | Tarea programada | Persistencia primaria | Intervalo de 3 minutos |
DotNetSvcCoreTask | Tarea programada | Persistencia del SISTEMA | 15 minutos, oculto |
DotNetSvcUserTask | Tarea programada | Persistencia del usuario | Disparador de inicio de sesión |
EdgeWebViewUpdateTask | Tarea programada | Tarea de legado | Limpiado durante la desinstalación |
\Microsoft\Windows\NetFramework\DotNetSvcCoreTask | Task-uri | Ruta de arranque de tarea | Tarea programada oculta |
Elevation:Administrator!new:{A6BFEA43-501F-456F-A845-983D3AD7B8F0} | com-moniker | Circunvalación UAC | Servicio ITaskElevado |
0x666[.]info | dominio | macOS C2 | Dropper de macOS |
t[.]me/ax03bot | URL | Respaldo de Telegram | Dead-drop en macOS C2 |
thoroughly-publisher-troy-clara[.]trycloudflare[.]com | dominio | Prior C2 | Túnel Cloudflare |
Referencias
Reportes y kits de herramientas previos referenciados en este análisis:
- Phantom en la bóveda: Obsidiana abusada para entregar PhantomPulse RAT
- Blockscout Ethereum Explorer
- La RPDC adopta el EtherHiding
- Entrevista contagiosa / objetivo de reclutadores falsos a desarrolladores del sector cripto
- RustDoor y Koi Stealer para macOS
- Evolución de Cola de Castora y Galleta de Nutria
- Prueba de concepto DbgNexum
- Número #129 de la UACME: circunvalación UAC de Schuac
- Explorando los Bypasses UAC de Windows
- Bypass AMSI con parcheo de memoria