Em abril de 2025, descrevemos uma versão, na época nova, do backdoor Triada, que infectava firmwares de dispositivos Android falsificados distribuídos por meio de marketplaces populares. O malware residia nas partições do sistema dos firmwares e infiltrava-se no Zygote (o processo “pai” de todos os aplicativos no sistema), resultando na infecção de qualquer aplicativo no dispositivo. Isso permitia que o trojan roubasse dados do cadastro de aplicativos de mensagem e redes sociais, entre outras coisas.
Essa descoberta nos motivou a realizar uma investigação mais ampla em busca de outras ameaças em firmwares de dispositivos Android. Assim, identificamos o novo backdoor Keenadu, que, assim como o Triada, estava incorporado nos firmwares e infectava todos os aplicativos executados no dispositivo. O backdoor já estava amplamente disseminado. Quando foi descoberto, nossos usuários começaram a entrar em contato massivamente com o suporte técnico para obter informações sobre essa ameaça. O objetivo deste relatório é esclarecer dúvidas e descrever essa nova ameaça.
Nossas conclusões são as seguintes:
- Identificamos um novo backdoor denominado Keenadu embutido no firmware de dispositivos de múltiplos fabricantes. A inserção ocorreu durante o processo de compilação: uma biblioteca estática maliciosa era vinculada ao
libandroid_runtime.so. Uma vez no dispositivo, assim como o Triada, ele infectava o processoZygote. Em alguns casos, o firmware malicioso era instalado por meio de uma atualização remota (OTA). - Uma cópia do backdoor era injetada no espaço de endereçamento de cada aplicativo ao ser executado no dispositivo. O malware é um carregador multinível que concede aos invasores controle praticamente ilimitado sobre o dispositivo da vítima.
- Conseguimos obter as cargas maliciosas baixadas pelo Keenadu. Dependendo do aplicativo infectado, elas substituem pesquisas no navegador, monetizam instalações de aplicativos e manipulam secretamente elementos publicitários.
- Uma das cargas maliciosas obtidas durante a investigação também foi encontrada em múltiplos aplicativos distribuídos tanto por fontes não oficiais quanto pelo Google Play e pela Xiaomi GetApps.
- Nos firmwares de alguns dispositivos, o Keenadu estava integrado em aplicativos-chave do sistema, como o serviço de reconhecimento facial, o launcher do sistema etc.
- Durante a investigação, estabelecemos que existe uma conexão entre as maiores botnets Android: Triada, BADBOX, Vo1d e Ke
A cadeia completa de infecção é a seguinte:

Esquema completo da infecção
As soluções da Kaspersky detectam as ameaças descritas abaixo com os seguintes veredictos:
HEUR:Backdoor.AndroidOS.Keenadu.*
HEUR:Trojan-Downloader.AndroidOS.Keenadu.*
HEUR:Trojan-Clicker.AndroidOS.Keenadu.*
HEUR:Trojan-Spy.AndroidOS.Keenadu.*
HEUR:Trojan.AndroidOS.Keenadu.*
HEUR:Trojan-Dropper.AndroidOS.Gegu.*
Dropper malicioso em libandroid_runtime.so
No início da investigação, algo que chamou nossa atenção foram bibliotecas suspeitas localizadas nos caminhos /system/lib/libandroid_runtime.so e /system/lib64/libandroid_runtime.so (a partir de agora, usaremos a representação curta /system/lib[64]/ para designar esses dois diretórios). Essa é uma biblioteca que existe na plataforma legítima do Android. Em particular, nela é definido o método nativo println_native para a classe android.util.Log. Os aplicativos usam esse método para gravar no logcat. Nas bibliotecas suspeitas, a implementação desse método chamava uma função adicional, diferentemente das bibliotecas legítimas.

Chamado de função suspeita
A função suspeita decifrava dados presentes no corpo da biblioteca usando RC4 e os gravava no caminho /data/dalvik-cache/arm[64]/system@framework@vndx_10x.jar@classes.jar. Esses dados constituem a carga maliciosa carregada via DexClassLoader. O ponto de entrada é o método main da classe com.ak.test.Main, onde provavelmente “ak” se refere ao nome dado ao malware pelo autor, considerando que essa combinação de letras também aparece em outros pontos do código. Em particular, os desenvolvedores deixaram diversos trechos de código que registram mensagens de erro do malware no logcat durante sua execução. Para essas mensagens, é usada a tag AK_CPP.

Decifração da carga maliciosa
A carga maliciosa verifica se não está sendo executada em aplicativos do sistema pertencentes ao conjunto de serviços do Google, nem em aplicativos do sistema das operadoras Sprint e T-Mobile. Essas versões geralmente correspondem a dispositivos vendidos a baixo custo pelas operadoras mediante contrato de serviços de telecomunicações. Se o malware for executado nesses processos, interrompe suas operações. Também possui um mecanismo para cessar a execução caso arquivos com determinados nomes sejam encontrados nos diretórios do sistema.
Em seguida, o trojan verifica se está sendo executado no processo system_server, que gerencia todo o sistema e possui privilégios máximos. Ele é iniciado pelo processo Zygote no início da execução. Caso a verificação seja positiva, o trojan cria uma instância da classe AKServer; caso contrário, se o código estiver em execução em qualquer outro processo, cria-se uma instância da classe AKClient. Em ambos os casos, é invocado um método ao qual é passado o nome do processo do aplicativo. Os nomes das classes sugerem que o trojan se baseia em uma arquitetura cliente-servidor.

Inicialização do system_server no Zygote
O processo system_server cria e inicia diversos serviços do sistema por meio da classe SystemServiceManager. A base desses serviços é a arquitetura cliente-servidor, e os clientes são solicitados no código dos aplicativos por meio da chamada do método Context.getSystemService. A comunicação com o servidor ocorre por meio do binder, o mecanismo nativo de comunicação entre processos (IPC) do Android. Essa abordagem oferece múltiplas vantagens, inclusive do ponto de vista da segurança. Entre elas estão a possibilidade de restringir o acesso de certos aplicativos a funções específicas do sistema e a presença de abstrações que simplificam o uso desses recursos para desenvolvedores, ao mesmo tempo que protegem o sistema contra possíveis vulnerabilidades nos aplicativos.
Os autores do Keenadu adotaram uma abordagem semelhante. A lógica principal reside na classe AKServer, que opera no processo system_server. O AKServer funciona como um serviço do sistema malicioso, enquanto o AKClient atua como stub (proxy) que permite invocar métodos remotos no AKServer por meio do binder. A seguir, apresentamos um diagrama do funcionamento do backdoor:

