Seguridad

Plex2Shell: la cadena de vulnerabilidades que permite secuestrar tu servidor de medios Plex

Tengo un servidor de medios con Plex detrás de un reenvío de puertos desde hace años, y esta semana lo apagué por una nota de seguridad que me llegó tarde. El 16 de octubre de 2026 se publicó el código de una cadena de cuatro vulnerabilidades encadenadas que permite ejecutar código en cualquier Plex Media Server sin autenticación. Se le puso nombre: Plex2Shell. Al día siguiente ya se veían ataques reales en un honeypot (un servidor señuelo), y el 20 de octubre la agencia CISA de Estados Unidos metió los cuatro CVE en su catálogo de vulnerabilidades explotadas conocidas. La última actualización oficial de Plex, el 19 de octubre, es bastante más directa que el comunicado original: si tu servidor es anterior a 1.43.3.10861 y está alcanzable desde Internet, da por hecho que puede estar comprometido.

No es una vulnerabilidad teórica de laboratorio. Lo que se está instalando en los servidores comprometidos es un minero de criptomonedas y un proxy residencial: software que enruta el tráfico de terceros por tu conexión doméstica para que parezca tráfico normal de una IP residencial. Eso último es lo que más me preocupa, porque un minero te cuesta CPU y una factura eléctrica, mientras que un proxy residencial abre la puerta a que alguien use tu red para alcanzar VPN corporativas y buzones de correo desde una IP que parece la tuya. Este post es la lista de verificación que yo aplicaría hoy: actualizar, verificar si ya te comprometieron, limpiar y cerrar la exposición de red.

TL;DR — Lo que vas a tener al final

  • Tiempo de setup: 20-30 minutos para actualizar y auditar, más lo que tarde la limpieza si hay rastros.
  • Requisitos: acceso root o sudo al host donde corre Plex, y el identificador de versión que ya tienes a mano en Settings → General.
  • Resultado: Plex Media Server en 1.43.3.10861 o superior, sin procesos del minero ni binarios sospechosos en la carpeta Codecs, y con el puerto 32400 cerrado al exterior.
  • Troubleshooting: si la carpeta Codecs no se deja limpiar o el servicio no arranca tras la actualización, la vía sana es reconstruir desde una instalación limpia en lugar de arrastrar el directorio de datos viejo.

Actualiza Plex Media Server a la 1.43.3.10861 o superior

El punto de corte lo define Plex en su propio aviso de seguridad: 1.43.3.10861 y posteriores no están afectados. La versión que hay publicada al momento de escribir esto es la 1.43.5.11079-b3b13e506, así que si tienes una versión de la serie 1.43.3 hay que actualizar igual. Ojo con un detalle de la cadena de versiones de Plex: la numeración del paquete de Debian es distinta a la que ves en la interfaz web. El archivo que descarga el sitio oficial es plexmediaserver_1.43.5.11079-b3b13e506_amd64.deb y su versión interna es la que aparece en Settings → General. Para la auditoría lo que manda es esa versión interna.

Verifica qué versión tienes corriendo ahora

El endpoint /identity devuelve un XML con la versión exacta del servidor, y es la forma más rápida de confirmar si ya te parcheaste o no. Necesita un token de Plex, que es el mismo valor que usas en la URL de cualquier biblioteca. Si prefieres no tocar la terminal, la respuesta está en la interfaz: Settings → General, arriba del todo.

curl -s "http://localhost:32400/identity?X-Plex-Token=TU_TOKEN_PLEX" | grep -o 'version="[^"]*"'

Si la respuesta trae algo como version="1.43.3.10861" o mayor, la parte de los CVE ya está cubierta. Si trae un número anterior, sigue leyendo: actualizar es el primer paso, no el último.

Actualiza cuando corre en Docker

Si tu Plex corre en contenedor, el proceso es tirar la imagen vieja, bajar la nueva y recrear el contenedor. Fíjate en que el tag latest ya apunta a la versión corregida, pero es más seguro fijar la versión exacta para que un redeploy futuro no te devuelva a un build viejo sin que te des cuenta.

docker pull plexinc/pms-docker:1.43.5.11079-b3b13e506
docker compose up -d --force-recreate
docker ps --filter name=plex --format 'table {{.Names}} {{.Image}} {{.Status}}'

El volumen de configuración debe seguir montado en /config, tal como está en la documentación oficial de plexinc/pms-docker. Si al recrear el contenedor pierdes las bibliotecas, es que el volumen no estaba declarado: revisa el docker-compose.yml antes de ejecutar nada.

