Im Rahmen unserer laufenden Datensicherheitsuntersuchungen deckte Varonis Threat Labs eine Sicherheitslücke bei der Remote-Codeausführung (RCE) in der PostgreSQL-Datenbanksoftware auf, die mehrere in PostgreSQL-Erweiterungen gefundene Sicherheitslücken nutzt.
Eine RCE-Sicherheitslücke ermöglicht es einem Angreifer, beliebige Befehle auf dem zugrunde liegenden Betriebssystem des Datenbankservers auszuführen. Ein erfolgreicher Angriff könnte zur Datenexfiltration und Zerstörung führen und dem Angreifer einen ersten Zugangsvektor zu Ihrem Netzwerk verschaffen.
Hintergrund
Unsere Forscher haben eine Sicherheitslücke in PL/Perl entdeckt, einer vertrauenswürdigen Spracherweiterung, die in viele Standard-Postgres-Distributionen eingebaut ist. Zusammen mit einer Sicherheitslücke in der Postgres-Erweiterung PL/Rust könnte dieses Primitiv für eine RCE ausgenutzt werden, was potenziell zu Datenexfiltration, Zerstörung und weiterer Bewegung im Netzwerk führen könnte.
Während die von uns identifizierte Sicherheitslücke in Postgres auftrat, war die von uns getestete Umgebung Amazon Relational Database Service (RDS) nicht anfällig für einen erfolgreichen Angriff. Als wir die Sicherheitslücke in Amazon RDS ausführten, bevor Postgres Patches veröffentlichte, erkannte AWS die Aktivität schnell und stoppte sie im Rahmen ihrer automatisierten Schutzmaßnahmen.
Angesichts der zusätzlichen Schutzmaßnahmen (wie SELinux), die wir festgestellt haben, hatten die versuchten Befehle keine praktische Anwendung, da vor dem Herunterfahren unserer Datenbank durch AWS keine Datenbank- oder Kunden-übergreifenden Informationen zugänglich waren.
Das Postgres-Team veröffentlichte am 14. November 2024 eine Empfehlung und eine Lösung für das Problem, und AWS gab am 6. Mai 2025 die folgende Erklärung ab:
AWS hat bestätigt, dass Amazon Relational Database Service (RDS) und Aurora von dem Problem nicht betroffen waren. Aus Vorsicht empfehlen wir unseren Kunden, auf die neueste Version zu aktualisieren, die für ihre Umgebung gilt. Diese Updates sind über die [AWS Management Console, AWS CLI oder RDS API] verfügbar.
Wir möchten Varonis für die Zusammenarbeit mit uns bei dieser Untersuchung im Rahmen des koordinierten Offenlegungsprozesses danken.
- Amazon Web Services (AWS)
Als allgemeine Empfehlung raten wir Postgres-Kunden, ihre PostgreSQL-Datenbanken zu aktualisieren. Nicht verwaltete eigenständige Postgres-Kunden, die PL/Rust verwenden, sollten die Erweiterung auf die neueste Version aktualisieren und ihre Datenbank-Fehlerlogs auf verdächtige Aktivitäten überwachen.
Lesen Sie weiter, um mehr über die RCE-Schwachstelle in PostgreSQL zu erfahren und wie unsere Forscher die Sicherheitslückenprüfung auf Amazon RDS durchgeführt haben.
Auf der Suche nach Schwachstellen in Amazon RDS
Amazon RDS ist ein vollständig verwalteter Datenbankdienst, der mehrere gängige relationale Datenbanken unterstützt, einschließlich Postgres.
Es ist wichtig daran zu denken, dass AWS im Rahmen des Modells der geteilten Verantwortung die Sicherheit des Datenbankservers und Clusters verwaltet, während die Kunden von Amazon RDS für die Konfiguration und Sicherung des Netzwerkzugriffs, der Datenbankzugriffskontrolle und der Daten selbst verantwortlich sind.
Der Zugriff mit den höchsten Berechtigungen, den Amazon RDS-Nutzer haben können, ist die von AWS verwaltete Rolle rds_superadmin. Entgegen seinem Namen ist dieser Zugriff kein Postgres-Superadmin. Der rds_superadmin kann nicht mit dem Betriebssystem interagieren, keine benutzerdefinierten Netzwerkverbindungen öffnen, keine nicht vertrauenswürdigen Funktionen schreiben und keine Dateien auf den Datenträger lesen oder schreiben.
Während unseres Tests haben wir zunächst das Eskalieren von Berechtigungen in einer Amazon Aurora PostgreSQL 17-Datenbank untersucht. Laut AWS „beinhaltet Aurora ein Hochleistungs- Speichersubsystem. Die MySQL- und PostgreSQL-kompatiblen Datenbank-Engines sind angepasst, um die Vorteile dieses schnellen verteilten Speichers zu nutzen.“
Dies schafft einen Bereich von zusätzlichem Interesse (oder Neugier), um nach Sicherheitslücken in der AWS-Integration von Open-Source PostgreSQL mit dem managed Service zu suchen.
Wir haben uns für eine gängige Methode entschieden, eine Sicherheitslücke in einer Postgres-Erweiterung auszunutzen, um mit dem System zu interagieren oder einen Befehl als Datenbank-Superuser auszuführen. Die PL/Perl-Erweiterung fiel uns auf, weil sie von PostgreSQL gewartet wird und sofort einsatzbereit in Standard-Postgres-Builds enthalten ist, einschließlich Amazon RDS und Amazon Aurora.
Initiales Primitiv: Modifizieren von Umgebungsvariablen mit PL/Perl
PL/Perl ist eine vertrauenswürdige Spracherweiterung für PostgreSQL, die es ermöglicht, PostgreSQL-Funktionen und -Verfahren in der Programmiersprache Perl zu schreiben, einer prozeduralen Sprache, die häufig zum Konvertieren oder Verarbeiten großer Datenmengen verwendet wird.
In der PostgreSQL-Dokumentation heißt es:„Normalerweise wird PL/Perl als eine ‚vertrauenswürdige‘ Programmiersprache namens plperl installiert.“ In dieser Konfiguration sind bestimmte Perl-Vorgänge deaktiviert, um die Sicherheit zu wahren. Im Allgemeinen sind die Vorgänge eingeschränkt, die mit der Umgebung interagieren.
This includes file handle operations, require, and use (for external modules). There is no way to access internals of the database server process or to gain OS-level access with the permissions of the server process, as a C function can do. Thus, any unprivileged database user can be permitted to use this language.”
However, Perl has a built-in interface for reading and setting environment variables, the %ENV hash map, that is integrated into the core of the language and is not protected by Perl security modules such as “Strict” and“Opcode”, which PL/Perl relies on for security.
Wir haben uns gefragt, ob wir mit Umgebungsvariablen experimentieren können, da dies oft zu interessanten Ergebnissen führt. Durch das Schreiben einer vertrauenswürdigen plperl-Funktion haben wir die folgende Syntax zum Festlegen von Umgebungsvariablen verwendet:

