Recentemente, enquanto trabalhávamos com um de nossos clientes, descobrimos um bug interessante que tem o potencial de ser um vetor de ataque para alguns projetos DeFi. Esse erro está especialmente relacionado ao conhecido padrão de token ERC777. Além disso, não é apenas um simples problema de reentrada comum entre hackers conhecidos.
Este artigo fornece uma explicação abrangente do ERC777, abrangendo todos os detalhes necessários. Existem poucos recursos para se aprofundar nas especificidades dos tokens ERC777, e este artigo é um guia detalhado valioso para qualquer pessoa interessada em aprender mais sobre os tokens ERC777.
Na última parte do artigo, nossas descobertas recentes serão explicadas.
Uma breve descrição do vetor de ataque
Essa vulnerabilidade aproveita as características do ERC777 e pode definir uma função de recebimento de gancho. Ao utilizar a capacidade de fazer chamadas arbitrárias no contrato de destino, um chamador mal-intencionado pode chamar o contrato de registro ERC777 e atribuir um endereço de gancho específico ao contrato de destino. Portanto, sempre que o contrato alvo receber tokens ERC777 no futuro, o contrato Hook do invasor será acionado. Esse gancho pode ser explorado de várias maneiras: seja para ataques de reentrada para roubar tokens, ou simplesmente para reverter transações, impedindo que o contrato alvo envie ou receba tokens ERC777.
ERC777 e seu Gancho
O que é ERC777
ERC777 é um dos padrões de token com gancho de transferência. Aqui está a descrição do EIP: , e aqui está uma prática ERC777 [4] 。
A principal motivação para implementar tokens ERC777 é imitar o comportamento de transferências de token nativo. Ao acionar contratos inteligentes quando os tokens são recebidos, os desenvolvedores podem executar uma lógica específica para aprimorar a funcionalidade e criar interações de token mais dinâmicas.
No entanto, essas chamadas extras durante o processo de transferência tornam o ERC777 diferente dos tokens ERC20. Esses ganchos introduzem um novo vetor de ataque que pode afetar contratos inteligentes que não foram projetados para lidar com chamadas adicionais durante transferências de token. Esse comportamento inesperado cria riscos de segurança para esses contratos.
A seguir está uma lista de alguns tokens ERC777 com alguma liquidez na rede principal Ethereum:
Quando o Gancho acontece
Os tokens ERC20 simplesmente atualizam os saldos durante as transferências. Mas os tokens ERC777 fazem isso:
Faça uma chamada de Gancho para o endereço do iniciador do token
Atualizar saldo
Faça uma chamada de Gancho para o endereço do receptor do token
Isso é bem ilustrado no token VRA:
Código fonte:
Agora, vamos examinar o código dessas chamadas:
como você viu:
Esta função lê um contrato chamado implementador de _ERC1820_REGISTRY
Se a função encontrar um implementador, esse implementador será chamado.
Vamos explorar esse registro e ver o que são implementadores.
Registro e implementadores
Todos os tokens ERC777 estão relacionados ao contrato do Registry:
Esse endereço é usado pelos tokens ERC777 para armazenar os destinatários do Gancho configurados. Esses receptores Hook são chamados de "implementadores de interface".
Isso significa que Alice pode escolher Bob como seu implementador de interface. Se Alice receber ou enviar tokens ERC777, Bob receberá o Gancho.
Alice pode gerenciar diferentes tipos de Hook. Portanto, quando Alice envia tokens, ela pode escolher Bob como implementador da interface, e somente quando Alice recebe tokens, ela escolhe Tom como implementador.
Ela também pode escolher diferentes implementadores de interface para diferentes tokens na maioria dos casos.
Estas preferências são armazenadas neste registro mapeado:
_interfaceHash é o ID do implementador de interface escolhido por Alice para um evento.
E qualquer um pode ler o implementador da interface de Alice com esta função:
Como você pode ver, esta é a função que encontramos anteriormente no código VRA.
A variável _TOKENS_SENDER_INTERFACE_HASH é usada como _interfaceHash, que pode ser qualquer byte. Mas o token VRA usa esses bytes para identificar esse tipo de Hook:
Receber Gancho
Para configurar uma função de recebimento do Hook, Alice só precisa chamar essa função no registro e inserir o endereço de Bob como o parâmetro _implementer.
Ela também deve especificar um _interfaceHash. Ela obterá este _TOKENS_SENDER_INTERFACE_HASH do código do token VRA.
Há mais um detalhe importante.
Depois de configurar o implementador para o VRA acima, Alice também saberá que, mesmo que outros tokens ERC777 sejam transferidos, Bob receberá a chamada. como imBTC [5] , imBTC tem o mesmo _interfaceHash nos tokens enviados.
Isso se deve ao fato de que todos os tokens ERC777 compartilham o mesmo contrato de registro para armazenar as preferências do Hook. Mas cabe aos tokens ERC777 atribuir nomes aos seus Hooks e, embora às vezes sejam semelhantes, nem sempre.
Como encontrar tokens ERC777
Chamar o registro é um recurso de todos os ERC777s. Então podemos tentar dune.com [6] para chamar todos os contratos inteligentes que chamam o registro.
Podemos usar este script SQL. Na verdade, deveríamos ter filtrado adicionalmente os endereços de token, mas pelo menos tivemos um começo perfeito e terminamos com 78 endereços.
Nota do tradutor: tabela de rastros de dunas [7] Gravará o registro de chamada interna da transação.
Esse registro é a única possibilidade?
Teoricamente, ninguém pode garantir que algum token use esse contrato 0x1820 como um registro. Mas podemos usar dune.com [8] Venha conferir.
Verificamos e 0x1820 é o único registro com valiosos tokens ERC777. Os tokens de outros registros não são tão valiosos.
A situação geral dos tokens Hookable
ERC777 não é apenas um padrão com Hooks. Também ERC223, ERC995 ou ERC667. Eles não são tão incomuns. Você deve ter ouvido falar do token LINK que implementa ERC667 [9] 。
Vetor de ataque usando chamada arbitrária
Este é um vetor de ataque recentemente descoberto para um de nossos clientes.
Os pesquisadores geralmente assumem que os tokens ERC777 fazem chamadas para chamadores e receptores. Mas, na verdade, o iniciador e o receptor podem escolher qualquer "Bob" como receptor do Gancho.
Então imagine o que acontece quando combinado com esses contratos que fazem chamadas arbitrárias para qualquer endereço com quaisquer dados?
Existem funções de chamada arbitrária que podem ser amplamente utilizadas em agregadores DEX, carteiras e contratos multicall.
Nota do tradutor: A função de chamada arbitrária significa que existe uma função como esta no contrato:
função ute(endereço alvo, valor uint, assinatura de memória de string, dados de memória de bytes, uint eta) public pagável;
Pode chamar qualquer outro método.
Método de ataque:
O invasor encontra um contrato de destino (Target) que permite chamadas de função arbitrárias
O Atacante será chamado com o hookHash utilizado no token ERC777.
Sempre que o contrato de destino (Target) receber tokens ERC777, o atacante receberá uma chamada de gancho.
Os seguintes ataques variam dependendo do código alvo:
O invasor pode entrar novamente quando alguns usuários executam funções no contrato de destino
O invasor pode reverter diretamente, para que a transação do usuário seja restaurada diretamente
Se o agregador DEX calcular que o melhor caminho de conversão é por meio de um par de negociação DEX com tokens ERC777, ele poderá encontrar problemas.
Proteger
Após horas de discussão com os clientes, encontramos uma solução que não interrompia chamadas arbitrárias.
É melhor para o lado do projeto limitar o uso de Registry1820 como o endereço de qualquer chamada. Portanto, nenhum invasor pode explorar chamadas arbitrárias para definir o implementador de interface.
Falando por experiência
Projetos e auditores devem prestar atenção ao comportamento do Hook descrito no ERC777. Esses tokens fazem chamadas não apenas para receptores e iniciadores, mas também para alguns outros receptores Hook.
Nesse sentido, projetos que permitem chamadas arbitrárias devem ter um cuidado especial e considerar outro vetor de ataque para o ERC777.
Ver original
Esta página pode conter conteúdo de terceiros, que é fornecido apenas para fins informativos (não para representações/garantias) e não deve ser considerada como um endosso de suas opiniões pela Gate nem como aconselhamento financeiro ou profissional. Consulte a Isenção de responsabilidade para obter detalhes.
Possíveis problemas de segurança com ERC777 e contratos de chamada arbitrária
Recentemente, enquanto trabalhávamos com um de nossos clientes, descobrimos um bug interessante que tem o potencial de ser um vetor de ataque para alguns projetos DeFi. Esse erro está especialmente relacionado ao conhecido padrão de token ERC777. Além disso, não é apenas um simples problema de reentrada comum entre hackers conhecidos.
Este artigo fornece uma explicação abrangente do ERC777, abrangendo todos os detalhes necessários. Existem poucos recursos para se aprofundar nas especificidades dos tokens ERC777, e este artigo é um guia detalhado valioso para qualquer pessoa interessada em aprender mais sobre os tokens ERC777.
Na última parte do artigo, nossas descobertas recentes serão explicadas.
Uma breve descrição do vetor de ataque
Essa vulnerabilidade aproveita as características do ERC777 e pode definir uma função de recebimento de gancho. Ao utilizar a capacidade de fazer chamadas arbitrárias no contrato de destino, um chamador mal-intencionado pode chamar o contrato de registro ERC777 e atribuir um endereço de gancho específico ao contrato de destino. Portanto, sempre que o contrato alvo receber tokens ERC777 no futuro, o contrato Hook do invasor será acionado. Esse gancho pode ser explorado de várias maneiras: seja para ataques de reentrada para roubar tokens, ou simplesmente para reverter transações, impedindo que o contrato alvo envie ou receba tokens ERC777.
ERC777 e seu Gancho
O que é ERC777
ERC777 é um dos padrões de token com gancho de transferência. Aqui está a descrição do EIP: , e aqui está uma prática ERC777 [4] 。
A principal motivação para implementar tokens ERC777 é imitar o comportamento de transferências de token nativo. Ao acionar contratos inteligentes quando os tokens são recebidos, os desenvolvedores podem executar uma lógica específica para aprimorar a funcionalidade e criar interações de token mais dinâmicas.
No entanto, essas chamadas extras durante o processo de transferência tornam o ERC777 diferente dos tokens ERC20. Esses ganchos introduzem um novo vetor de ataque que pode afetar contratos inteligentes que não foram projetados para lidar com chamadas adicionais durante transferências de token. Esse comportamento inesperado cria riscos de segurança para esses contratos.
A seguir está uma lista de alguns tokens ERC777 com alguma liquidez na rede principal Ethereum:
Quando o Gancho acontece
Os tokens ERC20 simplesmente atualizam os saldos durante as transferências. Mas os tokens ERC777 fazem isso:
Faça uma chamada de Gancho para o endereço do iniciador do token
Atualizar saldo
Faça uma chamada de Gancho para o endereço do receptor do token
Isso é bem ilustrado no token VRA:
Código fonte:
Agora, vamos examinar o código dessas chamadas:
como você viu:
Vamos explorar esse registro e ver o que são implementadores.
Registro e implementadores
Todos os tokens ERC777 estão relacionados ao contrato do Registry:
Esse endereço é usado pelos tokens ERC777 para armazenar os destinatários do Gancho configurados. Esses receptores Hook são chamados de "implementadores de interface".
Isso significa que Alice pode escolher Bob como seu implementador de interface. Se Alice receber ou enviar tokens ERC777, Bob receberá o Gancho.
Alice pode gerenciar diferentes tipos de Hook. Portanto, quando Alice envia tokens, ela pode escolher Bob como implementador da interface, e somente quando Alice recebe tokens, ela escolhe Tom como implementador.
Ela também pode escolher diferentes implementadores de interface para diferentes tokens na maioria dos casos.
Estas preferências são armazenadas neste registro mapeado:
_interfaceHash é o ID do implementador de interface escolhido por Alice para um evento.
E qualquer um pode ler o implementador da interface de Alice com esta função:
Como você pode ver, esta é a função que encontramos anteriormente no código VRA.
A variável _TOKENS_SENDER_INTERFACE_HASH é usada como _interfaceHash, que pode ser qualquer byte. Mas o token VRA usa esses bytes para identificar esse tipo de Hook:
Receber Gancho
Para configurar uma função de recebimento do Hook, Alice só precisa chamar essa função no registro e inserir o endereço de Bob como o parâmetro _implementer.
Ela também deve especificar um _interfaceHash. Ela obterá este _TOKENS_SENDER_INTERFACE_HASH do código do token VRA.
Há mais um detalhe importante.
Depois de configurar o implementador para o VRA acima, Alice também saberá que, mesmo que outros tokens ERC777 sejam transferidos, Bob receberá a chamada. como imBTC [5] , imBTC tem o mesmo _interfaceHash nos tokens enviados.
Isso se deve ao fato de que todos os tokens ERC777 compartilham o mesmo contrato de registro para armazenar as preferências do Hook. Mas cabe aos tokens ERC777 atribuir nomes aos seus Hooks e, embora às vezes sejam semelhantes, nem sempre.
Como encontrar tokens ERC777
Chamar o registro é um recurso de todos os ERC777s. Então podemos tentar dune.com [6] para chamar todos os contratos inteligentes que chamam o registro.
Podemos usar este script SQL. Na verdade, deveríamos ter filtrado adicionalmente os endereços de token, mas pelo menos tivemos um começo perfeito e terminamos com 78 endereços.
Esse registro é a única possibilidade?
Teoricamente, ninguém pode garantir que algum token use esse contrato 0x1820 como um registro. Mas podemos usar dune.com [8] Venha conferir.
ele retorna esses endereços
0x1820a4b7618bde71dce8cdc73aab6c95905fad24 0xc0ce3461c92d95b4e1d3abeb5c9d378b1e418030 0x820c4597fc3e4193282576750ea4fcfe34ddf0a7
Verificamos e 0x1820 é o único registro com valiosos tokens ERC777. Os tokens de outros registros não são tão valiosos.
A situação geral dos tokens Hookable
ERC777 não é apenas um padrão com Hooks. Também ERC223, ERC995 ou ERC667. Eles não são tão incomuns. Você deve ter ouvido falar do token LINK que implementa ERC667 [9] 。
Vetor de ataque usando chamada arbitrária
Este é um vetor de ataque recentemente descoberto para um de nossos clientes.
Os pesquisadores geralmente assumem que os tokens ERC777 fazem chamadas para chamadores e receptores. Mas, na verdade, o iniciador e o receptor podem escolher qualquer "Bob" como receptor do Gancho.
Então imagine o que acontece quando combinado com esses contratos que fazem chamadas arbitrárias para qualquer endereço com quaisquer dados?
Existem funções de chamada arbitrária que podem ser amplamente utilizadas em agregadores DEX, carteiras e contratos multicall.
Método de ataque:
Se o agregador DEX calcular que o melhor caminho de conversão é por meio de um par de negociação DEX com tokens ERC777, ele poderá encontrar problemas.
Proteger
Após horas de discussão com os clientes, encontramos uma solução que não interrompia chamadas arbitrárias.
É melhor para o lado do projeto limitar o uso de Registry1820 como o endereço de qualquer chamada. Portanto, nenhum invasor pode explorar chamadas arbitrárias para definir o implementador de interface.
Falando por experiência
Projetos e auditores devem prestar atenção ao comportamento do Hook descrito no ERC777. Esses tokens fazem chamadas não apenas para receptores e iniciadores, mas também para alguns outros receptores Hook.
Nesse sentido, projetos que permitem chamadas arbitrárias devem ter um cuidado especial e considerar outro vetor de ataque para o ERC777.