Como Criei Acidentalmente um Chat de Voz Impossível de Espionar

Como Criei Acidentalmente um Chat de Voz Impossível de Espionar

Um desenvolvedor relata como, ao tentar resolver problemas de latência em chamadas de voz, acabou criando um sistema de comunicação P2P que, por sua arquitetura, se tornou intrinsecamente privado e difícil de interceptar.

MundiX News·08 de julho de 2026·10 min de leitura·👁 1 views

Como Criei Acidentalmente um Chat de Voz Impossível de Espionar

Imediatamente, desaponto os amantes de frases de efeito: eu não criei um "mensageiro seguro", não pensei em vigilância, escutas ou privacidade em geral. Minha única intenção era ter a capacidade de ligar rapidamente e sem impedimentos para qualquer pessoa. O resultado foi um chat de voz onde a conversa é fisicamente impossível de ser escutada externamente, e eu só percebi isso muito depois. Portanto, "impossível de escutar" no título não é o objetivo, mas sim um efeito colateral.

A história começou de forma banal: uma noite comum, uma conversa no Discord, mas em algum momento a latência na entrega da voz atingiu 3-5 segundos, tornando a comunicação impossível. Tentamos por cerca de quarenta minutos corrigir a situação: trocamos servidores VPN, reiniciamos o "Запрет" (um serviço russo de acesso à internet) e mudamos estratégias, e, desesperados, reinstalamos o próprio Discord. A latência às vezes desaparecia, mas sempre retornava. Buscamos alternativas: o Telemost, com sua interface corporativa e existindo apenas na web, foi descartado quase imediatamente. A situação piorou: na Rússia, a maioria das alternativas não abre sem VPN (exceto clones francamente vergonhosos do Discord mencionado acima), e o TeamSpeak tem uma barreira de entrada tão alta que é mais fácil ir pessoalmente ao interlocutor: registrar-se, instalar o aplicativo, encontrar um servidor público e descobrir como se conectar. Em cerca de uma hora e meia, vasculhamos tudo o que aparecia e nenhum dos serviços conseguiu resolver a tarefa mais simples: ligar agora mesmo e ouvir um ao outro sem latência e sem a necessidade de gerenciar VPNs/serviços de contorno.

No final, as últimas esperanças se dissiparam: se não há alternativas, vamos criá-las. Em uma noite, esbocei um protótipo – a ideia era primitiva, "nada supérfluo": entre e fale. Sem registro com código de confirmação por e-mail, sem onboarding, sem pop-ups "permita notificações", e depois de algumas semanas percebi que esse "nada supérfluo" era a principal característica. A efemeridade e a ausência de toda a parafernália moderna que descartei por preguiça e minimalismo acabaram sendo exatamente o que os outros não têm. O projeto foi nomeado "Void", agora ele já está em produção e cumpre exatamente a função para a qual foi criado. A seguir, explicarei como ele funciona internamente, por que, devido a uma decisão, ele se tornou rápido, privado e inconveniente para escutas, e onde me queimei no caminho.

Por que a Latência Ocorria

Se analisarmos a origem da latência, a resposta será bastante tediosa. O fato é que a voz não vai diretamente para o interlocutor, mas faz uma curva através de um servidor localizado em algum lugar longe da Rússia. Minha voz ia para o data center do Discord, de lá para um amigo, e a resposta dele voltava pelo mesmo caminho. Milhares de quilômetros extras em cada direção, e a VPN apenas piorava essa situação, adicionando mais uma curva por cima. E essa coisa, o servidor de mídia no meio da conversa, é a raiz de tudo. Como todo o áudio passa por ele, tecnicamente a voz está completamente em suas mãos: eles podem gravar, analisar e, se solicitado educadamente, compartilhar. Além disso, como existe uma conta, há algo a que se vincular: histórico, moderação e, mais recentemente, verificação de idade por passaporte. Remova o servidor do meio da conversa, e metade desses problemas desaparece de uma vez, simplesmente porque sua fonte desaparece. Assim, a questão era puramente de engenharia: como fazer com que duas pessoas falassem diretamente, e o servidor apenas as conectasse – e não participasse mais. Acontece que, para isso, o navegador há muito tempo possui o WebRTC, basta juntar tudo.

O Servidor Conecta e Não Participa Mais

