2 Punkte von GN⁺ 2024-06-06 | 1 Kommentare | Auf WhatsApp teilen
  • Entropy ist ein CLI-Tool, das in großen Codebasen nach Zeilen mit hoher Entropie scannt, um Zeichenketten zu finden, die wie Secret-Werte aussehen
  • Zeilen mit hoher Entropie werden als Kandidaten mit hoher Wahrscheinlichkeit für Secrets behandelt; der Fokus liegt darauf, offengelegte Secret-Werte in Codebasen zu finden
  • Installation und Ausführung werden über Installation aus Go-Quellen, go run, Homebrew und Docker angeboten
  • Mit den Ausführungsoptionen -top, -ext und -ignore-ext lassen sich die Anzahl der Ergebnisse, einzubeziehende Erweiterungen und auszuschließende Erweiterungen festlegen
  • Bei der Ausführung mit Docker muss das aktuelle Verzeichnis nach /data gemountet und am Ende des Befehls /data angegeben werden, damit das lokale Dateisystem gescannt wird

Was Entropy macht

  • Entropy ist ein CLI-Tool, das Codebasen scannt und Zeilen mit hoher Entropie findet
  • Zeilen mit hoher Entropie sind häufig Secret-Werte und helfen dabei, Secret-Leaks in Codebasen zu finden

Installation und Ausführungsarten

  • Installation mit Go

    • Die empfohlene Installationsmethode ist die Installation aus den Quellen mit Go
    • Nach der Installation wird es mit dem Befehl entropy ausgeführt
go install github.com/EwenQuim/entropy@latest
entropy
  • Es gibt auch eine Ausführung als Einzeiler
go run github.com/EwenQuim/entropy@latest
  • Installation mit Homebrew

    • Der Homebrew-Installationsbefehl lautet wie folgt
brew install ewenquim/repo/entropy
entropy
  • Ausführung mit Docker

    • Bei der Docker-Ausführung wird das aktuelle Verzeichnis nach /data im Container gemountet
docker run --rm -v $(pwd):/data ewenquim/entropy /data

Beispiele für wichtige Optionen

  • -h: Zeigt die verfügbaren Optionen an
entropy -h
  • -top: Legt die Anzahl der auszugebenden Top-Ergebnisse fest
  • -ext: Legt die zu scannenden Erweiterungen fest
entropy -top 20 -ext go,py,js
  • -ignore-ext: Legt die auszuschließenden Erweiterungen fest
  • Dateien und Ordner können gemeinsam als Argumente übergeben werden
entropy -top 5 -ignore-ext min.js,pdf,png,jpg,jpeg,zip,mp4,gif my-folder my-file1 my-file2

