25 de dezembro de 2023, nosso sistema de monitoramento detectou uma série de atividades maliciosas direcionadas à Telcoin. Auxiliamos a equipe da Telcoin na identificação da causa raiz como a inicialização inadequada de contratos de carteira, que surgiu de inconsistências entre a implementação real da carteira e seu proxy correspondente. Este relatório tem como objetivo fornecer uma análise detalhada para compreender completamente o incidente.
0x0: Design Básico
Antes de examinar a vulnerabilidade, é importante primeiro entender as relações entre os contratos inteligentes envolvidos. Essencialmente, estes podem ser abstraídos em uma combinação de três padrões de design: CloneFactory, Cloneable Proxy e Beacon Proxy, que estão representados no diagrama a seguir.

0x1: Análise de Vulnerabilidade
A vulnerabilidade decorre da inicialização inadequada de contratos de carteira, que é causada por uma incompatibilidade entre a implementação real da carteira e seu proxy correspondente. Especificamente, durante o processo de inicialização, o proxy inicializou o slot de armazenamento 0 para um estado não nulo ao escrever nos bits menos significativos da localização de armazenamento. Subsequentemente, o código da carteira também escreveu no slot de armazenamento 0, sobrescrevendo assim o valor inicial do proxy nos bits menos significativos. Esse problema não é resultado de uma vulnerabilidade inerente em nenhum dos contratos inteligentes, mas sim da interação entre os dois.
A seguir, ilustraremos os detalhes com base no rastreamento de transação fornecido abaixo:

Especificamente, dentro da função CloneableProxy:Proxy.initialize(), há uma delegatecall que invoca a função Wallet.initialize(). Essa invocação ocorre por meio de uma delegatecall para a função CloneableProxy:Implementation.initialize(). Como resultado, quaisquer modificações no armazenamento feitas pela função Wallet.initialize() serão refletidas no armazenamento do contrato CloneableProxy:Proxy.
Para compreender completamente as implicações, é necessário examinar o layout de armazenamento do contrato CloneableProxy:Proxy. A definição deste contrato é descrita da seguinte forma:

Dado que nem o Proxy nem os contratos ERC1967Upgrade possuem variáveis de armazenamento, o slot 0 é utilizado por duas variáveis de armazenamento — _initialized e _initializing — ambas herdadas do contrato Initializable.

Agora, vamos examinar o contrato Wallet. Dentro da função Wallet.initialize(), é evidente que o slot 0xaa serve como sinalizador de inicialização. Isso é destacado pelo seguinte trecho de código nas linhas 3–4 e 11–12:

Observe que o slot 0 é alocado para _state, que armazena os próximos 32 bytes do calldata após o seletor de função, conforme indicado na linha 21. Para informações adicionais detalhadas, consulte o comentário no início do contrato Wallet:

Há uma incompatibilidade perceptível em relação ao uso do slot 0: o contrato CloneableProxy:Proxy o interpreta como o sinalizador de inicialização, enquanto a função Wallet:initialize() o trata como o estado da carteira.
Consequentemente, após o processo de inicialização, os dois bytes menos significativos do slot 0 serão redefinidos para zero. Isso efetivamente define tanto _initialized quanto _initializing como zero. Como resultado, o contrato CloneableProxy:Proxy torna-se vulnerável à reinicialização por meio da função initialize(), pois a proteção do modificador initializer pode ser contornada.

Obviamente, o potencial de exploração depende do estado da carteira. Uma vez atualizado para um valor não nulo, o estado da carteira impede qualquer reinicialização adicional deste contrato. Após a inicialização, à medida que o estado da carteira é atualizado a cada transação, a probabilidade de que os dois bytes menos significativos do slot 0 sejam não nulos aumenta, o que efetivamente imuniza a carteira contra reinicialização. Isso explica por que a maioria das carteiras vulneráveis tinha pouco ou nenhum histórico de transações, deixando-as expostas ao ataque.
0x2: Análise do Ataque
O atacante começou reinicializando o contrato CloneableProxy:Proxy vulnerável para alterar o endereço do contrato Beacon. Em seguida, o atacante procedeu à transferência dos ativos contidos no contrato CloneableProxy:Proxy, conforme detalhado abaixo:

É notável que vários contratos vulneráveis foram comprometidos em uma única transação, com o atacante executando essa estratégia repetidamente.
0x3: Resumo dos Ataques
Observamos 4.958 ataques no total, executados por seis contas distintas, conforme segue:

0x4: Correção e Recomendações
Nossa investigação revelou que o problema central decorre do uso inconsistente do slot de armazenamento 0, levando à possibilidade de reinicialização de contratos vulneráveis. Obviamente, a correção envolve um gerenciamento cuidadoso das alocações de armazenamento.
A partir deste incidente, extraímos vários insights críticos:
-
Exercite extrema cautela ao manipular slots de armazenamento com assembly inline, pois erros podem levar a vulnerabilidades significativas.
-
Mantenha um monitoramento vigilante dos status dos contratos. A capacidade de responder rapidamente depende do recebimento de alertas em tempo hábil.
-
Implemente um mecanismo de pausa nos contratos para permitir a suspensão imediata das atividades caso um comprometimento seja detectado.
Além disso, o fato de que este incidente envolveu múltiplas transações de ataque direcionadas a diferentes contratos de carteira destaca a necessidade urgente de soluções de monitoramento de ameaças e bloqueio de ataques, como o Phalcon. Tais ferramentas são essenciais para mitigar riscos futuros e proteger contra perdas potenciais.
0x5: Cronologia dos Eventos
09:23 AM PST, 25 de dezembro: Nosso sistema detectou a primeira transação maliciosa na rede Polygon:

