— Recorrência de vulnerabilidade On-chain (vulnerabilidade de reentrância)
Bem vindo a nos seguir e discutir conosco
0x01 Introdução
A reentrância significa que o contrato A chama o contrato B, e o contrato B chama recorrentemente a função no contrato A através da função fallback().
0x02 Contrato vulnerável
Tomemos como exemplo a versão atual da Solidity 0.8:
contrato
O contrato EtherStore usa a função <address>.call{}() na função de transferência withdraw(), que permite que os hackers usem a função fallback() para recorrentemente chamar a função withdraw(), transferindo assim todo o dinheiro do contrato da EtherStore.
0x03 contrato de ataque
Continuamos a escrever o código de ataque, seguindo o contrato acima:
ataque
O código de ataque primeiro cria um constructor para receber o endereço do contrato do código vulnerável, e então escreve a função de ataque: após depositar o dinheiro deposit(), chama a função Withdraw() de reentrada e então escreve a função Fallback() de reentrada para chamar recorrentemente a função reentrante.
0x04 Reincidência de vulnerabilidades
Implantamos nosso primeiro contrato, depositando 0,1 ether:
A seguir, trocamos a conta na metamask para implantar o segundo contrato. Ao implantar, é necessário passar no endereço do primeiro contrato. Em seguida, depositar 0,01 Ether no contrato a atacar:
Entre eles, de 1 a 7 é o processo de ataque, e 8 e 9 são os resultados de confirmação dos ataques. Podemos ver que 110000000000000000 é exatamente 0.1 ether + 0.01 ether, indicando que o ataque foi bem sucedido.
Podemos consultar os registros das transações na chain, atacando o endereço do contrato:
https://kovan.etherscan.io/tx/0x20e72a9a84f336be320c58e7e5e7f0ac6d8947a450668c3414c7cc0a1da7200f
Pode-se ver que a transação tem uma função de chamada recorrente, que é o registro da vulnerabilidade da reentrância na chain.
0x05 Conselho sobre segurança
Os desenvolvedores podem optar por bloquear, para evitar a reentrância:
Se o código de ataque também for escrito como antes, quando a função acima é chamada uma segunda vez, a partir da função callback(), a checagem de require não passará. Isto impede a reentrância.
Autor: [email protected], tradução de: Fátima Lima. O original pode ser lido aqui.
Top comments (0)