A parte do servidor do Void é Node.js, WS e um pouco de Express. Enquanto a chamada está ativa, o servidor faz exatamente uma coisa: conecta os participantes. Recebe de um a descrição da conexão (SDP), a transmite para o outro, troca candidatos ICE entre eles – ou seja, mensagens do tipo "é assim que você pode me alcançar". Alguns kilobytes de texto de serviço para estabelecer a conexão, e depois disso o servidor sai da conversa. Não há banco de dados. Não "tem, mas nós realmente não olhamos", mas sim não existe como fenômeno. As salas ficam em um Map comum na memória do processo: código da sala e lista de quem está nela. Saiu o último participante – com ele, desapareceu o registro da memória. Um único JSON com estatísticas anônimas é gravado em disco: quantas salas por dia, quantas conexões foram diretas, quantas foram via relay. Não há apelidos, mensagens ou gravações de chamadas lá, porque elas não chegam ao servidor. O código-fonte, literalmente, todo o "banco de dados" do servidor é um único Map na memória do processo: Map { roomCode => { users: Map { userId => { ws, nickname, mic, sound, screen } }, cleanupTimer: setTimeout id | null } }. Saiu o último participante – rooms.delete(code), e da sala não restou absolutamente nada. Daí o "impossível de escutar" do título. Escutar a conversa externamente é simplesmente impossível, ela não está no servidor. No banco de dados, que não existe, também não está. E entre si, os interlocutores criptografam o fluxo diretamente: no WebRTC, isso é DTLS – SRTP, as chaves são negociadas entre os navegadores, ninguém as detém no meio. Mesmo quando um par, devido a uma rede instável, passa por um relay, o relay apenas encaminha pacotes criptografados e não pode descriptografá-los. Metadados, quem se conectou com quem, o servidor vê no momento do contato, mas não grava em lugar nenhum: a sala vive na memória e desaparece com o último participante. E aqui está uma nota honesta: "impossível de escutar" refere-se ao caminho entre os interlocutores, e não aos seus dispositivos. Se o dispositivo de alguém estiver infectado, nenhum P2P salvará: o som será capturado exatamente onde ele soa ou é pronunciado, antes de qualquer criptografia. A criptografia protege o canal, não o endpoint vulnerável. O Void remove a possibilidade de escuta no caminho, mas se o adversário já estiver no seu sistema – ele ouvirá a conversa, e a arquitetura não resolve isso.

Por que Poucas Pessoas na Sala

Como o servidor não mistura o áudio, os participantes devem se conectar uns aos outros. Para dois, é uma conexão; para um grupo, "cada um com cada um", o número de conexões cresce exponencialmente: para cinco pessoas são 10, para dez já são 45, e cada um envia seu áudio para todos os outros em um fluxo separado. Por isso, as salas são mantidas pequenas: o teto é de dez pessoas, e essa, infelizmente, é o preço da solução. Se você precisa de uma sala para cem pessoas, terá que colocar um SFU no meio, e ele novamente começará a ver o fluxo. Eu não queria colocar um SFU, pois para isso teria que descartar exatamente o motivo pelo qual tudo começou. "Perfect negotiation", ou onde o WebRTC morde. Durante os testes, situações em que ambos os lados decidem atualizar a conexão simultaneamente e enviar ofertas um ao outro não foram raras. Isso é chamado de glare, e o código que não espera tal evento morre nesse momento: ambos esperam uma resposta que ninguém enviará. Isso é corrigido por um recurso da especificação W3C chamado "perfect negotiation". Cada conexão recebe um papel: educado e não educado, e é determinado simetricamente pela comparação de IDs – dois lados terão papéis opostos sem qualquer acordo entre eles. O código-fonte: cujo ID é "maior" como string, esse é o educado. O interlocutor tem a comparação espelhada, então exatamente um se torna educado: peer._polite = String(clientId) > String(userId);. O educado, em caso de colisão, reverte sua oferta e aceita a do outro, e o não educado – impõe a sua: const offerCollision = peer.signalingState !== "stable" && !peer._isSettingRemoteAnswerPending; const ignoreOffer = !peer._polite && offerCollision; if (ignoreOffer) return; // não educado: mantemos nossa oferta await peer.setRemoteDescription(new RTCSessionDescription(data.offer)); await peer.setLocalDescription(); // educado: cedemos, rollback implícito. Em seguida, setLocalDescription() sem argumentos entende por si só o que é apropriado agora, oferta ou resposta. Sem "perfect negotiation", a chamada em grupo se desfaz exatamente no momento em que dois mudam algo simultaneamente (e eles mudarão), e eu tropecei nisso classicamente: em duas abas tudo funciona, mas em uma sala real – conexões travadas do nada. A conclusão é bastante banal: "funciona para mim" e "funciona na realidade" no WebRTC – são coisas completamente diferentes.

NAT, VPN e Por Que Ainda é Preciso Chegar ao Interlocutor