Und es hat funktioniert!
Die Postgres-Funktionen werden im Kontext einer PostgreSQL-Sitzung ausgeführt. Wenn ein Client eine Verbindung zu einer PostgreSQL-Datenbank herstellt, erzeugt der Hauptprozess von PostgreSQL einen Arbeitsprozess zur Bearbeitung der verbundenen Datenbanksitzung. Die Sicherheitslücke in PL/Perl ermöglichte es uns, Umgebungsvariablen in Sitzungs-Arbeitsprozessen festzulegen
Nun mussten wir einen Weg finden, dieses Primitiv, das Festlegen von Umgebungsvariablen eines PostgreSQL-Arbeitsprozesses, in ein RCE zu verwandeln. Es gibt mehrere Techniken zum Ausführen von beliebigem Code durch Manipulation von Umgebungsvariablen, wir entschieden, sie nicht zu verwenden.
- Umgebungsvariablen können verwendet werden, um Konfigurationsparameter für Postgres und seine Erweiterungen festzulegen, was dazu führen kann, dass beliebiger Code ausgeführt wird, wenn Erweiterungen geladen werden. Diese werden jedoch normalerweise vom Hauptprozess von Postgres geladen, bevor ein Arbeitsprozess abgezweigt wird und wir können die Umgebungsvariablen in diesem Kontext nicht beeinflussen. Darüber hinaus werden sensible SQL-Befehle und die meisten Postgres-Erweiterungen in Sandbox-Prozessen ausgeführt und führen Hintergrundaufgaben mit der in Postgres integrierten Funktionalität zum Erzeugen von Arbeitsprozessen aus dem Hauptprozess von Postgres aus, so dass sie von unseren Umgebungsänderungen nicht betroffen sind.
- Gängige Umgebungsvariablen wie PATH und LD_PRELOAD sind bekannte Methoden, um beliebigen Code auszuführen. Die Umgebungsvariable PATH weist das Betriebssystem an, wo nach Binärdateien gesucht werden soll, wenn diese mit relativen Namen statt mit vollständigen Pfaden ausgeführt werden, während LD_PRELOAD Linux-Prozesse anweist, ein gespeichertes Objekt von der Festplatte zu laden, bevor ein neuer Prozess ausgeführt wird. Beide Methoden können verwendet werden, um beliebige Binärdateien auszuführen, erfordern jedoch das Schreiben einer Datei auf dem Server und wir wollten etwas Einfacheres.
Wir haben in den GitHub-Repositories von Postgres und seiner in Amazon RDS verfügbaren Erweiterung nach Prozessaufrufen gesucht, die wir verwenden könnten.
.png?width=1050&height=741&name=Image_AttackersPlaybook_202408%20(1).png)
PL/Rust — Nutzung des PL/Perl-Primitivs zur Ausführung von Code
Die kürzlich veröffentlichte PL/Rust ist eine vertrauenswürdige Spracherweiterung, die es ermöglicht, Postgres-Funktionen in der Programmiersprache Rust zu schreiben. Es wird von Amazon RDS unterstützt, jedoch nicht von Amazon Aurora.
Um PL/Rust, eine kompilierte Sprache, auf einer Postgres-Instanz zu installieren, muss das Sprachentwicklung-Set auf dem Server installiert werden. Es enthält einen Compiler, rustc, und cargo – den Paketmanager von Rust. Beim Erstellen einer plrust-Funktion führt die Erweiterung, die ebenfalls in Rust geschrieben ist, den Kompilierungsprozess aus der aktuellen Sitzung des Postgres-Nutzers durch und übernimmt dieselbe Umgebung. Das bedeutet, wenn wir eine PostgreSQL-Funktion in der Sprache plrust erstellen, `cargo build` unter Verwendung unserer geänderten Umgebungsvariablen ausgeführt wird.