Actualiza cuando corre como paquete nativo

En Debian, Ubuntu, Fedora o CentOS el paquete se instala a mano con dpkg. El nombre del archivo lleva dentro la versión del servidor, así que la descarga no admite suposiciones: se toma de la API oficial de descargas de Plex.

cd /tmp
curl -L -o plexmediaserver.deb "https://downloads.plex.tv/plex-media-server-new/1.43.5.11079-b3b13e506/debian/plexmediaserver_1.43.5.11079-b3b13e506_amd64.deb"
sudo dpkg -i plexmediaserver.deb
sudo systemctl restart plexmediaserver

En NAS el paquete suele llegar tarde al gestor de aplicaciones del fabricante. El propio aviso de Plex dice que en ese caso la instalación manual es el camino: descargas el binario correspondiente a tu modelo y lo instalas desde la interfaz del NAS. Para todo lo demás, el script de actualización automática de Plex se encarga, y conviene confirmar que está activo.

Comprueba si tu servidor ya fue comprometido

Actualizar cierra la puerta de entrada, pero no limpia lo que ya entró. El aviso de Plex del 19 de octubre es explícito: los sistemas comprometidos pueden seguir comprometidos después del parche si el atacante dejó archivos, procesos o preferencias modificadas. La hoja de ruta de la investigación empieza por ahí.

Busca procesos que no deberían estar corriendo

Los nombres de proceso que cita Plex en su aviso son myawesomeproxy, mylovelyminer y x12345. A esos se suman los artefactos que aparecen en los indicadores públicos de esta campaña: un dropper llamado docker, un binario x empaquetado con UPX y el xmrig del minero. Cualquier cosa con esos nombres significa que ya te comprometieron.

ps aux | grep -E 'myawesomeproxy|mylovelyminer|x12345|xmrig'
sudo ss -tnp | grep -i plex
getent hosts proxystream.st

Las tres líneas miran cosas distintas. La primera busca los procesos conocidos. La segunda lista las conexiones TCP abiertas del servidor: si ves tráfico saliente hacia destinos desconocidos mientras no estás reproduciendo nada, ahí está el proxy. La tercera resuelve el dominio proxystream.st, que el aviso de Plex nombra de forma explícita como indicador de la actividad del proxy residencial. Resolverlo no prueba nada por sí solo, pero si tu servidor resuelve ese nombre y además tiene un proceso desconocido, el diagnóstico ya está hecho.

Revisa la carpeta Codecs y compara hashes

La carpeta Codecs es donde Plex guarda las librerías de códecs que carga con dlopen al arrancar el transcodificador. El punto débil de esa rutina es que carga cualquier archivo .so que encuentre en el directorio, sin exigir firma, sin pedir permiso de ejecución y sin verificar símbolos. Por eso el paso 4 de la cadena escribe ahí su propia librería compartida. En una instalación nativa la ruta es esta:

sudo find "/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Codecs" -type f -name '*.so' -newermt '2026-09-01' -ls
sudo find /tmp -maxdepth 2 -type f -newermt '2026-10-01' -exec sha256sum {} +

La primera orden lista las librerías compartidas con fecha de modificación reciente: en una instalación sana no debería haber ninguna con fecha posterior a la actualización. La segunda calcula el hash de todo lo reciente que hay en /tmp, que es donde el atacante deja el material de descarga. Para comparar contra los hashes conocidos de esta campaña puedes armar un archivo de referencia y validarlo en bloque:

cat > /tmp/plex_iocs.txt <<'EOF'
5712ef510481f15fe8b18fdd10b73026d57cb3d9d151878a692358b99a464441
68938fb428f2bcfef4ede62f7b29cd0f15f37ed59e94462c099f2ca64e36baa7
b20f39fc00d242e706b6c30367ad811c676e0575050a4ec2f30104b696944b49
e546b10aee5edc754da4f9b0baace00392257121911f630145078eafad1e6bd9
2d3c618b21a7e2f8bcd735da188e44a7609ff3f204832dd0781cd09e4388c9db
EOF
sudo find /tmp /var/tmp -maxdepth 2 -type f | grep -E 'mylovelyminer|myawesomeproxy|x12345|xmrig|/docker$' | xargs -r sudo sha256sum | grep -F -f /tmp/plex_iocs.txt

Ese bloque no imprime nada si el servidor está limpio: busca por nombre los archivos típicos de la campaña, calcula su hash y lo cruza contra la lista de referencia, así que cualquier coincidencia aparece en pantalla. Si ves una línea con la ruta y el hash, ya tienes el archivo. Estos cinco hashes son los que circulan en la herramienta de verificación pública plex2shell-check, la misma que usa la comunidad para auditar servidores expuestos; el write-up del investigador no los publica, así que tómalos como referencia y no como lista cerrada. Un resultado limpio no sustituye la revisión manual de la carpeta Codecs.

