Como as Transmissões Piratas da Copa do Mundo Realmente Funcionam

Eu quis descobrir como aquele truque escondido à plena vista realmente funcionava. Sites de streaming pirata existem desde sempre, mas durante a Copa do Mundo você não conseguia abrir um fórum de esportes sem alguém soltando um link para uma partida ao vivo — Full HD, sem buffering, sem login. Eu sempre presumi que havia algo exótico acontecendo por baixo dos panos. Um amigo me mandou um link antes do jogo Inglaterra-Croácia. “Assiste isso”, ele disse. Então eu abri o DevTools.

Eu esperava uma playlist HLS raspada ou um feed retransmitido. Em vez disso, encontrei uma tag <video>, uma instância do Shaka Player apontando para um CDN legítimo da Akamai, e duas strings hexadecimais em um bloco <script> que faziam todo o trabalho. Aquelas strings hexadecimais eram as chaves de descriptografia do DRM. No código-fonte da página. Não atrás de uma API. Não criptografadas. Apenas envoltas em JavaScript que parecia assustador e não fazia nada.

Aí alguém me mostrou um app Android fazendo a mesma coisa para todas as partidas da Copa do Mundo — mas “do jeito certo”, com configs criptografadas, Firebase Remote Config, um servidor de licenças, tudo. Uma seção dedicada “MUNDIAL FIFA 2026” com 28 canais, incluindo multicam, câmera do jogador e câmera do técnico para cada jogo. Levou cerca de uma hora para perceber que era a mesma vulnerabilidade vestindo um terno mais bonito.

O que começou como trinta minutos de curiosidade virou um fim de semana inteiro. No fim, eu tinha mapeado 670 transmissões ao vivo em 169 CDNs em 33 países pelo lado da web, e mais 525 canais de um único app Android — todos protegidos por um esquema de DRM que a própria W3C chama de ferramenta de “teste”. Durante uma Copa do Mundo em que a Inglaterra está aplicando quatro na Croácia e cada gol está simultaneamente disponível em centenas de transmissões não autorizadas.

Aviso
Esta é uma análise de vulnerabilidade. Nenhuma chave real, URL de transmissão ou ferramenta funcional é publicada. Nomes de apps e domínios estão omitidos. O objetivo é documentar uma fragilidade sistêmica na forma como as plataformas implementam DRM — não viabilizar a pirataria.

Todo navegador que reproduz vídeo criptografado usa as Encrypted Media Extensions (EME) da W3C. As EME suportam quatro sistemas de chave. Três deles — Widevine, FairPlay, PlayReady — usam servidores de licença, trocas de chave criptografadas e descriptografia respaldada por hardware. O quarto é o ClearKey.

O ClearKey envia a chave de descriptografia ao navegador em texto puro.

É isso. A mesma criptografia AES-128 do Widevine. A mesma entrega via MPEG-DASH. Mas onde o Widevine negocia chaves por um canal seguro e descriptografa o vídeo dentro de um sandbox de hardware no qual o navegador não consegue espiar, o ClearKey entrega a chave bruta ao JavaScript e diz “aqui está”.

text

    WIDEVINE L1                          CLEARKEY
    ───────────────────────              ───────────────────────
    License server (HTTPS)               No license server
    Encrypted key exchange               Key in plaintext JS
    Hardware TEE decryption              Software decryption
    Key never in JS memory               Key IS the JS
    Per-device, per-session policy       No policy at all

O DASH Industry Forum afirma que o ClearKey é “recomendado apenas para fins de teste”. Algumas plataformas decidiram usá-lo em produção mesmo assim. Tanto os sites quanto o app que analisei dependem dessa decisão.

Examinei dezenas de sites de streaming pirata. Todos seguem o mesmo padrão.

text

    ┌──────────────────────────────────────────────────────────────┐
                        HOW IT ACTUALLY WORKS                     
    └──────────────────────────────────────────────────────────────┘

    STEP 1                    STEP 2                    STEP 3
    User visits               Clicks a channel          Page loads an <iframe>
    pirate-site.co            (e.g. "Sky Sports")       from a different domain

    ┌──────────────┐          ┌──────────────┐          ┌──────────────────┐
                              ┌────┐┌────┐│            player-host.co  
      Channel       click     ESPN││DAZN││  iframe                    
      Grid Page    ───────>   ├────┤├────┤│ ───────>   Shaka Player    
                              Sky ││beIN││            + DRM keys      
      (static                 └────┘└────┘│            + manifest URL  
       HTML)                └──────────────┘          └────────┬─────────┘
    └──────────────┘                                             
                                                                  fetches
                                                                 
                                                    ┌──────────────────────┐
                                                      LEGITIMATE CDN      
                                                      (akamaized.net,     
                                                       skycdp.com,        
                                                       indazn.com)        
                                                                          
                                                      Encrypted DASH      
                                                      segments            
                                                    └──────────────────────┘

    The pirate site serves ZERO video.
    The CDN bill belongs to the legitimate provider.
    The pirate site hosts ~50KB of HTML.

