- 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
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 altaPor 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
Ele ficava zoando Go e meus programas capengas e, sem querer, acabei aprendendo bastante Ruby naquele dia também
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
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/
Claro que, para descomprimir, também seria preciso fornecer esse dicionário como entrada separada
Superei esse problema fazendo todas as senhas de banco de dados serem
abcd"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"como uma linha de alta entropiaSenha: postgres
"correct horse battery staple"parece só uma sequência comum de palavras, então acho que teria baixa entropiaFico 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áticaQual 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 CarrollMas 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
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
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
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
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?
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
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