No description
  • Python 99.3%
  • Makefile 0.7%
Find a file
2021-12-20 20:43:50 +01:00
log4j_scanner WIP 2021-12-20 20:43:50 +01:00
.gitignore initial commit 2021-12-19 14:42:31 +01:00
huk-log4j-scanner.spec initial commit 2021-12-19 14:42:31 +01:00
huk-log4j-scanner_el7.py initial commit 2021-12-19 14:42:31 +01:00
huk-log4j-scanner_el8.py initial commit 2021-12-19 14:42:31 +01:00
Makefile initial commit 2021-12-19 14:42:31 +01:00
README.md WIP 2021-12-20 11:16:03 +01:00

huk-log4j-scanner

huk-log4j-scanner ist ein in Python geschriebener datei- und prozessbasierter Scanner, der verwundbare Versionen von Log4J finden kann. Er ist in der Lage alle gängigen Java-Containerformate (*.jar, *.war, *ear, *.zip; zur Einfachheit nachfolgenden nur noch "Jars" genannt) rekursiv zu durchsuchen und greift dabei auf mehrere Erkennunstechniken zurück.

Der Scanner wurde primär für Linux entwickelt, sollte aber mit wenigen Anpassungen (Erkennung von geöffneten Prozessen) auch auf anderen Platformen funktionieren.

Bedienung

Der Scanner ist in zwei Module (process für den prozessbasierten Scanner und path für den dateibasierten Scanner) unterteilt, die sich wie folgt aufrufen lassen:

$ huk-log4j-scanner [common options] process [process scanner opptions]
$ huk-log4j-scanner [common options] path [path scanner opptions]

Der Scanner bietet folgende modulunabhängige Optionen (common options):

  • -d/--debug Debug-Ausgaben: zeigt z.B. an welche Pfade exkludiert/ignoriert wurden (Vorsicht: sehr viele Ausgaben!)
  • -v/--verbose Verbose-Ausgaben: zeigt z.B. an welche Jars gescannt werden
  • -l/--log-file LOG_FILE Loggt alle Ausgaben zusätzlich in die Datei LOG_FILE
  • -o/--output {human,csv,json,yaml} Bestimmt das Ausgabeformat der Scan-Ergebnisse
    • human Eine für Menschen lesbare Ausgabe (mit Farben)
    • csv Maschinenlesbare Ausgabe im CSV-Format
    • json Maschinenlesbare Ausgabe im JSON-Format
    • yaml Maschinenlesbare Ausgabe im YAML-Format
  • -O/--output-file OUTPUT_FILE Schreibt die Scan-Ergebnisse in die Datei OUTPUT_FILE

Prozessbasierter Scanner

Der prozessbasierte Scanner scannt alle geöffneten/geladenen Jars von allen laufenden Prozessen und wertet diese aus. Dabei werden auch die laufende Container beachtet und ggf. geöffnete Dateien im Container-Filesystem (Overlay) gescannt.

$ huk-log4j-scanner [common options] process [-e EXCLUDE]

Der prozessbasierte Scanner bietet folgende Optionen (process scanner options):

  • -e/--exclude EXCLUDE Pfade (Verzeichnisse oder Dateien) die nicht gescannt werden sollen. Diese Option kann mehrmals angegeben werden

Achtung: Der prozessbasierte Scan folgt allen Symlinks und lies somit potentiell auch Netzwerk-Filesysteme aus.

Dateibasierter Scanner

Der dateibasierte Scanner scannt alle übergegebenen Pfade rekursiv nach Jars - unabhängig davon ob sie geöffnet/geladen sind oder nicht. Netzwerk-Filesysteme (nfs, cifs, gpfs, glusterfs) und Symlinks, die außerhalb des übergebenen Pfades zeigen, werden standardmäßig ignoriert.

$ huk-log4j-scanner [common options] path [path ...] [-e EXCLUDE] [-n]

Dem dateibasierten Scanner können mehrere Pfade (path) übergeben und er bietet zusätzlich folgende Optionen (path scanner options):

  • -e/--exclude EXCLUDE Pfade (Verzeichnisse oder Dateien) die nicht gescannt werden sollen. Diese Option kann mehrmals angegeben werden
  • -n/--include-netfs Netzwerk-Filesysteme werden bei der Suche inkludiert.

Achtung: Standardmäßig werden Netzwerk-Filesysteme exkludiert. Diese können mit -n/--include-ntfs inkludiert werden. Diese Option sollte nur mit Bedacht aktiviert werden. Ein Netzwerk-Filesysteme, dass von mehreren Servern/Clients gleichzeitig gemountet muss nicht von jedem einzelnen Server/Clients gescannt werden (ein Scan genügt). Ebenfalls sollte ein paralleler Scan von mehreren Servern/Clients verhindert werden.

Erkennungsmethodik

Der Scanner verwendete mehrere Methodiken um Log4J-Instanzen zu finden.

Er ist in der Lage folgende gängigen Java-Containerformate rekursiv zu scannen:

  • jar
  • war
  • ear
  • zip
  • Entpackte zip-/war-/ear-/zip-Archive, die *.class Dateien beinhalten

Dabei wird nach bestimmten Merkmalen gescannt um Log4J zu erkennen und seine Version zu bestimmen:

  • Suche nach Magic Files (Java-Klassen, die in jeder Log4J-Version dabei sind) die auf Log4J hinweisen
    • V1: org/apache/log4j/Layout.class
    • V2: org/apache/logging/log4j/core/Logger.class
  • Scan der MANIFEST.MF zur Identifizierung und Versionsbestimmung
  • Scan der pom.properties zur Identifizierung und Versionsbestimmung
  • Prüfsummenbasierter Scan von *.class Dateien zur Identifizierung und Versionsbestimmung
  • Prüfung ob ein Patch zur Mitigation angewendet wurde (Entfernen der JndiLookup.class)

Wird Log4J erkannt und kann seine Version bestimmt werden, dann wird mittels eines CVE-Mappings (siehe version.py) bestimmt, ob diese Version verwundbar ist.

Ergebnisse

Die Ergebnisse werden standardmäßig als Tabelle ausgegeben und in 3 Status unterteilt:

  • vulnerable = Betroffen
  • mitigated = Betroffen, aber die JdniLookup.class wurde entfernt
  • ok = Nicht betroffen

Beispiel:

found 3 matching files

status     | version    | path
-----------+------------+-------------------------------------------------------
vulnerable | 2.13.1     | /some/to/path/somejar1.jar
mitigated  | 2.12.1     | /some/to/path/somejar2.jar
ok         | 2.12.2     | /some/to/path/somejar3.jar
ok         | 2.17.0     | /some/to/path/somejar4.jar

Beispiele

Scannen aller laufenden Prozesse mit Verbose-Ausgabe:

$ huk-log4j-scanner -v process 

Scannen von /usr, aber /usr/share soll nicht gescannt werden:

$ huk-log4j-scanner path -e /usr/share /usr 

Scannen von /, aber /dev/, /proc und /sys sollen nicht gescannt werden. Funde in /opt/mycompany sollen im Ergebnise nicht angezeigt werden. Die Ausgabe soll als JSON in Datei result.json geschrieben werden.

$ huk-log4j-scanner -o json -O result.json path -e /dev -e /proc -e /sys /