Seguridad

Descubriendo SC: la amenaza persistente en WordPress para sysadmins Linux

TL;DR — Lo que vas a tener al final

  • Tiempo de setup: 30 minutos a 2 horas dependiendo de la complejidad del entorno.
  • Requisitos: Acceso root, Linux moderno, conexión a internet para descargar dependencias.
  • Resultado: Servicio funcional y estable, documentado paso a paso.
  • Troubleshooting: Logs estándar en /var/log/, comandos de verificación al final de cada sección.

Qué es SC y por qué importa a un sysadmin Linux

El 30 de septiembre de 2026, los analistas de Sucuri publicaron el desglose de un backdoor de WordPress al que bautizaron como SC, por los marcadores SC_ que aparecen en el código inyectado. Lo que documentaron no es una variante más del malware de siempre: es una malla auto-curativa (self-healing mesh) que vive en al menos ocho ubicaciones a la vez y en la que cada componente puede reconstruir a todos los demás.

Si administras un servidor con WordPress, ya sea un blog personal, una intranet pequeña o un sitio de e-commerce sobre LAMP, esta clase de infección cambia las reglas. Limpiar los archivos visibles no alcanza. Lo que vuelve a aparecer después del borrado no es el mismo archivo: es una copia escrita por otro componente que sigue vivo. La próxima vez que el lector del blog o el carrito de WooCommerce devuelva un 200, la infección ya está restaurada.

Lo que hace a SC diferente es la combinación de tres elementos:

  • Persistencia fuera del filesystem. Una copia del payload vive en una fila de la tabla wp_options y, en servidores con soporte, en un segmento de memoria compartida System V. El primer request que pasa por el drop-in correcto reescribe todo el árbol de archivos.
  • Redundancia deliberada. El mismo plugin falso está en wp-content/plugins y en wp-content/mu-plugins; los dos drop-ins de carga temprana (db.php y advanced-cache.php), el bloque inyectado en functions.php del tema activo, y un loader disparado por auto_prepend_file mantienen copias y reglas de reinyección.
  • Canal de mando sobre infraestructura legítima. En vez de hablar con un dominio fijo, el payload consulta un smart contract en Ethereum a través de unos veinte gateways RPC públicos. Bloquear el dominio visto en el tráfico no interrumpe la comunicación.

El caso reportado por Sucuri no determina el vector inicial ni cuántas instalaciones están afectadas, pero la familia SC, según el analista Gabriel Barbosa, ilustra un patrón que los sysadmins Linux no deben subestimar: una infección de WordPress ya no es un problema de archivos, es un problema de sistema distribuido pequeño.

Las ocho ubicaciones del payload

Sucuri recuperó cada componente del backdoor en un compromiso distinto. El siguiente orden refleja el flujo de ejecución durante un request típico en WordPress, de más temprano a más tarde.

# Ubicación Tipo Qué hace Cuándo se carga
1 .user.ini, php.ini o .htaccess Config Define auto_prepend_file apuntando al loader #2. PHP lo cachea hasta 300 s. Antes de cada request PHP en el árbol
2 wp-content/c1b12371.php * Shim visible Incluye el loader oculto #3 si existe. Si no, no hace nada: silencio cómplice. Prepend del #1
3 wp-content/.c1b12371.php * String-table loader Reconstruye el plugin falso desde copias en plugins, cache, un ZIP o un segmento shm. Define la constante SC_AUTO_PREPEND. Inclusión por el shim
4 wp-content/db.php Drop-in bootstrap Lleva el payload completo como blob gzip+base64. Lo descodifica y reescribe el plugin cuando desaparece. Bootstrap temprano de WordPress
5 advanced-cache.php Drop-in aún más temprano Busca el payload en cinco lugares independientes (mu-plugin, plugin, shm, ZIP, opción de la base de datos) y lo inyecta en plugins_loaded. Bootstrap si WP_CACHE está activo
6 wp-content/themes/<tema-activo>/functions.php Bloque inyectado Bloque acotado entre marcadores al final de un functions.php legítimo. Es el gemelo de db.php: reescribe el plugin cuando falta. Casi cada request
7 wp-content/mu-plugins/hyper-engine-kit.php * Payload backdoor Se filtra de la lista de plugins y de los chequeos de update. Habla con el C2, escanea el sitio, crea admin oculto, regenera la malla. Autoload de mu-plugins
8 wp-content/plugins/hyper-engine-kit/hyper-engine-kit.php * Copia redundante Idéntico al #7, con una página de ajustes creíble para parecer un plugin de caché. Autoload normal de plugins

