Rusty Pearl : exécution de code à distance dans les instances Postgres. 

Varonis découvre une vulnérabilité RCE dans PostgreSQL via PL/Perl et PL/Rust. Découvrez comment AWS RDS a réagi et comment sécuriser votre environnement Postgres.

 

Veuillez noter que cet article a été traduit avec l'aide de l'IA et révisé par un traducteur humain.

Tal Peleg
9 minute de lecture
Dernière mise à jour 2 juin 2025

Dans le cadre de nos recherches en cours sur la sécurité des données, Varonis Threat Labs a découvert une vulnérabilité d'exécution de code à distance (RCE) dans le logiciel de base de données PostgreSQL, qui exploite plusieurs vulnérabilités trouvées dans les extensions PostgreSQL.

Une vulnérabilité RCE permet à un attaquant d'exécuter des commandes arbitraires sur le système d'exploitation sous-jacent du serveur de base de données. Une attaque réussie pourrait entraîner l'exfiltration et la destruction de données, ainsi que permettre à l'attaquant d'obtenir un vecteur d'accès initial à votre réseau.

Contexte

Nos chercheurs ont découvert une vulnérabilité dans PL/Perl, une extension de langage de confiance intégrée à de nombreuses distributions par défaut de Postgres. En plus d'une vulnérabilité dans l'extension Postgres PL/Rust, cette primitive pourrait être exploitée pour une exécution de code à distance (RCE), ce qui pourrait entraîner l'exfiltration de données, la destruction de données et de nouveaux mouvements dans le réseau.

Bien que la vulnérabilité que nous avons identifiée se trouvait dans Postgres, l'environnement Amazon Relational Database Service (RDS) que nous avons testé n'était pas vulnérable à une attaque réussie. Lorsque nous avons exécuté la vulnérabilité sur Amazon RDS, avant que Postgres ne publie des correctifs, AWS a rapidement détecté et arrêté l'activité dans le cadre de ses protections automatisées.

Étant donné les protections supplémentaires (comme SELinux) que nous avons observées, les commandes tentées n'avaient aucune application pratique, car aucune information inter-base de données ou inter-client n'était accessible avant qu'AWS ne ferme notre base de données.

L'équipe Postgres a publié un avis et une solution au problème le 14 novembre 2024, et AWS a émis la déclaration suivante le 6 mai 2025 :

AWS a confirmé qu'Amazon Relational Database Service (RDS) et que les services Aurora n'ont pas été affectés par le problème. Par mesure de précaution, nous encourageons les clients à mettre à jour vers la dernière version applicable à leur environnement. Ces mises à jour sont disponibles via la [console de gestion AWS, AWS CLI ou l'API RDS].

Nous tenons à remercier Varonis pour sa collaboration sur cette recherche dans le cadre du processus de divulgation coordonnée.

- Amazon Web Services (AWS)

 

De manière générale, nous recommandons aux clients Postgres de mettre à jour leurs bases de données PostgreSQL. Les clients Postgres autonomes non gérés utilisant PL/Rust doivent mettre à jour l'extension vers la dernière version et surveiller les logs d'erreurs de leur base de données pour détecter toute activité suspecte.

Poursuivez votre lecture pour en savoir plus sur la vulnérabilité RCE dans PostgreSQL et comment nos chercheurs ont effectué des tests de vulnérabilité sur Amazon RDS.

Recherche de vulnérabilités dans Amazon RDS

Amazon RDS est un service de base de données entièrement géré qui prend en charge plusieurs bases de données relationnelles courantes, y compris Postgres.

Il est important de se rappeler que dans le cadre du modèle de responsabilité partagée, AWS gère la sécurité du serveur de base de données et du cluster, tandis que les clients d'Amazon RDS sont responsables de la configuration et de la sécurisation de l'accès au réseau, du contrôle d'accès à la base de données et des données elles-mêmes.

L'accès le plus privilégié que les utilisateurs d'Amazon RDS peuvent avoir est le rôle rds_superadmin géré par AWS. Contrairement à son nom, cet accès n'est pas un superadministrateur Postgres. Le rôle rds_superadmin ne peut pas interagir avec le système d'exploitation, ouvrir des connexions réseau personnalisées, écrire des fonctions non approuvées, et ne peut pas lire ou écrire des fichiers sur le disque.

Lors de notre test, nous avons d'abord examiné l'élévation des privilèges dans une base de données Amazon Aurora PostgreSQL 17. Selon AWS, « Aurora comprend un sous-système de stockage haute performance. Ses moteurs de base de données compatibles avec MySQL et PostgreSQL sont personnalisés pour tirer parti de ce stockage distribué rapide. »

Cela crée un domaine d'intérêt supplémentaire pour que nous recherchions des vulnérabilités dans l'intégration AWS du PostgreSQL open source avec le service géré.

Nous avons choisi de suivre une méthode courante consistant à exploiter une vulnérabilité dans une extension Postgres pour interagir avec le système ou exécuter une commande en tant que superutilisateur de la base de données. L'extension PL/Perl a retenu notre attention car elle est maintenue par PostgreSQL et incluse d'emblée dans les versions par défaut de Postgres, y compris Amazon RDS et Amazon Aurora.

Primitive initiale : modification des variables d'environnement avec PL/Perl

PL/Perl est une extension de langage fiable pour PostgreSQL qui permet d'écrire des fonctions et des procédures PostgreSQL en Perl, un langage procédural couramment utilisé pour convertir ou traiter de grandes quantités de données.

La documentation PostgreSQL indique : «Normalement, PL/Perl est installé en tant que langage de programmation « fiable » nommé plperl. Dans cette configuration, certaines opérations Perl sont désactivées pour préserver la sécurité. En général, les opérations qui sont limitées sont celles qui interagissent avec l'environnement. »

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.

Nous nous sommes demandé si nous pouvions jouer avec les variables d’environnement, car cela donne souvent des résultats intéressants. En écrivant une fonction plperl fiable, nous avons utilisé la syntaxe suivante pour définir les variables d'environnement :

A pl/perl function that sets an environment variable
00_PLPERL_FUNCTION_SET_ENV
A pl/perl function that sets an environment variable

Et ça a marché !

Les fonctions Postgres sont exécutées dans le contexte d'une session PostgreSQL. Lorsqu'un client se connecte à une base de données PostgreSQL, le processus principal de PostgreSQL lance un processus de travail pour gérer la session de base de données connectée. La vulnérabilité dans PL/Perl nous a permis de définir des variables d'environnement sur les processus de travail de session.

Il nous fallait maintenant trouver un moyen d'élever cette primitive, qui consiste à définir les variables d'environnement d'un processus de travail PostgreSQL, au rang de RCE. Il existe de multiples techniques pour exécuter du code arbitraire en manipulant des variables d'environnement, que nous avons décidé de ne pas utiliser.

  1. Les variables d'environnement peuvent être utilisées pour définir les paramètres de configuration de Postgres et de ses extensions, ce qui peut entraîner l'exécution d'un code arbitraire lorsque les extensions sont chargées. Cependant, celles-ci sont normalement chargées par le processus principal de Postgres avant qu'un processus de travail ne soit forké, et nous ne pouvons donc pas affecter les variables d'environnement dans ce contexte. De plus, les commandes SQL sensibles et la plupart des extensions Postgres s'exécutent dans des processus en sandbox et effectuent des tâches en arrière-plan en utilisant la fonctionnalité intégrée de Postgres pour générer des processus de travail à partir du processus principal de Postgres, de sorte qu'elles ne sont pas affectées par les modifications de notre environnement.
  2. Les variables d'environnement courantes telles que PATH et LD_PRELOAD sont des méthodes connues pour exécuter du code arbitraire. La variable d'environnement PATH indique au système d'exploitation où chercher les fichiers binaires lorsqu'ils sont exécutés avec des noms relatifs au lieu de chemins complets, tandis que LD_PRELOAD indique aux processus Linux de charger un objet stocké sur le disque avant d'exécuter un nouveau processus. Ces deux méthodes peuvent être utilisées pour exécuter des fichiers binaires arbitraires, mais elles nécessitent l'écriture d'un fichier sur le serveur, et nous voulions quelque chose de plus simple.

Nous avons recherché des invocations de processus que nous pouvions utiliser dans les dépôts GitHub de Postgres et son extension disponible dans Amazon RDS.

More from Varonis Threat Labs.
See more
Image_AttackersPlaybook_202408 (1)

PL/Rust — Utilisation de la primitive PL/Perl pour exécuter du code

La nouvelle version de PL/Rust est une extension de langage fiable permettant d'écrire des fonctions Postgres dans le langage de programmation Rust. Il est pris en charge par Amazon RDS, mais pas par Amazon Aurora.

Pour installer PL/Rust, qui est un langage compilé, sur une instance Postgres, le kit de développement du langage doit être installé sur le serveur. Il contient un compilateur, rustc, et cargo — le gestionnaire de paquets de Rust. Lors de la création d'une fonction plrust, l'extension, également écrite en Rust, exécute le processus de compilation à partir de la session actuelle de l'utilisateur Postgres, en héritant du même environnement. Cela signifie que lorsque nous créons une fonction PostgreSQL dans le langage plrust, « cargo build » est exécuté en utilisant nos variables d'environnement modifiées.

Cargo inherits environment variables we can control from the PostgreSQL worker process
01_SAFETY_ENV_INHERITANCE
Cargo inherits environment variables we can control from the PostgreSQL worker process

À ce stade, l'utilisation des méthodes d'exécution de code mentionnées précédemment nécessiterait le chargement de fichiers sur le serveur. Notre cible étant RDS, ce n'était pas une option.

Au lieu de cela, nous avons examiné les variables d’environnement qui configurent cargo pendant le processus de compilation. L'extension PL/Rust supprime plusieurs variables d'environnement problématiques avant d'exécuter cargo. Cependant, de nombreuses variables d'environnement ne sont pas effacées par plrust ni mentionnées dans la documentation de plrust. L'une de ces variables nous a permis de faire exécuter n'importe quel fichier binaire de notre choix par cargo.

This is PL/Rust clears some sensitive environment variables before executing cargo
02_CARGO_CODE
This is PL/Rust clears some sensitive environment variables before executing cargo

Cette opération seule ne permettait pas une exécution de code sans restriction car elle ne fournissait pas de contrôle sur les arguments de la ligne de commande. Pour contourner cela, nous avions besoin d'un fichier binaire qui exécute les commandes à partir des variables d'environnement avant d'analyser les arguments de la ligne de commande. Nous l'avons spécifiquement configuré pour utiliser un autre fichier binaire inclus dans la version par défaut de PL/Rust, rust-gdb, utilisé pour le débogage des applications Rust. rust-gdb, lorsqu'il lit la variable d'environnement RUST_GDB, ignore complètement les arguments de ligne de commande et utilise la valeur de la variable pour déterminer quel fichier binaire exécuter, et peut contrôler entièrement les arguments de ligne de commande.

Dans cargo (en haut), si une variable d'environnement wrapper est définie, exécutez-la au lieu de lire la variable d'environnement rustc ; dans rust-gdb (en bas), si RUST_GDB est défini, remplacez tous les arguments de la ligne de commande.

03_WRPPER_CODE

Dans cargo (en haut), si une variable d'environnement wrapper est définie, exécutez-la au lieu de lire la variable d'environnement rustc ; dans rust-gdb (en bas), si RUST_GDB est défini, remplacez tous les arguments de la ligne de commande.

Cela nous a permis d'exécuter du code sur notre laboratoire PostgreSQL.

En utilisant une fonction PL/Perl qui définit les arguments de la ligne de commande, puis construit une fonction PL/Rust, en invoquant cargo, qui lance rust-gdb à la place du compilateur rust par défaut. rust-gdb invoque à son tour la commande « id » spécifiée dans la variable d'environnement RUST_GDB, produisant la sortie dans stdout, comme présentée par Postgres lorsque le processus de compilation échoue.

04_LAB_RCE

En utilisant une fonction PL/Perl qui définit les arguments de la ligne de commande, puis construit une fonction PL/Rust, en invoquant cargo, qui lance rust-gdb à la place du compilateur rust par défaut. rust-gdb invoque à son tour la commande « id » spécifiée dans la variable d'environnement RUST_GDB, produisant la sortie dans stdout, comme présentée par Postgres lorsque le processus de compilation échoue.

Blog_VTL-RustyPearl_Diagram1_202505_V2 (1)

L'impact de l'exécution de code arbitraire sur Amazon RDS

De retour dans le cloud, nous avons tenté d’exploiter cette vulnérabilité sur notre serveur Amazon RDS, mais nous avons constaté que rust-gdb manquait de certains fichiers binaires qu’il s’attendait à trouver et qu’il n’exécutait pas notre commande shell. Nous avons donc décidé d'utiliser /bin/bash à la place.

Bien que Bash n'accepte pas les arguments de la ligne de commande transmis par PL/Rust, la variable d'environnement BASH_ENV indique à Bash de charger et d'exécuter un script d'initialisation shell avant d'analyser la ligne de commande. C'est exactement comme la façon dont rust-gdb analyse et exécute la variable RUST_GDB avant de lire les arguments de la ligne de commande.

La valeur de BASH_ENV est soumise à l'expansion des paramètres, à la substitution des commandes et à l'expansion arithmétique avant d'être interprétée comme un nom de fichier. Définir la variable d’environnement sur « $(command 2>&1) » provoquera l’exécution de command et l’affichage de sa sortie dans stderr, qui est renvoyée par la compilation d’une fonction plrust lorsqu’elle échoue.

Grâce à cette méthode, nous avons pu exécuter la commande avec succès ! En raison des restrictions de sécurité en place, nous n'avons pas eu l'autorisation d'accéder à des emplacements de données sensibles d'Amazon RDS ni d'effectuer un accès réseau en exploitant cette vulnérabilité.

Néanmoins, les clients devraient mettre à jour leurs bases de données et surveiller les logs d'erreurs pour détecter toute activité suspecte.

PoC execution of commands, without function code, showing proof of RCE on Amazon RDS
05_RDS_RCE
PoC execution of commands, without function code, showing proof of RCE on Amazon RDS

Recommandations pour les clients Postgres

Nous recommandons aux clients Postgres de mettre à jour leurs bases de données vers la dernière version mineure au minimum, qu'ils utilisent un déploiement autonome ou un déploiement dans le cloud géré comme avec Amazon RDS. Les utilisateurs de bases de données autonomes avec PL/Rust doivent mettre à jour cette extension avec la dernière version et supprimer les outils de débogage tels que rust-gdb des environnements de production.

Bien que dans ce cas nous ayons utilisé plrust pour exécuter du code, d'autres extensions, y compris des extensions personnalisées, peuvent également être affectées.

Les administrateurs de bases de données doivent bloquer l'installation des extensions qu'ils n'utilisent pas en les excluant du paramètre de configuration de la base de données rds.allowed_extensions.

Par exemple, voici des instructions pour bloquer l'installation d'extensions inutilisées dans Amazon RDS :

  1. Connectez-vous à la console de gestion AWS et ouvrez la console Amazon RDS à l'adresse https://console.aws.amazon.com/rds/.
  2. Sélectionnez la base de données PostgreSQL existante que vous souhaitez modifier.
  3. Sous l’onglet « Configuration », localisez le groupe de paramètres attaché au
  4. S'il s'agit d'un groupe de paramètres par défaut, vous devrez créer un nouveau groupe de paramètres et le rattacher à l'instance, puisque la valeur par défaut du paramètre rds.allowed_extensions autorise toutes les extensions.
  5. Sinon, vous pouvez utiliser ce guide pour modifier le paramètre.
  6. Assurez-vous que le paramètre allowed_extensions inclut uniquement les extensions que vous approuvez pour l'exécution sur votre base de données.

Conclusion

Il est important de se rappeler que bien qu'AWS fournisse des outils de sécurité à ses clients pour une utilisation avec RDS, il incombe toujours aux clients cloud d'appliquer les meilleures pratiques de sécurité lors du déploiement et de la configuration de leurs ressources, du contrôle d'accès, de l'accès réseau, ainsi que de la conformité et de la protection des données.

Amazon RDS fournit aux clients des ressources supplémentaires sur les bonnes pratiques de sécurité.

Vous avez besoin d'aide pour sécuriser votre environnement AWS ? Découvrez Varonis pour AWS et planifiez une démonstration pour voir la solution à l'oeuvre.

Que dois-je faire maintenant ?

Vous trouverez ci-dessous trois solutions pour poursuivre vos efforts visant à réduire les risques liés aux données dans votre entreprise:

1

Planifiez une démonstration avec nous pour voir Varonis en action. Nous personnaliserons la session en fonction des besoins de votre organisation en matière de sécurité des données et répondrons à vos questions.

2

Consultez un exemple de notre évaluation des risques liés aux données et découvrez les risques qui pourraient subsister dans votre environnement. Cette évaluation est gratuite et vous montre clairement comment procéder à une remédiation automatisée.

3

Suivez-nous sur LinkedIn, YouTube et X (Twitter) for pour obtenir des informations sur tous les aspects de la sécurité des données, y compris la DSPM, la détection des menaces, la sécurité de l’IA et plus encore.

Essayez Varonis gratuitement.

Obtenez un rapport détaillé sur les risques liés aux données basé sur les données de votre entreprise.
Se déploie en quelques minutes.

Keep reading

Varonis tackles hundreds of use cases, making it the ultimate platform to stop data breaches and ensure compliance.

effraction-et-réentrée :-anatomie-d'une-attaque-bec-m365-résiliente-utilisant-les-connecteurs-entrants 
Effraction et réentrée : anatomie d'une attaque BEC M365 résiliente utilisant les connecteurs entrants 
Varonis a découvert une attaque BEC exploitant les outils d'administration de Microsoft 365, révélant des méthodologies avancées d'attaquants et une exploitation des privilèges administratifs.
un-rapport-sur-la-sécurité-des-données-révèle-que-99-%-des-organisations-ont-des-informations-sensibles-exposées-à-l'ia
Un rapport sur la sécurité des données révèle que 99 % des organisations ont des informations sensibles exposées à l'IA
Le rapport 2025 de Varonis sur l'état de la sécurité des données présente les résultats basés sur l'étude de 1 000 environnements informatiques réels, afin de révéler le côté obscur de l'essor de l'IA et les mesures proactives que les organisations peuvent mettre en œuvre pour sécuriser les informations critiques.
explorer-l’infrastructure-en-tant-que-code :-explication-détaillée 
Explorer l’infrastructure en tant que code : explication détaillée 
Découvrez comment l’infrastructure en tant que code (IaC) renforce la sécurité, simplifie les opérations et optimise la gestion de l’infrastructure.