An diesem Punkt würde die Verwendung der zuvor erwähnten Methoden zur Codeausführung das Hochladen von Dateien auf den Server erfordern. Da unser Ziel RDS war, war das keine Option.
Stattdessen haben wir uns die Umgebungsvariablen angesehen, die cargo während des Kompilierungsprozesses konfigurieren. Die PL/Rust-Erweiterung entfernt mehrere problematische Umgebungsvariablen, bevor cargo ausgeführt wird. Viele Umgebungsvariablen werden jedoch weder von plrust gelöscht noch in der Dokumentation von plrust erwähnt. Eine solche Variable ermöglichte es uns, cargo jedes beliebige Binärprogramm ausführen zu lassen.

Dies allein ermöglichte keine uneingeschränkte Codeausführung, da es keine Kontrolle über die Befehlszeilenargumente ermöglichte. Um dies zu umgehen, benötigten wir eine Binärdatei, die Befehle aus Umgebungsvariablen ausführt, bevor sie Befehlszeilenargumente analysiert. Wir haben es speziell so konfiguriert, dass eine andere Binärdatei verwendet wird, die mit dem Standard-Build für PL/Rust, rust-gdb, geliefert wird und zum Debuggen von Rust-Anwendungen verwendet wird. Wenn rust-gdb die Umgebungsvariable RUST_GDB liest, ignoriert es jegliche Befehlszeilenargumente vollständig und verwendet den Wert der Variable, um zu bestimmen, welche Binärdatei ausgeführt werden soll.
Wenn in cargo (oben), eine Wrapper-Umgebungsvariable festgelegt ist, führen Sie diese aus, anstatt die rustc-Umgebungsvariable zu lesen. Wenn in rust-gdb (unten), RUST_GDB festgelegt ist, überschreiben Sie alle Befehlszeilenargumente.