Esquema de funcionamento do backdoor Keenadu
Cabe destacar que o Keenadu viola novamente os princípios fundamentais de segurança do Android. Primeiro, por estar integrado ao libandroid_runtime.so, ele opera no âmbito de todos os aplicativos do dispositivo, obtendo acesso a todos os seus dados e tornando ineficaz o isolamento entre aplicativos previsto pelo sistema. Segundo, ele fornece interfaces para burlar permissões (que discutiremos adiante) que regulam os direitos dos aplicativos no sistema. Trata-se, portanto, de um backdoor pleno, que permite aos invasores obter controle praticamente ilimitado do dispositivo da vítima.
Arquitetura do AKClient
O AKClient é estruturado de forma bastante simples. Ele se integra a todos os aplicativos executados no dispositivo e obtém uma instância da interface para comunicação com o servidor por meio de uma mensagem de broadcast protegido (protected broadcast) com a ação com.action.SystemOptimizeService. Por meio do binder, esse stub invoca o método attach no AKServer, passando como parâmetro um objeto IBinder que encapsula a lógica para carregar DEX arbitrários no âmbito do aplicativo infectado. Isso permite ao AKServer executar cargas maliciosas de acordo com o aplicativo afetado.
Arquitetura do AKServer
Ao iniciar, o AKServer envia duas mensagens de broadcast protegido: com.action.SystemOptimizeService e com.action.SystemProtectService. A primeira, como mencionado, transmite aos demais processos infectados com AKClient uma instância da interface para interagir com o AKServer. Junto com a mensagem com.action.SystemProtectService, é transmitida uma instância de outra interface para interagir com o AKServer. Por meio dessa interface, módulos maliciosos carregados nos contextos de outros aplicativos podem:
- conceder qualquer permissão a qualquer aplicativo no dispositivo;
- revogar qualquer permissão de qualquer aplicativo no dispositivo;
- obter a geolocalização do dispositivo;
- obter informações sobre o dispositivo.

Interface maliciosa para gerenciar permissões e obter dados do dispositivo
Após estabelecida a interação entre as partes cliente e servidor, o AKServer inicia a tarefa maliciosa principal chamada MainWorker. Na primeira execução, o MainWorker registra a hora atual. Em seguida, o malware verifica o idioma da interface e o fuso horário do dispositivo. Se o idioma for um dos dialetos do chinês e o fuso horário corresponder a uma região chinesa, o malware encerra sua execução. O malware não opera em dispositivos que não possuam a Google Play Store ou os Google Play Services. Caso o dispositivo passe nessas verificações, o trojan inicia a tarefa PluginTask. O PluginTask decifra os endereços dos servidores de comando e controle (C2) do seguinte modo:
- A string contendo o endereço cifrado é decodificada em Base64.
- Os dados obtidos (um buffer comprimido com gzip) são descomprimidos.
- Os dados descomprimidos são decifrados com AES-128 em modo CFB. A chave de decifração é o hash MD5 da string
ota.host.ba60d29da7fd4794b5c5f732916f7d5c, e o vetor de inicialização é a string0102030405060708.
Após decifrar os endereços dos servidores C2, o trojan coleta dados sobre o dispositivo da vítima — modelo, IMEI, endereço MAC, versão do sistema operacional etc. — e os cifra da mesma forma que os endereços dos servidores, exceto que a chave AES utilizada é o hash MD5 da string ota.api.bbf6e0a947a5f41d7f5226affcfd858c. Os dados cifrados são enviados ao servidor C2 por meio de uma solicitação POST para o caminho /ak/api/pts/v4. Dois parâmetros são incluídos na solicitação:
- m: hash MD5 do IMEI do dispositivo;
- n: tipo de conexão de rede (w: Wi-Fi, m: internet móvel).
A resposta do servidor C2 contém o campo code, que pode indicar um erro retornado pelo servidor. Se o valor for zero, não há erro, e a resposta incluirá o campo data: um JSON cifrado de forma análoga aos dados da solicitação, contendo informações sobre as cargas maliciosas.
Como o Keenadu chegou ao libandroid_runtime.so
Após analisar as primeiras etapas da infecção, decidimos investigar como exatamente o backdoor chegava aos firmwares dos dispositivos Android. Não demorou para encontrarmos, em fontes abertas na internet, reclamações de usuários de tablets do fabricante Alldocube sobre consultas DNS suspeitas originadas dos dispositivos. A empresa já havia reconhecido a presença de software malicioso em um de seus modelos de tablet. Contudo, seu comunicado público não fornecia detalhes sobre qual malware específico havia sido inserido nem como isso ocorreu. Tentaremos responder a essas perguntas.