* Los nombres de archivo varían entre sitios. c1b12371 y hyper-engine-kit son los observados en el caso de Sucuri.

Qué hace el backdoor, paso a paso

Una vez que el payload está cargado, ejecuta cuatro acciones que conviene entender porque cada una tiene un indicador que puedes buscar en logs y tablas.

Se esconde

Filtra la lista de plugins, el transient de actualizaciones y las vistas de plugins del sitio y la red para borrar su propia entrada. Emite además JavaScript en el admin que limpia la fila de la tabla como red de seguridad. El resultado: wp plugin list puede no mostrarlo, y un escaneo superficial va a pasarlo por alto.

Habla con el C2 por Ethereum

El payload lleva una lista de unos veinte gateways RPC públicos de Ethereum y selectores de métodos de smart contracts. En vez de consultar un dominio fijo, los consulta a través de servicios legítimos, lo que hace muy difícil bloquearlo solo por DNS o IP. Los selectores de método leen instrucciones del contrato; el reply puede ser:

  • JavaScript para inyectar en el front-end (skimmers de checkout en tiendas WooCommerce).
  • Código PHP para instalar.
  • Listas de plugins de seguridad para desactivar y borrar, posiblemente reasignando o elevando otra cuenta antes.

Fingerprint, beacon y reescritura

Recolecta URL y host, versiones de WordPress y plugins, hashes de rutas, temas activos, lista de mu-plugins y tokens de sesión de administradores. Cifra el bundle y lo postea al endpoint resuelto. Con la respuesta actualiza la persistencia: reescribe db.php, advanced-cache.php, el bloque en functions.php, el loader y su .htaccess y .user.ini, el ZIP de restore, el segmento de memoria compartida y la fila de la base de datos. Abre incluso una conexión cruda a la base para insertar la opción de payload, sin pasar por la API de WordPress.

Crea un administrador oculto

O adopta uno existente o genera uno nuevo escribiendo directo en wp_users y wp_usermeta, con capacidades bajo la meta key por defecto. Luego lo oculta de la lista de usuarios, del conteo y de las vistas por rol, y falsifica cookies válidas de autenticación para esa cuenta. El operador entra sin contraseña. Variantes relacionadas usan triggers en MySQL que recrean al admin en cualquier INSERT, así que borrar la cuenta no alcanza hasta que se quite el trigger.

Dónde vive la persistencia fuera de disco

El error más común de cualquier sysadmin que se enfrenta a una reinfección es mirar solo /var/www. SC almacena el payload en tres lugares que sobreviven al borrado de archivos.

Ubicación Por qué sobrevive Cómo se limpia
Fila de wp_options con nombre aleatorio El blob gzip+base64 se lee por conexión directa. La próxima request a advanced-cache.php lo reescribe a disco. wp db query "DELETE FROM wp_options WHERE option_name LIKE 'sc_%'" + revisar filas con LENGTH(option_value) > 10000
Segmento de memoria compartida System V Está en RAM del servidor, no en disco. En hosting compartido puede pertenecer a otra cuenta del mismo servidor. ipcrm -M <key> como root, o pedir al proveedor. Inofensivo si los drop-ins que lo leen ya están limpios.
Cron hooks de WordPress y tareas del cron del sistema Se reejecutan en el siguiente wp-cron.php aunque el sitio esté sin tráfico. wp cron event list --allow-root + wp cron event delete <hook> para los hooks sospechosos

Las variantes de SC vistas por Sucuri además usan triggers de MySQL para recrear al administrador en cualquier INSERT a la tabla wp_users. Esto es crítico: si limpiás archivos y la base, pero queda el trigger, el próximo registro vuelve a meter al admin escondido.

# Auditoría de triggers sospechosos
mysql -u root -p wordpress_db -e 
  "SELECT TRIGGER_NAME, EVENT_MANIPULATION, EVENT_OBJECT_TABLE, ACTION_STATEMENT
   FROM information_schema.TRIGGERS
   WHERE TRIGGER_SCHEMA = DATABASE();"

Indicadores de compromiso que puedes buscar hoy

Antes de tocar nada, un buen primer barrido es buscar los marcadores de SC en las rutas que menciona Sucuri. Estos comandos asumen el path estándar de Debian/Ubuntu, ajustá DOCROOT si usas otro layout.