Busca la preferencia que permite escribir archivos

El cuarto paso de la cadena usa una preferencia del servidor que se le pega literalmente a las opciones de x264 en cada transcodificación. Si esa preferencia aparece con un valor que tú no configuraste, alguien estuvo aquí. Y ojo con el punto inverso: el atacante borra esa preferencia al terminar para que no persista, así que su ausencia no descarta que hubiera pasado por ahí.

sudo grep -i 'TranscoderH264Options' "/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Preferences.xml"
sudo find /var/lib/plexmediaserver -name 'Preferences.xml' -exec grep -l 'TranscoderH264Options' {} +

El archivo de preferencias vive en el directorio de datos de Plex, que en Debian, Fedora, CentOS y Ubuntu es /var/lib/plexmediaserver/Library/Application Support/Plex Media Server/. En una instalación con Docker la misma ruta cuelga de /config. La segunda orden sirve para el caso de que tengas varias instancias o un directorio de datos en una ruta no estándar.

Entiende cómo funciona la cadena Plex2Shell

Vale la pena entender la secuencia, porque cada eslabón explica por qué la defensa no es solo actualizar sino también cerrar la exposición de red y revisar las credenciales.

La cadena que publicó el investigador tiene cinco pasos, y los cuatro CVE que la componen se reparten entre ellos de una forma que no siempre coincide entre fuentes.

El primer paso es una SSRF sin autenticación en el endpoint /player/timeline (CVE-2026-96652). El control de acceso de ese endpoint comprueba que exista la cabecera X-Plex-Token, pero no que su valor sea válido: con un token basura pasa. El parámetro protocol se inserta crudo en la URL de callback, así que el atacante logra que el propio servidor se haga un POST a 127.0.0.1. El servidor termina haciendo una petición a sí mismo desde loopback, y esa es la llave que abre el siguiente paso.