10:28 AM PST, 25 de dezembro: A equipe de suporte da Telcoin relatou o incidente no canal de comunicação interno.
10:32 AM — 10:37 AM PST, 25 de dezembro: Membros da equipe Telcoin notificaram a comunidade do Discord da Telcoin e criaram uma chamada de emergência com todos os principais membros relevantes da equipe.
10:45 AM PST, 25 de dezembro: Uma regra de Firewall de Aplicação Web foi implementada para restringir todo o acesso à Infraestrutura da Telcoin.
11:02 AM PST, 25 de dezembro: A equipe Telcoin iniciou conversas com o Seal 911
11:11 AM PST, 25 de dezembro: Uma sala de guerra foi estabelecida pela equipe Telcoin e outros membros de segurança para descobrir a causa raiz do problema e discutir possíveis soluções para bloquear o ataque.
01:14 PM PST, 25 de dezembro: A equipe Telcoin emitiu publicamente um alerta aos usuários via X (Twitter):
03:39 PM PST, 25 de dezembro: A Telcoin contatou a Chainalysis & Slowmist para ajudar a investigar os fundos roubados, realizando uma investigação na qual rotularam as carteiras e endereços roubados e compartilharam essas informações com exchanges.

10:35 PM PST, 25 de dezembro: Mediante convite da equipe Telcoin, nos juntamos à sala de guerra e compartilhamos nossa análise para determinar a causa raiz.
11:00 PM PST, 25 de dezembro a 02:06 AM PST, 26 de dezembro: Após identificar a causa raiz, a equipe Telcoin desenvolveu com sucesso uma estratégia de mitigação replicando o exploit de forma segura e controlada. Este processo envolveu a reinicialização dos proxies de carteira para alinhá-los com um novo beacon implementado de forma segura. Dado que este exploit era uma oportunidade única, a Telcoin pode atualizar preventivamente as configurações das carteiras, desabilitando assim a capacidade do atacante de explorar ainda mais essas vulnerabilidades.
02:07 AM PST, 26 de dezembro a 02:14 AM PST, 26 de dezembro: A equipe Telcoin implementou o processo de mitigação em todas as carteiras não previamente comprometidas para garantir cobertura abrangente. Para uma implantação rápida e eficiente, o processo foi executado em lotes dentro de uma janela de tempo estritamente definida. A Telcoin então iniciou o processo de preparação e teste interno do plano de remediação para uma restauração completa de todas as carteiras afetadas e uma correção permanente para todas as carteiras.
04:52 PM PST, 26 de dezembro: A Telcoin e nossa equipe iniciaram discussões sobre os seguintes tópicos:
-
Visão Geral do Incidente
-
Cronologia dos Eventos: Um relato cronológico de como o incidente se desenrolou.
-
Análise de Causa Raiz: Uma análise aprofundada das causas subjacentes do incidente.
-
Recomendações para Melhoria
-
Auditoria de Código
12:27 PM PST, 29 de dezembro: Após várias rodadas de discussão, começamos a colaborar com a equipe Telcoin para redigir o relatório pós-mortem e auditar as remediações.
03 de jan, 2024: O rascunho do pós-mortem foi fornecido.
04 de jan, 2024: Nossas descobertas de auditoria, incluindo problemas identificados e recomendações, foram apresentadas.
04 a 10 de jan, 2024: Colaboramos com a equipe Telcoin para finalizar o pós-mortem e revisar as correções.
Além disso, vale ressaltar que de 25 de dezembro até a data atual, a Telcoin tem trabalhado ativamente em estreita colaboração com empresas investigativas de blockchain e autoridades policiais em relação ao incidente.
Sobre a BlockSec
A BlockSec é uma empresa pioneira em segurança blockchain estabelecida em 2021 por um grupo de especialistas em segurança de renome mundial. A empresa está comprometida em aprimorar a segurança e a usabilidade para o emergente mundo Web3, a fim de facilitar sua adoção em massa. Para esse fim, a BlockSec fornece serviços de auditoria de segurança para contratos inteligentes e chains EVM, a plataforma Phalcon para desenvolvimento de segurança e bloqueio proativo de ameaças, a plataforma MetaSleuth para rastreamento e investigação de fundos, e a extensão MetaDock para construtores web3 navegarem com eficiência no mundo cripto.
Até o momento, a empresa atendeu mais de 300 clientes estimados, como MetaMask, Uniswap Foundation, Compound, Forta e PancakeSwap, e recebeu dezenas de milhões de dólares americanos em duas rodadas de financiamento de investidores proeminentes, incluindo Matrix Partners, Vitalbridge Capital e Fenbushi Capital.
Website: https://blocksec.com/



