ÍNDICE:
- Declaração de propósito.
- Introdução.
- O que são códigos de operação (opcodes).
- Entendendo os códigos de operação create e create2.
- Create: Implantação do contrato básico.
- Create2: Endereços previsíveis e calculados.
- Explorando as aplicações do create e create2 no hack do Tornado Cash.
- Considerações de segurança e práticas recomendadas de geração de endereço.
- Conclusão.
DECLARAÇÃO DE PROPÓSITO
Depois de ler este artigo, espera-se que o leitor entenda o seguinte;
- Compreensão do que são códigos de operação.
- Entenda as funções dos códigos de operação create e create2.
- Entenda as diferenças entre os códigos de operação create e create2.
- Compreensão da aplicação dos códigos de operação create e create2 no hack da DAO do Tornado Cash.
- Obtenha um melhor conhecimento das práticas recomendadas de geração de endereços e considerações de segurança recentes em projetos de governança e geração de endereços.
INTRODUÇÃO:
Os códigos de operação são um aspecto fundamental da blockchain Ethereum; eles são um conjunto de instruções ou comandos pelos quais a EVM opera. Neste artigo, vamos nos concentrar em dois desses códigos de operação (create e create2), suas diferenças e como eles foram combinados de maneira inteligente na execução do hack da DAO do Tornado Cash. Por fim, concluiremos com considerações de segurança e práticas recomendadas relacionadas à geração de endereços e segurança de contratos inteligentes em relação ao uso, vantagens e perigos de utilizar qualquer um desses dois códigos de operação na implantação de contratos inteligentes.
Este artigo foi criado para ajudar iniciantes e desenvolvedores experientes a entender e compreender o tópico acima, mas suponho que o leitor tenha um entendimento básico de blockchain, EVM, implantação de contrato inteligente, interação e execução. No entanto, tenho certeza de que o conhecimento que você busca será transferido.
O QUE SÃO OS CÓDIGOS DE OPERAÇÃO?
Os opcodes, abreviação de códigos de operação, são instruções fundamentais para a Ethereum Virtual Machine (EVM) que definem as operações a serem executadas pela EVM. Os códigos de operação são instruções de baixo nível representadas por valores hexadecimais e formam o bytecode que é executado pela EVM durante a execução de contratos inteligentes. Cada código de operação representa uma operação ou ação específica que a EVM pode executar. Os códigos de operação definem uma ampla gama de funcionalidades, incluindo operações aritméticas, instruções de fluxo de controle, manipulação de memória, acesso ao armazenamento, gerenciamento de gás e interação com a rede Ethereum.
Uma lista e uma descrição adequada de todos os códigos de operação da EVM pode ser encontrada na Seção 9.4 “Execution” (Execução) do yellow paper da Ethereum (https://ethereum.github.io/yellowpaper/paper.pdf).
ENTENDENDO OS CÓDIGOS DE OPERAÇÃO CREATE E CREATE2:
Os códigos de operação create e create2 são duas das instruções de baixo nível mais populares que os desenvolvedores de contratos inteligentes utilizam na implantação de contratos inteligentes; ambos atingem o mesmo objetivo de implantar e gerar endereços para contratos inteligentes, mas diferem em certas maneiras, que abordaremos em breve. Estarei apresentando os conceitos do create e do create2 com uma ilustração muito simples da vida real.
Imagine dois desenvolvedores de blockchain, Alex e Bob, tirando férias para viajar. Alex decide que viajará para as Maldivas, então se prepara adequadamente, consegue um visto, faz uma reserva de hotel com antecedência e reserva um voo direto para as Maldivas. Enquanto Bob se registra em uma empresa de turismo para um pacote de férias, ele está limitado apenas aos destinos de férias disponíveis, mas seu voo, acomodação e reservas serão organizados pela agência de turismo.
Esta ilustração pode parecer muito simplificada, mas pode estar diretamente relacionada aos códigos de operação CREATE e CREATE2 na EVM. Na analogia utilizada, os dois desenvolvedores tinham algo em comum: ambos queriam férias. Da mesma forma, os códigos de operação create e create2 têm algo em comum, o fato é que ambos levam à implantação e à geração de endereços para contratos inteligentes. A principal diferença está no fato de que, semelhante à situação de Bob, usar o código de operação create oferece flexibilidade limitada e previsibilidade de endereços de contratos inteligentes; basicamente dependemos de um determinador único e estrito para nosso endereço de contrato, ao contrário de usar o código de operação create2, onde podemos facilmente (em comparação com create) prever e definir condições adequadas (usando um salt, ou sal) para gerar um endereço de contrato de nossa escolha.
CREATE: IMPLANTAÇÃO DO CONTRATO BÁSICO
O código de operação 'create' é o código de operação de criação de contrato mais comumente utilizado. Quando os contratos são implantados a partir de scripts ou outros ambientes de desenvolvimento, o código de operação create é a instrução de baixo nível executada pela EVM para implantar e gerar um endereço de contrato. O código de operação create difere de outros métodos de implantação de contrato inteligente no sentido de que, quando os contratos são implantados usando esse método, o endereço do contrato é gerado tomando os últimos 20 bytes do hash Keccak256 da codificação rpl do endereço do implantador e do nonce da transação (é um número arbitrário que só pode ser usado uma vez).
Portanto, para cada endereço do implantador, seu nonce é o principal determinante para definir o endereço do contrato que está sendo implantado. Isso pode ser visto como uma escala bidirecional porque estamos basicamente sacrificando o determinismo pela facilidade e simplicidade.
CREATE2: ENDEREÇOS PREVISÍVEIS E COMPUTADOS
O código de operação create2, que não era amplamente conhecido antes, tornou-se cada vez mais popular. Ele tem sido utilizado por empresas de DeFi como a 1inch e desempenhou um papel significativo no hack do Tornado Cash de 2023. O código de operação create2 é uma modificação do popular código de operação create e foi proposto na EIP1014, com sua principal força sendo que ele permite a criação de contratos com um endereço determinístico baseado em uma entrada adicional chamada de valor “salt”. Usando o código de operação create2, os endereços de contrato inteligente são determinados pelos últimos 20 bytes do hash keccak-256 do seguinte: offset de contrato, endereço do implementador, salt e código de inicialização do contrato. Esses quatro combinados criam uma oportunidade para o determinismo, pois os desenvolvedores podem usar a força bruta para determinar o salt (um código hexadecimal aleatório de 32 bytes), que, quando usado, geraria um endereço de sua escolha.
EXPLORANDO AS APLICAÇÕES DO CREATE E CREATE2 NO HACK DA DAO DO TORNADO CASH:
Sem objeção, um dos hacks de Defi mais criativos no segundo trimestre de 2023 é o hack da Governança do Tornado Cash, onde o hacker utilizou uma combinação de create, create2 e autodestruição para acumular 1.2 milhão de tokens de voto do Tornado Cash, que estavam sendo negociados entre $5 a $7 no momento do ataque. Nesta seção, faremos um mergulho profundo nos detalhes do ataque.
A ação começou quando uma proposta legítima para penalizar participantes trapaceiros da rede no projeto do Tornado Cash foi aprovada com sucesso por uma votação da DAO. Por incrível que pareça, alguns dias depois da proposta ter sido aprovada na votação da DAO, a implementação da função contida no contrato foi alterada e, ao ser executada, conseguiu conceder ao invasor 1,2 milhão de tokens de voto, o que era mais do que os 700 mil votos legítimos até então, concedendo assim ao invasor o controle da DAO. Isso levou a mais pesquisas sobre o que realmente aconteceu, e foi descoberto o seguinte:
O hacker implantou o contrato da proposta usando o código de operação create de um contrato de fábrica filho que também foi implantado de um contrato de fábrica pai usando o código de operação create2. Sim, entendo que isso pode parecer confuso, mas a imagem abaixo pode ajudar.
A partir da ilustração acima, o invasor escreveu um contrato de fábrica pai que implanta o contrato de fábrica filho, que serve como um contrato de fábrica para implantar dois contratos: um contrato de proposta legítimo e um contrato de proposta malicioso. Lembre-se de que, na seção anterior, mencionamos que a EVM usa o código de operação create para implantar um contrato com uma combinação de apenas o endereço do implantador e seu nonce, enquanto uma combinação de offset, endereço do implantador, salt e bytecode de inicialização é usada para implantar com o código de operação create2.
Ao que tudo indica, o invasor usou uma combinação de seu endereço e nonce para implantar e gerar o endereço do contrato de fábrica pai (0xaf5…..dbacb) (CREATE).
Keccak256(rlp.encode([0x592...89de9, 6]))[12:]
Então ele faz uma chamada para uma função no contrato de fábrica pai, que usa o código de operação create2 para implantar o contrato de fábrica filho,
keccak256( 0xff ++ 0xaf5...dbacb ++ salt(Y) ++ keccak256(0x608....0000))[12:]
Por fim, o contrato de fábrica filho implanta o contrato de proposta legítimo usando o endereço do contrato de fábrica filho e seu nonce, que neste caso é 1, para obter o endereço do contrato de proposta legítimo (0xc50….752d).
Keccak256(rlp.encode([0x7dc...1353d, 1]))[12:]
O invasor então cria uma proposta na DAO do Tornado Cash visando o endereço do contrato de proposta legítima, que, após verificação dos membros da Dao, passa na votação da Dao e está pronto para execução após um período de espera. O invasor, ao atingir seu objetivo de passar na votação da Dao, passa a chamar uma “função emergencyStop” no contrato de fábrica pai que aciona uma autodestruição nos contratos de fábrica filho e de proposta legítima, redefinindo assim seu nonce e movendo seus endereços de volta para um estado inexistente.
Por fim, o invasor chama uma função no contrato de fábrica pai que utiliza create2 para reimplantar o contrato de fábrica filho em seu endereço anterior usando o mesmo conjunto de parâmetros da implantação inicial.
keccak256( 0xff ++ 0xaf5...dbacb ++ salt(Y) ++ keccak256(0x608....0000))[12:]
O contrato de fábrica filho, que foi reimplantado no mesmo endereço que o anterior, agora tem seu nonce redefinido para 0. Usando o código de operação create que combina o endereço do contrato de fábrica filho e seu novo nonce(1), um novo contrato malicioso é implantado no mesmo endereço que o contrato de proposta legítima anterior.
Keccak256(rlp.encode([0x7dc...1353d, 1]))[12:]
Neste ponto, quando a proposta da Dao é executada e o contrato da Dao faz uma chamada delegada para o endereço do contrato da proposta que o hacker apresentou na proposta inicial, a implementação maliciosa do contrato é executada, não a implementação legítima que foi inicialmente apresentada na proposta.
Com isso, o invasor conseguiu obter o controle da Dao por meio da proposta maliciosa, transferindo 1.2 milhão de tokens de voto para sua conta, da qual conseguiu retirar 10.000 votos como Tron. Isso fez com que o preço do token Tornado Cash, que inicialmente era negociado entre US$ 5 e US$ 7, caísse 30%.
Por meio do controle de governança, o invasor agora tem o poder de retirar todos os votos bloqueados e drenar todos os tokens no contrato de governança.
CONSIDERAÇÕES DE SEGURANÇA E MELHORES PRÁTICAS DE GERAÇÃO DE ENDEREÇOS:
A geração de endereços de contratos inteligentes é um aspecto importante da tecnologia blockchain, permitindo a criação de identificadores exclusivos para contratos localizados na blockchain com segurança, transparência e determinismo sem precedentes. Embora seja crucial implementar práticas robustas de geração de endereços para garantir integridade e confiabilidade, também é pertinente garantir que as melhores práticas do setor sejam empregadas para mitigar riscos potenciais e proteger os ativos e funcionalidades contidos no contrato inteligente.
Para garantir as melhores práticas para geração de endereços de contratos inteligentes, é importante utilizar mecanismos determinísticos fornecidos pela Ethereum, como os códigos de operação “create” e “create2”, bem como utilizar salts exclusivos ao usar “create2” para aprimorar o determinismo e também evitar colisão. Por fim, mantenha-se atualizado com os padrões da Ethereum. Seguindo essas diretrizes, os desenvolvedores podem gerar endereços de contratos inteligentes confiáveis e seguros, minimizando assim possíveis problemas e vulnerabilidades.
Acredito que o hack do Tornado Cash serve como um alerta para nosso atual sistema Dao, de que é necessário mais esforço no aspecto da auditoria de propostas e que os membros da Dao precisam ter cuidado com o que votam. Da mesma forma que se deve confiar na descrição de uma proposta com uma pitada de ceticismo, a lógica da proposta deve ser tratada da mesma forma e, finalmente, propostas com a capacidade de autodestruição não devem passar por uma votação da Dao.
CONCLUSÃO:
Este artigo analisa a ideia crucial dos códigos de operação create e create2. Ele se concentra no uso dos métodos create e create2 para gerar endereços de contratos e se inspira no hack da DAO do Tornado Cash. Ele também enfatiza com sucesso a importância de procedimentos sólidos de geração de endereços no desenvolvimento de contratos inteligentes para melhorar a segurança e evitar possíveis vulnerabilidades. Este artigo oferece assistência útil aos desenvolvedores que desejam criar contratos inteligentes seguros e confiáveis, compreendendo as funções específicas do create e create2. Os insights do hack da DAO do Tornado Cash servem como um estudo de caso, fornecendo lições e considerações úteis para evitar tais vulnerabilidades no futuro. De modo geral, o objetivo deste artigo é desmistificar os códigos de operação create e create2 e, ao mesmo tempo, promover práticas seguras de contratos inteligentes.
Artigo escrito por Idogwu Chinonso. Traduzido por Marcelo Panegali.
Oldest comments (0)