Hinweise zur Docker-Nutzung

  • Die Docker-Option -v wird verwendet, um das aktuelle Verzeichnis in den Container zu mounten
  • /data ist das Standardverzeichnis, in dem das Tool nach Dateien sucht
  • Wenn am Ende des Befehls /data nicht hinzugefügt wird, wird nicht das lokale Dateisystem durchsucht, sondern das Innere des Containers
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 Kommentare

 
GN⁺ 2024-06-06
Hacker-News-Kommentare
  • Interessant. Wenn ich das machen würde, hätte ich es vermutlich nach dem Prinzip umgesetzt, dass hohe Entropie sich schlecht komprimieren lässt, etwa so:
    perl -lne 'next unless $_; $z = qx(echo "$_" | gzip | wc -c); printf "%5.2f %s\n", $z/length($_), $_'
    Allerdings behandelt diese Methode jede Zeile wie ein Wörterbuch statt die ganze Datei, daher gibt es bei sehr kurzen Zeilen ein kleines Problem, weil sie sich schlecht komprimieren lassen.
    Auf Zeilen wie return map { $_ > 1 ? 1 : ($_ < 0 ? 0 : $_) } @vs; hat es reagiert; das ist zwar gültiger Code, wirkt aber tatsächlich ziemlich entropiereich.
    Umgekehrt konnte man es auch austricksen, sodass es Zeilen mit hoher Entropie nicht erkennt, indem man einen Kommentar in natürlichem Englisch anhängt.
    Ich bin gerade unterwegs und kann es mir nicht genauer ansehen, aber ein Vergleich dieses Perl-Befehls mit diesem Tool wäre interessant. Der Vorteil des Perl-Befehls ist, dass er auf fast jedem Nicht-Windows-Rechner sofort läuft; um angenommen zu werden, muss er also nicht unbedingt besonders leistungsfähig sein.

    • Vor langer Zeit habe ich beim Lösen von Advent-of-Code-Aufgaben Go gelernt. Nach jeder Aufgabe drängte mich mein Mitbewohner, ihm den Code zu zeigen, und schrieb dann meine 10 bis 50 Zeilen Go-Lösung als Ruby-Einzeiler neu.
      Dabei machte er sich ständig über Go und mein unbeholfenes Programm lustig, und ganz unbeabsichtigt habe ich an dem Tag auch viel Ruby gelernt.
    • Es könnte ein fairerer Indikator sein, die Dateigröße anhand aller Zeilen der Datei außer der getesteten Zeile zu messen, dann diese Zeile hinzuzufügen und erneut zu messen; also die Größendifferenz.
      Man könnte auch alle Code-Dateien aneinanderhängen und dann zeilenweise über das gesamte Repository testen, aber das wäre vermutlich zu langsam.
    • Ich würde zwar einen besseren Kompressor als gzip verwenden, aber diesen Trick habe ich schon mehrfach genutzt.
      xz oder zstd könnten bessere Optionen sein, und aus der Perspektive, dass die beste Kompressionsrate auch die bessere Entropieschätzung ist, kann man sich auch die Gewinner des Hutter Prize [1] ansehen.
      [1] http://prize.hutter1.net/
    • Ich frage mich, ob es unter Kommandozeilen-Tools wie zip eines gibt, bei dem man mit einer oder mehreren Dateien ein Wörterbuch vordefinieren und dann kleine Dateien mit diesem Wörterbuch komprimieren kann.
      Natürlich müsste man dieses Wörterbuch beim Dekomprimieren ebenfalls separat als Eingabe angeben.
    • Ich nutze Yelps secret scanner als pre-commit-Hook; über den Installationsmechanismus von pre-commit lässt er sich ziemlich einfach einrichten.
  • Ich habe dieses Problem transzendiert, indem ich alle Datenbankpasswörter auf abcd gesetzt habe.

    • In unserer Codebasis hat dieses Tool "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890" als Zeile mit hoher Entropie erkannt.
    • Benutzername: postgres
      Passwort: postgres
    • Das erinnert mich an https://xkcd.com/936/. "correct horse battery staple" dürfte eine niedrige Entropie haben, weil es einfach wie eine gewöhnliche Wortfolge aussieht.
  • Ich frage mich, ob es gute Artikel darüber gibt, wie man Entropie für solche Aufgaben einsetzt. Ich wollte schon lange wissen, wie Leute das in der Praxis verwenden und ob es funktioniert, habe aber nie selbst tiefer nachgeforscht.
    Schon die Frage, wie man die „Entropie“ von Text definiert, ist unklar. Hier ist es ziemlich simpel: -Sum(x log(x)), also etwa x = countOccurences(char) / len(text). Dabei stellt sich die Frage, wie gut das in der Praxis tatsächlich funktioniert.
    Wie lang muss ein String sein? Hat natürliche Sprache eine nahezu konstante Entropie? Gibt es bessere Ansätze?
    Zum Beispiel sollte "vorpal" „offensichtlich“ eine geringere Entropie haben als "hJ6&:a". Letzteres sieht so aus, als würde es einen viel größeren Zeichensatz als natürliche Sprache verwenden, und selbst wenn nicht, ist die Zeichenreihenfolge wichtig: Ersteres klingt wie ein echtes Wort, obwohl es ein von Carroll erfundenes Wort ist.
    Aber diese „Entropie“, die alle verwenden, weiß davon überhaupt nichts. Beide hätten exakt dieselbe „Entropie“.
    Für noch einen GitHub-Passwortsucher mag das gut genug funktionieren, aber ich frage mich, ob es etwas Besseres gibt. Gibt es ein Maß, das die Zufälligkeit von Text sinnvoller erfasst?
    Es gibt Dutzende solcher Projekte, und alle verwenden „Entropie“ wie selbstverständlich, aber ich habe noch keine solide Forschung zu diesem Thema gesehen.

    • Entropie ist ein Maß für die Komplexität oder Unordnung eines Signals. Der interessante Teil ist, dass diese Unordnung relativ zu einer geeigneten Basis oder einem Wörterbuch ist.
      Etwas kann in einer Codierung komplex wirken, in der richtigen Codierung aber eine niedrige Entropie haben.
      Um die Entropie eines Signals korrekt zu beurteilen, muss man die richtige Basis kennen oder sie aus dem Kontext ableiten.
      Um das Tool aus dem ursprünglichen Beitrag stärker zu machen, wäre es sinnvoll, einige vorab berechnete Wörterbücher für typische Textbereiche wie Source Code oder natürliche Sprache vorzuhalten und dann zu vergleichen, wie gut sich der String mit jedem Wörterbuch codieren bzw. komprimieren lässt.
      Strings mit hoher Entropie, etwa Secrets, lassen sich mit keinem der verfügbaren Wörterbücher gut komprimieren.
    • Die Entropie eines bestimmten Strings ist kein strenger mathematischer Begriff. Per Definition kann ein bereits bekannter String nur einen einzigen Wert haben, also beträgt seine „Entropie“ 0 Bit.
      Dass wir nicht-zufällige von zufälligen Daten unterscheiden können, liegt daran, dass unter allen möglichen Zuständen nur eine kleine Teilmenge für Menschen als nützlich gilt und wir einigermaßen wissen, wie diese Teilmenge aussieht, sodass wir abschätzen können, durch welchen Prozess ein bestimmter String erzeugt wurde.
      Natürlich sind statistische Tests wie https://en.wikipedia.org/wiki/Diehard_tests gut genug, um Daten mit niedriger und hoher Entropie zu unterscheiden, aber moderne Pseudozufallszahlengeneratoren haben kein Problem damit, all diese Tests zu bestehen. Und das, obwohl die tatsächliche „Entropie“ im Grunde nur aus dem Seed-Wert und der Komplexität des Algorithmus besteht.
    • Die Kolmogorow-Komplexität eines beliebigen Strings ist nicht berechenbar.
  • Weitere Tools, die einen Blick wert sind:
    trufflehog: https://github.com/trufflesecurity/trufflehog
    detect-secrets: https://github.com/Yelp/detect-secrets
    semgrep secrets: https://semgrep.dev/products/semgrep-secrets -- kostenpflichtig, kann aber je nach Fall in einer bestehenden Lizenz enthalten sein

    • Zum Finden interessanter Strings und Secrets ist auch PyWhat einen Blick wert: https://github.com/bee-san/pyWhat
    • noseyparker ist ebenfalls brauchbar: https://github.com/praetorian-inc/noseyparker
      Ich denke, solche Lösungen sind beim Finden von Secrets deutlich besser als ein einfacher entropiebasierter Ansatz.
      Entropie ist zwar allgemeiner, aber diese Tools sind bereits gut etabliert und wurden über wirklich viele Datensätze hinweg validiert.
  • Vor ein paar Jahren war es hilfreich, dass DrJones fragte, was Strings mit hoher Entropie sind[0], und einen guten Artikel dazu verlinkte[1].
    [0] https://news.ycombinator.com/item?id=13304641
    [1] https://www.splunk.com/en_us/blog/security/random-words-on-e...

  • Ich musste an das alte ent-Programm denken, das ich schon lange nutze.
    https://fourmilab.ch/random/

  • Es wäre nützlich, wenn es auch die gesamte git-Historie eines Projekts durchsuchen würde. Selbst wenn ein Secret einmal committed und später entfernt wurde, kann es in der Historie weiterhin vorhanden sein.

  • Ich verstehe nicht, warum man Go installieren muss, um dieses Tool auszuführen. War nicht einer der Vorteile von Go, dass Entwickler einfach ein einzelnes Binary ausliefern können, das direkt funktioniert?

    • Weil es ein Security-Tool ist, widerspricht es dem Zweck, dem Binary von Anfang an zu vertrauen. Wenn der Source vorhanden ist, hat man zumindest die Möglichkeit zu prüfen, was es tatsächlich tut.
    • Ich wollte es in Homebrew aufnehmen lassen, aber der PR wurde abgelehnt; daher werde ich wohl einen eigenen brew tap erstellen oder sie davon überzeugen müssen, es anzunehmen.
      Ein Docker-Image plane ich ebenfalls.
      Ehrlich gesagt hatte ich nicht erwartet, dass es so populär wird, daher ist das Repository noch nicht zu 100 % vorbereitet.
    • Der Docker-Container ist jetzt verfügbar und auf der Homepage dokumentiert.
  • Sprachmodelle wie Llama 3 modellieren die Überraschung pro Token und könnten daher die überraschendsten Bereiche erkennen, also die Bereiche mit der höchsten Entropie.
    Das vollständige Alphabet kann, wie in einem der Beispiele, aus einer bestimmten Perspektive eine hohe Entropie haben; ein Sprachmodell, das mit Code vertraut ist, würde eine Base62-Alphabet-Konstante in einer Codebase aber überhaupt nicht überraschend finden.