Reclamação de usuário sobre consultas DNS suspeitas
As consultas DNS descritas pelo autor da reclamação também nos pareceram incomuns. De acordo com nossos dados, os domínios C2 do Keenadu conhecidos na época resolviam os seguintes endereços IP:
- 67.198.232[.]4
- 67.198.232[.]187
Esses mesmos endereços também resolviam os domínios keepgo123[.]com e gsonx[.]com, o que sugere que o tablet do autor da reclamação também estaria infectado com o Keenadu. No entanto, uma única coincidência de endereços IP não é suficiente para confirmar essa hipótese. Para validá-la, seria necessário analisar o próprio dispositivo. Consideramos adquirir o mesmo modelo de tablet, mas isso não foi necessário, afinal a Alldocube disponibiliza publicamente os arquivos de firmware para seus dispositivos, permitindo que qualquer pessoa interessada os verifique quanto à presença de software malicioso.
Para analisar o firmware, é preciso primeiro entender seu formato. Os firmwares da Alldocube são arquivos RAR que contêm diversas imagens e outros arquivos, além de um utilitário para gravação (flashing) em formato executável para Windows. O componente mais relevante para análise é o sistema de arquivos do Android. Suas partições principais, incluindo a partição de sistema, estão contidas em uma imagem chamada super.img, um Android Sparse Image. Para simplificar, omitiremos detalhes sobre o formato (que podem ser obtidos, por exemplo, do código-fonte da libsparse), é suficiente mencionar que existem utilitários de código aberto para extrair partições desses arquivos como imagens de sistema de arquivos.
Extraímos o libandroid_runtime.so do firmware do modelo Alldocube iPlay 50 mini Pro (T811M) de 18 de agosto de 2023. Ao analisar a biblioteca, identificamos nela o backdoor Keenadu. Além disso, deciframos a carga maliciosa e extraímos dela os endereços dos servidores C2, localizados nos domínios keepgo123[.]com e gsonx[.]com, confirmando as suspeitas do usuário de que seus dispositivos estavam infectados com esse backdoor. Ademais, todas as versões posteriores do firmware para esse modelo também continham o Keenadu, inclusive aquelas lançadas após o comunicado do fabricante.
É importante destacar os firmwares do modelo Alldocube iPlay 50 mini Pro NFE. A sigla NFE (Netflix Enabled) indica que esses dispositivos possuem um módulo DRM adicional que permite streaming em alta qualidade, o que exige conformidade com o padrão Widevine L1 do Google Widevine DRM. Consequentemente, o processamento de mídia ocorre em um TEE (Trusted Execution Environment), reduzindo o risco de acesso não autorizado a conteúdo por código não confiável e impedindo cópias não autorizadas. Apesar da certificação Widevine, esses dispositivos não foram protegidos contra infecção. Ao contrário de outros modelos, o primeiro firmware do Alldocube iPlay 50 mini Pro NFE, lançado em 7 de novembro de 2023, estava limpo. Contudo, todas as versões subsequentes, incluindo a mais recente de 20 de maio de 2024, continham o Keenadu.
Durante a análise dos firmwares da Alldocube, observamos que todos possuem assinatura válida. Isso significa que, para integrar o backdoor ao libandroid_runtime.so, não bastou que o invasor comprometesse o servidor de atualizações OTA. Foi também necessário obter as chaves privadas usadas para assinar o firmware, que normalmente não deveriam estar acessíveis a partir do servidor OTA. É altamente provável que o trojan tenha sido inserido durante a fase de compilação do firmware.
Confirmamos essa hipótese ao identificar a biblioteca estática libVndxUtils.a (hash MD5: ca98ae7ab25ce144927a46b7fee6bd21), que contém o código do Keenadu. Essa biblioteca maliciosa foi escrita em C++ e compilada com o sistema CMake. Curiosamente, ainda permanecem nos metadados da biblioteca os caminhos para os arquivos-fonte no computador do desenvolvedor:
- D:\work\git\zh\os\ak-client\ak-client\loader\src\main\cpp\__log_native_load.cpp: contém o código do dropper.
- D:\work\git\zh\os\ak-client\ak-client\loader\src\main\cpp\__log_native_data.cpp: contém a carga maliciosa cifrada com RC4 e seu
O ponto de entrada do dropper é a função __log_check_tag_count. O invasor inseriu a chamada dessa função na implementação do método println_native.

Fragmento de código onde o invasor inseriu a chamada maliciosa
Segundo nossos dados, a dependência maliciosa estava localizada no repositório de código-fonte do firmware nos seguintes caminhos:
- vendor/mediatek/proprietary/external/libutils/arm/libVndxUtils.a
- vendor/mediatek/proprietary/external/libutils/arm64/libVndxUtils.a
É interessante notar que o trojan em libandroid_runtime.so decifra e grava no disco a carga maliciosa no caminho /data/dalvik-cache/arm[64]/system@framework@vndx_10x.jar@classes.jar. É provável que o invasor tenha tentado disfarçar a dependência maliciosa como um componente vndx legítimo, supostamente proprietário da MediaTek. Na realidade, esse componente não existe nos produtos da MediaTek.
Por fim, de acordo com nossa telemetria, o trojan não está presente apenas em dispositivos Alldocube, mas também em aparelhos de outros fabricantes. Em todos os casos, o backdoor está integrado em firmwares de tablets. Alertamos os fabricantes mencionados sobre a infecção.
Com base no exposto, concluímos que o Keenadu chegou aos firmwares de dispositivos Android como resultado de um ataque à cadeia de suprimentos, ou seja, uma das etapas da cadeia de compilação do firmware foi comprometida, introduzindo uma dependência maliciosa no código-fonte. Assim, é possível que os fabricantes não tivessem conhecimento de que seus dispositivos já estavam infectados antes da comercialização.
Módulos do backdoor Keenadu
Como mencionado, o Keenadu, devido à sua arquitetura, permite aos invasores obter controle praticamente ilimitado sobre o dispositivo da vítima. Para entender exatamente como essa capacidade foi explorada, decidimos analisar as cargas maliciosas baixadas pelo backdoor. Para isso, simulamos uma solicitação de um dispositivo infectado ao servidor C2. Na primeira solicitação, o servidor C2 não retornou nenhum arquivo. Em vez disso, devolveu uma data e hora para a próxima solicitação: 2,5 meses após a primeira solicitação. Por meio de análise em caixa preta do servidor C2, descobrimos que a solicitação inclui a data de ativação do backdoor e, se não tiverem se passado dois meses e meio desde então, o C2 não entrega cargas maliciosas.
Provavelmente, essa medida visa dificultar a análise e reduzir a probabilidade de detecção dessas cargas. Após ajustarmos a data de ativação na solicitação para um período anterior, o servidor C2 retornou uma lista de cargas maliciosas para análise.
O servidor dos invasores envia informações sobre as cargas maliciosas em forma de array de objetos. Cada objeto contém um link para download da carga, seu hash MD5, nomes de pacotes-alvo, nomes de processos-alvo etc. A seguir, apresentamos um exemplo desse objeto. É interessante observar que os invasores utilizaram a Alibaba Cloud para construir sua CDN.

