WEB3DEV

Cover image for O que Você Precisa Saber Sobre os Ataques de Reentrância por Contratos Inteligentes
Adriano P. Araujo
Adriano P. Araujo

Posted on • Atualizado em

O que Você Precisa Saber Sobre os Ataques de Reentrância por Contratos Inteligentes

Contratos inteligentes. Ouvimos muito sobre como essas ‘classes’ de código têm o potencial de mudar o mundo. De fato, é a própria razão pela qual a Ethereum está onde está hoje, ao poder ir além do que o Bitcoin queria oferecer.

Por mais empolgante que tenha sido essa inovação, havia certas advertências que valiam a pena considerar quanto a tecnologia blockchain como uma tendência. Muito parecido com qualquer unidade de código escrita, há todas as chances de que a existência de bugs de software possa empurrar bruscamente a adoção da tecnologia blockchain do  pico das expectativas infladas até o vale da desilusão.


Sumário

1 . Erros comuns de contratos inteligentes

2 . Sua primeira olhada nos ataques de reentrância de contratos inteligentes

3 . Por que os ataques de reentrância por contratos inteligentes são tão devastadores

4 . Como ocorrem os ataques

5 . 3 maneiras de corrigir erros de reentrância no contrato inteligente

6 . Os ataques de reentrância de contratos inteligentes são limitados a Ethereum?


Falando nisso, mesmo que a própria blockchain não possa ser invadida em um sentido convencional do termo, ainda existe uma possibilidade distinta de perder milhões em criptografia, graças à existência de erros de contrato inteligentes.

Erros comuns de contratos inteligentes

Os erros de software, em geral, tendem a se tornar aparentes quando resultados ou comportamentos inesperados.

Agora, existem vários tipos de bugs que se pode experimentar ao usar o referido software: alguns deles incluem bugs funcionais, lógicos, de fluxo de trabalho e de nível de unidade, entre outros tipos. Dado o quão prejudicial isso pode ser para a experiência do usuário, o teste geralmente ocorre para resolver esses erros.

Não muito diferente, os erros de contrato inteligentes também têm tipos ou classificações que variam de lógica e dados a desempenho e segurança, todos com causa, consequência, critérios de detecção e nível de gravidade. Além disso, como resultado, eles também falham em atender aos requisitos de funcionalidade, desempenho, segurança e capacidade de manutenção.

Fonte: https://www.tatvasoft.com/outsourcing/2022/07/different-types-of-software-bugs.html

Entre aqueles com um nível crítico de gravidade, o bug de reentrância causa grandes danos, pois resulta na perda de milhões em criptografia e ocorreu recentemente em 2021.

Dito isto, mesmo que esses ataques tendam a crescer em complexidade, existem correções que podem dificultar o próximo hack, explorando essa vulnerabilidade.

Sua primeira olhada nos ataques de reentrância de contratos inteligentes

Praticamente qualquer dicionário de inglês fornecerá o significado de reentrância, que pode ser simplificado para o termo ‘para reinserir’.

No contexto da ciência da computação, existem certas funções que podem ser reentrâncias repetidamente seguras, apesar de serem interrompidas no caso de um sistema de processador único ou podem ser executadas simultaneamente em vários processadores.

No entanto, no caso de contratos inteligentes, reentrar em uma função repetidamente pode significar um desastre, como descobriremos. Antes de começarmos a explicar como essa vulnerabilidade é explorada, algumas coisas devem ser estabelecidas: a reentrância geralmente ocorre entre dois contratos inteligentes, onde, por uma questão de simplicidade, o contrato A é o contrato vulnerável e o contrato B é malicioso. Segundo, sempre que as chamadas de função de contrato são feitas, a Máquina Virtual Ethereum ( EVM ) transfere a execução do contrato de chamada para o que está sendo chamado, do contrato A para B.

Fonte: https://cryptomarketpool.com/reentrancy-attack-in-a-solidity-smart-contract/

