
Trouver les serveurs Plex Media affectés par Plex2Shell (CVE-2026-96652 et trois autres)
Détecte les serveurs Plex Media Server affectés par Plex2Shell, la chaîne de quatre failles (CVE-2026-96652, CVE-2026-96654, CVE-2026-96655, CVE-2026-96656) qui permet aux attaquants de prendre le contrôle d'un Plex Media Server antérieur à 1.43.3.10861 sans se connecter. Fait partie de shouldipanic.ch.
Plex2Shell est exploité depuis le 17 octobre 2026 (cryptomineurs, proxys) et figure sur la liste des vulnérabilités exploitées connues de la CISA. Tout Plex Media Server antérieur à 1.43.3.10861 accessible depuis Internet est à risque.
plex2scan se présente sous deux formes :
plex2scan.py : un fichier Python unique sans dépendances pour vérifier
vos propres serveurs : plages d'IP, scan de ports incluant le port 32400 de Plex, découverte de vhosts
et vérification de la version de Plex.
Chaque Plex Media Server répond à GET /identity sans connexion et y indique sa
version. plex2scan charge la page d'accueil (pour reconnaître Plex grâce à son
en-tête X-Plex-Protocol ou à la page Plex Web) et interroge /identity une fois.
Rien d'autre n'est envoyé : pas de connexion, pas d'exploit.
curl -LO https://github.com/akaihigurashi/plex2scan/releases/latest/download/plex2scan.py
python3 plex2scan.py 203.0.113.0/24
Python 3.8 ou plus récent, rien à installer. Exemples :
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
| Statut | Signification |
|---|---|
VULNERABLE | Plex Media Server antérieur à 1.43.3.10861 |
POSSIBLY VULNERABLE | Plex Media Server détecté, version masquée |
PATCHED | Plex Media Server 1.43.3.10861 ou plus récent |
NOT DETECTED | Aucun Plex Media Server visible |
Les résultats sont listés du plus grave au moins grave, avec une courte raison. Les résultats masqués (ports fermés, erreurs, vhosts qui n'affichent que le site par défaut) apparaissent avec -a, les preuves avec -v.
| Option | Ce qu'elle fait |
|---|---|
-p LIST | Ports : web (20 ports courants + 32400, par défaut), all, ou 80,443,32400 |
-n | Pas de scan de ports, uniquement 443 et 80 |
--names FILE | Votre propre liste de noms d'hôtes, vérifiée comme vhosts |
--no-vhosts | Ne pas chercher d'autres sites web sur la même IP |
-a / -v | Afficher les résultats masqués / afficher les preuves |
-o FILE | Écrire aussi tous les résultats dans un CSV |
-d | Débogage : chaque requête, en-tête et correspondance |
-q | Pas de bannière (pour les scripts) |
-V | Afficher la version |
-h | Toutes les options |
myawesomeproxy, mylovelyminer ou x12345, des fichiers .so/.dll inconnus dans le dossier Codecs de Plex, des connexions vers proxystream.st, une charge CPU élevée alors que rien ne se lit. La mise à jour ne supprime pas un attaquant déjà présent.AlienVault OTX et HackerTarget fonctionnent sans clés. VirusTotal, Shodan et SecurityTrails nécessitent une clé API, lue depuis des variables d'environnement :
| Variable | Source |
|---|---|
PANIC_VT_KEY | DNS passif VirusTotal |
PANIC_SHODAN_KEY | Noms d'hôtes Shodan |
PANIC_SECURITYTRAILS_KEY | IP inverse SecurityTrails |
Conservez-les dans un fichier .env que vous seul pouvez lire, et chargez-le juste pour le scan :
( set -a; . ./.env; set +a; python3 plex2scan.py 203.0.113.10 )
--vt-key, --shodan-key et --securitytrails-key fonctionnent également, mais les arguments en ligne de commande sont visibles par les autres utilisateurs locaux (ps) et finissent dans l'historique de votre shell. Les valeurs des clés sont masquées dans les messages d'erreur. (Merci à Jonas Hüsser pour cela.)
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
Ou avec Compose : téléchargez docker-compose.yml, définissez
PANIC_ORIGIN, puis docker compose up -d. Le conteneur n'écoute que sur localhost ;
placez un reverse proxy avec TLS devant celui-ci
(exemple nginx).
| Variable | Valeur par défaut | Rôle |
|---|---|---|
PANIC_ORIGIN | – | Adresse publique. Les requêtes provenant d'autres origines sont refusées. Définissez-la. |
PANIC_OPERATOR / PANIC_CONTACT | – | Section de contact facultative en bas de la page |
PANIC_IMPRINT_URL | – | Lien facultatif vers des mentions légales existantes |
PANIC_TRUSTED_PROXY | 127.0.0.1,::1 | Proxies dont l'en-tête X-Real-IP est approuvé |
PANIC_DENY_HOSTS / PANIC_DENY_IPS | – | Ne jamais vérifier ces domaines / adresses |
PANIC_AUDIT_DIR | /data/audit | Fichiers de journal d'audit quotidiens |
PANIC_RETENTION_DAYS | 30 | Les fichiers d'audit plus anciens que cette valeur sont supprimés |
La page bénéficie des mêmes protections que php2scan : case à cocher de consentement, journal d'audit, refus des clients VPN/Tor/datacenter, limitation de débit, cache des résultats, noms d'hôtes publics uniquement avec la connexion épinglée à l'adresse vérifiée, sites web qui ne sont jamais vérifiés (services bien connus, les 100 sites les plus visités, sites gouvernementaux, pays sanctionnés), et aucun accès depuis les pays sanctionnés. Outre le site web lui-même (443, puis 80), la page n'examine que le port 32400, et uniquement s'il est ouvert.
Le moteur de scan (récupération, empreinte, scan de ports, découverte de vhosts, serveur
web) réside dans panic-core.
Tout ce qui est spécifique à Plex2Shell se trouve dans check.py.
plex2scan.py et web.py sont générés à partir des deux :
git clone https://github.com/akaihigurashi/panic-core ../panic-core
python3 ../panic-core/bundle.py check.py