WEB3DEV

Cover image for Notas do Auditor: Semantic Grep & Solidity
Paulo Gio
Paulo Gio

Posted on

Notas do Auditor: Semantic Grep & Solidity

Hoje, gostaríamos de iniciar uma série de artigos nos quais examinaremos novas ferramentas promissoras e aprenderemos exatamente como usá-las, bem como seus benefícios e desvantagens.

Nesta série, abordaremos apenas aspectos relevantes para auditoria e hacking de recompensas de bugs (bug bounty) que não são cobertos em outros lugares!

https://miro.medium.com/v2/resize:fit:1100/format:webp/1*nKPJccyWSAUczTPcPAfbNw.jpeg

Imagem: Sudoku + Photomosh

Saudações, caros leitores!

Em primeiro lugar, queremos começar agradecendo sinceramente às pessoas que criaram as ferramentas SolGrep e SemGrep, todos que as apoiam, e os autores de todos os materiais de referência! E hoje, caros leitores, isso tudo será disponibilizado para vocês!

Acreditamos que ninguém duvida que a base de qualquer implementação segura é uma abordagem especial para a escrita de código. Portanto, este artigo se concentrará apenas naqueles aspectos que podem ser realmente úteis para tornar seu código seguro!

Assim, abaixo você verá não um artigo típico, mas uma sistematização do conhecimento (SoK), na qual me basearei em autores que eu mesmo confio dentro deste assunto e, claro, nossos auditores da pessimistic.io!

Algumas palavras sobre nossa ferramenta, SmartCheck — que pode servir como um reforço do que vamos falar a seguir. Mesmo em sua forma bruta, mostra bons resultados, e o segundo lugar no artigo da Trail of Bits não é ruim para uma ferramenta que paramos de dar suporte há três anos. No entanto, vamos passar para o nosso tópico de hoje. Fique ligado!

https://blog.pessimistic.io/slither-an-auditors-cornucopia-a8793ea96e67

Siga-nos agora mesmo, confira nosso artigo recente sobre Slither, e vamos começar! A propósito, há alguns espaços vagos agora, então se o seu projeto precisa de uma auditoria, sinta-se à vontade para nos escrever. Visite nossa página de relatórios públicos aqui.

Certifique-se de ler o resto da série:

https://blog.pessimistic.io/

Básicos: O que é a Semântica?

Para entender completamente o que vamos falar a seguir, sugiro que comecemos explicando alguns dos termos que usaremos com frequência no texto!

Entendemos e respeitamos seu tempo limitado, por isso criamos uma folha de dicas específica sem informações supérfluas apenas para você (no final do artigo)!

Semântica: Em Profundidade

Semântica — o ramo da linguística e lógica preocupado com o significado. A semântica é o estudo da referência, significado ou verdade. O termo pode ser usado para se referir a subcampos de várias disciplinas distintas, incluindo filosofia, linguística e ciência da computação.

Como disciplina científica, a semântica descreve os processos que um computador segue ao executar um programa naquela linguagem específica. Isso pode ser mostrado descrevendo a relação entre a entrada e a saída de um programa, ou uma explicação de como o programa será executado em uma determinada plataforma, criando assim um modelo de computação.

https://www.dataversity.net/brief-history-semantics/#

Grep Explicado

O Grep (Global Regular Expression Print, ou Impressão de Expressão Regular Global) é uma ferramenta de linha de comando para procurar conjuntos de dados de texto simples por linhas que correspondem a uma expressão regular.

https://miro.medium.com/v2/resize:fit:640/format:webp/1*1OP_qVke1FTMiDmh3I_yqQ.jpeg

Fonte

Para colocá-lo de outra maneira, é uma ferramenta (em um sentido amplo: método) para identificar certos padrões em um determinado dado e usa expressões regulares (Regular Expressions, ou RegEx) para isso.

A palavra grep é usada como um verbo que significa encontrar ou procurar por uma string. Frequentemente, isso implica procurar uma string fixa. Mas grep (Global Regular Expression Print) como indica o acrônimo do comando, procura por uma expressão regular.

É um comando Nix altamente versátil para combinar strings. Veja “Computerphile: De onde veio o GREP” para uma breve história:

Uma Expressão Regular Explicada

