- 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
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.
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.
Man könnte auch alle Code-Dateien aneinanderhängen und dann zeilenweise über das gesamte Repository testen, aber das wäre vermutlich zu langsam.
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/
Natürlich müsste man dieses Wörterbuch beim Dekomprimieren ebenfalls separat als Eingabe angeben.
Ich habe dieses Problem transzendiert, indem ich alle Datenbankpasswörter auf
abcdgesetzt habe."ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"als Zeile mit hoher Entropie erkannt.Passwort: postgres
"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 etwax = 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.
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.
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.
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
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?
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.
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.