WEB3DEV

Cover image for Hackeando o Etherscan: Criando falsa transferência de Token
Paulo Gio
Paulo Gio

Posted on

Hackeando o Etherscan: Criando falsa transferência de Token

Agora, vamos brincar um pouco mais com o evento Transfer e ver como podemos enganar o Etherscan mais uma vez.

A princípio, teremos um rápido lembrete de como o Etherscan rastreia o número de tokens para todos os detentores de um contrato inteligente.

Etherscan, use o evento transfer em solidity para rastrear todas as transferências na blockchain.

Sempre que um token é transferido, o evento Transfer é acionado com o endereço _from, o endereço _to e o valor como argumentos.

O saldo exibido no Etherscan é a soma (e a diferença) de todos os eventos de transferência.

Para mais informações, você pode conferir o primeiro artigo desta série sobre como hackear o Etherscan: https://medium.com/@TrustChain/hacking-etherscan-erc20-cheating-46dc229f5f8

1. Transferência falsa no Etherscan.

E se criarmos uma função chamada fake_transfer() e a invocarmos, o que acontecerá?

function fake_transfer(address from,address to,uint256 amount){
    emit Transfer(from, to, amount);
}
Enter fullscreen mode Exit fullscreen mode

Esta é exatamente a mesma função que _transfer() em contratos inteligentes ERC20, mas apenas o evento permanece.

Após a execução da função, apenas o evento Transfer será registrado na blockchain, mas o estado do contrato inteligente (como saldos) NÃO mudará.

Se implantarmos este contrato, é claro que o Etherscan mostrará resultados ruins.

constructor() ERC20("MyToken", "MTK") {    

_mint(msg.sender,100000000000000000000000000000000000000000000);
   // não se esqueça de remover o evento transfer na função _mint 

fake_transfer(0x0000000000000000000000000000000000000000,msg.sender,1000);
}
Enter fullscreen mode Exit fullscreen mode

https://miro.medium.com/max/1100/1*eBfmcslvLmOqBMonFmbR2A.png

Resultado do contrato falso

Como os decimais ainda são 18, o Etherscan mostra 10^(-18+3) = 10^-15 tokens transferidos do endereço 0 para o proprietário. Mas nós “cunhamos” uma quantia que tem muito mais zeros…

Portanto, o valor que você vê no Etherscan PODE NÃO SER VÁLIDO.

2. Encontrando o verdadeiro saldo do dono (ou não)

Como verificar o verdadeiro valor do dono do contrato? (para garantir que o proprietário não despeje o token como uma moeda sem valor (shitcoin) e drene todo o seu dinheiro)

Uma das maneiras de fazer isso é consultar a função balanceOf() e ver o resultado.

Pode funcionar facilmente, e podemos fazê-lo com ethers.js, também podemos usar a Metamask ou podemos consultar o Etherscan para este endereço específico.

https://miro.medium.com/max/1100/1*Jy3gCvfJxj3AkUDWnCQYHg.png

https://miro.medium.com/max/720/1*E8TI2lcgW6IrLcO6711nvg.png

A boa notícia é que conseguimos recuperar o valor “verdadeiro” .(1000….000000000 tokens)

A razão é que esses métodos dependem de balanceOf() em vez do evento Transfer, que são mais precisos, mas mais difíceis de implementar.

_(Mais preciso porque, por exemplo, se quisermos classificar cada posse pelo número de tokens que eles possuem, o Etherscan precisa fazer um loop para todos os endereços possíveis, e isso é impossível na vida real, pois são cerca de 2160 endereços Ethereum possíveis no total, então o evento transfer foi criado.)

3. Capturando a função de equilíbrio

Mas e se capturarmos a função balanceOf()?

Quero dizer por “capturar”, modificar o valor de retorno de balanceOf() retornando um valor falso.

Por exemplo, em vez de:

function balanceOf(address account) public view returns (uint256) {
   return _balances[account];
}
Enter fullscreen mode Exit fullscreen mode

Escrevemos:

function balanceOf(address account) public view returns (uint256) {if (account == 0x6166f7E....) {
       return 1000;
   } else {
       return _balances[account];
   }
}
Enter fullscreen mode Exit fullscreen mode

Este contrato inteligente retorna 1000 se account for igual ao endereço 0x6166f7E... mesmo que balances[0x6166f7E...] seja igual a outro valor.

Portanto, 0x6166f7E pode falsificar seu saldo para qualquer pessoa.

Além disso, no construtor, posso adicionar quantos tokens quiser para o endereço 0x6166f7E.

constructor() ERC20("MyToken", "MTK") {    _mint(msg.sender,100000000000000000000000000000000000000000000);
   // não esqueça de remover o evento Transfer na função _mint()
   // msg.sender = 0x6166f7E    
   fake_transfer(0x000000000...000000,msg.sender,1000);
   // emita Transfer(0 address,msg.sender,1000)
}
Enter fullscreen mode Exit fullscreen mode

Como resultado, o proprietário do contrato pode ocultar seu saldo para os detentores E para o Etherscan sem que ninguém perceba.

Vamos implantar este contrato inteligente e ver o que acontece no Etherscan & Metamask:

https://miro.medium.com/max/1100/1*4_66y5xydQpqMwtSXYa8zw.png

https://miro.medium.com/max/640/1*J4v-P4l8xPwk8teY7VV2Mg.png

A Metamask e o Etherscan mostram o mesmo valor: 0,00000…1 (=10^-15 MTK)

Mas nós cunhamos uma quantidade incrível um pouco antes!

_mint(msg.sender,100000000000000000000000000000000000000000000);
Enter fullscreen mode Exit fullscreen mode

Então, conseguimos enganar a Metamask e o Etherscan. (e qualquer outra carteira que dependa da função balanceOf())

4. Você ainda pode confiar no Etherscan?

Parece assustador, certo? Ainda existe uma maneira de confiar no Etherscan ou em qualquer projeto criptográfico que possa enganar seus detentores?

Em teoria sim.

Se o código do contrato inteligente for VERIFICADO (e o construtor também), será muito mais difícil enganar o Etherscan. Mas se uma dessas 2 condições estiver ausente, é muito mais fácil enganar o Etherscan.

A blockchain é transparente, isso significa que todos os dados, todas as transações registradas ou qualquer saldo de endereço são armazenados na blockchain e, portanto, disponíveis gratuitamente para qualquer pessoa.

Mas, na realidade, isso não é tão simples, especialmente se você não tiver habilidades técnicas.

Na verdade, a única maneira de descobrir se o contrato está "capturado" é inverter o bytecode do smart contract para entender toda a lógica do contrato e ver o que está acontecendo dentro dele.

Se você quiser entender como fazer engenharia reversa de contrato inteligente na blockchain, você pode conferir minha série sobre reversão e depuração de contrato inteligente, que ensina essa habilidade (rara): https://medium.com/@TrustChain/list/reversing-and-degugging-evm-smart-contracts-f4dd9195d07b

Qualquer outra maneira que você encontrar não é perfeita e pode ser facilmente contornada…

Artigo original publicado por TrustChain. Traduzido por Paulinho Giovannini.

Latest comments (0)