À medida que os protocolos DeFi continuam a esquentar no ecossistema Ethereum, a CipherTrace vê cada vez mais explorações e vetores de ataque surgindo. Na semana passada, em 28 de dezembro de 2020, o contrato de mineração de escudo do Cover Protocol, Blacksmith, foi explorado. Os hackers usaram um bug no contrato de mineração para cunhar uma quantidade infinita de tokens COVER e drenar mais de US$ 4.4 milhões do projeto.
Protocolo de Cobertura liberado seu post-mortem de ontem afirmando que, sem o conhecimento dos desenvolvedores, o bug estava presente desde a implantação inicial do contrato do Blacksmith, destacando a importância de auditorias de segurança completas e testes de pentes de smart contractsO que são contratos inteligentes? Um contrato inteligente é um profissional de informática ... Mais.
Uma linha do tempo de cunhagem infinita
A linha do tempo do invasor inicial
- O pool de liquidez do New Balancer foi adicionado ao contrato Blacksmith.sol.
- Atacante depósitos 1,326,879.99 tokens BPT no contrato Blacksmith.sol.
- O mesmo atacante então executado a exploração, retirando fundos do contrato.
- O atacante foi capaz de continuar cunhar recompensas e retirar fundos no valor de aproximadamente US$ 4.4 milhões.
Em uma reviravolta interessante, supostos “hackers brancos” ligados à Grap Finance também exploraram o bug para cunhar cerca de US$ 4 milhões em tokens COVER. A Grap Finance acabou devolvendo os fundos ao Cover Protocol.
Cronograma da conta de propriedade externa (EOA) do Grap Finance Deployer
- O novo pool de liquidez foi aprovou para mineração de liquidez.
- Implantador Grap Finance EOA depositado 15,255.55 BPT (DAI/Base) no pool da Cover por meio do contrato Blacksmith.sol.
- Cerca de quatro minutos depois, os fundos foram retirado na capa deixando 1 Wei no saldo EOA do Grap Finance Deployer.
- Outro usuário externo retirou a maior parte de seu saldo do contrato Blacksmith.sol na mesma época, o que levou a Grap Finance com toda a liquidez para o pool DAI/Basis no contrato Blacksmith.sol.
- Implantador Grap Finance depositado devolver 15,255.55 BPT (DAI/Base) ao pool.
- Então Grap Finance Deployer reivindicações as recompensas e, devido à exploração, cunha 40,796,131,214,802,500,000.21 COVER.
- Depois de queimar alguns tokens cunhados, Grap Finance Deployer envia voltar Ether para Cover afirmando “Da próxima vez, cuide de suas próprias coisas.”
Como cunhar tokens infinitos – uma análise técnica
BACKGROUND
Esta exploração nos leva de volta aos fundamentos da linguagem de programação Solidity, que é usada para implementar contratos inteligentes no Ethereum. Uma vez compilados esses contratos, a Máquina Virtual Ethereum (EVM) será capaz de compreender as instruções (ou seja, opcodes) que são usadas para executar diversas funções e manipular memória e armazenamento. O EVM possui três áreas diferentes onde pode armazenar dados: memória, armazenamento e pilha. Compreender essas áreas é importante para entender como o bug foi explorado.
Semelhante à memória de acesso aleatório (RAM) em um dispositivo de computação, o “memória”A palavra-chave no Solidity aloca memória para uma variável específica. Neste caso, essa variável tem como escopo uma função específica. A memória é limpa assim que a função é executada, mas pode permanecer se o conteúdo dessa memória for armazenado antes do retorno da função.
A "armazenamento”A palavra-chave no Solidity permite que variáveis atuem como um ponteiro para o armazenamento de dados em mapeamentos ou estruturas de dados. Os dados de armazenamento são persistentes entre chamadas de função e transações. Nos bastidores, o armazenamento é essencialmente um armazenamento de valores-chave que mapeia palavras de 256 bits para palavras de 256 bits.
Observe que a EVM não é uma máquina de registro, mas uma máquina de pilha – portanto, todos os cálculos são realizados em uma área de dados chamada a pilha. A pilha tem capacidade máxima de 1024 itens, mas apenas os 16 primeiros são facilmente acessíveis, o que pode ser usado para trocar o elemento superior por um dos 16 elementos abaixo dele e mais.
O inseto
Os hackers exploraram o Blacksmith.sol do Cover Protocol – um contrato de mineração de escudo que permite que os stakers sejam recompensados em tokens do projeto ou pool específico, como tokens CLAIM e NOCLAIM, dentro do Cover Protocol.
Para entender melhor o bug, primeiro vamos dar uma olhada no público piscinas variável que é um mapeamento (ou seja, armazenamento de dados):
At linha 118, vemos que o contrato armazena em cache os dados do pool na memória por meio da palavra-chave “memory”.
Em seguida linha 121, o contrato atualiza o pool no armazenamento conforme o updatePool(endereço _lpToken) função utiliza um Conjunto de armazenamento de pool variável.
No entanto, se você olhar mais abaixo no depósito (endereço _lpToken, uint256 _amount) função, ele usa a mesma piscina variável da linha 118 que foi armazenada em cache na memória dentro da função para cálculos para pool.accRewardsPerToken. Neste ponto, o piscina variável foi copiada do piscinas mapeamento e foi salvo na memória.
Como resultado, quaisquer alterações feitas no piscina variável dentro do depósito (endereço _lpToken, uint256 _amount) função não alterará o piscinas mapeamento no armazenamento on-chain do contrato devido ao fato de que as variáveis que usam a palavra-chave “memory” têm escopo apenas dentro da própria função. A partir daí, o contrato atualiza o pool.accRewardsPerToken dentro do updatePool(endereço _lpToken) função, que usa armazenamento. Então agora, dentro do updatePool(endereço _lpToken) funcionar o pool.accRewardsPerToken que é atualizado aumenta enormemente, pois era tecnicamente um novo pool e não associado ao piscina em memória.
Após esta vulnerabilidade e uso indevido entre memória e armazenamento, o miner.rewardWriteoff dentro do depósito (endereço _lpToken, uint256 _amount) função é calculada incorretamente, além de usar o valor incorreto pool.accRewardsPerToken, como ainda estamos dentro da função de depósito que está lidando com uma instância de memória em cache de piscina.
Além da função de depósito, qualquer pessoa, como Grap Finance, pode obter uma quantidade absurda de tokens cunhados ao executar o reivindicarRecompensas(endereço _lpToken) função. Essa função, que serve para pegar suas recompensas, acaba chamando _claimCoverRewards (conjunto de memória pool, minerador de memória Miner) que faz referência ao miner.rewardWriteoff que destacamos acima. Como essa variável é muito menor que o valor real pool.accRewardsPerToken, o contrato resulta na cunhagem de uma abundância de tokens.
Principais lições
A CipherTrace espera que este histórico do bug explorado traga à luz a importância de auditorias de segurança completas e testes de pentesting de contratos inteligentes em qualquer blockchainUm blockchain - a tecnologia subjacente ao bitcoin e outros c… Mais alguém escolhe implantar. Embora a Grap Finance tenha devolvido os fundos recebidos por meio da exploração, o hacker original ainda conseguiu lucrar mais de US$ 4 milhões com o protocolo DeFi, e o valor do token COVER despencou quase 99%.
Fonte: https://ciphertrace.com/infinite-minting-exploit-nets-attacker-4-4m/