malware · cryptomining · rootkit · linux · kernel · monero · privilege-escalation · cve-2026-31431 · container-escape

Rootpacket: un kit de criptojacking para Linux que se esconde en el kernel

Kinryū Labs analizó Rootpacket, un kit de criptojacking para Linux que incluye un rootkit de kernel para falsear el uso de CPU y memoria, escala a root mediante CVE-2026-31431 (un fallo de caché de páginas de AF_ALG que además se escapa de los contenedores hacia el host), se hace pasar por un driver de Intel y desactiva los mismos servicios expuestos que usan los mineros rivales para entrar.

Por Davis Zheng·

CVE
CVE-2026-31431
CVSS
7.8 (CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

TLP:CLEAR. Autorizado para publicación. Esto es solo análisis estático: no se ejecutó ninguna muestra, y cada hallazgo proviene de extracción de cadenas, desensamblado y revisión de código fuente. La cartera de Monero, el pool y la infraestructura del atacante se publican como indicadores defensivos.

Resumen ejecutivo

  • ~45%CPU que muestra top mientras corre cerca del 100%
  • 3mecanismos de persistencia
  • 7.8CVSS, CVE-2026-31431 (LPE de page-cache AF_ALG)
  • hostroot desde un contenedor sin privilegios

Rootpacket es un kit de criptojacking de múltiples componentes para Linux. Agrupa un rootkit a nivel de kernel para el sigilo, un exploit de escalada de privilegios para CVE-2026-31431 en la interfaz criptográfica AF_ALG de Linux, un minero de Monero XMRig 6.26.0 empaquetado con UPX y renombrado a xrandom, y un script de eliminación de competidores. El código está escrito en gran parte en turco (nombres de variables, comentarios, cadenas de estado), lo que apunta a un operador turcohablante.

El kit corre en uno de dos modos. En modo root carga un rootkit de módulo de kernel cargable (LKM) disfrazado de intel_uncore_freq_aux, lo instala mediante DKMS para que sobreviva a las actualizaciones de kernel, registra un servicio systemd y limpia la máquina de rivales. Cuando no consigue root, recurre a un modo de espacio de usuario que persiste mediante crontab y ejecuta el minero como demonio. El minero se conecta a pool.supportxmr.com:443 por stratum+ssl y mina Monero con RandomX.

El componente en el que vale la pena detenerse es el rootkit. Mientras el minero clava el procesador cerca del 100 por cien, el rootkit reescribe /proc/stat para que top y htop reporten un tranquilo 40 a 50 por cien, y oscila esa cifra usando jiffies para que la carga parezca real en vez de quedarse clavada en un valor constante. Hace lo mismo con /proc/meminfo, y filtra los listados de directorios para ocultar sus propios procesos y archivos.

Valoraciones clave

  • El objetivo es el criptojacking (confianza alta). El kit incluye XMRig 6.26.0, una cartera de Monero fija y una configuración de minería de pool.supportxmr.com, con la donación al desarrollador de XMRig desactivada para que todas las ganancias vayan al operador.
  • La escalada de privilegios es CVE-2026-31431 (“Copy Fail”), una escritura determinista en la caché de páginas en la ruta algif_aead de AF_ALG de Linux (CVSS 7.8, divulgada en abril de 2026). Como la caché de páginas se comparte en todo el host, la misma escritura se escapa de un contenedor para conseguir root en el host, así que un contenedor infectado es un host comprometido (confianza alta).
  • El operador está muy por encima de la típica cuadrilla de soltar-y-minar (confianza alta). Un rootkit LKM a medida con hooks ftrace, persistencia DKMS que se reconstruye sola para nuevos kernels, un exploit de caché de páginas funcional para CVE-2026-31431 y persistencia en capas systemd/DKMS/cron son un nivel de ingeniería que la mayoría de los criptojackers nunca alcanza.
  • El operador es probablemente turcohablante (confianza media). Nombres de variables, comentarios y mensajes de estado en turco como ROOT ele gecirildi! recorren todo el kit.
  • Rootpacket está hecho para poseer un host en exclusiva y conservarlo. Su killservice.sh elimina mineros rivales y luego desactiva los servicios expuestos al exterior que los criptojackers usan para el acceso inicial, incluida la Docker API en 2375/2376, el mismo vector que documentamos en nuestro artículo sobre RedTail. Estas cuadrillas pelean por las mismas máquinas mal configuradas.

Arquitectura del kit

Rootpacket es un dropper modular. Las piezas:

setup.sh         Punto de entrada. Comprueba el nivel de privilegios, elige un modo de despliegue.
getroot          Escalada de privilegios. Explota CVE-2026-31431 (AF_ALG) para root local.
xrandom          XMRig 6.26.0 empaquetado con UPX, renombrado para esquivar la detección por nombre.
kernel/
  stealth.c      Rootkit LKM, compilado vía DKMS, disfrazado de driver de Intel.
  install.sh     Motor de persistencia DKMS.
killservice.sh   Eliminación de competidores y "endurecimiento".
rootpacket.tar.gz  Una copia interna de todo el kit, empaquetada para su redistribución.

Modo root. setup.sh ejecuta getroot si aún no es root, copia xrandom a /opt/kernel-kd/, crea un servicio systemd, ejecuta kernel/install.sh para compilar y cargar el rootkit mediante DKMS, ejecuta killservice.sh para despejar la competencia, e inicia el minero como un servicio persistente.

Recurso de espacio de usuario. Cuando root está fuera de alcance, setup.sh copia xrandom a ~/.xrandom/, escribe un lanzador con un bloqueo de PID, instala una entrada crontab que se dispara al reiniciar y cada minuto, y lanza el minero con setsid para que sobreviva a la shell padre.

CaracterísticaModo rootModo espacio de usuario
Ubicación del minero/opt/kernel-kd/xrandom~/.xrandom/xrandom
Persistenciasystemd (kernel-kd.service)crontab (@reboot + */1 * * * *)
RootkitSí (LKM vía DKMS)No
Matar competidoresSí (killservice.sh)No
Se ejecuta comoroot (systemd)usuario actual (demonio setsid)

getroot: CVE-2026-31431, root por corrupción de la caché de páginas

getroot es un binario ELF64 x86-64 enlazado estáticamente y sin strip, construido a partir de getroot.c. Explota CVE-2026-31431 (“Copy Fail”), un fallo lógico en la interfaz algif_aead de AF_ALG del kernel de Linux divulgado el 29 de abril de 2026 (CVSS 7.8). El bug concede una escritura determinista de 4 bytes controlada por el atacante en la caché de páginas del kernel, y getroot la usa para parchear un binario SUID en memoria y salir como root.

PropiedadValor
TipoELF 64-bit LSB executable, x86-64, enlazado estáticamente, sin strip
CVECVE-2026-31431 “Copy Fail” (CVSS 7.8, AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
SubsistemaAF_ALG algif_aead, plantilla AEAD authencesn(hmac(sha256),cbc(aes))
AfectadoLinux 4.14 a 6.19.11 (el fallo llegó en 2017, commit 72548b093ee3); corregido en 6.18.22, 6.19.12, 7.0+
Objetivo/usr/bin/su — su .text en memoria se parchea en la caché de páginas
FiabilidadDeterminista, sin condición de carrera
Uso / recurso./getroot <cmd> [args...]; si el exploit no acierta, ejecuta el comando con los privilegios actuales de todos modos

El mecanismo. Una optimización in situ de 2017 en el código AEAD dejó las páginas de caché que se hicieron splice situadas tanto en la scatterlist de origen como en la de destino. Cuando la plantilla authencesn escribe su valor temporal ESN de 4 bytes en el desplazamiento elegido por el atacante assoclen + cryptlen, esa escritura aterriza dentro de la página de caché de un archivo legible por el usuario. La comprobación HMAC entonces falla y recvmsg() devuelve EBADMSG, pero el kernel nunca revierte la escritura. getroot analiza las cabeceras ELF de /usr/bin/su para calcular el desplazamiento de archivo de su punto de entrada, luego repite splicesendmsg (llevando los 4 bytes a escribir en el AAD) → recvmsg, una vez por cada trozo de 4 bytes de shellcode, parcheando /usr/bin/su en la caché de páginas. Después hace execve de /usr/bin/su: el kernel carga la página ahora corrupta, el shellcode corre como SUID-root, y getroot confirma getuid() == 0 antes de ejecutar el comando del operador (imprimiendo el turco [+] ROOT ele gecirildi!). El archivo en disco nunca se toca, así que la monitorización de integridad de archivos no ve nada.

Escape de contenedor al host. La caché de páginas de Linux es global del host; los contenedores no tienen la suya propia. Un proceso dentro de un contenedor sin privilegios que hace splice del /usr/bin/su del host corrompe la copia en caché del host, así que el execve da root en el host, no solo en el contenedor. Un contenedor infectado es, por tanto, un host comprometido, y setup.sh pasa a cargar el rootkit de kernel en el host. Detener y eliminar el contenedor no basta; hay que reconstruir el host.

Ejecutamos getroot una vez en una VM aislada (Kali, kernel 6.6.15). Ejecutó toda la secuencia AF_ALG pero no obtuvo root en esa compilación y recurrió a ejecutar el comando sin privilegios, lo que encaja con un exploit que apunta a disposiciones de kernel concretas. No ejecutamos el minero.

xrandom: el minero

xrandom es una copia renombrada y empaquetada con UPX de XMRig 6.26.0, el minero de Monero de código abierto.

PropiedadValor
Identidad realXMRig 6.26.0
EmpaquetadoUPX 4.2.4 (2,8 MB empaquetado, 10,1 MB desempaquetado)
AlgoritmoRandomX (rx/0)
Poolpool.supportxmr.com:443 por stratum+ssl
Cartera46NVDFL6v5STw5Qw4j77PoBSHRTYnHZGZ8WRoGvHmpaMX7ZyhNUP2u24TLV9pNgncz1bZF2Vm8KkaNTzU7SXqrnFUx5zgHQ
Nivel de donación0 (donación al desarrollador de XMRig desactivada)

Minar por el puerto 443 con TLS deja que el tráfico se mezcle a primera vista con HTTPS ordinario, aunque el handshake stratum tiene una huella TLS distinta para quien mire de cerca.

stealth.c: el rootkit de kernel

Esta es la parte más desarrollada del kit. Es un rootkit LKM que usa hooking de funciones por ftrace para interceptar funciones del kernel y borrar el rastro del malware, y se hace pasar por un driver de hardware de Intel en todo momento.

PropiedadValor
Nombre del módulointel_uncore_freq_aux
Metadatos falsosMODULE_AUTHOR("Intel Corporation"), MODULE_DESCRIPTION("Intel Uncore Frequency Control Driver"), MODULE_VERSION("1.2.0")
Hookingftrace vía kallsyms_lookup_name (resuelto mediante un kprobe en kernels 5.7 y posteriores)
Controlsysfs en /sys/kernel/intel_uncore_freq/ (enabled, cpu_lo, cpu_hi, mem_lo, mem_hi, hide_tag)

Qué engancha y por qué:

  • Enmascarado de CPU. Engancha show_stat para reescribir /proc/stat, falseando la utilización entre límites configurables (40 a 50 por cien por defecto) y oscilando con jiffies para que el número se mueva como una carga real en vez de quedarse plano.
  • Enmascarado de memoria. Engancha meminfo_proc_show para reescribir /proc/meminfo, falseando MemFree, MemAvailable, Buffers, Cached, Active e Inactive.
  • Ocultación de procesos. Engancha iterate_dir para filtrar los listados de /proc, ocultando los PID cuyos nombres coinciden con un conjunto fijo: stealth, masscan, sshruns, ransomx, cpumask, xrandom, cpm_, kcpm, mask_helper, ftrhook, kintel_aux. Un operador puede añadir más nombres en tiempo de ejecución mediante /sys/kernel/intel_uncore_freq/hide_tag.
  • Ocultación de archivos. Oculta las rutas que coinciden con stealth, cpumask, kintel_aux, intel_uncore_freq_aux, y el propio directorio sysfs.
  • Autoocultación. Al cargarse se quita de /proc/modules y /sys/module/ con list_del_init, borra su kobject de sysfs e incrementa su propio contador de referencias con try_module_get para que rmmod no lo descargue.

Esa lista de ocultación es también una pista: junto al minero esconde masscan, sshruns y ransomx, así que el operador probablemente está ejecutando un escáner y puede tener algo más que un minero en el kit.

El efecto práctico es que un administrador que mira top ve una máquina ocupada pero normal, no encuentra ningún proceso pícaro, y no puede ver el módulo de kernel que está mintiendo. Las pistas son físicas y fuera de banda: la máquina se calienta, los ventiladores aceleran y el consumo eléctrico sube, nada de lo cual el rootkit puede falsear.

Persistencia: tres mecanismos, divididos por modo

La persistencia de Rootpacket depende del modo en el que aterriza. En modo root apila dos mecanismos que se refuerzan entre sí; en modo espacio de usuario recurre a un tercero.

#MecanismoModoDetalle
1servicio systemdrootkernel-kd.service, Type=simple, Restart=always, RestartSec=3
2módulo DKMSrootInstala el rootkit bajo /lib/modules/$(uname -r)/extra/; sobrevive a las actualizaciones de kernel
3crontabuser@reboot más cada minuto (* * * * *), con un bloqueo de PID y setsid

La entrada DKMS es la más terca: instala el rootkit a través del propio sistema de compilación de módulos del kernel, así que una actualización de kernel rutinaria lo reconstruye y rearma en vez de eliminarlo.

killservice.sh: despejar y cerrar la máquina

El script se autodenomina “cryptojacker hardening” (“endurecimiento del criptojacker”) en su banner, y esa descripción es precisa desde el punto de vista del operador. Corre en tres fases.

Fase 1: apagar servicios expuestos. Apunta a servicios que escuchan en 0.0.0.0 que son puntos de entrada comunes del criptojacking, deteniendo, desactivando y enmascarando cada uno, poniendo chmod 000 en los binarios y añadiendo reglas DROP de iptables:

ServicioPuerto
Redis6379
Docker2375/2376
PostgreSQL5432
MongoDB27017
Elasticsearch9200/9300
Memcached11211
Hadoop YARN8088
Jenkins8080
Confluence8090

La línea de Docker es el tejido conectivo con nuestro informe sobre RedTail: Rootpacket cierra la misma puerta 2375/2376 por la que entra RedTail. Un operador que aterriza primero mina el host y luego deja fuera a la siguiente cuadrilla, endureciendo la máquina contra las técnicas que ellos habrían usado.

Fase 2: eliminar mineros rivales. Mata procesos, borra archivos, limpia trabajos cron y purga claves SSH ligadas a familias de criptojacking conocidas, incluidas XMRig, Kinsing (kdevtmpfsi), TeamTNT (tntrecht, mdrfckr), sustes, watchdogs y minerd, junto con escáneres como masscan, pnscan y zgrab.

Fase 3: eliminar rootkits de espacio de usuario. Quita las entradas LD_PRELOAD maliciosas conocidas (libprocesshider.so, libjdk.so, libpamx.so, un falso libselinux.so.3 y xhide) de /etc/ld.so.preload y borra las bibliotecas, despejando los rootkits de espacio de usuario de competidores que podrían interferir con el suyo.

Atribución

Los nombres de variables, comentarios y cadenas de estado en turco del kit (por ejemplo ROOT ele gecirildi!, “root obtenido”) apuntan a un operador turcohablante con confianza media. Encontramos una URL de distribución o staging en linuxutil5.pages[.]dev, alojada en Cloudflare Pages, lo que encaja con el patrón de hacer staging de cargas útiles en infraestructura gratuita y reputada para mezclarse. El rootpacket.tar.gz interno, una copia autocontenida de todo el kit, le da al operador un paquete listo para empujar al siguiente host.

Indicadores de compromiso

Red

IndicadorContexto
pool.supportxmr.com / pool.supportxmr.com:443Pool principal de minería de Monero, stratum+ssl
linuxutil5.pages[.]devDistribución / staging (Cloudflare Pages)
api.xmrig.com, randomx.xmrig.com:443Endpoints de API y benchmark de XMRig
donate.v2.xmrig.com, donate.ssl.xmrig.comPools de donación al desarrollador de XMRig (presentes, donación desactivada)
stratum+ssl:// al puerto 443Tráfico de minería TLS saliente

Cartera de Monero: 46NVDFL6v5STw5Qw4j77PoBSHRTYnHZGZ8WRoGvHmpaMX7ZyhNUP2u24TLV9pNgncz1bZF2Vm8KkaNTzU7SXqrnFUx5zgHQ

Archivos (SHA-256)

ArchivoSHA-256MD5
rootpacket.tar.gz (externo)e2d0dab6b29df89d123fe8581047a03ac9b89ae8fa0d1f334b5aefbb93152857
getrootdda96d8a4bcc39dc7679347a4386bf1024152d2ccc46d333725ad0cda855d952
xrandom (empaquetado)ec3ef3dce99fa6cbc480f0f0b0c292676afed68704c44396271c7dc6afea2937

Build ID: getroot 148d8d902efd93ed892a541972fbcea3a99d05a3, xrandom d7a91225bdd2e3ab67cabded9d7809bcc724401f.

Artefactos en el host

RutaContexto
/opt/kernel-kd/xrandomBinario del minero (modo root)
~/.xrandom/xrandom, ~/.xrandom/run.shMinero y lanzador (modo espacio de usuario)
/tmp/.xrandom.lockBloqueo de PID (modo espacio de usuario)
/etc/systemd/system/kernel-kd.serviceUnidad systemd maliciosa
/usr/src/intel_uncore_freq_aux-1.2.0/Fuente DKMS del rootkit
/sys/kernel/intel_uncore_freq/Interfaz de control sysfs del rootkit
/lib/modules/*/extra/intel_uncore_freq_aux.koMódulo del rootkit compilado

De comportamiento

  • Un proceso llamado xrandom ejecutándose como root o como el usuario actual.
  • Cifras de CPU en /proc/stat que no concuerdan con los contadores de rendimiento de hardware (perf stat), o con la velocidad de los ventiladores y el consumo eléctrico.
  • Un servicio systemd kernel-kd (habilitado, Type=simple, Restart=always).
  • Una entrada cron etiquetada # xrandom-userland-autostart.
  • Un módulo de kernel intel_uncore_freq_aux que se carga en el arranque pero está ausente de lsmod.

Detección

Si el rootkit no está cargado

systemctl status kernel-kd.service
ls -la /opt/kernel-kd/ ~/.xrandom/
dkms status | grep intel_uncore_freq
crontab -l | grep xrandom
lsmod | grep intel_uncore

Si el rootkit está cargado

Las vistas del espacio de usuario están comprometidas, así que la detección tiene que venir desde debajo o desde al lado del rootkit:

  • Compara la CPU de /proc/stat con los contadores de hardware mediante perf stat. Una brecha grande es la pista.
  • Vigila los hooks ftrace sobre show_stat, meminfo_proc_show e iterate_dir.
  • Trata una discrepancia entre la CPU reportada y la potencia, el calor o la velocidad de los ventiladores reales como una señal fuerte.

Atrapar la escalada de privilegios

  • Un socket AF_ALG, SOCK_SEQPACKET abierto por un proceso que no es una herramienta cripto conocida (cryptsetup, openssl, gpg, systemd-cryptsetup) es la pista central. El orden completo es socket(AF_ALG)bindsetsockopt(SOL_ALG)acceptpipesplicesendmsgsplicerecvmsg (repetido), luego execve(/usr/bin/su).
  • Compara los bytes en disco de cada binario SUID con su vista en la caché de páginas. sha256sum lee a través de la caché y muestra la copia corrupta, así que lee el disco directamente con dd if=<file> iflag=direct y haz el hash de eso, luego compara. Un desajuste en un binario SUID es corrupción de la caché de páginas.

YARA candidata

rule Rootpacket_Cryptojacker
{
    meta:
        description = "Rootpacket Linux cryptojacking toolkit"
        reference   = "Kinryu Labs CTI 2026-06-16"
    strings:
        $wallet = "46NVDFL6v5STw5Qw4j77PoBSHRTYnHZGZ8WRoGvHmpaMX7ZyhNUP2u24TLV9pNgncz1bZF2Vm8KkaNTzU7SXqrnFUx5zgHQ" ascii
        $svc    = "kernel-kd" ascii
        $cron   = "xrandom-userland-autostart" ascii
        $mod    = "intel_uncore_freq_aux" ascii
    condition:
        $wallet or 2 of ($svc, $cron, $mod)
}

Remediación

  1. Elimina el rootkit desde un estado limpio conocido. Arranca desde un medio live o de recuperación. Borra /lib/modules/*/extra/intel_uncore_freq_aux.ko* y ejecuta dkms remove intel_uncore_freq_aux/1.2.0 --all, luego borra /usr/src/intel_uncore_freq_aux-1.2.0/ y reconstruye el initramfs (update-initramfs -u, dracut -f o mkinitcpio -P). La entrada DKMS tiene que irse o se reconstruye.
  2. Elimina el servicio: systemctl stop kernel-kd; systemctl disable kernel-kd; rm /etc/systemd/system/kernel-kd.service; systemctl daemon-reload.
  3. Elimina el minero: rm -rf /opt/kernel-kd/ ~/.xrandom/ /tmp/.xrandom.lock, luego pkill -9 -f xrandom.
  4. Limpia cron de las líneas # xrandom-userland-autostart.
  5. Restaura lo que killservice.sh rompió. Pone chmod 000 en Redis, Docker, PostgreSQL, MongoDB y otros binarios y añade reglas DROP de iptables. Reinstala los paquetes afectados y revisa el cortafuegos.
  6. Caza lateralmente. El rootpacket.tar.gz interno está hecho para redistribuirse, así que revisa otros hosts en busca de los mismos indicadores, y revisa los registros en busca de explotación de los servicios de killservice.sh para hallar la vía de entrada.
  7. Cierra CVE-2026-31431. Parchea a un kernel corregido (6.18.22, 6.19.12, 7.0+, o el backport de tu distribución). Donde no puedas parchear de golpe, desactiva la interfaz vulnerable: echo 'install algif_aead /bin/false' > /etc/modprobe.d/disable-algif-aead.conf luego rmmod algif_aead. Para contenedores, bloquea AF_ALG (family 38) en el perfil seccomp.
  8. Asume el compromiso del host desde un contenedor. Como la escritura en la caché de páginas cruza el límite del contenedor, trata cualquier host que ejecutara setup.sh, incluso desde dentro de un contenedor, como totalmente comprometido. Reconstruye el host en vez de solo eliminar el contenedor.

Mapeo de MITRE ATT&CK

TácticaTécnica
Initial AccessT1190 Exploit Public-Facing Application (Redis, Docker, MongoDB, Elasticsearch, Jenkins, Hadoop YARN, implícito)
ExecutionT1059.004 Unix Shell
Privilege EscalationT1068 Exploitation for Privilege Escalation (CVE-2026-31431, AF_ALG algif_aead); T1611 Escape to Host (caché de páginas compartida)
PersistenceT1543.002 Systemd Service; T1053.003 Cron; T1547.006 Kernel Modules (DKMS)
Defense EvasionT1014 Rootkit; T1036.005 Masquerading: Match Legitimate Name; T1027.002 Software Packing (UPX); T1070.004 File Deletion; T1564.001 Hidden Files
DiscoveryT1057 Process Discovery (caza de rivales)
Lateral MovementT1570 Lateral Tool Transfer (paquete de redistribución interno)
ImpactT1496 Resource Hijacking (minería de Monero)

Metodología y notas del analista

  • El análisis fue principalmente estático (extracción de cadenas, desensamblado, revisión de código fuente, análisis estructural) en Kali Linux x86-64. También ejecutamos getroot una vez en una VM aislada (kernel 6.6.15) para observar su comportamiento: intentó la secuencia AF_ALG, no obtuvo root en esa compilación y recurrió a ejecutar el comando sin privilegios. El minero no se ejecutó, y nada se subió.
  • El componente de escalada de privilegios es CVE-2026-31431, identificado a partir de la plantilla authencesn(hmac(sha256),cbc(aes)) ligada al socket AF_ALG, el objetivo de caché de páginas /usr/bin/su, y el bucle de escritura splice/sendmsg/recvmsg en el binario.
  • Las muestras (el kit y sus componentes) están disponibles para otros investigadores y defensores que las soliciten. Escribe a [email protected] con una breve nota sobre quién eres y para qué las necesitas.
How to cite
Kinryū Labs (2026). Rootpacket: un kit de criptojacking para Linux que se esconde en el kernel. https://kinryu.sh/es/reports/rootpacket-linux-cryptojacking-rootkit/