Uma Expressão Regular (ou Regex) - é um padrão (ou filtro) que descreve um conjunto de strings (em um sentido amplo: uma linguagem para descrever padrões de texto) que corresponde ao padrão.

https://github.com/gnidan/solregex

Exemplo Web2

Para uma melhor compreensão, considere como procederíamos se fôssemos resolver o seguinte problema: Crie uma regra que procura por emails específicos em um banco de dados fornecido.

  1. Obtenha os dados de entrada (.txt, por exemplo );
  2. Consiga uma ferramenta Grep apropriada (que possa procurar em .txt);
  3. Escreva uma regra (Expressão Regular);
  4. Pesquise!

https://miro.medium.com/v2/resize:fit:1100/0*jU_83o8snHQTGr2o

Exemplo Web3 (Solidity)

Para uma melhor compreensão deste tópico, considere como procederíamos se fôssemos resolver outro problema: Crie uma regra que busca por padrões específicos em um certo código Solidity.

  1. Pegue o contrato Solidity e certifique-se de que ele compila corretamente;
  2. Pegue uma ferramenta Grep adequada que possa trabalhar com o código Solidity. Lembre-se de que a ferramenta Grep geralmente verifica a Árvore Sintática Abstrata (AST). Não esqueça que, como resultado, sua solução deve tornar a escrita de regras mais fácil e adaptável;
  3. Escreva uma regra (Expressão regular);
  4. Pesquise!

Como um compilador realmente funciona?

Primeiramente, devemos notar que os compiladores essencialmente pegam o texto, analisam e processam, e depois o transformam em binário para o seu computador ler. Isso impede que você tenha que escrever código binário manualmente para o seu computador e, além disso, permite que você escreva programas complexos com mais facilidade.

Em outras palavras, o compilador converte o código-fonte de alto nível para o código de baixo nível. Então, a máquina alvo executa o código de baixo nível. O processo de compilação consiste em várias fases:

  1. Análise léxica
  2. Análise sintática
  3. Análise semântica
  4. Geração de código intermediário
  5. Otimização
  6. Geração de código de máquina

Para prosseguir para o próximo tópico, primeiro devemos entender como isso ocorre no Solidity e, como resultado, como podemos usá-lo para auditar e escrever código com segurança. É fundamental entender as especificidades do processo que vamos abordar abaixo.

https://medium.com/codex/getting-to-know-grep-a-quick-guide-f71db5d17572

O que o compilador realmente faz com o código Solidity?

Podemos dividir aproximadamente todo o processo nas três fases seguintes:

  1. Divisão do código em tokens
  2. Análise da sintaxe
  3. Construção de uma AST

https://miro.medium.com/v2/resize:fit:1100/format:webp/1*6byD2Y5YfQNndlQ687AotA.png

Fonte + Solidity CheatSheet

O que o compilador faz com a AST?

Aqui também podemos dividir todo o processo em três fases, que estão listadas abaixo:

  1. Análise da semântica (neste ponto os erros do compilador são expostos/derivados!)
  2. Otimização da AST (é para isso que o valor de execução na configuração do projeto é especificado — confira este exemplo!)
  3. Geração do bytecode!

Exemplos de Desempenho do Compilador

Aqui está um exemplo simples de algumas das fases do compilador:

https://miro.medium.com/v2/resize:fit:640/0*dopPlzRcGNhGSeKA

https://miro.medium.com/v2/resize:fit:720/0*BXhxliyOc2RJMtFF

Greps & Solidity: Soluções

Os auditores não poderiam ter perdido uma abordagem tão intrigante por muito tempo... Os bons resultados na busca por bugs também trabalham a seu favor.

Então, que tipos de utilitários do Grep estão disponíveis para Solidity agora? Vamos conferir:

Revisão do SolGrep

Então você tem um conjunto de contratos inteligentes e quer encontrar todos os contratos que têm um método public chamado withdrawEth, mas o Grep léxico gera muitos falsos positivos? É aqui que o SolGrep pode auxiliar:

SolGrep

https://miro.medium.com/v2/resize:fit:1100/0*m3TDSiyVizN674YA

Vantagens: Escrito especificamente para o Solidity; fácil de usar e pronto para uso; possui uma lista de regras básicas para contratos.

Desvantagens: Esta ferramenta não é tão útil por padrão; você também precisa escrever suas próprias regras em JS; o repositório não tem sido atualizado há muito tempo.