Exemplo de informação sobre a carga maliciosa
Os arquivos baixados pelo Keenadu possuem um formato próprio, no qual são armazenados a carga maliciosa cifrada e sua configuração. A descrição do formato, em pseudocódigo, é a seguinte (struct KeenaduPayload):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
struct KeenaduChunk { uint32_t size; uint8_t data[size]; } __packed; struct KeenaduPayload { int32_t version; uint8_t padding[0x100]; uint8_t salt[0x20]; KeenaduChunk config; KeenaduChunk payload; KeenaduChunk signature; } __packed; |
Após o download, o Keenadu verifica a integridade do arquivo por meio do hash MD5. Além disso, os autores do trojan implementaram um mecanismo de assinatura de código com o algoritmo DSA, verificado antes da decifração e execução da carga. Isso garante que somente o invasor com a chave privada possa criar cargas maliciosas válidas. Se a verificação da assinatura for bem-sucedida, a configuração e o módulo malicioso são decifrados com AES-128 em modo CFB. A chave de decifração é o hash MD5 da concatenação da string 37d9a33df833c0d6f11f1b8079aaa2dc com o “salt”, e o vetor de inicialização é a string 0102030405060708.
A configuração contém informações sobre os métodos de inicialização e finalização do módulo, seu nome e versão. A seguir, apresentamos um exemplo de configuração de um dos módulos:
|
1 2 3 4 5 6 7 8 9 10 11 |
{ "stopMethod": "stop", "startMethod": "start", "pluginId": "com.ak.p.wp", "service": "1", "cn": "com.ak.p.d.MainApi", "m_uninit": "stop", "version": "3117", "clazzName": "com.ak.p.d.MainApi", "m_init": "start" } |
Agora que descrevemos o algoritmo de carregamento de módulos maliciosos pelo backdoor, podemos passar à análise dos módulos identificados.
Carregador do Keenadu
Este módulo (MD5: 4c4ca7a2a25dbe15a4a39c11cfef2fb2) tem como alvo conhecidas lojas virtuais, com os seguintes nomes de pacote:
- com.amazon.mShop.android.shopping (Amazon)
- com.zzkko (SHEIN)
- com.einnovation.temu (Temu)
Seu ponto de entrada é o método start da classe com.ak.p.d.MainApi. Essa classe inicia a tarefa maliciosa HsTask, um carregador cujo conceito é semelhante ao do AKServer. Ao iniciar, o carregador coleta dados sobre o dispositivo infectado (modelo, IMEI, endereço MAC, versão do SO etc.) e informações sobre o aplicativo em que está sendo executado. Os dados são codificados da mesma forma que as solicitações do AKServer para o caminho /ak/api/pts/v4 e enviados por POST ao servidor C2 no caminho /ota/api/tasks/v3.

Coleta de dados pelo plugin
Em resposta, o servidor dos invasores retorna uma lista de módulos a serem baixados e executados, além de uma lista de arquivos APK a serem instalados no dispositivo da vítima. É interessante notar que, nas versões mais recentes do Android, a entrega desses APKs é feita por meio de sessões de instalação. Provavelmente, essa técnica visa contornar restrições introduzidas nas últimas versões do SO, que impedem aplicativos de terceiros de obter permissões sensíveis, como a de Acessibilidade.

Uso de sessão de instalação
Infelizmente, durante a investigação não obtivemos exemplos dos módulos ou APKs baixados por esse carregador. No entanto, usuários relataram online que tablets infectados adicionavam produtos automaticamente aos carrinhos de compras sem o conhecimento do usuário.