O site pirata é apenas um intermediário que conhece duas strings hexadecimais. Ele aponta o navegador do espectador para um CDN real, entrega a chave de descriptografia, e o navegador faz o resto. O CDN nunca sabe que o espectador não é um assinante pagante.

A página do host do player contém um bloco <script> com as chaves, envolto em uma ofuscação que um script Node de 30 linhas desfaz em menos de um segundo:

javascript

// Before: 40 lines of _0x4a2f, IIFEs, string-array lookups
// After: this is what it actually does

var drmKeyId = 'a1b2c3d4e5f6a7b80000000000000000';
var drmKey   = '0123456789abcdef0123456789abcdef';

player.configure({
    drm: { clearKeys: { [drmKeyId]: drmKey } }
});
player.load('https://cdn.legitimate-provider.com/manifest.mpd');

Duas variáveis. Duas strings hexadecimais. Essa é toda a “proteção DRM”. A ofuscação — renomeação de variáveis, arrays de strings, achatamento de fluxo de controle — é desfeita pelo eval(), porque o navegador também tem que executá-la. Se o navegador consegue executar, um script consegue executar.

Uma vez extraídas, as chaves se espalham por playlists M3U no GitHub e no Telegram. Encontrei um único arquivo M3U com 545 entradas ClearKey em 92 CDNs. Público, pesquisável, indexado pelo Google. Tempo da extração até a distribuição global: minutos. Tempo para a chave ser revogada: geralmente nunca.

Nem toda operação pirata é uma página web estática. Algumas distribuem um app Android completo — com telas de login, analytics do Firebase, configs criptografadas e uma UI profissional. Um app que analisei durante a Copa do Mundo segue essa abordagem. 525 canais. 36 categorias. Uma seção dedicada “MUNDIAL FIFA 2026” com ângulos multicam para cada partida.

A config criptografada de canais do app — 525 canais em 36 categorias, com URLs criptografadas em AES e credenciais de DRM. [URLs omitidas]

O app busca sua lista de canais como um JSON criptografado em AES de um servidor remoto. Cada campo — URLs de transmissão, URIs de licença de DRM, cabeçalhos HTTP — é texto cifrado AES codificado em base64. A chave de descriptografia é uma string de 16 caracteres armazenada no Firebase Remote Config, buscada na inicialização.

Parece sério. Aí você olha o texto cifrado:

text

    236 URLs share the same first 35 encrypted blocks.

    Block 0: f91b7f273abccc6e...  ← identical across all 236
    Block 1: 932b23560f1d43ba...  ← identical
    Block 2: a7d788a399cea962...  ← identical
    ...

    ECB mode. Same plaintext block = same ciphertext block.
    The URLs all start with the same CDN domain prefix.

O AES-ECB é o exemplo clássico de como não usar AES. Todo curso de criptografia ensina isso com o pinguim do ECB — criptografe um bitmap com ECB e a imagem ainda é reconhecível porque blocos de texto puro idênticos produzem blocos de texto cifrado idênticos. Este app criptografa 236 URLs que começam com o mesmo domínio de CDN, produzindo 236 textos cifrados com um prefixo idêntico de 560 bytes. A análise de padrões por si só revela a estrutura antes mesmo de você encontrar a chave.

Uma vez descriptografadas, as credenciais ClearKey não estão em uma troca de chaves separada. Elas estão na própria URI de licença, como parâmetros de query em texto puro:

text

    drm_license_uri (after decryption):

    https://[redacted]/?keyid=49eb924b...&key=6e131b04...
                              ^^^^^^^^        ^^^^^^^^
                              ClearKey ID     ClearKey Key
                              (in the URL)    (in the URL)

O “servidor de licenças” do app é uma URL que contém a chave. Não há desafio-resposta. Nenhuma vinculação de sessão. O app busca a URL, a URL é a chave, e a chave descriptografa a transmissão.

Três camadas de indireção — Firebase Remote Config, criptografia AES, um endpoint de “servidor de licenças” — todas colapsando na mesma falha: a chave de descriptografia acaba no cliente, em texto puro, porque o ClearKey exige isso.

text

    ┌──────────────────────────────────────────────────────────────┐
    │           ANDROID APP ARCHITECTURE                           │
    └──────────────────────────────────────────────────────────────┘

    1. App launches
       └──> Firebase Remote Config
            └──> Fetches AES key ("claveapp") + config URLs

    2. App fetches encrypted JSON (525 channels)
       └──> Base64 decode ──> AES-128-ECB decrypt
            └──> Stream URLs, DRM license URIs, headers (plaintext)

    3. For CLEARKEY channels (348 of 525):
       └──> "License URI" = https://[redacted]/?keyid=XXX&key=YYY
            └──> Key ID and Key are IN THE URL

    4. App configures ExoPlayer with ClearKey
       └──> Fetches DASH manifest from legitimate CDN
            └──> Decrypts video with the key from step 3

    Package name: com.example.myapplication
    Encryption:   AES/ECB/PKCS5Padding (textbook insecure)
    Key storage:  Firebase Remote Config (single API call to extract)
    Key length:   16 characters, static, never rotated

