
Trova i server Plex Media Server interessati da Plex2Shell (CVE-2026-96652 e altri tre)
Individua i Plex Media Server affetti da Plex2Shell, la catena di quattro vulnerabilità (CVE-2026-96652, CVE-2026-96654, CVE-2026-96655, CVE-2026-96656) che consente agli attaccanti di prendere il controllo di un Plex Media Server precedente alla versione 1.43.3.10861 senza effettuare l'accesso. Parte di shouldipanic.ch.
Plex2Shell è stato sfruttato dal 17 ottobre 2026 (cryptominer, proxy) ed è nella lista Known Exploited Vulnerabilities della CISA. Ogni Plex Media Server precedente alla versione 1.43.3.10861 raggiungibile da internet è a rischio.
plex2scan è disponibile in due forme:
plex2scan.py: un singolo file Python senza dipendenze per verificare
i propri server: intervalli IP, scansione delle porte inclusa la porta 32400 di Plex, scoperta dei vhost
e controllo della versione di Plex.
Ogni Plex Media Server risponde a GET /identity senza autenticazione e comunica lì la propria
versione. plex2scan carica la pagina iniziale (per riconoscere Plex tramite il suo
header X-Plex-Protocol o la pagina Plex Web) e interroga /identity una volta.
Non viene inviato nient'altro: nessun login, nessun 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 successivo, nessuna installazione necessaria. Esempi:
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
| Stato | Significato |
|---|---|
VULNERABLE | Plex Media Server precedente alla 1.43.3.10861 |
POSSIBLY VULNERABLE | Plex Media Server trovato, versione nascosta |
PATCHED | Plex Media Server 1.43.3.10861 o successivo |
NOT DETECTED | Nessun Plex Media Server visibile |
I risultati sono elencati dal peggiore al migliore, con una breve motivazione. I risultati nascosti (porte chiuse,
errori, vhost che mostrano solo il sito predefinito) compaiono con -a, le prove con -v.
| Opzione | Cosa fa |
|---|---|
-p LIST | Porte: web (20 porte comuni + 32400, predefinito), all, oppure 80,443,32400 |
-n | Nessuna scansione delle porte, solo 443 e 80 |
--names FILE | La tua lista di hostname, verificata come vhost |
--no-vhosts | Non cercare altri siti web sullo stesso IP |
-a / -v | Mostra i risultati nascosti / mostra le prove |
-o FILE | Scrive tutti i risultati anche in CSV |
-d | Debug: ogni richiesta, header e corrispondenza |
-q | Nessun banner (per gli script) |
-V | Stampa la versione |
-h | Tutte le opzioni |
myawesomeproxy,
mylovelyminer o x12345, file .so/.dll sconosciuti nella cartella Codecs di Plex,
connessioni a proxystream.st, carico elevato della CPU mentre non viene riprodotto nulla. L'aggiornamento
non rimuove un attaccante già presente.AlienVault OTX e HackerTarget funzionano senza chiavi. VirusTotal, Shodan e SecurityTrails richiedono una chiave API, letta dalle variabili d'ambiente:
| Variabile | Fonte |
|---|---|
PANIC_VT_KEY | DNS passivo di VirusTotal |
PANIC_SHODAN_KEY | Hostname di Shodan |
PANIC_SECURITYTRAILS_KEY | Reverse IP di SecurityTrails |
Conservale in un file .env leggibile solo da te, e caricalo solo per la scansione:
( set -a; . ./.env; set +a; python3 plex2scan.py 203.0.113.10 )
--vt-key, --shodan-key e --securitytrails-key funzionano anche, ma gli argomenti da riga di comando sono visibili agli altri utenti locali (ps) e finiscono nella cronologia della shell. I valori delle chiavi sono mascherati nei messaggi di errore. (Grazie a Jonas Hüsser per questo.)
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
Oppure con Compose: scarica docker-compose.yml, imposta
PANIC_ORIGIN, poi esegui docker compose up -d. Il container è in ascolto solo su localhost;
metti davanti ad esso un reverse proxy con TLS
(esempio nginx).
| Variabile | Predefinito | Scopo |
|---|---|---|
PANIC_ORIGIN | – | Indirizzo pubblico. Le richieste provenienti da altre origini vengono rifiutate. Impostala. |
PANIC_OPERATOR / PANIC_CONTACT | – | Sezione di contatto opzionale in fondo alla pagina |
PANIC_IMPRINT_URL | – | Link opzionale a un imprint esistente |
PANIC_TRUSTED_PROXY | 127.0.0.1,::1 | Proxy di cui è considerato attendibile l'header X-Real-IP |
PANIC_DENY_HOSTS / PANIC_DENY_IPS | – | Domini / indirizzi da non controllare mai |
PANIC_AUDIT_DIR | /data/audit | File di log di audit giornalieri |
PANIC_RETENTION_DAYS | 30 | I file di audit più vecchi di questo valore vengono eliminati |
La pagina ha le stesse protezioni di php2scan: casella di consenso, log di audit, client VPN/Tor/datacenter rifiutati, limite di frequenza, cache dei risultati, solo hostname pubblici con la connessione vincolata all'indirizzo controllato, siti web che non vengono mai controllati (servizi ben noti, i 100 siti più visitati, siti governativi, paesi sanzionati) e nessun accesso da paesi sanzionati. Oltre al sito web stesso (443, poi 80) la pagina esamina solo la porta 32400, e solo se è aperta.
Il motore di scansione (recupero, fingerprinting, scansione delle porte, scoperta dei vhost, web
server) risiede in panic-core.
Tutto ciò che è specifico di Plex2Shell si trova in check.py.
plex2scan.py e web.py sono generati da entrambi:
git clone https://github.com/akaihigurashi/panic-core ../panic-core
python3 ../panic-core/bundle.py check.py
GPL-3.0, vedi LICENSE. Font: Inter e JetBrains Mono (SIL Open Font License). Non affiliato né approvato da Plex, Inc.; "Plex" è un loro marchio registrato.