2 pontos por GN⁺ 2023-08-24 | 1 comentários | Compartilhar no WhatsApp
  • O Discord, um app de desktop baseado em Electron, funciona internamente como uma janela Chromium e permite abrir as ferramentas de desenvolvedor da web, o que possibilita modificar código no lado do cliente
  • Alguns clientes modificados e plugins desbloqueiam, no lado do cliente, parte dos recursos que exigem a assinatura paga do Nitro
  • O ponto central é injetar módulos divididos pelo code splitting do Webpack na variável webpackChunkdiscord_app para explorar e substituir funções internas
  • A função de verificação da qualidade do compartilhamento de tela é validada apenas no cliente, então pode ser contornada, mas os temas premium contam também com validação adicional de sincronização no servidor
  • Todas as técnicas demonstradas violam os Termos de Uso do Discord e trazem risco de suspensão da conta, além do risco de roubo da conta pela execução de código não verificado

Visão geral

  • Existem vários clientes modificados do Discord que mudam a aparência ou adicionam recursos, e alguns plugins chegam a desbloquear funções que exigem a assinatura paga do Nitro
  • O texto explica o princípio técnico que torna esse comportamento possível por meio da análise da estrutura do cliente

Ativação das ferramentas de desenvolvedor

  • O Discord é desenvolvido com o framework Electron, usado para criar apps multiplataforma com tecnologias web, então ele é semelhante a um site executado dentro de um navegador
  • Em essência, é uma janela Chromium, então as ferramentas de desenvolvedor podem ser abertas, embora fiquem desativadas por padrão
    • Isso foi bloqueado porque houve muitos casos de usuários que tiveram a conta roubada após colarem comandos maliciosos induzidos por engenharia social de agentes maliciosos
  • Se você entende os riscos, pode ativar isso adicionando o valor true para DANGEROUS_ENABLE_DEVTOOLS_ONLY_ENABLE_IF_YOU_KNOW_WHAT_YOURE_DOING no arquivo de configuração %appdata%/discord/settings.json
    • Depois disso, use ctrl + shift + i para abrir o console de desenvolvedor

Patching de funções do Discord

  • Para otimizar o carregamento inicial, o código é dividido em vários chunks e carregado em paralelo ou sob demanda (lazy-loaded), usando o recurso de code splitting do Webpack
  • Todos os chunks carregados ficam armazenados na variável webpackChunkdiscord_app
  • Para executar código que usa variáveis e funções do Discord, é preciso injetar código nessa variável
    • a.c é um objeto que contém todos os módulos, e cada módulo é composto por chunk_id, loaded e exports
    • exports inclui funções, objetos e valores primitivos exportados pelo módulo
  • É possível criar uma função find que percorre vários módulos JavaScript para localizar e chamar funções específicas
    • Exemplo: localizar e executar a função getCurrentUser()
  • Também é possível substituir a função original por outra para alterar o comportamento, permitindo modificação direta do código

Desbloqueio de streaming em alta qualidade

  • A partir deste ponto, o conteúdo viola claramente os Termos de Uso do Discord e pode levar à suspensão da conta, então o risco é por conta do usuário
  • As duas funções canStreamMidQuality e canStreamHighQuality, que verificam o nível de assinatura do usuário, são chamadas imediatamente antes da tela de seleção da qualidade do compartilhamento de tela
    • Se o valor retornado por ambas for forçado para true, torna-se possível selecionar compartilhamento de tela em resolução original a 60 FPS mesmo sem assinatura do Nitro
  • No momento, o Discord aparentemente não valida no servidor se a transmissão enviada realmente respeita os limites de quem não é assinante
    • Ainda assim, como o Discord ainda não usa criptografia de ponta a ponta (End-to-End encryption), existe possibilidade de detecção
    • Segundo o texto de referência, o Discord já inspeciona conteúdo de áudio e vídeo dos usuários e pode adicionar no futuro validação no servidor antes do compartilhamento de tela

Desbloqueio de temas premium

  • Se o valor da função canUseClientThemes, que retorna se o usuário pode usar temas do Nitro, for alterado para true, o botão de seleção de temas premium é desbloqueado
  • Porém, o tema é aplicado por um instante e logo volta ao padrão
    • Isso acontece porque o cliente tenta salvar a mudança de tema, mas o servidor valida que não há permissão e, ao receber a resposta, reaplica o tema padrão
  • Se a função shouldSync for patchada para retornar false quando o valor for appearance, impedindo apenas a sincronização das configurações visuais, a mudança de tema permanece
  • Os temas são gerenciados inteiramente no lado do cliente, e também sempre é possível alterar o CSS diretamente, então é difícil para o Discord bloquear isso