Terceiro, este é um momento crítico desde o chamado contrato — O contrato B , no diagrama acima, — agora pode fazer chamadas próprias, o que pode ser arriscado se as atualizações no estado do contrato não tiverem sido feitas. Em poucas palavras, é o que ocorre quando a vulnerabilidade de reentrância é explorada pelo contrato B.

Por que os ataques de reentrância por contratos inteligentes são tão devastadores

Mesmo que esses ataques de reentrância de contratos inteligentes continuem diminuindo em gravidade, uma quantidade substancial de dinheiro foi perdida.

Provavelmente, o mais proeminente desses ataques envolve a DAO Hack, realizado em 2016, que levantou mais de $ 150 milhões de um grupo de 11.000 investidores. Como você sabe, uma organização autônoma descentralizada ( DAO ) consiste em código escrito na forma de contratos inteligentes que aplicam as regras, diretrizes e funcionalidades dessa organização. Cabe ressaltar que a necessidade de uma autoridade centralizada também é eliminada.

Agora, como em outros contratos inteligentes, um escrito para uma DAO também não pode ser alterado quando é implantado na blockchain. No caso da DAO hack, a capacidade de explorar a vulnerabilidades no código já foi observada por especialistas e se tornou realidade em 17 de junho de 2016.

Por meio de várias chamadas recursivas, o hacker conseguiu drenar $ 60 milhões de dólares em Ether, mas isso ocorreu devido à falha em que a transferência de Ether ocorreu antes que o saldo fosse atualizado no próprio contrato.

Fonte: https://moralis.io/what-is-reentrancy-reentrancy-smart-contract-example/

Se você olhar para o diagrama acima, o Ether foi transferido fazendo saques repetidos de uma função de fallback. À medida que avançamos para a próxima seção que envolve a revisão do código Solidity, veremos isso com mais detalhes.

Como ocorrem os ataques

Agora, vejamos como os ataques de reentrância ocorrem usando o código Solidity:

Fonte: https://solidity-by-example.org/hacks/re-entrancy/

O contrato da Ether Store tem três funções: deposit, withdraw e getBalance. Como é evidente nas definições das funções, o primeiro faz um determinado depósito para o referido endereço, o segundo retira um saldo com base no endereço enquanto a função getBalance retorna o saldo do contrato.

Fonte: https://solidity-by-example.org/hacks/re-entrancy/

Como você pode ver, o contrato de ataque é aquele que executa o hack em que um valor inicial de 1 ether é depositado no contrato inteligente. Isso é para que a verificação da linha “ require ( bal > 0 )” possa ser satisfeita antes que o ataque comece a fazer inúmeras retiradas através da função de fallback.

Como o saldo do remetente ainda não está definido como zero, como na linha “ balances [ msg.sender ] = 0 ”, o invasor pode continuar recebendo Ether através da função de fallback. Como o invasor pode fazer chamadas recursivas para o contrato na função de retirada  do  Ether Store, é muito possível que eles continuem fazendo isso até que os fundos do contrato sejam completamente drenados.

Por exemplo, vamos implantar os dois contratos no Remix IDE e adicionar um valor arbitrário de 6 Test Ether ao contrato EtherStore, conforme mostrado abaixo:

Funções acessíveis após a implantação do contrato EtherStore

Agora, vamos executar o contrato de ataque, mas primeiro depositando 1 ether e depois chamando a função withdraw ( ), como mostrado abaixo:

O contrato de ataque deposita 1 ether antes de chamar a função de withdraw ( )

Como você pode ver na captura de tela abaixo, todo o saldo do contrato EtherStore foi transferido para o contrato Attack, e é por isso que um saldo de 7 Ether está no contrato.

7 ETH agora depositado no contrato de ataque