O nome do pacote com.example.myapplication diz tudo sobre o rigor de desenvolvimento por trás dessa operação. O template padrão do Android Studio. Nem renomeado.

A parte mais silenciosamente condenatória — e a parte que mostra a real sofisticação da operação, que é majoritariamente logística — é onde a config criptografada está hospedada. O app busca seu JSON de canais em um repositório público do GitHub. Qualquer um pode navegá-lo. Qualquer um pode dar git clone nele. Qualquer um pode acompanhar o histórico de commits.

E o histórico de commits é a parte interessante:

O repositório público do GitHub que hospeda a lista de canais criptografada do app. Um commit aterrissa a cada 4–5 minutos — edições automatizadas no JSON de canais conforme as transmissões upstream são rotacionadas, derrubadas ou substituídas. Nome de usuário e dono do repo omitidos.

Um commit aterrissa a cada 4–5 minutos. O diff é sempre contra tv (10).json ou bearer.json — a lista de canais criptografada, e as credenciais de autenticação usadas para buscar novas transmissões do upstream. As mensagens de commit são todas "Actualizar tv (10).json desde tv.json" ou "Actualizar bearer.json desde panel - <timestamp>". Tradução: um job automatizado, em algum lugar, está reescrevendo a config de canais a cada poucos minutos e empurrando a atualização para que os celulares rodando o app peguem novas URLs de transmissão e credenciais de DRM rotacionadas dentro de um intervalo de polling.

Este é o verdadeiro fosso da operação. Não o AES-ECB (quebrado). Não o Firebase Remote Config (uma chamada de API). Não o “servidor de licenças” (uma URL com a chave dentro). O fosso é operacional: uma peça de automação que mantém o JSON de canais alinhado com quaisquer feeds upstream que estejam vivos em qualquer minuto dado, hospedada à plena vista em um CDN gratuito que eles não precisaram construir. Quando um provedor legítimo rotaciona uma chave, o bot percebe, busca a nova, recriptografa a config e faz o commit. Quando um CDN bloqueia o IP de origem, o bot encontra outro. Os celulares dos clientes fazem polling, veem o novo commit, buscam a nova config e continuam assistindo à partida. O usuário nem vê a rotação acontecer.

A defesa que todo mundo recorre é “revogar a chave”. Mas você não consegue revogar uma chave mais rápido do que um script consegue empurrar uma nova para um repositório do GitHub. O descompasso na cadência é o jogo inteiro.

Auditoria webApp Android
Transmissões670525 (348 ClearKey)
CDNs16934
Países33~8 (foco na América Latina)
Armazenamento da chaveBloco <script> JavaScriptFirebase Remote Config
OfuscaçãoRenomeação de variáveis JS + IIFEsAES-128-ECB (quebrado)
Chave em texto puro no clienteSimSim
Cobertura da Copa do MundoDezenas de canais de esportes28 canais dedicados + multicam

Ambas as abordagens — o site estático e o app Android completo — terminam no mesmo lugar: um par de chaves ClearKey na memória do cliente, sem mecanismo para impedir a extração, sem vinculação de sessão, sem revogação e sem rotação de chaves.

A economia explica tudo. Sites piratas hospedam ~50KB de HTML estático e apontam seu navegador para o CDN de outra pessoa. O app é um wrapper fino de ExoPlayer em torno da infraestrutura de outra pessoa. Nenhum serve vídeo. Ambos monetizam através de redes de anúncios.

O StreamEast teve 1,6 bilhão de visitas antes de ser fechado em setembro de 2025. A rede de IPTV da “Operação Takendown” tinha 22 milhões de usuários e EUR 250 milhões por mês. Um site de médio porte durante a Copa do Mundo — um milhão de visitantes no dia do jogo, seis impressões de anúncio cada, CPM de US$ 1,50 — fatura US$ 9.000 por dia contra custos de hospedagem essencialmente nulos.

A fiscalização não para de escalar — penas de prisão na Espanha, sentenças de US$ 18,75 milhões no Texas, 27.000 feeds derrubados na semana anterior à Copa do Mundo — e novos sites continuam aparecendo. Porque a vulnerabilidade é arquitetural. Você não consegue prender o caminho para fora de uma especificação que coloca a chave de descriptografia no navegador. Você também não consegue criptografar o caminho para fora dela, como o app Android demonstra: três camadas de criptografia, e a chave ainda acaba em texto puro no cliente, porque o ClearKey exige isso.

A correção é migrar inteiramente para fora do ClearKey — para Widevine, FairPlay ou PlayReady. Até lá, a combinação está escrita no verso do cadeado, e a Copa do Mundo está garantindo que todo mundo saiba onde olhar.

Related Content