DOCROOT=/var/www/html
# 1. Buscar prepends sospechosos
grep -rE 'auto_prepend_files*=' "$DOCROOT" --include='.user.ini' --include='php.ini' --include='.htaccess' 2>/dev/null
# 2. Detectar el shim y el loader oculto
ls -la "$DOCROOT/wp-content/".*.php "$DOCROOT/wp-content/"*.php 2>/dev/null | head -20
# 3. Marcadores SC_ en archivos PHP del sitio
grep -rlE 'SC_(AUTO_PREPEND|REBUILD|MARKER)' "$DOCROOT/wp-content" 2>/dev/null
# 4. Drop-ins modificados
ls -la "$DOCROOT/wp-content/db.php" "$DOCROOT/wp-content/advanced-cache.php" 2>/dev/null
# 5. Bloque inyectado en el tema activo
find "$DOCROOT/wp-content/themes" -maxdepth 2 -name functions.php 
  -exec grep -lE 'SC_AUTO_PREPEND|/* SC_BEGIN' {} ;
# 6. Plugin fantasma en mu-plugins
ls -la "$DOCROOT/wp-content/mu-plugins/" 2>/dev/null

Y en la base de datos, los indicadores son:

  • Filas en wp_options con nombre aleatorio y LENGTH(option_value) > 10000, especialmente si la columna empieza con la firma gzip x1fx8bx08 en base64.
  • Prefijo sc_ en option_name y transients.
  • Triggers en information_schema.TRIGGERS que apuntan a wp_users o wp_usermeta.
  • Un administrador que no aparece en wp-admin/users.php pero existe en wp_users con wp_capabilities pobladas.
# Detectar opciones sospechosas por tamaño y firma
wp db query "SELECT option_name, LENGTH(option_value) AS len
  FROM wp_options
  WHERE LENGTH(option_value) > 10000
  ORDER BY len DESC LIMIT 20;" --allow-root
# Buscar prefijos sc_ en options y transients
wp db query "SELECT option_name FROM wp_options
  WHERE option_name LIKE 'sc_%' OR option_name LIKE '%_sc_%' LIMIT 20;" --allow-root
# Listar cron hooks de WP para ver reescritores
wp cron event list --allow-root | grep -iE 'sc_|rebuild|persist'

Orden correcto de limpieza (no, no es borrar archivos)

Si borrás archivos en el orden equivocado, el siguiente request los restaura. El método que documenta Sucuri sigue la idea de cortar la ejecución primero, limpiar fuera de disco, después limpiar disco, todo en una sola pasada. El detalle está en el timing: PHP cachea auto_prepend_file hasta 300 segundos, así que si vaciás el target del prepend antes de quitar la directiva, el sitio se cae. Si quitás la directiva antes de vaciar el target, el shim sigue activo.

  1. Neutralizar el prepend. Reemplazar el contenido del archivo target con un stub inerte, después quitar la directiva de .user.ini, php.ini y .htaccess.
  2. Limpiar persistencia fuera de disco. Borrar la fila de wp_options con el payload, purgar el segmento de shm con ipcrm -M (con ayuda del proveedor en hosting compartido), y eliminar los hooks de cron y los triggers de MySQL.
  3. Eliminar el administrador oculto. Borrar la cuenta cuya meta key de capabilities está poblada y limpiar la opción huérfana que apunta a su ID.
  4. Remover los archivos en una pasada. Borrar los loaders y el shim, las dos copias del plugin falso (mu-plugins y plugins), el ZIP de restore, y los drop-ins maliciosos. En el functions.php del tema, recortar solo el bloque entre los marcadores, dejando intacto el resto del archivo.
  5. Rotar credenciales y cerrar la entrada. Cambiar todas las contraseñas que pudieron haber sido expuestas, forzar logout de todas las sesiones, actualizar core, plugins y tema, y revisar el vector inicial: plugin vulnerable, tema nulled, credencial filtrada, backup expuesto.

El orden importa tanto como los comandos. Cualquier defensa que elimine un componente dejando vivo otro del que depende es un auto-ataque: le entrega al malware la excusa para regenerarse.

Qué cambia esto para tu WordPress en producción

Si tu sitio es un blog personal sobre LAMP en un VPS pequeño, el riesgo principal no es SC en sí: es que el patrón que documenta Sucuri (persistencia fuera de disco + C2 sobre infraestructura legítima + múltiples rutas de reinyección) se vuelva la norma. La conclusión operativa no es agregar otro plugin de seguridad, es revisar tres cosas que muchos sysadmins dan por hechas.

Auditoría periódica de wp_options, cron y triggers

El detalle clave de SC es que la persistencia vive en la base de datos y en tareas programadas, no en archivos. Una auditoría mensual corta es más útil que un escáner de malware diario: revisa opciones grandes, cron hooks y triggers con un comando como el del indicador 6 anterior. Es trabajo de cinco minutos que evita una limpieza de seis horas.

