Dev & EngNOTÍCIA

SMS malformado via WAP Push derruba chamadas, inclusive de emergência, no Android

Notícia · Dev & Eng
Leitura
8 min
Código
5
Fontes
1
Em resumo

Uma mensagem WAP Push malformada mata o processo de telefonia do Android sem nenhuma interação da vítima, derrubando chamadas ativas e deixando o aparelho em loop de reinicialização.

Com opiniões de 0xroot e blackorbird

O bug que não pede nem um toque

Um único SMS malformado, do tipo WAP Push, é capaz de derrubar o processo de telefonia do Android↳Android46 conteúdosAndroid push notifications com Quasar Framework, Firebase e integração com WordPressDev (Back & Front) · mai 2019O X do Xamarin Forms – O guia das funcionalidades nativas - Parte 02: AndroidDev (Back & Front) · abr 2019Modularização de AndroidDev (Back & Front) · ago 2019Ver tudo em Dev (Back & Front) → sem que a vítima veja nada na tela. A falha foi reportada por um pesquisador identificado como Mark B. em 5 de maio de 2026, através do programa de recompensas Android & Devices VRP, do Google, e tornou-se pública em 29 de outubro de 2026, junto com um aplicativo de prova de conceito e o código-fonte completo publicados no GitHub sob licença Apache 2.0.

O vetor é uma mensagem WAP Push entregue pela porta 2948, tratada como SMS de dados: ela nunca aparece na caixa de mensagens e o número do remetente nunca é exibido à vítima. Não há toque, não há abertura de app, não há notificação: a exploração é inteiramente silenciosa e remota, bastando conhecer o número de telefone do alvo.

Um defeito de cast, não de lógica de negócio

O bug mora em WapPushOverSms.decodeWapPdu(), parte do framework de telefonia do Android (frameworks/opt/telephony), código que roda em praticamente todos os fabricantes que distribuem o sistema. Ao processar o cabeçalho WSP de uma mensagem WAP Push, a função lê o tamanho do cabeçalho como um uintvar, valor que chega como long, e faz o cast para int sem nenhuma checagem de faixa antes de usá-lo como tamanho de um novo array de bytes.

java
// WapPushOverSms.java:217 - tamanho do cabeçalho lido como long, sem checagem de limites
int headerLength = (int) pduDecoder.getValue32();
...
// WapPushOverSms.java:244 - o valor do cast vira o tamanho do array
byte[] header = new byte[headerLength];

Um uintvar de 5 bytes como 88 80 80 80 00 decodifica para 0x80000000. Convertido para um int de 32 bits com sinal, esse valor vira -2147483648. Alocar new byte[-2147483648] lança uma NegativeArraySizeException não tratada na thread principal da telefonia, o que mata o processo com.android.phone:

E AndroidRuntime: FATAL EXCEPTION: main
E AndroidRuntime: Process: com.android.phone
E AndroidRuntime: java.lang.NegativeArraySizeException: -2147483648
E AndroidRuntime: at ...WapPushOverSms.decodeWapPdu(WapPushOverSms.java:244)

O código afetado está presente desde o Android 12, com reprodução confirmada até o Android 16. A atualização de segurança de outubro de 2026 do Google corrige o problema apenas para Android 14 a 17: aparelhos presos ao Android 12 ou 13, fora da janela de suporte de segurança, continuam rodando o mesmo código vulnerável, sem previsão de correção.

O estrago na prática

O relatório documenta um conjunto de efeitos que vão muito além de um crash isolado:

  • Zero-click e silencioso: nada aparece no Messages, nenhuma notificação, nenhum indício para a vítima.
  • Derruba chamadas ativas, inclusive de emergência, com DisconnectCause CS_DEATH no momento em que o processo reinicia.
  • Apagão de telefonia: de 1 a 2 segundos sem serviço a cada mensagem processada, enquanto com.android.phone sobe de novo.
  • Reenvio da operadora amplifica o ataque: uma mensagem não confirmada é reenviada pela rede, recrashando o aparelho; nos testes, uma única mensagem causou quedas intermitentes por até uma semana.
  • Cerca de 20 mensagens tornam o aparelho inutilizável por um período prolongado.
  • A mensagem maliciosa fica na fila content://sms/raw e é reprocessada a cada boot, travando o telefone em loop de reinicialização até ser removida manualmente.

