paint-brush
Fuzzing Around: Teste de contrato inteligente por meio de entradas aleatóriaspor@alvinslee
1,289 leituras
1,289 leituras

Fuzzing Around: Teste de contrato inteligente por meio de entradas aleatórias

por Alvin Lee5m2023/04/24
Read on Terminal Reader

Muito longo; Para ler

Fuzzing é uma maneira de bombardear seu código com um monte de entradas aleatórias apenas para ver o que acontece. É uma maneira rápida, eficiente e de força bruta de testar casos extremos e cenários que você pode não imaginar. O Diligence Fuzzing oferece 10 horas de fuzzing gratuitamente para experimentar.
featured image - Fuzzing Around: Teste de contrato inteligente por meio de entradas aleatórias
Alvin Lee HackerNoon profile picture
0-item
1-item

Testar contratos inteligentes é realmente importante. Por que? Contratos inteligentes geralmente são imutáveis em produção, públicos , alvos de hackers e geralmente envolvem implicações financeiras significativas . O conto? Com contratos inteligentes, você não quer estragar tudo. Você precisa testar muito, testar com frequência e testar minuciosamente. O teste de contrato inteligente envolve todos os suspeitos usuais - teste de unidade, teste de integração, teste automatizado - mas também altamente recomendado é fuzzing - uma maneira de bombardear seu código com um monte de entradas aleatórias apenas para ver o que acontece.


Vamos dar uma olhada exatamente no que é o fuzzing como um método de teste e como você pode incluí-lo facilmente em seu fluxo de trabalho de teste de software usando ferramentas como ConsenSys Diligence Fuzzing . Vamos percorrer um tutorial usando um exemplo de contato inteligente defi para ver como isso é feito.


O que é teste de fuzzing e por que eu o usaria?

O teste fuzzing (ou teste fuzz) envolve o envio de milhões de dados inválidos, inesperados e (semi) aleatórios contra um contrato inteligente em um esforço para causar comportamento inesperado e detectar vulnerabilidades. É uma maneira rápida, eficiente e de força bruta de testar casos extremos e cenários que você pode não imaginar. Ele complementa seus outros fluxos de teste e suas auditorias.


O fuzzing já existe há algum tempo no desenvolvimento tradicional de pilha completa, mas uma nova classe de ferramentas está aqui que pode aplicar o fuzzing ao teste de contrato inteligente na web3. Algumas das ferramentas fuzzing incluem o Echidna e o MythX de código aberto.


Neste artigo, no entanto, vou mergulhar fundo no Diligence Fuzzing , que oferece fuzzing como um serviço - uma maneira muito legal e fácil de fuzz.


Para usar Diligence Fuzzing, você anota seus contratos inteligentes usando Scribble . Basicamente, você usa anotações Scribble em seu código para informar ao fuzzer que tipo de saída esperar para essa função.


Parece algo assim:


 /// #invariant {:msg "balances are in sync"} unchecked_sum(_balances) == _totalSupply;


Você chama o fuzzer a partir de uma IU da Web em que envia o código do contrato inteligente. Você clica em executar e, aproximadamente 10 minutos depois, obtém um relatório com os problemas encontrados, localização dos problemas, % de cobertura e muito mais.


Esta é uma maneira fácil e poderosa de verificar alguns casos extremos.

Testando um contrato inteligente DeFi

Digamos que temos um novo protocolo DeFi e o token correspondente que queremos lançar. DeFi é uma finança de ponta, divertida de escrever e é fundamental que não tenhamos nenhum bug. Os contratos inteligentes DeFi geralmente envolvem milhões (ou mais) em fundos de usuários. Portanto, queremos ter certeza de que nossos contratos inteligentes sejam testados (e auditados) da maneira mais completa possível.


NOTA IMPORTANTE: Este código contém vulnerabilidades DE PROPÓSITO! É para que possamos mostrar como o fuzzing pode detectar esses erros. Por favor, não use esse código para nada.


Vamos começar.