Reclamação de usuário no Reddit
Carregador de clickers
Esses módulos (exemplo: ad60f46e724d88af6bcacb8c269ac3c1) integram-se aos seguintes aplicativos:
- Gerenciador de papéis de parede do sistema (com.android.wallpaper)
- YouTube (com.google.android.youtube)
- Facebook (com.facebook.katana)
- Bem-estar digital (com.google.android.apps.wellbeing)
- Launcher do sistema (com.android.launcher3)
O módulo malicioso inicia suas operações obtendo dados de localização e endereço IP do dispositivo por meio do serviço GeoIP hospedado no servidor C2 dos invasores. Esses dados, juntamente com o tipo de conexão de rede e a versão do SO, são enviados ao servidor C2. Em resposta, o servidor retorna um arquivo com um formato especial, contendo um JSON cifrado com informações sobre as cargas maliciosas e a chave para decifrá-lo com XOR. A estrutura desse arquivo é descrita a seguir em pseudocódigo:
|
1 2 3 4 5 6 |
struct Payload { uint8_t magic[10]; // == "encrypttag" uint8_t keyLen; uint8_t xorKey[keyLen]; uint8_t payload[]; } __packed; |
O JSON obtido após a decifração representa um array de objetos com links para download das cargas maliciosas e informações sobre os pontos de entrada. A seguir, apresentamos um exemplo de tal objeto. As cargas maliciosas são cifradas segundo o mesmo princípio do JSON que as descreve.

Exemplo de informação sobre a carga maliciosa
Durante a investigação, obtivemos várias cargas maliciosas cujo objetivo principal é interagir com elementos publicitários em sites de temas diversos, como jogos, receitas e notícias. Cada módulo interage com um site específico, cujo endereço está codificado em seu código.
Módulo para o navegador Chrome
O módulo (MD5: 912bc4f756f18049b241934f62bfb06c) tem como alvo o navegador Google Chrome (com.android.chrome). Sua primeira ação é registrar um handler de eventos do ciclo de vida das atividades do aplicativo (Activity Lifecycle Callbacks). Sempre que uma atividade é iniciada no aplicativo-alvo, esse handler verifica seu nome. Se corresponder a ChromeTabbedActivity, o trojan busca o campo de entrada de texto (para pesquisas e URLs) chamado url_bar.

Busca pelo elemento de texto url_bar
Se o elemento for encontrado, o malware monitora as alterações de texto nele. Todas as consultas digitadas pelo usuário no url_bar são enviadas ao servidor dos invasores. Além disso, após o término da digitação, o trojan pode substituir o mecanismo de busca do usuário, conforme a configuração recebida do servidor C2.

Substituição do mecanismo de busca
Vale mencionar que a substituição pode não funcionar se o usuário selecionar uma sugestão diretamente, pois nesse caso não é pressionada a tecla “Enter” nem o botão de busca na barra de endereços (url_bar), evento que sinaliza ao malware o início de uma pesquisa. Contudo, os invasores se preparam para isso. O trojan também tenta localizar na atividade atual o elemento omnibox_suggestions_dropdown, que representa o grupo de sugestões do mecanismo de busca. O malware monitora toques nessas sugestões e realiza a substituição do mecanismo de busca.

Substituição do mecanismo de busca ao tocar em uma sugestão do navegador
Clicker Nova (Phantom)
O módulo (MD5: f0184f6955479d631ea4b1ea0f38a35d) era originalmente um clicker integrado ao gerenciador de papéis de parede do sistema (com.android.wallpaper). Paralelamente a nós, isso também foi descoberto por pesquisadores da Dr.Web, que, no entanto, não mencionaram em seu relatório o vetor de distribuição via backdoor Keenadu. O módulo utiliza tecnologias de machine learning e WebRTC para interagir com elementos publicitários. Os colegas da Dr.Web o denominaram Phantom, mas na resposta do servidor C2 ele é chamado de Nova. Além disso, a tarefa executada no código também se chama NovaTask. Com base nisso, consideramos que o nome original do clicker é Nova.

Nova, nome do plugin
Cabe destacar que, algum tempo após a publicação do relatório sobre esse clicker, o servidor C2 do Keenadu passou a removê-lo dos dispositivos infectados. É provável que os invasores tenham feito isso para evitar detecção.

Solicitação de download do módulo Nova
Além disso, na solicitação de download, o módulo Nova tinha um nome ligeiramente diferente. Consideramos que, sob esse novo nome, está oculta a versão mais recente do módulo, que funciona como carregador e pode baixar os seguintes componentes:
- Clicker Nova;
- Módulo espião que envia informações do dispositivo da vítima ao servidor dos invasores;
- Dropper Gegu SDK. Esse módulo, segundo nossos dados, é um dropper multinível que executa outros dois clickers.
Monetização de instalações
O módulo com hash MD5 3dae1f297098fa9d9d4ee0335f0aeed3 integra-se ao launcher do sistema (com.android.launcher3). Ao iniciar, verifica o ambiente em busca de artefatos de máquina virtual. Caso não os encontre, o malware registra um handler de eventos de sessão de instalação de aplicativos.

Registro do handler
Simultaneamente, o módulo solicita a configuração ao servidor C2. A seguir, apresentamos um exemplo dessa configuração.

Exemplo de configuração do módulo de monetização
Quando uma instalação de aplicativo é iniciada no dispositivo, o trojan envia informações sobre esse aplicativo ao servidor C2. Em resposta, o servidor fornece dados sobre o anúncio publicitário associado à promoção do aplicativo.

Informação sobre a fonte publicitária do aplicativo
Para cada sessão de instalação concluída com sucesso, o trojan executa solicitações GET no link do campo tracking_link da resposta, bem como no primeiro link do array click. Os links do array click, segundo o código, são templates nos quais são substituídos vários identificadores publicitários. É provável que essa seja uma tentativa de monetizar instalações de aplicativos, simulando tráfego proveniente do dispositivo da vítima para convencer plataformas publicitárias de que o aplicativo foi instalado a partir de um anúncio.
Módulo para Google Play
Embora o AKClient encerre sua execução ao detectar sua presença no processo do Google Play, extraímos seu payload diretamente do servidor C2. Este módulo (MD5: 529632abf8246dfe555153de6ae2a9df) obtém o identificador publicitário do Google Ads e o armazena na instância global da classe Settings com a chave S_GA_ID3. Esse identificador é posteriormente utilizado por outros módulos como identificador da vítima.

Obtenção do identificador publicitário
Outros vetores de distribuição do Keenadu
Durante a investigação, buscamos outras fontes de infecção pelo Keenadu. Como resultado, descobrimos que alguns dos módulos descritos acima também estavam presentes em ataques não relacionados à infecção do libandroid_runtime.so. Falaremos sobre esses casos com mais detalhes.
Aplicativos do sistema
De acordo com nossa telemetria, o carregador do Keenadu foi encontrado em diversos aplicativos do sistema, em firmwares de alguns dispositivos. Um desses aplicativos (MD5: d840a70f2610b78493c41b1a344b6893) era o serviço de reconhecimento facial com nome de pacote com.aiworks.faceidservice. O aplicativo contém modelos de machine learning treinados para reconhecimento facial, permitindo, por exemplo, autenticação. Para isso, define o serviço com.aiworks.lock.face.service.FaceLockService, utilizado pela interface do sistema (com.android.systemui) para desbloquear o dispositivo por reconhecimento facial.

Uso do serviço de reconhecimento facial na interface do sistema
No método onCreate do serviço com.aiworks.lock.face.service.FaceLockService, chamado ao criar o serviço, são registrados três receivers que monitoram eventos de ligar/desligar a tela, início de carregamento e disponibilidade de conexão de rede. Cada receiver chama o método startMars, cujo objetivo principal é inicializar o carregador malicioso por meio da chamada do método init da classe com.hs.client.TEUtils.

Chamada maliciosa
O carregador é uma versão muito semelhante à do Keenadu. Essa variante utiliza a biblioteca nativa libhshelper.so para carregar módulos e instalar APKs. Para isso, a biblioteca define os métodos nativos correspondentes na classe com.hs.helper.NativeMain.

Métodos nativos definidos pela biblioteca
Esse vetor de ataque (integração do carregador em aplicativos do sistema) não é novo. Já descrevemos casos semelhantes, como o carregador Dwphon, integrado a aplicativos do sistema responsáveis por atualizações OTA. No entanto, esta é a primeira vez que encontramos um trojan em um serviço de reconhecimento facial.
Além do serviço de reconhecimento facial, identificamos outros aplicativos do sistema infectados com o carregador do Keenadu. Entre eles está o launcher em alguns dispositivos (MD5: 382764921919868d810a5cf0391ea193). Nesses aplicativos, estava integrado o serviço malicioso com.pri.appcenter.service.RemoteService, que inicia a execução do trojan.
Também localizamos o loader Keenadu em um aplicativo com o pacote com.tct.contentcenter (hash: d07eb2db2621c425bda0f046b736e372). O aplicativo inclui o SDK publicitário fwtec, que obtém sua configuração por meio de uma solicitação HTTP GET para hxxps://trends.search-hub[.]cn/vuGs8 com follow-redirects desativado. Em resposta, o trojan espera o código 302 (redirecionamento) com URL no cabeçalho Location, cujos parâmetros contêm a configuração do SDK. O parâmetro hsby_search_switch atua como um switch de ativação: quando seu valor é 1, o SDK fwtec inicia o carregador do Keenadu dentro do processo do aplicativo.

Obtenção de configuração do C2
Carga por outros backdoors
Ao analisar nossa telemetria, identificamos uma versão incomum do carregador do Keenadu (MD5: f53c6ee141df2083e0200a514ba19e32) em diretórios de diversos aplicativos no armazenamento externo, localizados no caminho /storage/emulated/0/Android/data/%PACKAGE%/files/.dx/. Pelo código, o carregador foi projetado para operar em um sistema com o processo system_server comprometido. Além disso, os nomes das interfaces binder que ele continha eram diferentes das interfaces do AKServer. O carregador utilizava as seguintes interfaces:
- com.androidextlib.sloth.api.IPServiceM
- com.androidextlib.sloth.api.IPermissionsM
Outro backdoor, com estrutura semelhante e também encontrado em libandroid_runtime.so, usava as mesmas interfaces binder. A ativação desse backdoor em dispositivos infectados ocorre da seguinte forma: o libandroid_runtime.so importa a função maliciosa __android_log_check_loggable da biblioteca liblog.so (MD5: 3d185f30b00270e7e30fc4e29a68237f). Essa função é chamada na implementação do método nativo println_native da classe android.util.Log. Ela decifra com XOR de um byte a carga maliciosa codificada no corpo da biblioteca e a executa no contexto de todos os aplicativos do dispositivo.

Decifração da carga maliciosa
A carga maliciosa apresenta muitas semelhanças com o backdoor BADBOX, uma plataforma maliciosa complexa descrita inicialmente por pesquisadores da HUMAN Security. Em particular, coincidem os caminhos nos servidores C2 para os quais o trojan envia requisições HTTP. Portanto, consideramos que esta é uma das variantes do BADBOX.

O caminho /terminal/client/register estava presente no relatório da HUMAN Security
Nesse backdoor, também identificamos as interfaces binder utilizadas pelo carregador do Keenadu mencionado anteriormente. Isso indica que as instâncias correspondentes do Keenadu foram instaladas pelo BADBOX.

Uma das interfaces binder usadas pelo Keenadu está definida na carga maliciosa
Modificações de aplicativos populares
Infelizmente, a ausência de detecção do Keenadu ou de outro backdoor pré-instalado no firmware de um dispositivo não significa que o trojan não constitua uma ameaça. Por exemplo, o clicker Nova (Phantom) foi descoberto paralelamente por pesquisadores da Dr.Web. Em seu relatório, descrevem outro vetor de distribuição: por meio de modificações de aplicativos populares distribuídas majoritariamente por fontes não oficiais, bem como diversos aplicativos na loja GetApps.
Google Play
Aplicativos infectados também penetraram no Google Play. Durante a investigação, identificamos apps de câmeras IP trojanizados distribuídos na loja oficial Google Play. O volume combinado de downloads era superior a 300.000.

Aplicativos infectados no Google Play
Todos incluíam o serviço com.arcsoft.closeli.service.KucopdInitService, responsável por inicializar o clicker Nova. Notificamos o Google sobre aplicativos infectados distribuídos na loja, resultando na remoção imediata pelos desenvolvedores. O serviço malicioso estava presente em todos os apps, mas sua ativação dependia do nome do pacote: só era executado quando este correspondia a com.taismart.global.

O serviço malicioso era iniciado apenas sob certas condições
O Quarteto Fantástico: as conexões entre Triada, BADBOX, Vo1d e Keenadu
Ao descobrir que o BADBOX baixa um dos módulos do Keenadu, decidimos investigar mais a fundo se existem outras evidências de conexão entre esses trojans. Como resultado, identificamos semelhanças no código da carga maliciosa que decifra e executa código malicioso em libandroid_runtime.so entre BADBOX e Keenadu. Também encontramos similaridades entre o carregador do Keenadu e o módulo BB2DOOR do trojan BADBOX. Considerando as diferenças evidentes no código e o fato de que o BADBOX baixava o carregador do Keenadu, supomos que se trata de botnets distintas, e que os desenvolvedores do Keenadu podem ter se inspirado no código do BADBOX. Ademais, os autores do Keenadu concentram seus esforços principalmente em tablets Android.
Em nosso último relatório sobre o backdoor Triada, mencionamos que o servidor C2 de um dos módulos baixados por ele estava localizado no mesmo domínio que um dos servidores C2 da botnet Vo1d, o que pode indicar uma conexão entre esses dois trojans. Contudo, nesta investigação, descobrimos uma ligação entre Triada e a botnet BADBOX. Verificamos que, nos diretórios onde o BADBOX baixava o carregador do Keenadu, também estavam presentes outras cargas maliciosas para diversos aplicativos. A descrição dessas cargas merece um relatório separado, mas para fins de síntese, nos limitaremos à análise da carga maliciosa destinada a clientes do Telegram e Instagram* (MD5: 8900f5737e92a69712481d7a809fcfaa). O ponto de entrada dessa carga é a classe com.extlib.apps.InsTGEnter. Seu objetivo é roubar dados do cadastro das vítimas nos serviços infectados. É interessante notar que ela também contém código para roubo de dados do cadastro do cliente do WhatsApp, embora esse código não seja utilizado.

Código da carga maliciosa do BADBOX usado para roubo de dados do cadastro do WhatsApp
Os endereços dos servidores C2 para os quais o trojan exfiltra dados estão armazenados de modo cifrado no código do malware. Para decifrá-los, primeiro decodifica-se a string em Base64 e depois aplica-se XOR com a chave xiwljfowkgs.

Endereços decifrados dos servidores C2 da carga maliciosa
Após decifrar os endereços C2, identificamos o domínio zcnewy[.]com, associado a campanhas do Triada. Encontramos esse domínio em 2022 em modificações maliciosas do WhatsApp que continham o Triada. Na época, supúnhamos que o fragmento de código destinado ao roubo de dados do cadastro do WhatsApp e o dropper malicioso pertenciam ao Triada. Considerando que agora demonstramos que o domínio zcnewy[.]com está relacionado ao BADBOX, concluímos que as modificações maliciosas do WhatsApp descritas em 2022 continham dois trojans distintos: Triada e BADBOX. Para confirmar essa hipótese, reanalisamos uma dessas modificações (MD5: caa640824b0e216fab86402b14447953) e descobrimos que nela estavam integrados o código do dropper do Triada e o módulo do BADBOX, funcionalmente semelhante ao descrito acima. Embora os trojans fossem iniciados a partir do mesmo ponto de entrada, não interagiam entre si e tinham estruturas muito diferentes. Isso nos leva a crer que, em 2022, observamos um ataque conjunto de BADBOX e Triada.

Início de BADBOX e Triada a partir do mesmo ponto de entrada
Concluímos que diversas das maiores botnets Android mantêm interoperabilidade entre si. Até o momento, confirmamos a conexão de Triada com Vo1d e BADBOX, bem como a conexão de Keenadu com BADBOX. Pesquisadores da HUMAN Security também apontaram a ligação entre Vo1d e BADBOX. É importante ressaltar que as conexões descritas não são transitivas. Por exemplo, o fato de Triada e Keenadu estarem conectados ao BADBOX não implica necessariamente uma ligação direta entre Triada e Keenadu; essa última afirmação exigiria prova adicional. Porém, não nos surpreenderia se, em breve, surgissem relatórios capazes de demonstrar que essa conexão realmente existe.
As vítimas
Segundo nossos dados de telemetria, 13 715 usuários em todo o mundo encontraram o Keenadu ou seus módulos. Nossas soluções de segurança registraram o maior volume de usuários atacados por malware na Rússia, Japão, Alemanha, Brasil e Países Baixos.
Nossas recomendações
Nosso suporte técnico recebe frequentemente perguntas sobre as medidas a serem tomadas caso uma solução de segurança detecte o Keenadu no dispositivo. Nesta seção, abordaremos todos os cenários possíveis de mitigação do trojan.
Se a biblioteca libandroid_runtime.so estiver infectada
Nas versões modernas do Android, a partição de sistema, onde reside o libandroid_runtime.so, está montada em modo “somente leitura”. Mesmo que, teoricamente, fosse possível modificar essa partição, a biblioteca infectada não poderia ser removida sem danificar o firmware: o dispositivo deixaria de inicializar. Portanto, não é possível eliminar a ameaça com os meios padrão do sistema Android. O uso de um dispositivo infectado com o backdoor Keenadu pode causar diversos inconvenientes. Por exemplo, em avaliações de dispositivos infectados, compradores relatam publicidade intrusiva e sons inexplicáveis cuja origem não conseguem identificar.

Avaliação de tablets infectados
Se seu dispositivo estiver infectado com o backdoor Keenadu, recomendamos:
- Verificar a disponibilidade de atualizações de software. Pode haver um firmware limpo disponível para o seu dispositivo. Após a atualização, é essencial confirmar com uma solução de segurança confiável que o problema foi resolvido.
- Caso não exista uma atualização oficial limpa para o seu dispositivo, você pode instalar manualmente um firmware limpo. Lembre-se de que a instalação manual de firmware pode tornar o dispositivo inoperante.
- Até a substituição ou atualização do firmware, recomendamos não utilizar o dispositivo infectado.
Se um dos aplicativos do sistema estiver infectado
Infelizmente, assim como no caso anterior, não será possível remover tal aplicativo do dispositivo, pois ele reside na partição de sistema. Se você identificou o carregador do Keenadu em um aplicativo do sistema, recomendamos:
- Sempre que possível, substituir o aplicativo por uma alternativa. Por exemplo, se o launcher do sistema estiver infectado, é possível instalar qualquer outro launcher que não contenha software malicioso. Caso não haja alternativas (por exemplo, o serviço de reconhecimento facial estiver infectado), evite utilizar a funcionalidade correspondente.
- Desativar o aplicativo infectado por meio do ADB, caso tenha encontrado uma alternativa ou possa prescindir da funcionalidade. Isso pode ser feito com o comando:
adb shell pm disable --user 0 %PACKAGE%.
Se um aplicativo infectado foi instalado no dispositivo
Este é um dos cenários mais simples de infecção. Se a solução de segurança detectar no seu dispositivo um aplicativo infectado com o Keenadu, basta desinstalá-lo seguindo as instruções da solução de segurança.
Conclusão
Os desenvolvedores de backdoors pré-instalados em firmwares de dispositivos Android sempre se destacaram por sua alta qualificação. No caso do Keenadu, isso também se aplica. Os autores do malware demonstram profundo entendimento da arquitetura do Android, do processo de inicialização de aplicativos e dos princípios fundamentais de segurança do sistema operacional. Durante a investigação, ficamos surpresos com a abrangência das campanhas do Keenadu, pois além do backdoor principal nos firmwares, seus módulos estavam presentes em aplicativos do sistema e até mesmo em aplicativos do Google Play. Isso coloca o trojan na mesma escala de outros malwares como Triada ou BADBOX. O surgimento de um novo backdoor pré-instalado dessa magnitude indica que essa categoria de malware constitui um mercado distinto, marcado por intensa concorrência.
O Keenadu é uma plataforma maliciosa ampla e complexa que concede aos invasores controle ilimitado sobre o dispositivo da vítima. Embora, por enquanto, tenhamos demonstrado que o backdoor é utilizado principalmente para fraudes publicitárias, não descartamos a possibilidade de que, no futuro, o malware siga o caminho do Triada e comece a exfiltrar dados sensíveis.
Indicadores de comprometimento
Clientes do serviço Threat Intelligence têm acesso a indicadores de comprometimento (IoCs) adicionais, detalhes técnicos e uma regra YARA para detecção da atividade do Keenadu. Para mais informações, contate crimewareintel@kaspersky.com.
Bibliotecas maliciosas libandroid_runtime.so
bccd56a6b6c9496ff1acd40628edd25e
c4c0e65a5c56038034555ec4a09d3a37
cb9f86c02f756fb9afdb2fe1ad0184ee
f59ad0c8e47228b603efc0ff790d4a0c
f9b740dd08df6c66009b27c618f1e086
02c4c7209b82bbed19b962fb61ad2de3
185220652fbbc266d4fdf3e668c26e59
36db58957342024f9bc1cdecf2f163d6
4964743c742bb899527017b8d06d4eaa
58f282540ab1bd5ccfb632ef0d273654
59aee75ece46962c4eb09de78edaa3fa
8d493346cb84fbbfdb5187ae046ab8d3
9d16a10031cddd222d26fcb5aa88a009
a191b683a9307276f0fc68a2a9253da1
65f290dd99f9113592fba90ea10cb9b3
68990fbc668b3d2cfbefed874bb24711
6d93fb8897bf94b62a56aca31961756a
Payloads Keenadu
2922df6713f865c9cba3de1fe56849d7
3dae1f297098fa9d9d4ee0335f0aeed3
462a23bc22d06e5662d379b9011d89ff
4c4ca7a2a25dbe15a4a39c11cfef2fb2
5048406d8d0affa80c18f8b1d6d76e21
529632abf8246dfe555153de6ae2a9df
7ceccea499cfd3f9f9981104fc05bcbd
912bc4f756f18049b241934f62bfb06c
98ff5a3b5f2cdf2e8f58f96d70db2875
aa5bf06f0cc5a8a3400e90570fb081b0
ad60f46e724d88af6bcacb8c269ac3c1
dc3d454a7edb683bec75a6a1e28a4877
f0184f6955479d631ea4b1ea0f38a35d
Aplicativos de sistema infectados com o loader Keenadu
07546413bdcb0e28eadead4e2b0db59d
0c1f61eeebc4176d533b4fc0a36b9d61
10d8e8765adb1cbe485cb7d7f4df21e4
11eaf02f41b9c93e9b3189aa39059419
19df24591b3d76ad3d0a6f548e608a43
1bfb3edb394d7c018e06ed31c7eea937
1c52e14095f23132719145cf24a2f9dc
21846f602bcabccb00de35d994f153c9
2419583128d7c75e9f0627614c2aa73f
28e6936302f2d290c2fec63ca647f8a6
382764921919868d810a5cf0391ea193
45bf58973111e00e378ee9b7b43b7d2d
56036c2490e63a3e55df4558f7ecf893
64947d3a929e1bb860bf748a15dba57c
69225f41dcae6ddb78a6aa6a3caa82e1
6df8284a4acee337078a6a62a8b65210
6f6e14b4449c0518258beb5a40ad7203
7882796fdae0043153aa75576e5d0b35
7c3e70937da7721dd1243638b467cff1
9ddd621daab4c4bc811b7c1990d7e9ea
a0f775dd99108cb3b76953e25f5cdae4
b841debc5307afc8a4592ea60d64de14
c57de69b401eb58c0aad786531c02c28
ca59e49878bcf2c72b99d15c98323bcd
d07eb2db2621c425bda0f046b736e372
d4be9b2b73e565b1181118cb7f44a102
d9aecc9d4bf1d4b39aa551f3a1bcc6b7
e9bed47953986f90e814ed5ed25b010c
Aplicativos comprometidos com o clicker Nova
0bc94bc4bc4d69705e4f08aaf0e976b3
1276480838340dcbc699d1f32f30a5e9
15fb99660dbd52d66f074eaa4cf1366d
2dca15e9e83bca37817f46b24b00d197
350313656502388947c7cbcd08dc5a95
3e36ffda0a946009cb9059b69c6a6f0d
5b0726d66422f76d8ba4fbb9765c68f6
68b64bf1dea3eb314ce273923b8df510
9195454da9e2cb22a3d58dbbf7982be8
a4a6ff86413b3b2a893627c4cff34399
b163fa76bde53cd80d727d88b7b1d94f
ba0a349f177ffb3e398f8c780d911580
bba23f4b66a0e07f837f2832a8cd3bd4
d6ebc5526e957866c02c938fc01349ee
ec7ab99beb846eec4ecee232ac0b3246
ef119626a3b07f46386e65de312cf151
fcaeadbee39fddc907a3ae0315d86178
CDN para entrega de payloads
ubkt1x.oss-us-west-1.aliyuncs[.]com
m-file-us.oss-us-west-1.aliyuncs[.]com
pkg-czu.istaticfiles[.]com
pkgu.istaticfiles[.]com
app-download.cn-wlcb.ufileos[.]com
Servidores C2
110.34.191[.]81
110.34.191[.]82
67.198.232[.]4
67.198.232[.]187
fbsimg[.]com
tmgstatic[.]com
gbugreport[.]com
aifacecloud[.]com
goaimb[.]com
proczone[.]com
gvvt1[.]com
dllpgd[.]click
fbgraph[.]com
newsroomlabss[.]com
sliidee[.]com
keepgo123[.]com
gsonx[.]com
gmsstatic[.]com
ytimg2[.]com
glogstatic[.]com
gstatic2[.]com
uscelluliar[.]com
playstations[.]click



Dividir para conquistar: como o novo backdoor Keenadu ajudou a revelar conexões entre as maiores botnets Android