Por: 九九

fundo

Em 5 de dezembro de 2023, a plataforma de desenvolvimento básico Thirdweb da Web3 declarou que um problema de segurança foi encontrado no contrato inteligente pré-construído e todos os tokens ERC20, ERC721 e ERC1155 implantados usando o contrato inteligente pré-construído foram afetados. (Para versões específicas do código de contrato afetado, consulte: https://blog.thirdweb.com/security-vulnerability/)

Segundo inteligência da equipe de segurança SlowMist, em 7 de dezembro de 2023, o token Time na rede principal da ETH foi atacado justamente por causa dessa vulnerabilidade, e o invasor obteve lucro de aproximadamente US$ 190 mil. Ainda existem muitos contratos de token com vulnerabilidades sendo atacadas. A equipe de segurança do SlowMist interveio imediatamente na análise e compartilhou os resultados da seguinte forma:

conhecimento pré-requisito

1. ERC-2771 é o padrão para metatransações. Os usuários podem delegar a execução de transações a um encaminhador de terceiros, geralmente chamado de retransmissor ou encaminhador.

Normalmente o endereço do chamador direto no contrato é obtido usando msg.sender, mas no caso de usar ERC-2771, se msg.sender for a função de encaminhador, os dados da chamada recebida serão truncados e as últimas 20 palavras serão obtidas .seção como o endereço do chamador direto da transação.

2. Multicall é uma biblioteca de contratos inteligentes que permite a execução de múltiplas chamadas de função em lotes, reduzindo assim os custos de transação. Esta biblioteca é frequentemente usada para otimizar o desempenho e a experiência do usuário de DApps, especialmente quando são necessárias múltiplas operações de leitura.

Como pode ser visto no código, a biblioteca Multicall usada pelo contrato vulnerável no projeto thirdweb executa outras funções no contrato que faz referência à biblioteca chamando ciclicamente a função DelegateCall.

causa raiz

A causa raiz da vulnerabilidade é que o contrato de token usa as bibliotecas ERC-2771 e Multicall. O invasor chama a função multicall do contrato de token por meio da função de execução do contrato Forwarder para executar outras funções no contrato (como queimar tokens). Este método passa com êxito no julgamento isTrustedForwarder do ERC-2771 e, finalmente, resolve o chamador da função nos últimos 20 bytes dos dados de chamada maliciosos. Portanto, o invasor enganou o contrato fazendo-o pensar que o chamador era o endereço de outro usuário, o que por sua vez levou à queima dos tokens de outros usuários.

Análise das etapas do ataque

Aqui tomamos a transação de ataque 0xecdd11...f6b6 como exemplo para análise:

1. O invasor primeiro usou 5 WETH para trocar por 345.539.9346 tokens Time no pool Uniswap V2.

2. Em seguida, chame a função de execução do contrato Forwarder e construa dados maliciosos para chamar a função multicall do contrato de token. Neste momento, o contrato de token usará os dados maliciosos transmitidos pelo invasor para delegadoCall para executar a função de gravação de. o contrato de token e gravar o endereço do pool 62.227.259.510 tokens de tempo.

3. Como a etapa anterior queimou um grande número de tokens de tempo no pool, fazendo com que o preço dos tokens de tempo subisse instantaneamente, o invasor pode finalmente reverter a troca dos tokens de tempo obtidos na primeira etapa, esvaziando o pool.

Análise do princípio de ataque

Na função execute do contrato Forward, após verificar a assinatura de req.from, a chamada será utilizada para interagir com req.to (endereço do token). O req.data passado pelo invasor é

Como 0xac9650d8 é a assinatura da função multicall, a função multicall do contrato de token será chamada e o valor dos dados passado pela função multicall é 0x42966c680000000000000000000000000000000000c9112ec16d958e8da8180000760dc 1 e043d99394a10605b2fa08f123d60faf84.

Por que não há req.from no valor dos dados passado para a função multicall? Isso ocorre porque a camada inferior do EVM truncará o valor necessário com base no deslocamento ao processar a chamada. O deslocamento definido no valor calldata passado pelo invasor é 38 e o comprimento do valor é 1, portanto, ele apenas intercepta o valor dos dados. 42966c6800000000000000000000000000000000000c9112ec16d958e8da8180000760dc1e043d99394a10605b2fa08f123d60faf84.

Para obter detalhes, consulte a descrição da chamada no opcode EVM (https://www.evm.codes/?fork=shanghai).

Como 0x42966c68 é a assinatura da função burn, a função burn do contrato de token será chamada via delegado com base no valor dos dados construído pelo invasor.

A função _msgSender() é substituída pela biblioteca ERC-2771.

Como multicall é chamado por meio de delegadocall, o msg.sender passado por isTrustedForwarder é na verdade o endereço do contrato Forward, passando assim o julgamento e, em última análise, o valor retornado por _msgSender() são os últimos 20 bytes dos dados de chamada passados. ou seja, o endereço do pool é 0x760dc1e043d99394a10605b2fa08f123d60faf84.

para concluir

A causa raiz deste ataque é que o contrato faz referência a Multicall e ERC2771Context. O invasor pode inserir dados de chamada maliciosos na solicitação de encaminhamento, usar a função delegado de Multicall para julgar o encaminhador confiável e manipular _msgSender() no. sub-chamada. Análise, para que o token de qualquer usuário possa ser manipulado.

A equipe de segurança do SlowMist recomenda que as partes do projeto não usem Multicall e ERC2771Context ao mesmo tempo ao escrever contratos de token. Se a demanda esperada exigir referência simultânea, você deve verificar se o comprimento dos dados de chamada atende às expectativas ou usar a versão oficial mais recente do Multicall e do openzeppelin. ERC2771Contratos de contexto.

referência

Endereço do invasor: 0xfde0d1575ed8e06fbf36256bcdfa1f359281455a

Contrato de ataque: 0x6980a47bee930a4584b09ee79ebe46484fbdbdd0

Transações de ataque relacionadas: https://etherscan.io/tx/0xecdd111a60debfadc6533de30fb7f55dc5ceed01dfadd30e4a7ebdb416d2f6b6

Detalhes da versão afetada: https://blog.thirdweb.com/security-vulnerability/

Ferramenta de mitigação: https://mitigate.thirdweb.com/