O Android revela o seu IP real apesar da VPN, e a Google não vai corrigir
O Android tem um interruptor chamado «Bloquear ligações sem VPN». Ligue-o em conjunto com a VPN permanente e o sistema promete que nada sai do aparelho fora do túnel. Duas descobertas independentes deste ano mostram que qualquer aplicação vulgar passa ao lado desse interruptor e entrega o seu endereço IP real ao servidor que ela escolher. A Google fechou as duas comunicações sem corrigir nada.
Em resumo
- Dois contornos independentes, encontrados por dois investigadores diferentes, derrubam a VPN permanente com o bloqueio ligado.
- Nenhum precisa de uma permissão que o utilizador tenha de aprovar. Basta o acesso à internet, e esse é concedido automaticamente.
- O truque é o mesmo nos dois casos: levar um processo do sistema a enviar o pacote por si. Aos processos do sistema as regras de bloqueio não se aplicam.
- A Google marcou uma comunicação como «Won't Fix (Infeasible)» e fechou a outra sem agir. A GrapheneOS já corrigiu a primeira e anuncia a segunda.
O que o interruptor deveria garantir
Quando uma VPN sobe no Android, o sistema reescreve as regras de encaminhamento para que as aplicações abrangidas só cheguem à rede através dela. Cada socket leva uma marca que diz ao núcleo a que rede pertence, e se uma aplicação tentar ligar um socket diretamente à interface física de Wi-Fi a verificação falha e a chamada devolve um erro de permissões. É esta a mecânica por trás da definição, e funciona.
Funciona para as aplicações. Os sockets dos componentes do sistema ficam abaixo de um limiar chamado FIRST_APPLICATION_UID e são marcados como de sistema, o que lhes dá acesso a qualquer rede independentemente do que faça uma VPN no espaço do utilizador. O sistema tem de conseguir falar com a rede em qualquer circunstância, por isso a exceção em si é razoável. Torna-se problema no momento em que uma aplicação vulgar consegue convencer um processo do sistema a enviar um pacote em seu nome.
Fuga um: a despedida educada
O Android 16 trouxe uma função para fechar ligações QUIC de forma limpa. Se o socket de uma aplicação morre de repente, o servidor do outro lado fica com uma ligação meio aberta até expirar, por isso o sistema passou a permitir registar antecipadamente um pacote de despedida que ele próprio entrega. O investigador que encontrou a falha, e que publica como lowlevel, batizou o resultado de pequeno canhão UDP.
- A aplicação chama um método do serviço de rede e entrega-lhe um socket UDP e um bloco arbitrário de bytes. Nessa chamada não há verificação de permissões: nem no método, nem na descrição da interface, nem na política de segurança.
- O sistema regista quem chamou, a rede e os endereços e portas de origem e destino do socket.
- A aplicação termina. O núcleo comunica que o socket foi destruído.
- O processo do sistema abre um socket novo na rede Wi-Fi física, liga-o ao destino registado e envia os bytes registados. A VPN nunca vê esse pacote, e o destino vê o endereço real do aparelho.
O investigador comunicou a falha pelo programa de recompensas do Android. A comunicação foi fechada como Won't Fix (Infeasible), com o argumento de que aquilo está fora do modelo de ameaças. A Mullvad, que habitualmente não escreve sobre erros alheios, publicou um aviso em maio e voltou a submeter o caso no rastreador público; o registo foi depois marcado como inacessível sem explicação. A GrapheneOS lançou uma correção que desliga a otimização.
adb shell device_config put tethering close_quic_connection -1 desativa o fecho limpo de QUIC e tapa a fuga. Sobrevive a um reinício, mas uma atualização do sistema pode desfazê-lo e então é preciso repetir. O preço é que os sockets QUIC do outro lado ficam meio abertos até expirarem.
Fuga dois: o keepalive é enviado pelo próprio chip Wi-Fi
A segunda descoberta, publicada a 29 de julho por Armin Šupuk e analisada pela Mullvad a 10 de setembro, entra na mesma sala por outra porta. O Android expõe uma interface pública para manter viva uma tradução NAT: a aplicação pede ao sistema que emita periodicamente um pequeno pacote UDP para que uma ligação através do router de casa não caia. Por eficiência, a tarefa desce até ao chip Wi-Fi ou ao de dados móveis, que emite os pacotes por si.
A framework aceita o pedido sem verificar se quem chama é mesmo dono do recurso indicado e sem perguntar se lhe é aplicável o bloqueio da VPN. A partir daí o keepalive nasce no hardware de rede, abaixo da camada onde vivem as regras do túnel. Pacotes de formato fixo na porta UDP 4500 chegam ao endereço escolhido pela aplicação, levando o IP real.
O estudo segue o rasto de um modelo de confiança que se desfez com o tempo. A chamada começou como interface privilegiada que recebia um descritor de ficheiro em bruto, ganhou um ponto de entrada público, depois uma validação do recurso, e voltou a perdê-la numa reversão. O que ficou aceita o pedido sem exigir qualquer prova de propriedade.
A nota do próprio autor no rastreador da GrapheneOS é mais estreita do que o título do estudo: em aparelhos Pixel funciona por Wi-Fi e quase nunca por IPv6. Em contrapartida, é teimosa. A fuga continua com a aplicação em segundo plano, com o ecrã bloqueado, em modo Doze, em poupança de energia e sob o congelamento de processos, e sobrevive a forçar a paragem da aplicação.
O que escapa realmente
As suas mensagens não. Ambas as fugas são canais estreitos: a aplicação controla para onde vai o pacote e, no caso do QUIC, o que contêm alguns bytes. O que a outra ponta fica a saber é que um aparelho concreto com um IP público concreto existe e está online neste momento. Para uma aplicação que já sabe quem é o utilizador, esse é o elo que faltava entre uma conta e uma localização, precisamente aquilo que a VPN devia impedir.
Porque é que isto se repete
As duas fugas vêm da mesma decisão de desenho: funções de conveniência que deixam um processo do sistema agir em nome de uma aplicação, escritas sem perguntar se essa aplicação pode, naquele momento, sair para a rede por conta própria. A verificação do bloqueio filtra identidades de aplicações, portanto tudo o que corre com identidade de sistema fica fora do seu alcance.
E a lista não fica por duas. Na discussão da GrapheneOS um responsável notou que o projeto encontrou e corrigiu por conta própria pelo menos mais dez fugas, e que as que ocorrem sem uma aplicação tentar escapar de propósito têm prioridade sobre estas duas. O mesmo responsável foi direto quanto aos incentivos: a Google não paga por fugas de VPN, e comunicá-las serve para ficar registado, não para esperar uma correção.
O que pode fazer
Vale a pena
- Tratar a instalação de aplicações como o verdadeiro ponto de controlo. Os dois ataques exigem uma aplicação hostil já instalada, e nenhum lhe pede seja o que for.
- Se o túnel é por segurança e não por conveniência, passar para um Android que corrige isto diretamente, como a GrapheneOS.
- Aplicar o comando ADB acima, se estiver à vontade com isso, e repeti-lo depois das atualizações do sistema.
- Ter presente que a segunda fuga, no hardware testado, puxa pelo Wi-Fi. Em dados móveis o quadro é mais irregular.
Não ajuda
- Mudar de fornecedor de VPN. No Android todas as aplicações de VPN estão afetadas por igual, porque a fuga acontece por baixo delas.
- Ligar «Bloquear ligações sem VPN». É exatamente a definição que está a ser contornada.
- Esperar por uma correção da Google. As duas comunicações estão fechadas.
- Um corte de emergência dentro da aplicação de VPN. Ela não vê nem trava os pacotes emitidos pelo sistema ou pelo chip Wi-Fi.
O que isto muda na escolha de uma VPN
Vale a pena ser preciso quanto à culpa, porque a publicidade à volta disto não será. Nenhum serviço de VPN pode corrigir estas fugas e nenhum as criou: os pacotes nunca chegam à camada de aplicação onde trabalha um cliente de VPN. Aquilo por que se pode razoavelmente julgar um fornecedor, aqui, é se avisou os seus utilizadores. Se está a escolher uma aplicação para o telemóvel, o nosso guia de VPN para Android trata daquilo que a aplicação controla de facto, ou seja, tudo o que fica acima desta camada.
Isto afeta os iPhone?
Que versões do Android?
Consigo perceber que uma aplicação está a fazer isto?
A culpa é do meu fornecedor de VPN?
Devo deixar de usar VPN no Android?
• Another way to leak traffic on Android has been discovered - Mullvad
• Android NAT-T Keepalive Offload Bypasses VPN Lockdown - Armin Šupuk
• The Tiny UDP Cannon: An Android VPN Bypass - lowlevel
• Any app on recent Android versions can leak certain traffic - Mullvad
• Android NAT-T Keepalive Offload Bypasses VPN Lockdown - GrapheneOS issue tracker