WAF con virtual patching

El vector inicial de este tipo de infecciones suele ser un plugin o tema con CVE conocida y sin parchar. Un WAF con virtual patching (Cloudflare, Sucuri, Wordfence con la regla correcta) bloquea el exploit antes de llegar a la aplicación. La diferencia entre un WAF activo y uno apagado es la diferencia entre un escaneo de reconocimiento en logs y un backdoor publicado en disco.

Visibilidad de salidas a gateways públicos

El truco del C2 sobre gateways RPC de Ethereum no es exclusivo de SC. Cualquier backdoor moderno habla con servicios legítimos abuseados como transporte: Cloudflare Workers, Netlify Edge, Vercel, IPFS gateways, WebDAV públicos. Si tu firewall solo bloquea destinos sospechosos, te lo vas a perder. Una regla que marque como interesante cualquier request saliente del usuario www-data hacia categorías como cryptocurrency, RPC o CDN reduce el ruido y deja ver el beacon cuando aparece.

SC es un caso particular, pero la lección es general. Un WordPress comprometido en 2026 ya no se parece a un archivo PHP malicioso suelto en /uploads. Se parece más a un servicio distribuido pequeño, con base de datos, memoria, tareas programadas y un canal de mando escondido entre servicios legítimos. La defensa tiene que dejar de mirar solo wp-content y empezar a mirar la base, el cron y el firewall de salida.

Resumen accionable para sysadmins

  • Buscá los marcadores SC_ y los nombres de archivo c1b12371 / hyper-engine-kit en wp-content; si aparecen, asumí compromiso y entrá al orden de limpieza, no al de “borrar lo obvio”.
  • Auditoría mensual de wp_options por filas grandes con firma gzip+base64, de cron hooks y de triggers en information_schema.TRIGGERS.
  • WAF con virtual patching activo, no solo modo monitoreo. Un WAF en modo log es un logger caro.
  • Reglas de firewall de salida que registren (no necesariamente bloqueen) tráfico del usuario del web server hacia gateways RPC, IPFS, Cloudflare Workers y similares.
  • Si ya estás limpio, mantenete limpio: core, plugins y tema al día, backups probados y rotación de claves en cada incidente.

Preguntas frecuentes

¿Por qué Descubriendo SC: la amenaza persistente en WordPress para sysadmins Linux es relevante para sysadmins Linux?

Forma parte del flujo diario de administración. Los conceptos explicados se aplican directamente a servidores en producción y resuelven problemas reales que enfrentan sysadmins hispanohablantes.

¿Qué necesito para empezar con Descubriendo SC: la amenaza persistente?

Distribución Linux actualizada (Debian, Ubuntu, RHEL, Fedora o Arch), acceso root, y conexión a internet. Para producción: entorno de staging separado antes de aplicar cambios.

¿Cuáles son los errores más comunes con Descubriendo SC: la amenaza persistente?

Los tres más frecuentes: (1) saltar la lectura de logs, (2) aplicar cambios directos en producción sin probar, (3) olvidar permisos y ownership. La documentación y un plan de rollback siempre.

¿Cuándo usar Descubriendo SC: la amenaza persistente y cuándo una alternativa?

Esta solución es ideal para el caso descrito. Alternativas como Docker, Ansible o configuración manual pueden ser mejores según contexto: portabilidad, escala y reproducibilidad son los factores clave.

¿Cómo migro desde una configuración previa a Descubriendo SC: la amenaza persistente?

Documentar el estado actual, probar la nueva configuración en staging, validar funcionalmente, y aplicar en producción con rollback plan listo. Los posts de SoyLinux incluyen troubleshooting para los problemas más comunes.

Lee también

Alfonso Moreno | Sysadmin Senior

Soy Alfonso, sysadmin senior con RHCE y más de 10 años administrando sistemas Linux para empresas y proyectos personales. Me especializo en infraestructura, redes, virtualización, monitoring, automation y self-hosting. Sobre SoyLinux.com SoyLinux.com es un blog técnico en español sobre Linux, software libre y self-hosting. Lo mantengo en mi tiempo libre. Áreas de expertise - Linux server administration: RHEL, CentOS, Rocky, Alma, Fedora, Debian, Ubuntu - Network services: Postfix, BIND, Samba, NFS, Squid - Virtualización y containers: KVM, Proxmox, Docker, Podman - Monitoring: Prometheus, Grafana, Zabbix - Automation: Ansible, Bash scripting - Self-hosting: Vaultwarden, Nextcloud, Jellyfin, Immich, Homelab Contacto - Email: [email protected]

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *