2 pontos por GN⁺ 2024-06-06 | 1 comentários | Compartilhar no WhatsApp
  • Entropy é uma ferramenta CLI que escaneia linhas de alta entropia em grandes bases de código para encontrar strings que parecem valores secretos
  • Linhas de alta entropia são tratadas como alvos com alta probabilidade de serem segredos, com foco em encontrar valores secretos expostos dentro da base de código
  • A instalação e a execução são oferecidas via instalação do código-fonte em Go, go run, Homebrew e Docker
  • As opções de execução -top, -ext e -ignore-ext permitem definir a quantidade de resultados, as extensões incluídas e as extensões excluídas
  • Ao executar com Docker, é preciso montar o diretório atual em /data e adicionar /data ao fim do comando para escanear o sistema de arquivos local

O que o Entropy faz

  • Entropy é uma ferramenta CLI que escaneia uma base de código em busca de linhas de alta entropia
  • Como linhas de alta entropia muitas vezes são valores secretos, ela ajuda a encontrar vazamentos de segredos na base de código

Formas de instalação e execução

  • Instalação com Go

    • A forma recomendada de instalação é instalar a partir do código-fonte usando Go
    • Após a instalação, execute com o comando entropy
go install github.com/EwenQuim/entropy@latest
entropy
  • Também há uma forma de executar em uma única linha
go run github.com/EwenQuim/entropy@latest
  • Instalação com Homebrew

    • O comando de instalação via Homebrew é o seguinte
brew install ewenquim/repo/entropy
entropy
  • Execução com Docker

    • A execução com Docker monta o diretório atual em /data dentro do contêiner
docker run --rm -v $(pwd):/data ewenquim/entropy /data

Exemplos das principais opções

  • -h: mostra as opções disponíveis
entropy -h
  • -top: define a quantidade de resultados principais a exibir
  • -ext: define as extensões que serão escaneadas
entropy -top 20 -ext go,py,js
  • -ignore-ext: define as extensões a serem excluídas
  • É possível passar arquivos e pastas juntos como argumentos
entropy -top 5 -ignore-ext min.js,pdf,png,jpg,jpeg,zip,mp4,gif my-folder my-file1 my-file2

Pontos de atenção ao usar Docker

  • A opção -v do Docker é usada para montar o diretório atual dentro do contêiner
  • /data é o diretório padrão onde a ferramenta procura os arquivos
  • Se /data não for adicionado ao fim do comando, a busca será feita dentro do contêiner, e não no sistema de arquivos local
docker run --rm -v $(pwd):/data ewenquim/entropy -top 20 -ext go,py,js /data
docker run --rm -v $(pwd):/data ewenquim/entropy -top 5 /data/my-folder /data/my-file

1 comentários

 
GN⁺ 2024-06-06
Comentários do Hacker News
  • Interessante. Se fosse eu, acho que faria algo assim, usando o princípio de que alta entropia não comprime bem
    perl -lne 'next unless $_; $z = qx(echo "$_" | gzip | wc -c); printf "%5.2f %s\n", $z/length($_), $_'
    Só que esse método usa cada linha como se fosse um dicionário, em vez do arquivo inteiro, então linhas muito curtas não comprimem bem e isso causa alguns problemas
    Ele reagiu a uma linha como return map { $_ > 1 ? 1 : ($_ < 0 ? 0 : $_) } @vs;; embora seja código válido, de fato parece ter entropia bem alta
    Por outro lado, também foi possível enganá-lo acrescentando um comentário em inglês natural, impedindo a detecção da linha de alta entropia
    Estou em trânsito e não consigo olhar em detalhe, mas seria interessante comparar esse comando Perl com esta ferramenta. A vantagem do comando Perl é que ele roda direto em quase qualquer máquina que não seja Windows, então não precisa ser necessariamente poderoso para ser adotado

    • Há muito tempo, aprendi Go resolvendo problemas do Advent of Code; a cada problema, meu colega de casa insistia para ver o código e então reescrevia em uma linha de Ruby a solução que em Go tinha de 10 a 50 linhas
      Ele ficava zoando Go e meus programas capengas e, sem querer, acabei aprendendo bastante Ruby naquele dia também
    • Medir o tamanho do arquivo com todas as linhas exceto a que está sendo testada, depois adicionar essa linha e medir de novo, talvez desse uma métrica mais justa pela diferença de tamanho
      Também daria para concatenar todos os arquivos de código e testar linha por linha no repositório inteiro, mas provavelmente seria lento demais
    • Eu usaria um compressor melhor que gzip, mas já usei esse truque várias vezes
      xz ou zstd podem ser escolhas melhores e, pela ideia de que a melhor taxa de compressão equivale a uma estimativa melhor de entropia, também dá para olhar os vencedores do Hutter Prize [1]
      [1] http://prize.hutter1.net/
    • Fico me perguntando se, entre ferramentas de linha de comando como zip, existe alguma que permita predefinir um dicionário com um ou mais arquivos e depois comprimir arquivos pequenos com esse dicionário
      Claro que, para descomprimir, também seria preciso fornecer esse dicionário como entrada separada
    • Uso o secret scanner do Yelp como hook de pre-commit, e ele é bem fácil de configurar pelo mecanismo de instalação do pre-commit
  • Superei esse problema fazendo todas as senhas de banco de dados serem abcd

    • Na nossa base de código, essa ferramenta encontrou "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890" como uma linha de alta entropia
    • Nome de usuário: postgres
      Senha: postgres
    • Isso me lembra https://xkcd.com/936/. "correct horse battery staple" parece só uma sequência comum de palavras, então acho que teria baixa entropia
  • Fico curioso para saber se há algum bom texto sobre como usar entropia nesse tipo de tarefa. Há tempos tenho curiosidade sobre como as pessoas realmente usam isso e se funciona, mas nunca fui investigar a fundo
    Para começar, já é ambíguo definir o que seria “entropia” de um texto. Aqui é algo simples como -Sum(x log(x)), isto é, x = countOccurences(char) / len(text), mas isso levanta várias dúvidas sobre quão bem funciona na prática
    Qual precisa ser o tamanho da string? Línguas naturais têm uma entropia quase constante? Há abordagens melhores?
    Por exemplo, "vorpal" deveria ter “claramente” menos entropia do que "hJ6&:a". A segunda parece usar um conjunto de caracteres muito maior do que linguagem natural e, mesmo que não use, a ordem dos caracteres importa, então a primeira soa como uma palavra real, apesar de ser uma palavra inventada por Carroll
    Mas essa “entropia” que todo mundo usa não sabe nada disso. As duas teriam exatamente a mesma “entropia”
    Talvez funcione bem o suficiente para mais um buscador de senhas no GitHub, mas fico curioso se existe algo melhor. Haveria uma métrica que meça de forma mais significativa a aleatoriedade de um texto?
    Existem dezenas de projetos assim e todos usam “entropia” como algo óbvio, mas nunca vi uma pesquisa adequada sobre o tema

    • Entropia é uma métrica da complexidade ou desordem de um sinal. A parte interessante é que essa desordem é relativa a uma base ou dicionário adequado
      Algo pode parecer complexo em uma codificação, mas ter baixa entropia na codificação correta
      Para julgar com precisão a entropia de um sinal, é preciso conhecer a base correta ou inferi-la pelo contexto
      Para tornar a ferramenta do post original mais forte, seria bom ter alguns dicionários pré-computados para classes típicas de texto, como código-fonte ou linguagem natural, e comparar a compressibilidade ao codificar a string com cada dicionário
      Strings de alta entropia, como segredos, não comprimiriam bem com nenhum dos dicionários disponíveis
    • A entropia de uma string específica não é um conceito matemático rigoroso. Por definição, uma string já conhecida só pode ter um valor, então sua “entropia” é de 0 bit
      O motivo de conseguirmos distinguir dados não aleatórios de dados aleatórios é que, entre todos os estados possíveis, apenas um pequeno subconjunto é considerado útil para humanos, e temos alguma noção de como esse subconjunto se parece, o que nos permite estimar por qual processo uma determinada string foi gerada
      Claro que testes estatísticos como https://en.wikipedia.org/wiki/Diehard_tests são bons o bastante para distinguir dados de baixa entropia de dados de alta entropia, mas geradores pseudoaleatórios modernos não têm problema em passar por todos esses testes, mesmo que a “entropia” real seja basicamente apenas a semente e a complexidade do algoritmo
    • A complexidade de Kolmogorov de uma string arbitrária é incomputável
  • Ferramentas que vale ver junto:
    trufflehog: https://github.com/trufflesecurity/trufflehog
    detect-secrets: https://github.com/Yelp/detect-secrets
    semgrep secrets: https://semgrep.dev/products/semgrep-secrets -- é pago, mas dependendo do caso pode estar incluído na licença existente

    • Para encontrar strings interessantes e segredos, PyWhat também vale uma olhada: https://github.com/bee-san/pyWhat
    • noseyparker também é uma boa: https://github.com/praetorian-inc/noseyparker
      Acho que essas soluções são muito melhores para encontrar segredos do que uma abordagem simples baseada em entropia
      É verdade que entropia é algo mais genérico, mas essas ferramentas já estão bem estabelecidas e foram validadas passando por um volume enorme de datasets
  • Alguns anos atrás, foi útil graças ao DrJones, que perguntou o que era uma string de alta entropia[0] e compartilhou um bom texto relacionado[1]
    [0] https://news.ycombinator.com/item?id=13304641
    [1] https://www.splunk.com/en_us/blog/security/random-words-on-e...

  • Isso me lembra o programa ent, que uso há muito tempo
    https://fourmilab.ch/random/

  • Seria útil se ele também varresse todo o histórico git do projeto. Mesmo que um segredo tenha sido commitado e removido depois, ele ainda pode continuar no histórico

  • Não entendo por que é preciso instalar Go para executar essa ferramenta. Uma das vantagens do Go não era permitir que o desenvolvedor distribuísse um binário único que simplesmente funciona?

    • Como é uma ferramenta de segurança, confiar em um binário logo de cara vai contra o propósito. Com o código-fonte, pelo menos existe a opção de verificar o que ela realmente faz
    • Eu queria colocá-la no Homebrew, mas o PR foi recusado, então acho que vou ter que criar meu próprio brew tap ou convencê-los a aceitar
      Também pretendo criar uma imagem Docker
      Sinceramente, eu não esperava que ficasse tão popular, então o repositório ainda não está 100% pronto
    • O contêiner Docker já está disponível e está documentado na página inicial
  • Modelos de linguagem como o Llama 3 talvez consigam modelar o grau de surpresa por token e detectar as áreas mais surpreendentes, ou seja, as de maior entropia
    Como em um dos exemplos, o alfabeto inteiro pode ter alta entropia sob certo ponto de vista, mas um modelo de linguagem familiarizado com código não acharia nada surpreendente encontrar um alfabeto Base62 como constante em uma base de código