Wenn in cargo (oben), eine Wrapper-Umgebungsvariable festgelegt ist, führen Sie diese aus, anstatt die rustc-Umgebungsvariable zu lesen. Wenn in rust-gdb (unten), RUST_GDB festgelegt ist, überschreiben Sie alle Befehlszeilenargumente.
Dies ermöglichte es uns, Code in unserem PostgreSQL-Labor auszuführen.
Verwendung einer PL/Perl-Funktion, die die Befehlszeilenargumente festlegt, dann eine PL/Rust-Funktion erstellt und cargo aufruft, wodurch rust-gdb anstelle des Standard-Rust-Compilers erzeugt wird. rust-gdb ruft seinerseits den in der Umgebungsvariablen RUST_GDB angegebenen `id`-Befehl auf und erzeugt die Ausgabe in stdout, wie sie von Postgres präsentiert wird, sobald der Kompilierungsvorgang fehlschlägt.

Verwendung einer PL/Perl-Funktion, die die Befehlszeilenargumente festlegt, dann eine PL/Rust-Funktion erstellt und cargo aufruft, wodurch rust-gdb anstelle des Standard-Rust-Compilers erzeugt wird. rust-gdb ruft seinerseits den in der Umgebungsvariablen RUST_GDB angegebenen `id`-Befehl auf und erzeugt die Ausgabe in stdout, wie sie von Postgres präsentiert wird, sobald der Kompilierungsvorgang fehlschlägt.
Die Auswirkungen der Ausführung von beliebigem Code auf Amazon RDS
Zurück in der Cloud versuchten wir, diese Sicherheitslücke in unserem Amazon RDS-Server auszunutzen, stellten jedoch fest, dass rust-gdb einige erwartete Binärdateien vermisste und unseren Shell-Befehl nicht ausführen konnte. Also haben wir uns entschieden, stattdessen /bin/bash zu verwenden.
Obwohl Bash die von PL/Rust übergebenen Befehlszeilenargumente nicht akzeptiert, weist die Umgebungsvariable BASH_ENV Bash an, ein Shell-Initialisierungsskript zu laden und auszuführen, bevor die Befehlszeile geparst wird. Das ist genau die Art und Weise, wie rust-gdb die Variable RUST_GDB analysiert und ausführt, bevor Befehlszeilenargumente gelesen werden.
Der Wert von BASH_ENV wird einer Parametererweiterung, einer Befehlsersetzung und einer arithmetischen Erweiterung unterzogen, bevor er als Dateiname interpretiert wird. Das Festlegen der Umgebungsvariablen auf '$(command 2>&1)' verursacht, dass command ausgeführt wird und seine Ausgabe an stderr sendet, was von der Kompilierung einer plrust-Funktion zurückgegeben wird, wenn sie fehlschlägt.
Mit dieser Methode konnten wir den Befehl erfolgreich ausführen! Aufgrund der geltenden Sicherheitsbeschränkungen hatten wir keine Berechtigung, auf sensible Amazon RDS-Datenstandorte zuzugreifen oder Netzwerkzugriffe mit dieser Sicherheitslücke durchzuführen.
Dennoch sollten Kunden ihre Datenbanken aktualisieren und die Logs auf verdächtige Aktivitäten überwachen.