Para que duas pessoas se conectem diretamente, cada uma precisa saber seu endereço externo e contornar o NAT. Servidores STUN, leves e públicos, fazem isso, eles simplesmente respondem "é assim que você parece de fora". Para a maioria das pessoas em casa, isso é suficiente, e o áudio segue o caminho mais curto possível entre vocês. O caminho mais curto é a chave para a latência mínima: você ouve como se a pessoa estivesse na casa ao lado, porque o áudio não viaja através de um data center em outro país. Mas tudo quebra no NAT simétrico e especialmente no CG-NAT das operadoras móveis, onde centenas de assinantes compartilham um único endereço externo, onde simplesmente não é possível estabelecer uma conexão direta. De acordo com minhas estatísticas, após uma dúzia de horas de testes em tais redes, cerca de 23% dos pares não se conectam diretamente e recorrem a uma opção de backup – um servidor TURN (no meu caso, é o coturn), que retransmite o tráfego quando não há caminho direto. Sim, para tal par, a chamada fisicamente passa pelo meu servidor. Mas o coturn retransmite pacotes já criptografados (DTLS-SRTP) e não sabe como descriptografá-los. É claro que é possível desativar o TURN completamente, mas nesse caso, os próprios ~23% de pares complexos falham no STUN-only, então ele está em produção. Código-fonte: Não há um banco de dados separado para o TURN também: as credenciais são de curta duração e calculadas dinamicamente pelo esquema padrão do coturn: const expiry = Math.floor(Date.now() / 1000) + 3600; // TTL = 1 hora const username = ${expiry}:${userId}; const credential = crypto.createHmac("sha1", TURN_SECRET).update(username).digest("base64");. E sobre VPN: se o próprio site estiver bloqueado e só abrir com VPN – o túnel será usado apenas para abrir a página e trocar sinalização – apenas alguns segundos na conexão. A conversa em si continua diretamente e a VPN não a afeta: o ping da chamada não depende de por qual país seu túnel passa, porque o áudio não passa por ele.

Quando a Rede Falha – Como Lidar?

A conexão P2P é frágil, e as razões para isso podem ser muitas: o Wi-Fi mudou, pacotes foram perdidos, a operadora mudou a rota, a conexão foi interrompida. Sem um mecanismo para lidar com tais casos, seria uma interrupção da chamada, então, sobre o WebRTC, foi necessário construir uma máquina de recuperação. Funciona mais ou menos assim: o status desconectado ainda não é o fim, esperamos pacientemente alguns segundos, muitas vezes a rede se conserta sozinha. Se não ajudar – o lado faz um ICE-restart, procura a rota novamente. Se não ajudar em alguns segundos – reconstrói a conexão do zero, o outro lado, por um flag, faz o mesmo. Separadamente, há um watchdog para conexões mortas: a cada duas segundos ele verifica o contador de pacotes recebidos, e se a conexão estiver viva em status, mas não houver pacotes por mais de cinco segundos, ele não espera o timeout de meio minuto, mas reconstrói imediatamente. Na prática, isso detecta "parece conectado, mas não há comunicação" significativamente mais rápido. Isso custa um segundo desagradável: no momento da reconstrução, o som cai por um ou dois segundos. O microfone, nesse caso, não é perdido, a conversa continua.

O Que Foi Obtido do Navegador Quase de Graça

Como tudo vive na web, algumas coisas saíram a um custo irrisório. Cancelamento de ruído – é o RNNoise, compilado em WASM e rodando no AudioWorklet: teclado, cooler e rua são cortados diretamente no cliente, antes mesmo de serem enviados ao interlocutor. Chat e arquivos seguem o mesmo P2P, via RTCDataChannel, em pedaços binários de 60 KB (um pouco abaixo do limite do SCTP), arquivos de até 100 MB. Compartilhamento de tela com áudio e em Full HD, pelo mesmo canal direto. Nada disso chega ao servidor, as garantias são as mesmas do áudio.

O Que No Final Não é Perfeito

Sem uma seção de desvantagens – nada: Mesh não suporta escala. Dez pessoas é o teto, e aumentá-lo sem passar para SFU é impossível, e SFU mataria a principal característica. Isso não é "falta de tempo", é uma bifurcação, e eu conscientemente me inclinei para a privacidade. UserId é falsificável. O cliente inventa seu próprio ID, o servidor apenas verifica o formato. Teoricamente, você pode se passar por outro ID. Na prática, não há nada a roubar: entre as sessões não há estado, não há contas. Não construí uma fortaleza em torno de um galinheiro vazio. Não há push na web. Fechou a aba – você não ouvirá a chamada, não há como "puxá-lo", porque não há conta nem sua sessão no servidor. Na versão desktop, isso é parcialmente corrigido pelo tray, na web – de forma alguma. Reiniciar o servidor mata as salas. O outro lado da ausência de BD. Para uma chamada de vinte minutos, ok, mas se você cair no momento da implantação – entre novamente. Desktop apenas no Windows. O aplicativo em Tauri existe para Windows, macOS e Linux ainda não. A web funciona em qualquer lugar onde o WebRTC funcione. Tudo da lista acima – não é um fracasso, mas sim o preço de uma construção onde o servidor não precisa saber nada sobre você. Mas dizer que tudo é perfeito seria uma mentira.