Dito isto, é preciso lembrar que isso não significa que haja uma falha na blockchain Ethereum ou mesmo na linguagem de programação Solidity. Em vez disso, o DAO hack ocorreu devido à supervisão do programador de contratos inteligentes e resultou na divisão da blockchain Ethereum em duas cadeias separadas, com os atacantes ainda fugindo com uma quantidade significativa de fundos.

3 maneiras de corrigir erros de reentrância no contrato inteligente

Agora, existem três maneiras pelas quais se pode corrigir esse erro de reentrância: usando o padrão de verificações-efeitos-interações, usando um guarda de não reentrância oferecido pela biblioteca Open Zeppelin ou usando um endereço de garantia intermediário.

Agora, quando implementamos o padrão de verificações-efeitos-interações, impedimos que a função de retirada no contrato acima seja acessada. Pelo menos, a menos que o estado ‘ associado ’ a essa chamada da função de retirada tenha sido alterado.

Mesmo que seja melhor esperar até que a interação externa ocorra com sucesso, o padrão exige que o estado seja atualizado antes de continuar com a interação externa. Em outras palavras, o saldo é reduzido antes da conclusão da retirada, conforme mostrado abaixo:

Fonte: https://solidity-by-example.org/hacks/re-entrancy/

É por isso que a aplicação do padrão de verificações-efeitos-interações é considerada contra-intuitiva. Ainda assim, com o estado alterado, isso evita a reentrância e, portanto, é considerado uma das soluções.

Outra solução requer o uso do framework Open Zeppelin para adicionar um bloqueio de mutex. Especificamente, você usaria o modificador nonReentrancy, conforme encontrado no contrato ReentrancyGuard.sol nessa chamada para garantir que o referido contrato não seja repetidamente chamado, direta ou indiretamente.

Veja como você precisaria reescrever a função de retirada para acomodar esse bloqueio de mutex usando a biblioteca OpenZeppelin e o modificador nonReentrant:

Fonte: https://solidity-by-example.org/hacks/re-entrancy/

Se você pretende usar este código, substitua o texto addContractLink na instrução de importação acima pela seguinte chamada entre aspas duplas.

A terceira e última correção envolve o uso de um endereço de garantia intermediário que mantém os fundos retirados do contrato. O receptor pode efetuar o pagamento, mas apenas uma vez, pois um compromisso impede a reentrância do contrato. Obviamente, se o compromisso tiver várias contas, há uma chance de reentrância, mas que pode ser evitada usando o padrão de verificação de efeitos-interações, bem como os métodos de proteção de reentrância descritos acima.

Agora, mesmo que essas três correções funcionem, vale a pena notar que esse problema de reentrância não surge se você usar uma blockchain como a Aeternity, visto que sua linguagem de programação de contrato inteligente Sophia, em virtude da adoção do paradigma de programação funcional, impede tal condição em primeiro lugar

Os ataques de reentrância de contratos inteligentes são limitados a Ethereum

Desde que esse tipo de bug causou o DAO Hack na blockchain Ethereum, outros protocolos tomaram medidas para impedir que esse erro ocorresse no deles.

Portanto, embora seja inteiramente possível considerar esse bug como não sendo mais prejudicial, houve ataques de reentrância em 2021. Esses ataques também resultaram na perda de milhões também, portanto, não devem ser considerados bobos.

Mas sim, esses ataques são limitados principalmente à blockchain Ethereum e é por isso que também focamos em fornecer código de solidity para as correções. Dito isto, como a maioria das cadeias é compatível com EVM, faz sentido que os desenvolvedores também fiquem cientes de tais erros persistentes e de suas correções.

Agora, se você também deseja manter contato com as atualizações mais recentes no desenvolvimento da Web3 como parte de uma comunidade em crescimento, pode participar do nosso Metaverse, nosso servidor do Discord abaixo: 

https://discord.com/invite/4WeVkXyM5K


Este artigo foi escrito por Daniel Chakraborty
 e traduzido por Adriano P. de Araujo. O original em inglês pode ser encontrado aqui.

Top comments (0)