https://miro.medium.com/v2/resize:fit:1100/0*l5Zl9v0zMebkQfTU

O SolGrep encontra recursivamente contratos inteligentes em um diretório específico, analisa as unidades de origem para entender a semântica da linguagem, e disponibiliza essas informações para uma poderosa função de filtro baseada em JavaScript.

https://morioh.com/p/0b57ca54d92f

Desta forma, você pode:

  • Extrair informações semânticas do código-fonte Solidity com base em funções de filtro personalizadas;
  • Encontrar contratos-alvo com base em um script de filtro personalizado que você define;
  • Criar e executar suas próprias regras ou regras incorporadas (por exemplo, para verificações no processo de integração contínua, ou CI);
  • Processar números e gerar estatísticas a partir de uma base de código;
  • Encontrar doppelgängers! Ou seja, contratos duplicados que compartilham a mesma estrutura de código (correspondências AST_EXACT e AST_FUZZY)

Ele usa o Grep da seguinte maneira:

  • Por nome de função;
  • Chamadas de função;
  • Por nome de contrato;
  • De acordo com tudo localizado na AST. Ele também pesquisa através de padrões personalizados (criando uma biblioteca separada).

Autor: tintinweb

Revisão do SemGrep

SemGrep

https://miro.medium.com/v2/resize:fit:1100/0*LOpqyAjFokAs1sl2

Vantagens: Atualizado frequentemente; tem muitas interfaces, muitas linguagens, muitos recursos.

Desvantagens: Suporte parcial (limitado) ao Solidity (nenhuma restrição notada até este momento); sem regras básicas (incorporadas).

https://miro.medium.com/v2/resize:fit:1100/0*U2nHGAm7B1yHuXvP

Em suma, o SemGrep é uma ferramenta leve de análise estática para muitas linguagens. Com o uso dela, você pode encontrar variantes de bugs com padrões que se parecem com código-fonte!

Confira:

https://github.com/Decurity/semgrep-smart-contracts

Aqui é onde o SemGrep pode ajudar:

  • Ele realiza uma pesquisa Grep (escrevendo padrões personalizados);
  • Na essência, é semelhante à ferramenta que discutimos acima — SolGrep. Falando de forma grosseira, é o mesmo que SolGrep, só que com padrões prontos (incorporados) para criação de regras.

Para iniciantes, é recomendado começar com a Plataforma Semgrep Cloud porque ela fornece uma interface visual, um projeto de demonstração, fluxos de trabalho de triagem e exploração de resultados, e facilita a configuração em CI/CD (Integração Contínua/Entrega Contínua). As varreduras ainda são locais e o código não é enviado.

Alternativamente, você também pode começar com a CLI sem fazer login e navegar pela saída do terminal para executar pesquisas únicas.

Como tudo isso pode ser útil para um auditor?

Em primeiro lugar, deve-se observar que essa é apenas mais uma ferramenta em nossa caixa de ferramentas de métodos de trabalho.

No entanto, somos pessimistas sobre o uso de IA no desenvolvimento em todas as etapas (tais ferramentas não podem ser 100% confiáveis), particularmente ao trabalhar com RegEx, mas os primeiros feedbacks indicam que ela pode facilitar significativamente a vida!

Com isso, ainda não notamos nenhuma aplicação clara para ferramentas Grep em nossas auditorias, mas se você o fizer, por favor, compartilhe suas experiências nos comentários do artigo! Seguindo nossa pesquisa, parece que podemos usá-lo para o seguinte:

  • Para escrever vários detectores (detectores que não podem ser implementados com o uso da ferramenta Slither);
  • Para realizar uma pesquisa aprofundada de construções sintáticas (Você pode usar isso ao realizar uma inspeção inicial do projeto. Por exemplo, para determinar rapidamente quantas funções externas, bibliotecas, etc., são usadas em um determinado projeto).

Recentemente, conduzimos algumas pesquisas sobre este assunto e chegamos a algumas conclusões interessantes... Então, nos próximos artigos, vamos explorar isso também; fique ligado!

Recursos e Referências

Principais:

Externos:

Bônus:

Artigo original publicado por Nikita Kirillov, officercia.eth. Traduzido por Paulinho Giovannini.

Oldest comments (0)