Uma Divulgação Honesta – Não é um "Matador de Discord"

Discord é sobre comunidades, servidores, papéis, online eterno, e essa é uma tarefa separada que o Void não resolve e não tenta resolver. Void é mais como "ligar rapidamente e ir embora", mais próximo de uma ligação telefônica do que de uma rede social. Por que tudo isso? Todo o projeto nasceu de um problema fundamental: eu queria apenas conversar, mas tive que lutar contra a latência e procurar para onde fugir. Então, eu o fiz principalmente para mim e alguns amigos, e a "privacidade" acabou sendo um efeito colateral, pois ao remover tudo o que era supérfluo do esquema, acabou não havendo nada para coletar – porque não há com o quê. Você pode experimentar o Void no navegador em void-room.space, sem instalação e registro: crie uma sala, envie o código para o interlocutor – e falem. Exatamente o que me faltou na época. O código está aberto no GitHub – ficarei feliz com estrelas e issues. P.S. Muitas coisas ficaram nos bastidores que não couberam no artigo: máquina de recuperação em caso de interrupções, eco, screencast-ducking, versão desktop em Tauri. Acumulei muitos problemas durante meses de desenvolvimento e, se houver demanda – ficarei feliz em analisar os mais interessantes separadamente. Paz!

🛡️⚡

Pare de pesquisar. Comece a hackear.

O MundiX é seu copiloto de pentest com IA: comandos exatos, análise de outputs e próximo passo na kill chain — em segundos.

Testar grátis por 7 dias →

Sem cartão para começar · Planos a partir de R$49/mês

📤 Compartilhar & Baixar

🧰 Ferramentas recomendadas

Divulgação: alguns links são patrocinados. Podemos receber comissão se você comprar — sem custo extra para você. Só indicamos o que faz sentido para a comunidade.

Aprendendo Kali Linux: Teste de segurança, pentest e hacking ético

Aprendendo Kali Linux: Teste de segurança, pentest e hacking ético

Com centenas de ferramentas pré-instaladas, a distribuição Kali Linux facilita o trabalho de os profissionais de segurança começarem a fazer testes de segurança rapidamente. No entanto, com mais de 600 ferramentas em seu arsenal, o Kali Linux também pode ser desafiador. A nova edição deste prático livro abrange as atualizações nas ferramentas e inclui uma melhor abordagem da análise forense e da engenharia reversa. Ric Messier, autor, não fica apenas no teste de segurança, mas também faz uma abordagem sobre a execução de análise forense, incluindo a análise em disco e na memória, assim como alguma análise básica de malware. • Explore as diversas ferramentas disponíveis no Kali Linux • Entenda o valor do teste de segurança e examine os tipos de teste disponíveis • Aprenda os aspectos básicos do pentest em todo o ciclo de vida do ataque • Instale o Kali Linux em vários sistemas, tanto físicos quanto virtuais • Descubra como usar diferentes ferramentas destinadas à segurança • Estruture um teste de segurança baseado nas ferramentas do Kali Linux • Estenda as ferramentas do Kali para criar técnicas de ataque avançadas • Use o Kali Linux para ajudar a criar relatórios quando o teste terminar “A abordagem concisa, clara e baseada na experiência adotada por Ric Messier para a introdução do Kali Linux e dos testes de cibersegurança é incomparável. Este livro é uma leitura excelente e acessível para iniciantes e um recurso valioso para qualquer pessoa.” —Alexander Arlt, Consultor sênior de segurança, Google

Ver na Amazon
Gshield 2 em 1 Hub Extensor Conector USB-C + USB-A e Adaptador de Rede Ethernet LAN RJ45 com 3 Entradas USB 3.0 até 5 Gbps em Liga de Alumínio para Computador e Notebook, Cinza

Gshield 2 em 1 Hub Extensor Conector USB-C + USB-A e Adaptador de Rede Ethernet LAN RJ45 com 3 Entradas USB 3.0 até 5 Gbps em Liga de Alumínio para Computador e Notebook, Cinza