El segundo es el pivote sobre loopback (CVE-2026-96654): la API interna de agentes de plugins, la familia /system/agents/*, se abre sin token cuando la petición viene de loopback, y el campo identifier se concatena sin codificar en la URL interna. Con eso el atacante controla la ruta y la query de la siguiente llamada y puede invocar cualquier función de plugin.

El tercero es el robo del token. El atacante elige una función que acepta una URL, la del agente de TheTVDB que Plex incluye para traer metadatos, y le pasa un destino que empieza por http://127.0.0.1. Cuando el framework de plugins hace una petición saliente, comprueba si la URL empieza así y, si es el caso, le adjunta el token de administrador del dueño en la cabecera X-Plex-Token. La comparación es un prefijo sin límites, así que un host que empiece con los mismos caracteres cuela y el token viaja al atacante. Con el token en la mano ya tiene control de administrador sobre el servidor sin haber usado nunca credenciales reales.

El cuarto es la entrega de la carga: con el token de administrador en la mano, el atacante hace que el servidor descargue desde su propio host un video portador a través del endpoint de transcodificación /video/:/transcode/universal, que no valida el destino. La preferencia TranscoderH264Options se añade literalmente a las opciones de x264 en cada transcodificación, y x264 tiene una opción de depuración que escribe los fotogramas decodificados en la ruta que le indiques. El resultado es un objeto compartido ELF escrito dentro del directorio de códecs, byte a byte controlado por el atacante.

El quinto y último es la ejecución. Al arrancar el transcodificador, Plex carga con dlopen todos los archivos .so de ese directorio, sin comprobar firma, sin exigir el permiso de ejecución y sin buscar símbolos concretos: una librería que solo tenga un constructor se ejecuta igual. El código corre con los privilegios del proceso de Plex, que en una instalación normal no es root.

Sobre el reparto de los CVE hay que ser honesto, porque las fuentes no coinciden al cien por ciento. El registro NVD, que es la fuente que replica el catálogo KEV de CISA, describe el CVE-2026-96655 como la SSRF autenticada del endpoint de transcodificación y el CVE-2026-96656 como la escritura arbitraria de archivos que se ejecutan al cargar. El aviso oficial de Plex etiqueta el robo del token como 96655 y la escritura de archivos como 96656, y el repositorio del investigador parte el 96655 entre la SSRF del transcodificador y la escritura de archivos, dejando la ejecución de código en el 96656. Lo que no cambia entre las tres fuentes es qué cuatro fallas componen la cadena, ni la versión que las corrige: 1.43.3.10861.

Lo interesante del método no es solo el resultado. El investigador documentó que usó modelos de lenguaje de forma intensiva para la búsqueda, pero con un flujo de cuatro pasos: reconocer, cazar, verificar con un agente independiente que intentara refutar cada hallazgo, y encadenar. Lo que hizo el trabajo pesado fueron las decisiones de qué priorizar. Es un recordatorio de que el volumen de hallazgos posibles se multiplica, y que el cuello de botella real es el criterio para decidir qué vale la pena encadenar.

Esta tabla sigue la descripción del registro NVD, que es la fuente que replica el catálogo KEV de CISA. La divergencia de atribución entre fuentes está explicada más abajo, después de la tabla.

CVE Componente CVSS 4.0 En la cadena En KEV de CISA
CVE-2026-96652 SSRF sin autenticación en /player/timeline 5.3 medio Si Si, desde el 20-oct-2026
CVE-2026-96654 Neutralización incompleta de URL en searchOne 6.9 medio Si Si, desde el 20-oct-2026
CVE-2026-96655 SSRF autenticado en /video/:/transcode/universal 5.3 medio Si Si, desde el 20-oct-2026
CVE-2026-96656 Escritura arbitraria de archivos vía TranscoderH264Options 8.6 alto Si Si, desde el 20-oct-2026
CVE-2026-96651 Recorrido de rutas en /system/agents/media/get 7.1 alto No, pero permite leer el token de la cuenta No

Esa última fila merece atención: CVE-2026-96651 no forma parte de la cadena de ejecución remota, pero permite leer archivos que el usuario del servicio puede leer, incluido el token que controla la cuenta de Plex y el servidor. Está corregida en la misma versión, así que la actualización cubre las cinco, pero conviene saber que existió: si alguien podía leer tus credenciales antes del parche, cambiar la contraseña no es opcional.

Reduce la exposición del puerto 32400

La forma más simple de que tu servidor no sea objetivo es que no sea alcanzable. Plex escucha en el puerto TCP 32400 y la función de acceso remoto de Plex es justamente lo que publica esa ruta hacia Internet. Conviene tener presente que cerrar el puerto al exterior no lo ciega por completo: un servidor que solo escuche en la red local sigue siendo explotable desde esa misma red, porque el atacante no necesita estar en Internet para alcanzar el puerto 32400. El aviso de Plex es directo: si no necesitas acceso remoto, desactívalo en Settings → Remote Access y evita reenviar el puerto 32400 directamente.

Si tu servidor tiene que ser accesible desde fuera, la alternativa sana es un proxy inverso con TLS que termine la conexión en tu red local, en lugar de abrir el puerto del servicio. El propio aviso de Plex menciona esa opción y la de usar únicamente clientes con conexión segura. En el blog ya hay una guía de proxy inverso con Caddy y otra de nginx con HTTPS automático, que son el camino para dejar de exponer el 32400 crudo.

Para saber por dónde estás expuesto hoy, una comprobación rápida desde una red externa te dice si el puerto responde desde Internet:

curl -s https://api.ipify.org
curl -s -o /dev/null -w '%{http_code}' "http://TU_IP_PUBLICA:32400/identity"
echo

Cualquier código HTTP que imprima esa segunda orden significa que hay algo respondiendo desde Internet: 200 si el endpoint devuelve datos y 401 si lo que rechaza es la petición sin token, pero en ambos casos el puerto está abierto. Lo que quieres ver es un 000, que es lo que imprime curl cuando la conexión no se puede establecer.

Cambia las credenciales de Plex y reconstruye si hace falta

Si tu servidor estuvo expuesto y vulnerable, el token de administrador pudo robarse. Plex en su aviso pide tres cosas que no son negociables en ese escenario: cerrar sesión en todos los dispositivos desde la configuración de la cuenta, cambiar la contraseña de Plex, y reconstruir el servidor desde una instalación limpia en lugar de reutilizar el directorio de datos anterior.

La reconstrucción es la parte que más gente pospone y la que más cambia las cosas. Si el atacante alcanzó ejecución de código como el usuario del servicio, no hay forma limpia de saber qué quedó. La opción mínima es borrar todo el contenido de la carpeta Codecs y revisar el archivo de preferencias en busca de opciones de transcodificador que no hayas configurado tú. La opción correcta es empezar de cero:

sudo systemctl stop plexmediaserver
sudo mv "/var/lib/plexmediaserver/Library/Application Support/Plex Media Server" "/var/lib/plexmediaserver/Library/Application Support/Plex Media Server.bak"
sudo systemctl start plexmediaserver

Al arrancar con el directorio de datos limpio, Plex vuelve a descargar sus códecs legítimos y tu biblioteca se reindexa. El directorio con sufijo .bak lo puedes borrar cuando confirmes que todo funciona, pero consérvalo un tiempo: contiene la configuración y las rutas de tus bibliotecas.

Y algo que la mayoría pasa por alto: cualquier cosa a la que el usuario del servicio de Plex pueda llegar puede estar expuesta. Eso incluye montajes SMB o NFS, copias de seguridad, otros servicios en el mismo host y las credenciales guardadas en la misma máquina o máquina virtual. Si tu Plex corría en un servidor que también monta los respaldos de la familia, el radio de impacto no se limita al servidor de medios.

Convierte esto en una rutina mensual

Shadowserver lleva escaneando desde el 4 de septiembre de 2026 los servidores Plex Media Server sin parche y reportó más de 36.000 instancias accesibles desde Internet que seguían vulnerables, cuando el aviso de Plex ya llevaba semanas publicado. Son servidores que nadie estaba mirando, y ese es el punto: un servicio doméstico que no aparece en el inventario de activos se queda en la versión vieja durante meses.

Mi lista de verificación mensual para este tipo de servicio es corta: versión de Plex al día, verificación de que no hay procesos ni librerías extrañas en Codecs, revisión de las conexiones salientes del servicio, confirmar que el puerto 32400 sigue cerrado al exterior y que el acceso remoto no quedó habilitado sin querer. Si tu servidor es un contenedor, incluye en el mismo chequeo el tag de la imagen: un latest sin fijar es una forma silenciosa de volver a una versión vieja.

Y si decides que Plex ya no compensa para lo que haces, la alternativa libre existe y el post que comparamos en detalle está en el bloque de lectura de más abajo. Pero ojo con el argumento inverso: migrar a otro servidor de medios no te protege de que ese servicio tenga el día su propia cadena de vulnerabilidades. Lo que evita que te comprometan es la combinación de parche, mínima exposición y monitoreo.

Preguntas frecuentes

¿Cómo verifico qué versión de Plex Media Server tengo instalada?

En la interfaz web: Settings → General, el número de versión aparece arriba del todo. Por terminal, el endpoint /identity lo devuelve en la respuesta: curl -s "http://localhost:32400/identity?X-Plex-Token=TU_TOKEN_PLEX" | grep -o 'version="[^"]*"'. Si el valor es 1.43.3.10861 o mayor, los cinco CVE de Plex publicados el 23 de septiembre de 2026 ya están corregidos en tu instalación.

¿Qué procesos y archivos reviso para saber si me comprometieron?

Procesos myawesomeproxy, mylovelyminer, x12345 o xmrig en la tabla de procesos; librerías .so con fecha reciente dentro de la carpeta Codecs; archivos nuevos en /tmp; conexiones TCP salientes sin explicar; y un valor en TranscoderH264Options dentro de Preferences.xml que no hayas configurado tú. El aviso de Plex nombra además proxystream.st como indicador de salida del proxy residencial.

¿Sirve con actualizar o tengo que reinstalar Plex desde cero?

Si no hay rastros, actualizar basta: el parche cierra el acceso y los cuatro CVE quedan fuera de alcance. Si hay rastros, actualizar no los elimina, y por eso Plex pide reconstruir desde una instalación limpia en lugar de reutilizar el directorio de datos anterior. El mínimo aceptable es vaciar la carpeta Codecs, revisar las preferencias del transcodificador y cambiar la contraseña de Plex.

¿Cómo compruebo si mi Plex estaba expuesto a Internet?

Desde una red externa, consulta tu IP pública y luego pide el endpoint /identity contra el puerto 32400. Si responde con un código HTTP, hay algo escuchando desde Internet, aunque rechace la petición por falta de token. La comprobación más concluyente es en tu router: revisa si hay una regla de reenvío de puertos hacia el 32400, y desactívala si no la usas.

¿Vale la pena seguir usando Plex o debería migrar a otro servidor de medios?

El riesgo aquí no es la licencia ni el soporte, es que Plex estaba expuesto a un ataque automatizado. Actualizar y cerrar la exposición resuelve el problema concreto. Migrar a otra plataforma solo tiene sentido por otras razones, y ninguna alternativa queda libre de sus propios CVE: lo que sostiene tu posición es el parche, la mínima superficie expuesta y el monitoreo, no la marca del software.

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 *