
Encontre servidores Plex Media Server afetados pelo Plex2Shell (CVE-2026-96652 e mais três)
Encontra Plex Media Servers afetados pelo Plex2Shell, a cadeia de quatro falhas (CVE-2026-96652, CVE-2026-96654, CVE-2026-96655, CVE-2026-96656) que permite a atacantes assumir o controlo de um Plex Media Server anterior a 1.43.3.10861 sem iniciar sessão. Parte de shouldipanic.ch.
O Plex2Shell tem sido explorado desde 17 de outubro de 2026 (criptomineradores, proxies) e consta da lista Known Exploited Vulnerabilities da CISA. Todos os Plex Media Servers anteriores a 1.43.3.10861 que sejam acessíveis a partir da internet estão em risco.
O plex2scan existe em duas formas:
plex2scan.py: um único ficheiro Python sem dependências para verificar
os seus próprios servidores: intervalos de IP, varrimento de portas incluindo a porta 32400 do Plex, descoberta de vhosts
e a verificação da versão do Plex.
Todos os Plex Media Servers respondem a GET /identity sem início de sessão e indicam a sua
versão aí. O plex2scan carrega a página inicial (para reconhecer o Plex pelo seu
cabeçalho X-Plex-Protocol ou pela página Plex Web) e consulta /identity uma vez.
Nada mais é enviado: sem início de sessão, sem exploração.
curl -LO https://github.com/akaihigurashi/plex2scan/releases/latest/download/plex2scan.py
python3 plex2scan.py 203.0.113.0/24
Python 3.8 ou mais recente, nada para instalar. Exemplos:
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
| Status | Meaning |
|---|---|
VULNERABLE | Plex Media Server anterior a 1.43.3.10861 |
POSSIBLY VULNERABLE | Plex Media Server encontrado, versão oculta |
PATCHED | Plex Media Server 1.43.3.10861 ou mais recente |
NOT DETECTED | Nenhum Plex Media Server visível |
Os resultados são listados do pior para o melhor, com um breve motivo. Resultados ocultos (portas fechadas,
erros, vhosts que mostram apenas o site padrão) aparecem com -a, as evidências com -v.
| Opção | O que faz |
|---|---|
-p LIST | Portas: web (20 portas comuns + 32400, padrão), all, ou 80,443,32400 |
-n | Sem varredura de portas, apenas 443 e 80 |
--names FILE | Sua própria lista de hostnames, verificada como vhosts |
--no-vhosts | Não procurar outros sites no mesmo IP |
-a / -v | Mostrar resultados ocultos / mostrar as evidências |
-o FILE | Também gravar todos os resultados em CSV |
-d | Depuração: cada requisição, cabeçalho e correspondência |
-q | Sem banner (para scripts) |
-V | Imprimir a versão |
-h | Todas as opções |
myawesomeproxy,
mylovelyminer ou x12345, arquivos .so/.dll desconhecidos na pasta Codecs do Plex,
conexões para proxystream.st, alto uso de CPU enquanto nada está sendo reproduzido. Atualizar
não remove um invasor que já está dentro.AlienVault OTX e HackerTarget funcionam sem chaves. VirusTotal, Shodan e SecurityTrails precisam de uma chave de API, lida de variáveis de ambiente:
| Variável | Fonte |
|---|---|
PANIC_VT_KEY | DNS passivo do VirusTotal |
PANIC_SHODAN_KEY | Hostnames do Shodan |
PANIC_SECURITYTRAILS_KEY | IP reverso do SecurityTrails |
Mantenha-as em um arquivo .env que só você pode ler, e carregue-o apenas para a varredura:
( set -a; . ./.env; set +a; python3 plex2scan.py 203.0.113.10 )
--vt-key, --shodan-key e --securitytrails-key também funcionam, mas argumentos de linha de comando são visíveis para outros usuários locais (ps) e acabam no histórico do seu shell. Os valores das chaves são mascarados nas mensagens de erro. (Agradecimentos a Jonas Hüsser por isto.)
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 com Compose: baixe docker-compose.yml, defina
PANIC_ORIGIN, depois docker compose up -d. O contêiner escuta apenas em localhost;
coloque um proxy reverso com TLS à frente dele
(exemplo nginx).
| Variável | Padrão | Finalidade |
|---|---|---|
PANIC_ORIGIN | – | Endereço público. Requisições de outras origens são recusadas. Defina-a. |
PANIC_OPERATOR / PANIC_CONTACT | – | Seção de contato opcional na parte inferior da página |
PANIC_IMPRINT_URL | – | Link opcional para um imprint existente |
PANIC_TRUSTED_PROXY | 127.0.0.1,::1 | Proxies cujo cabeçalho X-Real-IP é confiável |
PANIC_DENY_HOSTS / PANIC_DENY_IPS | – | Nunca verificar estes domínios / endereços |
PANIC_AUDIT_DIR | /data/audit | Arquivos de log de auditoria diários |
PANIC_RETENTION_DAYS | 30 | Arquivos de auditoria mais antigos que isso são excluídos |
A página tem as mesmas proteções que o php2scan: caixa de seleção de consentimento, log de auditoria, clientes de VPN/Tor/datacenter recusados, limite de taxa, cache de resultados, apenas hostnames públicos com a conexão fixada ao endereço verificado, sites que nunca são verificados (serviços conhecidos, os 100 sites mais visitados, sites governamentais, países sancionados) e nenhum acesso a partir de países sancionados. Além do próprio site (443, depois 80), a página só examina a porta 32400, e apenas se ela estiver aberta.
O motor do scanner (busca, fingerprinting, varredura de portas, descoberta de vhost, servidor
web) fica em panic-core.
Tudo o que é específico do Plex2Shell está em check.py.
plex2scan.py e web.py são gerados a partir de ambos:
git clone https://github.com/akaihigurashi/panic-core ../panic-core
python3 ../panic-core/bundle.py check.py
GPL-3.0, consulte LICENSE. Fontes: Inter e JetBrains Mono (SIL Open Font License). Não afiliado nem endossado pela Plex, Inc.; "Plex" é marca registrada da mesma.