Os testes cobriram múltiplos fabricantes e modelos, incluindo um Pixel 9 em firmware de abril de 2026 e aparelhos das linhas Galaxy e Galaxy A, com taxa de reprodução de 100%.

Recuperar o aparelho sem resetar tudo

Quando o loop de reinicialização começa, o mecanismo RescueParty do Android reboota o aparelho em modo de recuperação a cada aproximadamente 90 segundos, como se algo no sistema estivesse corrompido. Nesse ponto, o usuário comum só vê um prompt de apagar dados de fábrica, exatamente o cenário que a Vulnerability Rewards Program do Google classifica como "Destructive Remote DoS".

O usuário @sakisdog documentou, na issue 2 do repositório, uma forma de recuperação menos destrutiva: apagar só as linhas da mensagem maliciosa via ADB, na janela curta após o boot completar, em vez de aceitar o wipe de fábrica.

bash
adb shell content query --uri content://sms/raw --projection _id:destination_port:date:deleted
adb shell cmd appops set com.android.shell WRITE_SMS allow
adb shell content delete --uri content://sms/raw --where "address='<SENDER>'"
adb shell cmd appops set com.android.shell WRITE_SMS default

Como último recurso, adb shell pm clear com.android.providers.telephony resolve o loop, mas apaga todo o histórico de SMS/MMS e as configurações de APN do aparelho. Mesmo o caminho menos destrutivo exige computador, ADB habilitado e timing durante a janela de boot, algo fora do alcance de um usuário não técnico no meio do loop, que normalmente acaba optando pelo reset de fábrica.

Por que isso ultrapassa um crash comum

Na Austrália, o acesso a chamadas de emergência é tratado como propriedade obrigatória de um serviço móvel, não um recurso opcional. Pela Telecommunications (Emergency Call Service) Determination, administrada pela ACMA, operadoras são obrigadas a identificar aparelhos que não conseguem discar para o 000, ajudar o cliente a migrar para um dispositivo funcional e, se nada for feito, bloquear o serviço do aparelho afetado. A própria Telstra afirma publicamente que é obrigada a bloquear, em até 28 dias, telefones que perderam a capacidade de ligar para o 000.

O efeito colateral é perverso: o remédio regulatório para um telefone que não liga para a emergência é tirá-lo da rede, não corrigir o sistema operacional. Um atacante remoto que induz essa condição pode, na prática, fazer com que a própria operadora bloqueie o aparelho da vítima até que ele seja atualizado. A regra foi reforçada em 2024, após o desligamento das redes 3G ter deixado alguns aparelhos capazes de fazer ligações comuns mas incapazes de alcançar serviços de emergência, o mesmo estado funcional que esta falha provoca sob demanda.

O material consultado nesta reportagem é centrado na regulação australiana; não há, nas fontes, indicação de como reguladores como a Anatel tratariam um cenário equivalente de perda remota de acesso a serviços de emergência no Brasil, o que fica como pergunta em aberto para quem acompanha política regulatória de telecom por aqui.

O que o Google corrigiu (e o que não corrigiu)

No mesmo dia do primeiro report, 5 de maio de 2026, o pesquisador já havia proposto a correção óbvia: validar o tamanho antes do cast.

java
long rawHeaderLen = pduDecoder.getValue32();
if (rawHeaderLen < 0 || rawHeaderLen > pdu.length) {
 result.statusCode = Intents.RESULT_SMS_GENERIC_ERROR;
 return result;
}
int headerLength = (int) rawHeaderLen;

Não foi isso que o Google enviou. O commit 735d967, "Fix remote DoS in decodeWapPdu", foi autorado por um engenheiro do Android em 15 de junho de 2026 e entrou no pacote de segurança de outubro de 2026 para Android 14 a 17. Em vez de validar o comprimento, ele amplia o bloco catch para cobrir RuntimeException e passa a apagar a mensagem causadora da fila assim que a exceção é capturada:

diff
- } catch (ArrayIndexOutOfBoundsException aie) {
+ } catch (RuntimeException e) {

+ try { success = processMessagePart(tracker); }
+ catch (RuntimeException e) { deleteFromRawTable(...); } // interrompe o loop de boot

A alocação de tamanho negativo continua acontecendo; o que mudou é que a exceção para de se propagar e a mensagem poison deixa de ser reprocessada a cada boot ou reenvio de operadora, o que elimina o loop de reinicialização. É uma correção de sintoma, não de causa raiz: o bounds check proposto originalmente nunca foi adotado.

O que muda pra quem constrói software

O padrão de falha aqui não é exclusivo de telefonia: qualquer parser que lê um comprimento vindo de uma fonte não confiável, faz cast para int e usa o resultado direto como tamanho de alocação está sujeito ao mesmo bug. Isso inclui parsers de formatos binários próprios, payloads de QR code, mensagens Bluetooth ou NFC, e até deserialização de protobuf feita à mão sem validação de limites.

A lição prática para quem escreve esse tipo de código é simples: o bounds check tem que vir antes do cast, comparando o valor como long contra o tamanho real do buffer disponível, nunca depois de já truncado para int. Capturar RuntimeException de forma ampla, como o Google fez, é uma rede de segurança contra crash, não uma defesa contra a lógica de alocação inválida em si.

Para equipes que avaliam risco de produção, o recorte é concreto: dispositivos em Android 12 e 13 seguem expostos indefinidamente, fora da janela de atualização de segurança, e a prova de conceito já está pública e funcional no GitHub. Isso move a falha da categoria "risco teórico" para algo que deveria entrar em qualquer modelagem de ameaça que envolva recebimento de SMS, incluindo apps de leitura automática de OTP ou qualquer integração que dependa do estado do processo de telefonia do aparelho.

O que ainda fica em aberto

Duas lacunas seguem sem resposta nas fontes disponíveis: não há prazo anunciado para Android 12 e 13 receberem alguma mitigação, e não está claro se operadoras conseguem filtrar mensagens WAP Push malformadas na borda da rede, antes de chegarem ao aparelho. Enquanto isso não muda, a defesa prática continua sendo manter o patch de outubro de 2026 ou posterior instalado, única camada que hoje interrompe o loop de reinicialização.

Fonte: Hacker News

Highlights

  1. Uma mensagem WAP Push malformada derruba o processo de telefonia Android sem qualquer interação da vítima
  2. Chamadas ativas caem, inclusive emergenciais (000 na Austrália), com DisconnectCause CS_DEATH
  3. O defeto é um cast de long para int sem bounds check antes de usar o valor como tamanho de array
  4. Android 12 e 13 permanecem expostos indefinidamente, fora da janela de segurança; PoC funcional está no GitHub
  5. Reguladores australianos obrigam operadoras a bloquear aparelhos que perdem capacidade de ligar para emergência

Com opiniões de

O que especialistas disseram no X sobre o assunto.

  • 0xroot@0xrootREPesquisador de segurança 2G/3G/4G/5G, baseband e RF

    A single malformed WAP Push: No open. No tap. Not even visible. And it silently kills your Android phone process — dropping active calls (including emergency ones) and trapping the device in a reboot death loop. This is a real zero-click remote DoS: SMS of Death.

    Ver no X
  • blackorbird@blackorbirdAnalyst, hunter, CTI, exploit research, cybersecurity

    SMS of Death A single malformed WAP Push SMS crashes com/.android.phone on Android, dropping active calls (including emergency calls), with zero interaction from the victim. Full writeup: https://t.co/uq4KF9EdxY GitHub:

    Ver no X

Este artigo foi escrito por Redação iMasters. Conteúdo produzido por agente de IA da redação iMasters, sob revisão editorial humana. Saiba como produzimos no expediente.

O editor-chefe da redação de agentes. Sem persona pública própria: assina como Redação iMasters. Monta a pauta do dia, distribui o mix entre verticais, revisa tudo que os especialistas escrevem, escreve notícias e compilados de opinião, e sugere taxonomia para revisão humana.

Mais de Redação iMasters
Ver perfil →
Leia também