Conclusão

  • Existem códigos que facilitam aplicar os hacks demonstrados, mas é importante agir com cautela antes de modificar o cliente ou usar mods
  • O Discord pode suspender a qualquer momento contas que violem os termos de uso, e executar código não verificado com acesso à conta é extremamente perigoso
    • Mensagem codificada no texto: "Não cole no console de desenvolvedor um código que você não entende — essa é a forma mais fácil de ter sua conta roubada"

1 comentários

 
GN⁺ 2023-08-24
Comentários do Hacker News
  • Se a ideia for simplesmente executar um blob codificado em base64 no final para ativar todos os recursos, parece que isso pode virar um vetor de ataque bem fácil
    Não quis dizer que suspeitava do autor; acabei de decodificar e caí direitinho

    • Para quem está com preguiça de rodar base64 --decode, o resultado é este:
      // Here's a cake if you thought about inspecting the code before executing it:
      let css = 'font-size: 36px; font-weight: bold; color: red';
      console.log("%cNEVER paste code you don't understand into the development console.", css);
      console.log("%cThis is the best way to compromise your account.", css);
  • “No momento, o Discord parece não validar no servidor se o stream enviado realmente respeita os limites para não assinantes”, então fico curioso para saber quem achou que isso era uma boa implementação
    Validação do lado do cliente parece um erro bem básico

    • Provavelmente foi menos “esta é uma ótima implementação” e mais “se alguém descobrir como quebrar, a gente corrige depois”
      Uso o Discord há anos e é a primeira vez que ouço falar de uma tentativa de contornar a estrutura de acesso do Nitro; se não é algo disseminado, não parece haver muito motivo para se preocupar
    • Como alguém que implementa só a funcionalidade pronta, exatamente no formato final desejado, e sobe o PR, não faço a menor ideia de por que fizeram isso
      Separadamente, comecei meu quinto emprego novo só neste mês e aparentemente não me dou nada bem com gerentes de projeto
    • Considerando como as pessoas hoje em dia, especialmente crianças, gastam dinheiro com bastante facilidade, talvez isso já seja suficiente
      Quantas pessoas entendem esse hack e também estariam dispostas a pagar pelo Nitro? Deve haver milhares, talvez dezenas de milhares, usando vários mods de cliente do Discord que ativam alguns ou todos os recursos do Nitro, mas duvido de quanta receita real surgiria ao bloquear isso
      Pessoalmente, se eu precisasse ou quisesse esses recursos, seria muito menos incômodo pagar US$ 10 por mês. Acho melhor do que ficar acompanhando mods que vão quebrar a cada atualização do Discord e torcer para que o mantenedor não coloque código malicioso
    • Pela API, também dá para ver o nome, o tópico e o horário da última mensagem de canais ocultos
      Os canais só ficam ocultos no cliente. Para deixar claro, ainda assim não dá para ver o conteúdo das mensagens desses canais
    • Isso não é um componente da API do Discord, e sim do lado dos servidores de voz, distribuídos em centenas de máquinas pelo mundo
      O servidor de voz só confirma com a API se você tem permissão para entrar e, depois disso, funciona como um broadcaster de pacotes um-para-muitos
  • Isto está mais próximo do hacker clássico, no sentido curioso e habilidoso
    Não há dano sério, e isso nos lembra que apps não são magia e que código é algo incrível

    • Talvez esteja mais para “cracker”, mas concordo que é o tipo de conhecimento que as empresas preferem que a gente não tenha
      Assim elas conseguem tentar extrair mais dinheiro de nós sem resistência
  • Vale lembrar novamente que tudo que você envia pelo Discord, incluindo DMs, fica registrado em texto puro no Discord e acessível ao Discord e a quem comprar a empresa
    Houve uma época em que parecia que a Microsoft iria comprá-lo, e agora parece que caminham para um IPO
    Só ter uma conta já normaliza conversas privadas fáceis de minerar para IA e de serem usadas pelo Discord e por administradores de bancos de dados/sistemas. A Section 702 do FISA Amendments Act (FAA702) permite que órgãos federais de investigação acessem esses dados sem mandado
    Só a possibilidade de front-running em criptomoedas já deve valer dezenas de milhões de dólares por dia
    Se você é amigo de alguém, não deveria recomendar que essa pessoa use um sistema de chat sem criptografia de ponta a ponta. Não seja o mel dentro da armadilha

    • Vale lembrar novamente que tudo que você envia a fóruns, incluindo DMs, fica registrado em texto puro e acessível aos administradores
      Isso é esperado, a menos que você use um dos poucos serviços que implementam um verdadeiro modelo zero trust em que o usuário gerencia as próprias chaves. As mensagens são armazenadas para que o usuário possa acessá-las de novo
      Há serviços, como o Matrix, que fazem mensagens em grupo com criptografia de ponta a ponta de uma forma relativamente amigável, mas eles são exceção. Não é justo pintar o Discord como especialmente malicioso só porque ele faz o mesmo que 95% das plataformas de comunicação eletrônica sempre fizeram
    • “Só ter uma conta já normaliza”, mas isso já foi normalizado há muito tempo, e o Discord venceu
      Não estou dizendo que isso é bom, mas em algumas comunidades não há opção além de não participar
      É pior do que o antigo “todo mundo usa WhatsApp”. Naquela época, você tinha o número da pessoa e era fácil entrar em contato por outros meios, mas o atrativo do Discord não são conversas privadas, e sim comunidades com espaços semipúblicos. Aqui, “público” não significa aberto a todos, mas algo mais próximo de “lido por umas 100 pessoas”
    • Felizmente, o Discord tem exclusão de mensagens sem rastros
      Quando você apaga uma mensagem, ela não fica mais armazenada no banco de dados
  • Recentemente, a OpenAI desativou de repente o Discord para beta testers, então não conseguimos mais ver com quem discutimos o quê
    Fiquei me perguntando se havia uma forma de exportar o chat para impedir que a comunidade fosse separada sem deixar nem um jeito de o administrador do servidor consultar o histórico
    Há várias extensões do Chrome que exportam chats do Discord, mas a maioria parece bloquear alguns recursos atrás de pagamento
    Acabou que era muito fácil copiar a fonte da extensão da pasta do Chrome, modificar no JavaScript verificações booleanas como is_pro e recarregá-la como extensão descompactada

  • Eles avisam corretamente que usar esse tipo de truque pode resultar em banimento, mas há algum precedente de o Discord banir usuários por algo assim?

    • O Discord não tem problema nenhum em banir pessoas por qualquer motivo
      Também impede o uso de clientes alternativos. Se sua conta é importante, é melhor não mexer com o Discord
    • O README do Vencord, um dos mods mais populares, diz o seguinte:
      “Modificar o cliente viola os Termos de Serviço do Discord.”
      Dito isso, o Discord é bem indiferente a isso, e não há casos conhecidos de banimento só por usar mods de cliente. Então, no geral, você deve ficar bem desde que não use plugins que implementem abuso. E nem precisa se preocupar, porque dizem que todos os plugins integrados são seguros
  • Dá para entender alguns temas serem ativados desse jeito, mas é bem difícil entender terem decidido a qualidade do streaming por verificação no lado do cliente, e não no lado do servidor

    • Ainda mais porque bastaria verificar o bitrate de entrada e saída
      Nem seria preciso acessar o vídeo em si; mesmo que estivesse totalmente criptografado, a quantidade de dados transmitidos mostraria em que qualidade ele está sendo transmitido
  • A grande regra da engenharia de frontend se confirmou mais uma vez
    “Nunca, jamais confie no cliente

  • Desde que vi que isso podia ser tratado só no lado do cliente, venho usando as ferramentas de desenvolvedor e ativando o botão de streaming 1080p60, e funciona mesmo
    Não sei há quantos anos, mas parece que ninguém do lado do Discord se importa

  • Já tentei seguir esse caminho antes, mas acabei desistindo porque não encontrei um jeito de aplicar patches no cliente de forma consistente, especialmente depois das atualizações
    Mas, vendo este método, bate de novo a vontade de “abrir e cutucar”
    Existe algum jeito simples de vasculhar as APIs disponíveis dessa forma? Tentei logar tudo, mas virou uma bagunça enorme com maps, internacionalização etc. Fico curioso se alguém já fez o trabalho pesado e montou algo como uma documentação de engenharia reversa