2 points par GN⁺ 2024-06-06 | 1 commentaires | Partager sur WhatsApp
  • Entropy est un outil CLI qui analyse de grandes bases de code à la recherche de lignes à forte entropie, afin d’identifier des chaînes qui ressemblent à des secrets
  • Les lignes à forte entropie sont traitées comme des éléments présentant une forte probabilité d’être des secrets, avec un accent mis sur la détection de secrets exposés dans une base de code
  • L’installation et l’exécution sont proposées via installation depuis les sources Go, go run, Homebrew et Docker
  • Les options d’exécution -top, -ext et -ignore-ext permettent de définir le nombre de résultats, les extensions à inclure et les extensions à exclure
  • Lors de l’exécution avec Docker, il faut monter le répertoire courant dans /data et ajouter /data à la fin de la commande pour analyser le système de fichiers local

Ce que fait Entropy

  • Entropy est un outil CLI qui analyse une base de code pour trouver des lignes à forte entropie
  • Les lignes à forte entropie étant souvent des secrets, il aide à détecter les fuites de secrets dans une base de code

Modes d’installation et d’exécution

  • Installation avec Go

    • La méthode recommandée consiste à installer depuis les sources avec Go
    • Après l’installation, l’outil s’exécute avec la commande entropy
go install github.com/EwenQuim/entropy@latest
entropy
  • Une exécution en une seule ligne est également proposée
go run github.com/EwenQuim/entropy@latest
  • Installation avec Homebrew

    • La commande d’installation Homebrew est la suivante
brew install ewenquim/repo/entropy
entropy
  • Exécution avec Docker

    • L’exécution avec Docker consiste à monter le répertoire courant dans le conteneur sous /data
docker run --rm -v $(pwd):/data ewenquim/entropy /data

Exemples d’options principales

  • -h : affiche les options disponibles
entropy -h
  • -top : définit le nombre de premiers résultats à afficher
  • -ext : définit les extensions à analyser
entropy -top 20 -ext go,py,js
  • -ignore-ext : définit les extensions à exclure
  • Il est possible de passer des fichiers et des dossiers ensemble en arguments
entropy -top 5 -ignore-ext min.js,pdf,png,jpg,jpeg,zip,mp4,gif my-folder my-file1 my-file2

Points d’attention avec Docker

  • L’option Docker -v sert à monter le répertoire courant dans le conteneur
  • /data est le répertoire par défaut dans lequel l’outil cherche les fichiers
  • Si vous n’ajoutez pas /data à la fin de la commande, la recherche s’effectue dans le conteneur, et non sur le système de fichiers 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 commentaires

 
