
Encuentra servidores de Plex Media Server afectados por Plex2Shell (CVE-2026-96652 y tres más)
Encuentra servidores de Plex Media Server afectados por Plex2Shell, la cadena de cuatro fallos (CVE-2026-96652, CVE-2026-96654, CVE-2026-96655, CVE-2026-96656) que permite a los atacantes tomar el control de un Plex Media Server anterior a 1.43.3.10861 sin iniciar sesión. Forma parte de shouldipanic.ch.
Plex2Shell ha sido explotado desde el 17 de octubre de 2026 (criptomineros, proxies) y está en la lista de vulnerabilidades explotadas conocidas de CISA. Todo Plex Media Server anterior a 1.43.3.10861 que sea accesible desde internet está en riesgo.
plex2scan se presenta en dos formas:
plex2scan.py: un único archivo Python sin dependencias para comprobar
tus propios servidores: rangos de IP, escaneo de puertos incluyendo el puerto 32400 de Plex, descubrimiento de vhosts
y la comprobación de la versión de Plex.
Todo Plex Media Server responde a GET /identity sin iniciar sesión y comunica su
versión ahí. plex2scan carga la página de inicio (para reconocer Plex por su
cabecera X-Plex-Protocol o por la página de Plex Web) y consulta /identity una vez.
No se envía nada más: ni inicio de sesión, ni exploit.
curl -LO https://github.com/akaihigurashi/plex2scan/releases/latest/download/plex2scan.py
python3 plex2scan.py 203.0.113.0/24
Python 3.8 o superior, no hay nada que instalar. Ejemplos:
python3 plex2scan.py 203.0.113.10 # 21 ports incl. 32400 + every vhost on the IP
python3 plex2scan.py 203.0.113.10:32400 # only Plex's own port
python3 plex2scan.py plex.example.ch # a Plex behind a reverse proxy
python3 plex2scan.py 203.0.113.0/24 --names domains.txt # + hostnames from your own data
python3 plex2scan.py 203.0.113.10 -p all -o out.csv # all 65535 ports, CSV output
python3 plex2scan.py -h # all options
| Estado | Significado |
|---|---|
VULNERABLE | Plex Media Server anterior a 1.43.3.10861 |
POSSIBLY VULNERABLE | Plex Media Server encontrado, versión oculta |
PATCHED | Plex Media Server 1.43.3.10861 o posterior |
NOT DETECTED | Ningún Plex Media Server visible |
Los resultados se listan de peor a mejor, con una breve razón. Los resultados ocultos (puertos cerrados,
errores, vhosts que solo muestran el sitio por defecto) aparecen con -a, la evidencia con -v.
| Opción | Qué hace |
|---|---|
-p LIST | Puertos: web (20 puertos comunes + 32400, por defecto), all, o 80,443,32400 |
-n | Sin escaneo de puertos, solo 443 y 80 |
--names FILE | Tu propia lista de nombres de host, comprobada como vhosts |
--no-vhosts | No buscar otros sitios web en la misma IP |
-a / -v | Mostrar resultados ocultos / mostrar la evidencia |
-o FILE | Escribir también todos los resultados en CSV |
-d | Depuración: cada petición, cabecera y coincidencia |
-q | Sin banner (para scripts) |
-V | Mostrar la versión |
-h | Todas las opciones |
myawesomeproxy,
mylovelyminer o x12345, archivos .so/.dll desconocidos en la carpeta Codecs de Plex,
conexiones a proxystream.st, carga alta de CPU mientras no se reproduce nada. Actualizar
no elimina a un atacante que ya está dentro.AlienVault OTX y HackerTarget funcionan sin claves. VirusTotal, Shodan y SecurityTrails necesitan una clave de API, leída de variables de entorno:
| Variable | Fuente |
|---|---|
PANIC_VT_KEY | DNS pasivo de VirusTotal |
PANIC_SHODAN_KEY | Nombres de host de Shodan |
PANIC_SECURITYTRAILS_KEY | IP inversa de SecurityTrails |
Guárdalas en un archivo .env que solo tú puedas leer, y cárgalo solo para el escaneo:
( set -a; . ./.env; set +a; python3 plex2scan.py 203.0.113.10 )
--vt-key, --shodan-key y --securitytrails-key también funcionan, pero los argumentos de línea de comandos son visibles para otros usuarios locales (ps) y terminan en el historial de tu shell. Los valores de las claves se enmascaran en los mensajes de error. (Gracias a Jonas Hüsser por esto.)
docker run -d --name plex2scan --restart unless-stopped \
-p 127.0.0.1:8091:8091 \
-e PANIC_ORIGIN=https://plex2scan.example.ch \
-v plex2scan-data:/data \
ghcr.io/akaihigurashi/plex2scan:latest
O con Compose: descarga docker-compose.yml, establece
PANIC_ORIGIN, y luego docker compose up -d. El contenedor escucha solo en localhost;
coloca un proxy inverso con TLS delante de él
(ejemplo de nginx).
| Variable | Predeterminado | Propósito |
|---|---|---|
PANIC_ORIGIN | – | Dirección pública. Las solicitudes de otros orígenes se rechazan. Establécelo. |
PANIC_OPERATOR / PANIC_CONTACT | – | Sección de contacto opcional al pie de la página |
PANIC_IMPRINT_URL | – | Enlace opcional a un aviso legal existente |
PANIC_TRUSTED_PROXY | 127.0.0.1,::1 | Proxies cuya cabecera X-Real-IP es de confianza |
PANIC_DENY_HOSTS / PANIC_DENY_IPS | – | Nunca comprobar estos dominios / direcciones |
PANIC_AUDIT_DIR | /data/audit | Archivos de registro de auditoría diarios |
PANIC_RETENTION_DAYS | 30 | Los archivos de auditoría más antiguos que esto se eliminan |
La página tiene las mismas protecciones que php2scan: casilla de consentimiento, registro de auditoría, clientes de VPN/Tor/centros de datos rechazados, límite de tasa, caché de resultados, solo nombres de host públicos con la conexión fijada a la dirección comprobada, sitios web que nunca se comprueban (servicios conocidos, los 100 sitios más visitados, sitios gubernamentales, países sancionados), y sin acceso desde países sancionados. Además del sitio web en sí (443, luego 80), la página solo examina el puerto 32400, y solo si está abierto.
El motor del escáner (obtención, fingerprinting, escaneo de puertos, descubrimiento de vhosts, servidor
web) reside en panic-core.
Todo lo específico de Plex2Shell está en check.py.
plex2scan.py y web.py se generan a partir de ambos:
git clone https://github.com/akaihigurashi/panic-core ../panic-core
python3 ../panic-core/bundle.py check.py