Resumo: downgrade silencioso do AppsFlyer SDK v0.0.60 por sequestro de DNS
- Sequestro do registrador, domínio real: Os servidores da AppsFlyer nunca foram tocados. Os atacantes tomaram a conta do registrador, alteraram os nameservers e serviram um SDK rebaixado a partir do domínio real. As ferramentas de perímetro estavam a vigiar o perímetro errado.
- Downgrade silencioso de versão: O SDK comprometido recuou silenciosamente de v0.0.60 (hash 7dbae31c) para v0.0.59 (hash db0c4f61), substituiu o
window.fetche varreu o DOM à procura de endereços de carteiras em variantes de navegador e Node.js. A cside registou os hashes alternados dias antes de o incidente se tornar público. - Compare já os hashes: Se consome algum SDK de fornecedor através de um URL de CDN, compare hoje mesmo as versões e hashes servidos com uma baseline conhecida como válida. Se não conseguir impor SRI (SDKs dinâmicos não o permitem), adicione deteção em tempo de execução de substituições de API e mutações do DOM antes que aconteça o próximo downgrade silencioso.
Sem tempo? Veja o bloqueio in-browser de Magecart e skimmers da cside. Cobre tudo o que se segue numa única implementação.
Um agente malicioso comprometeu a infraestrutura de domínio que servia o AppsFlyer Web SDK e injetou um payload polimórfico de roubo de criptomoedas em milhares de sites. Os atacantes sequestraram o DNS ao nível do registrador, contornando os controlos de segurança padrão e permitindo-lhes servir código malicioso a partir do que parecia ser endpoints legítimos da AppsFlyer. O script injetado substituiu a API nativa window.fetch, monitorizou o DOM em busca de endereços de criptomoedas e enviou dados das vítimas para servidores de comando e controlo controlados pelos atacantes. Ambientes de servidor Node.js também foram visados, colocando frameworks SSR e pipelines de build em risco.
O que a telemetria da cside mostra
Antes de o incidente ser amplamente conhecido, a telemetria do Script Insights da cside registou comportamento invulgar do AppsFlyer Web SDK. A partir de 1 de março, a cside observou dois hashes de script diferentes a serem servidos a partir do endpoint oficial da AppsFlyer em toda a rede monitorizada. A rotação começou antes de o incidente ser confirmado, o que sugere que os atacantes estavam a testar a sua infraestrutura de implementação ou a servir deliberadamente builds polimórficas para evitar deteção.
A telemetria da cside confirmou que grandes plataformas carregaram o SDK comprometido. Domínios específicos estão a ser omitidos enquanto as organizações afetadas concluem a remediação. Para os controlos prescritivos que contêm este tipo de incidente, consulte as nossas boas práticas para proteger scripts de terceiros contra comprometimentos da cadeia de suprimentos.
O vetor de entrada: um sequestro de DNS ao nível do registrador
Os atacantes não violaram a infraestrutura AWS da AppsFlyer nem os seus repositórios internos. Obtiveram controlo através de um sequestro de DNS ao nível do registrador.
Ao comprometer a conta do registrador de domínio de appsflyer.com, os atacantes alteraram os seus nameservers autoritativos. Os registos de DNS mostram que, no início do ataque, os nameservers de appsflyer.com mudaram do AWS Route 53 para ns1.gcorelabs.net (GCore CDN).
Uma vez no controlo do DNS, os atacantes encaminharam todo o tráfego de websdk.appsflyer.com através dos seus próprios servidores. Interceptaram os pedidos ao SDK legítimo e entregaram um payload malicioso e rebaixado. Como o comprometimento ocorreu na camada de DNS, este método contornou as defesas de perímetro padrão e as proteções do lado do servidor.
O principal indicador forense: um downgrade silencioso de versão
Uma vez que os atacantes controlavam o DNS, não alteraram a lógica central do SDK da AppsFlyer, apenas o usaram para entregar o seu payload.
O sinal mais claro de adulteração foi um downgrade silencioso de versão. O SDK de referência antes do incidente era a versão 0.0.60 (hash 7dbae31c...). Durante o ataque, a versão servida a partir do endpoint oficial reverteu para 0.0.59 (hash db0c4f61...). As atualizações legítimas não retrocedem números de versão, pelo que isto constitui uma evidência clara de adulteração.
A cside comparou os SDKs limpo e rebaixado e identificou três linhas modificadas. Os atacantes removeram endpoints específicos de banner e alteraram a string de versão interna.
// SDK limpo (0.0.60)
VERSION:"0.0.60"
banner.appsflyer.com/
banner.appsflyer.com/sb/
dismissInjectPixel // presente na build limpa
// SDK comprometido (0.0.59)
VERSION:"0.0.59"
banner.appsflyer.com/ // endpoint .sb/ removido
// função dismissInjectPixel removida
Os atacantes evitaram alterar fvalid.appsflyer[.]com ou wa.appsflyer[.]com/events, o que teria quebrado as verificações de Subresource Integrity. Em vez disso, usaram o sequestro de DNS para encaminhar todo o tráfego de appsflyer.com através da sua infraestrutura, onde os payloads maliciosos eram servidos.
Após o ataque, a AppsFlyer moveu a sua infraestrutura para appsflyersdk[.]com e lançou uma build limpa 0.0.61 nesse domínio. O domínio appsflyersdk[.]com, registado em agosto de 2019, é propriedade da AppsFlyer.
Desofuscar os payloads polimórficos
O tráfego encaminhado através dos servidores comprometidos transportava o payload de roubo de criptomoedas. A análise de três ficheiros maliciosos revelou uma abordagem de implementação polimórfica com dois esquemas de ofuscação direcionados a ambientes de execução distintos.
Tipo de build 1: o payload do navegador (c7adfa8e)
O primeiro payload, com cerca de 170 KB, é executado no âmbito global window do navegador. Usa uma codificação base91 personalizada com um alfabeto de 83 caracteres para descodificar, em tempo de execução, uma tabela de strings com 786 entradas.
Numa sandbox, este payload substitui o window.fetch e regista um MutationObserver para varrer o DOM em busca de endereços de criptomoedas. Adiciona também um módulo interno chamado NetHooksmith ao objeto window (window.lIXMkR.NetHooksmith).
Tipo de build 2: os wrappers Node.js (87e46457 & 9b0fac22)
A segunda variante, encontrada em duas builds de cerca de 250 KB cada, usa uma técnica de ofuscação diferente, dirigida a ambientes de servidor. Em vez de base91, estes ficheiros encerram a lógica central em construtores Function() aninhados e descodificam strings através de um array de constantes rotativo combinado com String.fromCodePoint.
Estes wrappers usam objetos getter para se ligarem a contextos Node.js: por exemplo, get GKSDgsL(){return global} e get F1t0ak(){return exports}. Aplicações Node.js, frameworks SSR e pipelines de build que importaram o SDK via npm ou bundlers eram suscetíveis.
A cside interceptou chamadas a fromCodePoint durante a execução em sandbox para obter as strings descodificadas, o que confirmou que os wrappers executavam a mesma lógica central de substituição do fetch, mas usavam endereços de carteiras separados. Isto aponta para uma infraestrutura dedicada ao comprometimento do lado do servidor.
Os dois clusters de carteiras e a infraestrutura de C2
A análise em sandbox identificou dois clusters distintos de carteiras dos atacantes. O payload do navegador (Tipo de build 1) continha um conjunto de endereços, e os payloads Node.js (Tipo de build 2) continham outro. Ambos armazenavam estes dados num objeto global walletAddresses.
Cluster 1 (payload do navegador c7adfa8e)
- ETH:
0x1C069d0c73087D0Bae687a6f74a807350dCe1829 - BTC:
bc1qr7ngtnsh66demm4vzt4kmqxkqj8sqprnuklalt - SOL:
4LJi6mAczxZWbUvbMEk5scKhUZNPvfMDTjaVADkPFSsK - XRP:
rntqwheGbZihkabxf6xqZkUKGfTVyRhT14 - TRX:
TV6WtAkS4aAMJb3Rt2bfs8LxggF8Kmqbd9
Cluster 2 (wrappers Node.js 87e46457 & 9b0fac22)
- ETH:
0x782B93e52e62F25Bd002eeAA813B5A3fe49C9558 - BTC:
bc1q5nlx0exu0efldavw08wnjzpzluudaqh2qwlmjj - SOL:
B5hMeV7B72xqcjypzxxoPmLpNz3bi6VvZApQrnh8YwDP - XRP:
rEL7cB3jQNqtoym8oFJ36w1z3QLy9GjU - TRX:
T062f95a517fc05055b59e12c6f4b2a402
Endpoints de comando e controlo (C2)
Os payloads comunicavam com dois endpoints de C2 na infraestrutura sequestrada:
https://websdk[.]appsflyer[.]com/v1/api/plugin- obtinha novos endereços de carteiras na inicialização.https://websdk[.]appsflyer[.]com/v1/api/process- enviava endereços de carteiras exfiltrados e metadados usando um parâmetro de consulta?rd=contendo dados ofuscados por XOR.
Assinaturas comportamentais e deteção
Como os atacantes rodaram esquemas de ofuscação e endereços de carteiras, as assinaturas estáticas como as regras YARA foram ineficazes. O comportamento dos payloads, no entanto, é consistente e pode ser detetado.
As equipas de segurança devem procurar estes indicadores:
- Resultado no console: Todos os payloads imprimem "Generating new wallets..." no console durante a inicialização.
- Substituição do
fetch: O payload sobrescreve a APIfetchnativa para interceptar pedidos de saída com endereços de criptomoedas. - Poluição de objeto global: O payload cria um objeto global
walletAddresses; a variante de navegador adicionawindow.lIXMkR.NetHooksmith. - Supressão do console: O payload do navegador usa 32 referências a métodos de
consolepara ocultar avisos e erros. - Rastreio de mutações do DOM: O payload do navegador regista um
MutationObserverpara varrer novos elementos do DOM em busca de padrões de endereços de criptomoedas.
Além do incidente: a superfície de fingerprinting do SDK legítimo
A revisão do SDK limpo (hash 7dbae31c) revelou que o plugin PBA legítimo da AppsFlyer recolhia dados extensos de fingerprinting de dispositivos, incluindo verificações de fontes via canvas, deteção de bloqueadores de anúncios, deteção de bots e acesso a localStorage, sessionStorage e indexedDB.
O SDK também carrega código adicional de fvalid.appsflyer[.]com/af/cp.sdk.1.2.7.js em tempo de execução. Embora seja comum em SDKs de marketing, isto representa um risco contínuo para a cadeia de suprimentos. As organizações devem avaliar a necessidade deste tipo de rastreio e aplicar Content Security Policies (CSP) e Subresource Integrity (SRI) rigorosas a todo o código de terceiros.
Como a cside poderia ter ajudado
Um sequestro de domínio ao nível do registrador contorna as defesas de perímetro e a análise estática. A abordagem de segurança client-side da cside deteta e bloqueia este tipo de ataque em tempo real através dos seguintes mecanismos:
- Deteção de anomalias comportamentais: a cside monitoriza as ações dos scripts em vez de assinaturas estáticas e alerta para tentativas de sobrescrever o
window.fetchou aceder a entradas de criptomoedas. - Bloqueio de exfiltração de rede: se o payload for executado, os controlos de rede da cside podem bloquear ligações de saída para servidores de C2 e impedir a recuperação de carteiras e o roubo de dados.
- Alertas de rotação de hash: a telemetria da cside detetou hashes de script alternados dias antes de o ataque se tornar público, o que permitiu uma investigação precoce.
- Deteção de downgrade de versão: a cside regista as versões e hashes exatos dos scripts de terceiros. Um downgrade silencioso de
v0.0.60parav0.0.59desencadearia um alerta imediato de adulteração.
Ao aplicar medidas de zero-trust do lado do cliente, a cside impede que scripts de fornecedores comprometidos explorem a confiança dos utilizadores.
Indicadores de comprometimento (IOCs)
- Domínio:
appsflyer[.]com- Domínio legítimo sequestrado ao nível do registrador - Nameserver:
ns1.gcorelabs.net- Nameserver controlado pelos atacantes durante o sequestro - URL (C2):
https://websdk[.]appsflyer[.]com/v1/api/plugin- Endpoint de C2 do payload (rotação de carteiras) - URL (C2):
https://websdk[.]appsflyer[.]com/v1/api/process- Endpoint de C2 do payload (exfiltração) - Parâmetro de URL:
?rd=- Contém dados de exfiltração ofuscados por XOR - Carteira (ETH):
0x1C069d0c73087D0Bae687a6f74a807350dCe1829- Cluster 1 (payload do navegador) - Carteira (BTC):
bc1qr7ngtnsh66demm4vzt4kmqxkqj8sqprnuklalt- Cluster 1 (payload do navegador) - Carteira (SOL):
4LJi6mAczxZWbUvbMEk5scKhUZNPvfMDTjaVADkPFSsK- Cluster 1 (payload do navegador) - Carteira (ETH):
0x782B93e52e62F25Bd002eeAA813B5A3fe49C9558- Cluster 2 (wrappers Node.js) - String no console: "Generating new wallets..." - Resultado em texto simples de todos os payloads
- Objeto global:
walletAddresses- Injetado por todas as variantes de payload - Objeto global:
window.lIXMkR.NetHooksmith- Injetado pelo payload do navegador - String de versão:
0.0.59- Versão rebaixada do SDK que indica adulteração
Recomendações
- Compare imediatamente a versão e o hash do SDK servido por qualquer endpoint da AppsFlyer que consuma com hashes conhecidos como válidos; trate downgrades silenciosos como alertas de adulteração de alta prioridade.
- Bloqueie ou direcione para sinkhole os pedidos de saída para os endpoints de C2 identificados e os nameservers associados até que a remediação esteja concluída.
- Reforce a CSP e aplique SRI aos recursos de terceiros sempre que viável; considere hospedar internamente scripts críticos de fornecedores depois de verificar a integridade.
- Verifique os pipelines de build do lado do servidor e as implementações SSR em busca dos indicadores de wrapper Node.js descritos acima e rode quaisquer credenciais afetadas.
- Implemente a cside para vigiar substituições de API (como o
fetch) e a varredura de mutações do DOM por parte de scripts de terceiros.
Este incidente não é isolado. Para uma análise mais aprofundada sobre como a lavagem de infraestrutura estende a ameaça para além do comprometimento de um único fornecedor, consulte a nossa análise da infraestrutura de polyfills sancionada. Para um caso mais recente do mesmo mecanismo de entrega a visar diretamente utilizadores DeFi, veja o ataque à cadeia de suprimentos do lado do cliente de $3M à Polymarket.
Detalhes forenses, hashes de ficheiros e telemetria adicional estão disponíveis mediante pedido às organizações afetadas e aos respondentes a incidentes.
Nota: Esta publicação resume as conclusões da telemetria do Script Insights da cside e da análise em sandbox. Alguns domínios específicos e IOCs adicionais estão a ser omitidos enquanto as partes impactadas realizam a remediação.