Empfehlungen für Postgres-Kunden
Wir empfehlen Postgres-Kunden, ihre Datenbanken mindestens auf die neueste Minor-Version zu aktualisieren, unabhängig davon, ob sie eine eigenständige Bereitstellung oder eine verwaltete Cloud-Bereitstellung wie mit Amazon RDS nutzen. Nutzer von eigenständigen Datenbanken mit PL/Rust sollten diese Erweiterung auf die neueste Version aktualisieren und Debugging-Tools wie rust-gdb aus Produktionsumgebungen entfernen.
Obwohl wir in diesem Fall plrust zur Ausführung von Code verwendet haben, können auch andere Erweiterungen betroffen sein, einschließlich benutzerdefinierter Erweiterungen.
Datenbankadministratoren sollten die Installation von Erweiterungen verhindern, die sie nicht verwenden, indem sie diese aus dem Datenbankkonfigurationsparameter rds.allowed_extensions ausschließen.
Hier sind zum Beispiel die Anweisungen zum Blockieren der Installation nicht genutzter Erweiterungen in Amazon RDS:
- Melden Sie sich bei der AWS Management Console an und öffnen Sie die Amazon RDS-Konsole unter https://console.aws.amazon.com/rds/.
- Wählen Sie eine vorhandene PostgreSQL-Datenbank aus
- Suchen Sie unter der Registerkarte „Konfiguration“ die angehängte Parametergruppe
- Wenn es eine Standard-Parametergruppe ist, müssen Sie eine neue Parametergruppe erstellen und sie an die Instanz anhängen, da der Standardwert für den Parameter rds.allowed_extensions alle Erweiterungen zulässt.
- Andernfalls können Sie diese Anleitung verwenden, um den Parameter zu bearbeite.
- Stellen Sie sicher, dass der Parameter allowed_extensions nur die Erweiterungen enthält, die Sie zum Ausführen in Ihrer Datenbank genehmigen.
Fazit
Es ist wichtig, daran zu denken, dass AWS zwar Sicherheitstools für die Nutzung mit RDS bereitstellt, es jedoch weiterhin in der Verantwortung der Cloud-Kunden liegt, bei der Bereitstellung und Konfiguration ihrer Ressourcen, der Zugriffskontrolle, dem Netzwerkzugriff und der Einhaltung und dem Schutz von Daten Best Practices für Sicherheit anzuwenden.
Amazon RDS stellt zusätzliche Ressourcen für Kunden zu Sicherheit Best Practices bereit.
Benötigen Sie Hilfe beim Schutz Ihrer AWS-Umgebung? Entdecken Sie Varonis für AWS und vereinbaren Sie eine Demo, um es in Aktion zu sehen.
Wie soll ich vorgehen?
Im Folgenden finden Sie drei Möglichkeiten, wie Sie das Datenrisiko in Ihrem Unternehmen verringern können:
Vereinbaren Sie eine Demo mit uns, um Varonis in Aktion zu erleben. Wir passen die Session an die Datensicherheitsanforderungen Ihres Unternehmens an und beantworten alle Fragen.
Sehen Sie sich ein Beispiel unserer Datenrisikobewertung an und erfahren Sie, welche Risiken in Ihrer Umgebung lauern könnten. Varonis DRA ist völlig kostenlos und bietet einen klaren Weg zur automatischen Sanierung.
Folgen Sie uns auf LinkedIn, YouTubeund X (Twitter), um kurze Einblicke in alle Themen der Datensicherheit zu erhalten, einschließlich Data Security Posture Management (DSPM), Bedrohungserkennung, KI-Sicherheit und mehr.