Um exemplo usando Diligence Fuzzing (FaaS)

Passo 1: Configure uma conta Diligence.

Primeiro, precisamos da nossa conta Diligence. Inscreva-se em Diligência . Você ganha 10 horas de fuzzing gratuitamente para experimentar as coisas.

Etapa 2: crie uma nova chave de API.

Clique no nome da sua conta no canto superior direito, clique em “criar nova chave de API” e dê um nome a ela. Essa chave de API nos permite conectar ao FaaS.





Etapa 3: Configure seu ambiente local.

Clone o seguinte repositório:

https://github.com/ConsenSys/scribble-exercise-1.git


Na linha de comando, navegue até a pasta do repositório, que agora será a pasta raiz do seu projeto. Se necessário para sua máquina, ative um Python venv. Em seguida, execute os seguintes comandos para instalar as dependências do seu projeto:


 $ npm i -g eth-scribble ganache truffle $ pip3 install diligence-fuzzing

Etapa 4: insira sua chave de API.

Edite o arquivo .fuzz.yml para usar a chave de API da sua conta Diligence para o valor de key.

Seu arquivo resultante deve ficar assim:


 .fuzz.yml fuzz: # Tell the CLI where to find the compiled contracts and compilation artifacts build_directory: build/contracts ... campaign_name_prefix: "ERC20 campaign" # Point to your ganache node which holds the seed rpc_url: "http://localhost:8545" key: "DILIGENCE API KEY GOES HERE" ...

Passo 5: Escreva e anote seu contrato.

Agora vamos verificar nosso contrato inteligente em contracts/vulnerableERC20.sol . Aqui temos um token vulnerável (como é chamado!) Para nosso novo protocolo DeFi. Nós claramente precisamos testá-lo o máximo possível. Então, vamos adicionar uma verificação usando Scribble que o fuzzer irá pegar.


Acima da definição do contrato, adicione:


 /// #invariant "balances are in sync" unchecked_sum(_balances) == _totalSupply;


E acima da função de transferência, adicione:


 /// #if_succeeds msg.sender != _to ==> _balances[_to] == old(_balances[_to]) + _value; /// #if_succeeds msg.sender != _to ==> _balances[msg.sender] == old(_balances[msg.sender]) - _value; /// #if_succeeds msg.sender == _to ==> _balances[msg.sender] == old(_balances[_to]); /// #if_succeeds old(_balances[msg.sender]) >= _value;


Então agora vamos ver se o testador de fuzzing vai pegar alguma coisa. Observe as anotações que adicionamos ao contrato para ajudar o testador a entender o que esperamos que aconteça. E observe na configuração que o testador está configurado para ser executado por 10 minutos no máximo, portanto, pode não capturar tudo.

Etapa 6: divirta-se.

Agora estamos prontos para testar! Na pasta raiz do projeto, execute make fuzz para chamar o arquivo make, que irá compilar, construir e enviar tudo para o FaaS.

Passo 7: Veja os resultados.

Volte para o seu painel e você verá algo semelhante ao abaixo. Aguarde alguns segundos para que a campanha comece.



Após terminar de gerar, você deverá ver algo semelhante ao mostrado abaixo:

Vemos até cobertura de código!



E depois de alguns minutos, vemos uma falha!


Ao clicar nas propriedades, vemos quaisquer violações. E sim, temos um bug! Clique no local da linha para ver os detalhes de nossas possíveis vulnerabilidades de código.



Vamos parar por aí, mas se você deixar o fuzzer continuar funcionando, ele pode encontrar mais!


Conclusão

Fuzzing pode ser uma etapa crucial em seu processo de desenvolvimento e teste de software. Ele ajuda a identificar possíveis vulnerabilidades que, de outra forma, podem passar despercebidas. Ao usá-lo, você começa a reconhecer e compreender armadilhas e desafios comuns. Aproveite ferramentas como o Diligence Fuzzing , escreva contratos inteligentes melhores e torne-se um desenvolvedor melhor!