GN⁺ 2024-06-06
Commentaires sur Hacker News
  • Intéressant. Si je devais le faire, je pense que je partirais du principe que les éléments à forte entropie se compressent mal et j’utiliserais quelque chose comme ça
    perl -lne 'next unless $_; $z = qx(echo "$_" | gzip | wc -c); printf "%5.2f %s\n", $z/length($_), $_'
    Cela dit, cette méthode utilise chaque ligne comme dictionnaire plutôt que le fichier entier, donc les lignes très courtes se compressent mal et ça pose un petit problème
    Ça a réagi à une ligne comme return map { $_ > 1 ? 1 : ($_ < 0 ? 0 : $_) } @vs;, qui est du code valide mais qui a effectivement l’air d’avoir une entropie assez élevée
    À l’inverse, on pouvait aussi tromper la détection des lignes à forte entropie en ajoutant un commentaire en anglais naturel
    Je suis en déplacement donc je ne peux pas regarder ça en détail, mais ce serait amusant de comparer cette commande Perl à cet outil. L’avantage de la commande Perl, c’est qu’elle tourne immédiatement sur presque toutes les machines non-Windows, donc elle n’a pas besoin d’être exceptionnelle pour être adoptée

    • Il y a longtemps, j’ai appris Go en résolvant des problèmes Advent of Code, et à chaque fois que je finissais un problème, mon colocataire insistait pour voir mon code puis réécrivait ma solution de 10 à 50 lignes en Go en one-liner Ruby
      Il se moquait sans arrêt de Go et de mon programme bancal, et sans le vouloir j’ai aussi beaucoup appris Ruby ce jour-là
    • On pourrait peut-être obtenir une mesure plus juste en calculant la taille du fichier avec toutes les lignes sauf celle en cours de test, puis en la recalculant après avoir rajouté cette ligne, la différence de taille servant d’indicateur
      On pourrait aussi concaténer tous les fichiers de code puis tester ligne par ligne à l’échelle de tout le dépôt, mais ce serait probablement trop lent
    • J’utiliserais un meilleur compresseur que gzip, mais j’ai déjà employé cette astuce plusieurs fois
      xz ou zstd seraient peut-être de meilleurs choix, et si l’on considère que le meilleur taux de compression donne aussi une meilleure estimation de l’entropie, on peut aussi regarder les lauréats du Hutter Prize [1]
      [1] http://prize.hutter1.net/
    • Je me demande s’il existe un outil en ligne de commande, du genre zip, qui permette de précharger un dictionnaire à partir d’un ou plusieurs fichiers puis de compresser de petits fichiers avec ce dictionnaire
      Bien sûr, il faudrait aussi fournir ce dictionnaire séparément à la décompression
    • J’utilise le secret scanner de Yelp comme hook pre-commit, et c’est assez simple à configurer grâce au mécanisme d’installation de pre-commit
  • Ce problème est transcendé en mettant tous les mots de passe de base de données à abcd

    • Dans notre base de code, cet outil a détecté "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890" comme ligne à forte entropie
    • Nom d’utilisateur : postgres
      Mot de passe : postgres
    • Ça me fait penser à https://xkcd.com/936/. "correct horse battery staple" ressemble juste à une chaîne de mots ordinaires, donc j’imagine que ce serait à faible entropie
  • Je me demande s’il existe un bon article sur l’usage de l’entropie pour ce genre de tâche. Je me demande depuis longtemps comment les gens s’en servent en pratique et si c’est efficace, sans jamais avoir vraiment creusé le sujet
    Déjà, la façon de définir “l’entropie” d’un texte n’est pas très claire. Ici, c’est quelque chose de simple comme -Sum(x log(x)), avec x = countOccurences(char) / len(text), mais ça soulève pas mal de questions sur son efficacité réelle
    Quelle doit être la longueur d’une chaîne ? Les langues naturelles ont-elles une entropie presque constante ? Existe-t-il une meilleure approche ?
    Par exemple, "vorpal" devrait “clairement” avoir une entropie plus faible que "hJ6&:a". Le second semble utiliser un jeu de caractères bien plus large que le langage naturel, et même si ce n’était pas le cas, l’ordre des caractères compte : le premier sonne comme un vrai mot alors même qu’il a été inventé par Carroll
    Pourtant, cette “entropie” que tout le monde emploie ne sait absolument rien de tout cela. Les deux auraient exactement la même “entropie”
    Ça peut très bien suffire pour un simple détecteur de mots de passe GitHub, mais je me demande s’il n’existe pas mieux. Y a-t-il une métrique qui mesure de façon plus pertinente le caractère aléatoire d’un texte ?
    Il existe des dizaines de projets comme celui-ci, et tous utilisent “l’entropie” comme si ça allait de soi, mais je n’ai jamais vu de véritable recherche sur le sujet

    • L’entropie est une mesure de la complexité ou du désordre d’un signal. Le point intéressant, c’est que ce désordre est relatif à une base ou à un dictionnaire approprié
      Certaines choses paraissent complexes dans un encodage donné, mais peuvent avoir une faible entropie dans le bon encodage
      Pour évaluer correctement l’entropie d’un signal, il faut connaître la bonne base, ou l’inférer à partir du contexte
      Pour renforcer l’outil de l’article original, il vaudrait mieux disposer de quelques dictionnaires précalculés pour des catégories de texte typiques comme le code source ou le langage naturel, puis encoder chaque chaîne avec chacun de ces dictionnaires afin de comparer leur compressibilité
      Une chaîne à forte entropie, comme un secret, se compressera mal avec tous les dictionnaires disponibles
    • L’entropie d’une chaîne donnée n’est pas un concept mathématique rigoureux. Par définition, une chaîne déjà connue ne peut avoir qu’une seule valeur, donc son “entropie” est de 0 bit
      Si nous pouvons distinguer des données aléatoires de données non aléatoires, c’est parce que, parmi tous les états possibles, seuls certains sous-ensembles sont jugés utiles par les humains, et que nous avons une idée approximative de leur structure, ce qui nous permet d’estimer par quel processus une chaîne donnée a été générée
      Bien sûr, des tests statistiques comme https://en.wikipedia.org/wiki/Diehard_tests sont suffisamment bons pour distinguer des données à faible entropie de données à forte entropie, mais les générateurs pseudo-aléatoires modernes n’ont aucun mal à tous les réussir. Et cela alors que la véritable “entropie” ne se limite qu’à la graine et à la complexité de l’algorithme
    • La complexité de Kolmogorov d’une chaîne arbitraire est incalculable
  • Outils à voir aussi :
    trufflehog : https://github.com/trufflesecurity/trufflehog
    detect-secrets : https://github.com/Yelp/detect-secrets
    semgrep secrets : https://semgrep.dev/products/semgrep-secrets -- payant, mais peut dans certains cas être inclus dans une licence existante

    • PyWhat vaut aussi le détour pour trouver des chaînes intéressantes et des secrets : https://github.com/bee-san/pyWhat
    • noseyparker est aussi pas mal : https://github.com/praetorian-inc/noseyparker
      À mon avis, ce genre de solutions est bien meilleur pour trouver des secrets qu’une approche simple basée sur l’entropie.
      L’entropie est certes plus générale, mais ces outils sont déjà bien établis et ont vraiment été éprouvés sur énormément de jeux de données.
  • Ça m’a aidé il y a quelques années quand j’ai demandé ce qu’était une chaîne à forte entropie[0], et que DrJones m’a partagé un bon article lié[1]
    [0] https://news.ycombinator.com/item?id=13304641
    [1] https://www.splunk.com/en_us/blog/security/random-words-on-e...

  • Ça me rappelle le programme ent, que j’utilise depuis longtemps
    https://fourmilab.ch/random/

  • Ce serait utile si l’outil parcourait aussi tout l’historique git du projet. Même si un secret a été commité puis supprimé plus tard, il peut toujours rester dans l’historique.

  • Je ne vois pas pourquoi il faut installer Go pour exécuter cet outil. L’un des avantages de Go, ce n’était pas justement que le développeur peut distribuer un binaire unique qui fonctionne directement ?

    • Comme c’est un outil de sécurité, faire confiance au binaire dès le départ va un peu à l’encontre de l’objectif. Avec le code source, on a au moins la possibilité de vérifier ce qu’il fait réellement.
    • J’aurais voulu le mettre sur Homebrew, mais ma PR a été rejetée, donc il faudra soit créer un brew tap dédié, soit réussir à les convaincre de l’accepter.
      Une image Docker est aussi prévue.
      Honnêtement, je ne m’attendais pas à ce que ça devienne aussi populaire, donc le dépôt n’est pas encore prêt à 100 %.
    • Le conteneur Docker est désormais disponible et documenté sur la page d’accueil.
  • Des modèles de langage comme Llama 3 pourraient sans doute modéliser le degré de surprise token par token, puis détecter les zones les plus surprenantes, c’est-à-dire celles avec l’entropie la plus élevée.
    Comme dans l’un des exemples, l’alphabet complet peut avoir une forte entropie d’un certain point de vue, mais un modèle de langage familier du code ne trouverait pas du tout surprenant qu’un alphabet Base62 apparaisse comme constante dans une base de code.