Compatível com portas USB-C e USB-A, ideal para ampliar a conectividade de dispositivos como MacBook Pro e outros com portas USB-C. Inclui um adaptador USB-A extra, proporcionando uma conexão Ethernet estável e veloz de até 1 Gbps, perfeita para filmes, jogos online e videoconferências. Oferece três portas USB 3.0 com velocidades de transferência de até 5 Gbps, permitindo conectar mouse, teclado, discos rígidos e outros periféricos. Fabricado em alumínio durável, garantindo longa vida útil e resistência ao uso diário. Design compacto e leve, ideal para viagens de negócios e uso diário, facilitando o transporte e armazenamento. Funciona com Windows 10/8.1/8, Mac OS e Chrome OS, oferecendo versatilidade incomparável para diversas necessidades de conectividade. Assegura uma conectividade estável e rápida, perfeita para tarefas exigentes como transferência de dados, streaming e mais.

Ver na Amazon
Hacking APIs: Breaking Web Application Programming Interfaces

Hacking APIs: Breaking Web Application Programming Interfaces

Hacking APIs is a crash course on web API security testing that will prepare you to penetration-test APIs, reap high rewards on bug bounty programs, and make your own APIs more secure. You'll learn how REST and GraphQL APIs work in the wild and set up a streamlined API testing lab with Burp Suite and Postman. Then you'll master tools useful for reconnaissance, endpoint analysis, and fuzzing, such as Kiterunner and OWASP Amass. Next, you'll learn to perform common attacks, like those targeting an API's authentication mechanisms and the injection vulnerabilities commonly found in web applications. You'll also learn techniques for bypassing protections against these attacks. In the book's nine guided labs, which target intentionally vulnerable APIs, you'll practice: Enumerating APIs users and endpoints using fuzzing techniques Using Postman to discover an excessive data exposure vulnerability Performing a JSON Web Token attack against an API authentication process Combining multiple API attack techniques to perform a NoSQL injection Attacking a GraphQL API to uncover a broken object level authorization vulnerability

Ver oferta
Gray Hat Hacking: The Ethical Hacker's Handbook, Sixth Edition

Gray Hat Hacking: The Ethical Hacker's Handbook, Sixth Edition

Up-to-date strategies for thwarting the latest, most insidious network attacks This fully updated, industry-standard security resource shows, step by step, how to fortify computer networks by learning and applying effective ethical hacking techniques. Based on curricula developed by the authors at major security conferences and colleges, the book features actionable planning and analysis methods as well as practical steps for identifying and combating both targeted and opportunistic attacks. Gray Hat Hacking: The Ethical Hacker's Handbook, Sixth Edition clearly explains the enemy's devious weapons, skills, and tactics and offers field-tested remedies, case studies, and testing labs. You will get complete coverage of Internet of Things, mobile, and Cloud security along with penetration testing, malware analysis, and reverse engineering techniques. State-of-the-art malware, ransomware, and system exploits are thoroughly explained. Fully revised content includes 7 new chapters covering the latest threats Includes proof-of-concept code stored on the GitHub repository Authors train attendees at major security conferences, including RSA, Black Hat, Defcon, and B-Sides

Ver na Amazon
Bloqueador USB de privacidade de porta USB para PC, notebook, bloco de laptop,

Bloqueador USB de privacidade de porta USB para PC, notebook, bloco de laptop,

Proteção de privacidade aprimorada: protege o link de transmissão de dados para evitar roubo de informações, fornecendo proteção de segurança robusta que protege a privacidade do usuário durante transferências de arquivos e garante uma conexão segura para interações de dispositivos sem preocupações em vários ambientes Uso a longo prazo: a camada protetora resistente ao desgaste, combinada com um corpo de metal resistente, oferece gerenciamento de calor confiável e qualidade duradoura durante o uso diário Entrega eficiente de energia: a tecnologia de chip inteligente garante a identificação automática dos requisitos de energia, fornecendo carregamento eficiente alinhando-se com vários protocolos de carregamento rápido para maior conveniência Proteção contra sobrecarga: evitando riscos de sobrecarga, este bloqueador de dados USB protege a vida útil da bateria e garante um desempenho estável, mantendo um fluxo estável de energia para melhorar a longevidade do dispositivo de forma eficaz Prático de transportar: com atenção à portabilidade, este bloqueador de dados USB oferece um design compacto que é leve e fácil de transportar, melhorando a conveniência do usuário e operação eficiente

Ver na Amazon

📩 Newsletter MundiX

Receba novidades de cibersegurança + um checklist de pentest grátis. Sem spam.

Ao assinar você concorda em receber e-mails. Cancele quando quiser.