Skip to content

Chiffrement et sécurité des échanges MySQL, vous y pensez ?

Nombreux sont ceux qui possèdent un serveur web « dans le cloud », mutualisé ou tout simplement sur un réseau distant et qui le managent à distance. La ligne de commande MySQL peut avoir ses avantages : rapidité, précision, clarté… La possibilité d’ouvrir les services MySQL sur l’extérieur pour manager, questionner ou backuper son serveur fait partie des avantages de ce service. Néanmoins, on oublie souvent la sécurité des échanges MySQL. En effet, ces échanges transitent sur un réseau et ils transportent des informations qui sont très intéressantes pour des personnes qui traînent un peu trop leurs yeux.

Sniff des paquets MySQL

On peut retrouver plusieurs contextes dans lesquels on est amené à faire transiter des paquets utilisant le protocole MySQL, ces échanges qui passent (par défaut) par le port 3306 du serveur. Par exemple :

  • Une personne effectuant des manipulations en ligne de commande MySQL sur un serveur distant, sur un autre site, ou un serveur mutualisé par exemple
  • Un réseau dans lequel le serveur web et le serveur MySQL ne sont pas la même machine, auquel cas le serveur web doit aller questionner le serveur MySQL via le réseau
  • Un réseau dans lequel une machine effectue une sauvegarde des bases de données via le réseau (on évite souvent de positionner les backups/archives d’une base de données sur le serveur de base de données…), la réplication entre deux hôtes MySQL peut aussi permettre une récupération du contenu des paquets.
  • De manière plus vicieuse, les informations qui transitent lorsqu’un serveur de monitoring vérifie l’état de santé d’un serveur MySQL, nombre de requêtes par seconde, uptime, taille d’une base de données…

Nous allons étudier un peu la question ici et voir ce que l’on peut trouver (facilement) dans des échanges réseau MySQL. Le but étant de montrer la facilité d’avoir des informations ainsi que sensibiliser les lecteurs (vous !) à l’utilisation du chiffrement. On prendra également un peu de recul en voyant que le chiffrement peut aussi avoir ses inconvénients et que d’autres possibilités peuvent être étudiées pour manager, monitorer, sauvegarder ou gérer son serveur MySQL via le réseau.

Tout d’abord, nous allons mettre en place un petit LAN dans lequel nous ferons des tests. Le but étant de voir quelques cas d’architecture et cas de connexion au serveur dans lesquels la récupération des données est possible.

Il est commun de trouver des serveurs sur les réseaux qui centralisent les sauvegardes et les archives d’un serveur de base de données. Le cas le plus simple étant que la sauvegarde s’effectue via le protocole MySQL à distance sur le serveur. Les données sauvegardées passent alors tout simplement en clair sur le réseau. Un serveur web ou un client MySQL qui interroge une base de données à distance via le port 3306 (MySQL) fait également passer les requêtes ainsi que les réponses en clair sur le réseau.

attaque mitm mysql
Schéma d’un contexte de sniff réseau et d’attaque MITM

Un cas un peu plus poussé lorsqu’il s’agit du monitoring, les informations de monitoring peuvent ne sembler avoir aucune importance. Cependant en MySQL, elles peuvent divulguer des informations comme des noms de table et de base de données, le nom des utilisateurs utilisés pour aller questionner le serveur et le hash du mot de passe. Aussi anodin que peu paraître la supervision, son utilisation est également à sécuriser.

Sur ce premier schéma, on voit l’utilisation standard que l’on peut faire de l’accès MySQL distant, un premier serveur de base de données est ouvert sur l’extérieur (il n’écoute pas qu’en localhost), il faut bien sûr également qu’un utilisateur ait les droits d’accès au serveur depuis l’extérieur pour que les échanges puissent se faire. On voit également un serveur faisant office de client web, client MySQL ou simplement un serveur de monitoring ou de sauvegarde qui va aller envoyer des requêtes au serveur. Un pirate peut alors, plus ou moins aisément, aller s’interposer entre les deux entités pour sniffer ce qu’il s’y passe. Les techniques de MITM permettant une telle capture des données sont nombreuses, nous verrons cependant quelques techniques de protection un peu plus tard.

attaque mitm
Points vulnérables d’une attaque Man in the middle

Sur ce second schéma on retrouve un cas qui peut être plus souvent vu, nous disposons d’un serveur MySQL à l’extérieur du LAN (sur un espace mutualisé par exemple) et un client qui passe par un LAN, puis par internet pour aller le manager et le gérer. Un pirate sur le LAN (mais aussi dans l’espace mutualisé ou entre les deux, plus difficilement) aller intercepter les échanges MySQL. Un tel accès depuis un LAN qui n’est pas de confiance (public, université…) peut facilement cacher des postes malveillants capables d’intercepter le trafic.

Sécurité des échanges MySQL : cas d’étude d’un sniff réseau

Le fait est que la capture de paquets réseau (sniff) transportant du MySQL permet de lire et de déduire assez facilement un grand nombre d’informations. Les méthodes pour effectuer un sniff des paquets sera un problème dont nous ne parlerons pas ici, car il existe de multiples méthodes de le faire, mirroring depuis un switch via Mac flooding, ARP spoofing…

Nous allons ici voir ce que l’on peut réellement trouver dans les paquets que nous récupérons. Pour information, j’ai fait mes tests via un simple ARP spoofing entre les deux hôtes et en activant l’IP forwarding. J’ai installé un WordPress et un owncloud sur le premier serveur (web) ainsi qu’une base de données utilisée uniquement en CLI (pas d’appli web derrière). Avec mon poste pirate, je vais simplement me positionner entre les deux lors des échanges, faire un filtre sur le protocole MySQL et regarder ce que j’ai récupéré.

On va tout d’abord analyser une simple connexion à une base de données distante via un client MySQL :

wireshark mysql

mysql sniff attaque
Vue du mot de passe hashé dans un paquet mysql

Si l’on fouille un peu ce paquet, on voit les mêmes informations, mais en plus un password qui semble être hashé, qui passe également en clair :

Enfin si l’on effectue une requête simple, on la voit passer en clair, ce qui est logique également.

mysql sniff
On voit ici que le paquet transporte une requête MySQL (Query) et on voit également la requête en clair, ce qui peut nous donner des informations très intéressantes sur la structure finale de la base de données (table/attribut).

À partir de ce genre d’analyse, on peut voir qu’il est très facile, lorsqu’aucune mesure de sécurité n’est prise, de voir les informations qui transitent dans les échanges MySQL. Ce genre d’information peut par exemple servir à un attaquant dans le cadre de SQL Injection où il s’agit le plus souvent de deviner la structure d’une table. Plus généralement, voir le nom des tables et des attributs permet de déduire quel service tourne sur le serveur web, on peut par exemple facilement voir s’il s’agit d’une application de comptabilité, d’un WordPress, ses plug-ins, d’un owncloud , etc. Cela vient du fait que les tables portent souvent des noms qui permettent de les reconnaître.

Pour pousser les tests un peu plus loin, j’ai écrit un script Python avec la librairie orientée réseau Scapy. Celui-ci prend en entrée un fichier pcap ou un temps durant lequel il va sniffer le réseau et va ensuite partir à la recherche de « Query » MySQL afin d’essayer de trier le nom des tables et de leurs attributs ainsi que d’autres informations que l’on peut trouver dans les analyses que nous venons de voir. Il est alors très facile de reconstituer une partie d’une base de données (moins de sa structure) :

script sniff mysql
Résultat d’un script Pyhon sniffant et affichant les tables et champs mysql sniffés.

On peut également plus simplement parser ce que l’on récupère avec le sniff Scapy (ou Wireshark, tcpdump ou autre), pour n’afficher que les requêtes cette fois-ci en entier :

mysql sniff attaque
Ici, je récupère le « Raw » des paquets ce qui me permet de n’avoir que les requêtes, après quelques remises en forme, j’affiche les requêtes à la suite ce qui permet d’en extraire un grand nombre d’informations.

Protections : chiffrement et bonnes habitudes

Nous avons vu que les requêtes et échanges MySQL étaient facilement lisibles sur un réseau si aucune mesure de sécurité n’était prise.  Bien évidemment, les architectures et les cas présentés ici ne représentent pas 100% des cas, certains cas sont plus soucieux de la sécurité et de la performance de leur serveur, d’autres beaucoup moins. Nous allons à présent voir quelques techniques qui pourront nous permettre d’éviter des cas comme ceux vus plus haut.

  • Tout d’abord, pour les accès distants comme le fait de manager son serveur en CLI à distance via le port 3306, les sauvegardes ou les réplications ou encore le simple accès d’un serveur web à un serveur de base de données via le réseau, il est envisageable de mettre en place du SSL afin de chiffrer ces communications. Le SSL ne va pas empêcher la capture des paquets, mais va empêcher le pirate de comprendre les informations qui s’y trouvent. Le chiffrement des échanges assure une sécurité des données MySQL. Il faut également savoir qu’une fois le SSL mis en place, on garde le choix d’y accéder en mode sécurisé ou en mode clair (en cas d’urgence ou de problème).

Pourquoi le SSL n’est il pas mis en place systématiquement ? Il semblerait logique que ce soit le cas, mais le principal fait est que le chiffrement des requêtes côté client , le déchiffrement coté serveur, le chiffrement des réponses puis leur déchiffrement prend du temps. Le temps de chargement d’une page web pour le client sera alors forcément augmenté, d’une façon plus ou moins visible. Les serveurs web d’aujourd’hui se doivent d’être rapide pour un tas de raison (référencement, satisfaction utilisateur) et ajouter une charge de chiffrement/déchiffrement pour chaque requête peut devenir un luxe. Toutefois pour certains accès comme la supervision, le management à distance en CLI, les sauvegardes ou la réplication, il est fortement conseillé de mettre en place un accès chiffré vers le port 3306.

  • L’utilisation du SSH peut également être un atout, puisque tout ce qui passe dans le flux SSH est forcément chiffré, le pirate ne saura alors même pas distinguer les paquets contenant du MySQL des autres. Cela ne peut bien sûr pas être mis en place dans tout les cas, mais on peut aisément imaginer un système de supervision MySQL via SSH qui établit la communication SSH puis qui émet les requêtes directement en local sur le serveur.
  • Plus simplement, plutôt que de protéger le contenu des paquets, il peut également être possible de protéger leur accès en empêchant le pirate de les lire, plusieurs techniques permettent d’éviter que les paquets soient sniffés. On peut par exemple simplement, pour éviter l’ARP spoofing, mettre en place des enregistrements ARP fixes.

Résoudre le problème dans l’architecture en mettant le serveur MySQL derrière le serveur web et sur aucun autre réseau est aussi une possibilité, les protections par l’architecture sont nombreuses :

SniffMySQL08Il est fréquent de croiser ce genre d’architecture, pour des questions de performance, le serveur MySQL est directement relié au serveur web, le pirate est donc incapable de sniffer le réseau entre les deux afin de récupérer les informations. Dans la même logique, les solutions de virtualisation peuvent également protéger les serveurs d’un sniff réseau. L’essentiel à retenir est de savoir où passent les flux, comment, et d’avoir une vue complète de l’ensemble, quand un accès distant est rendu possible, la sécurité de celui-ci doit être correctement évaluée et cadrée !

N’hésitez pas à partager votre ressenti sur cet article ainsi que vos idées pour la sécurisation des accès distants MySQL dans les commentaires !

Partager :
Published inArticlesComprendre l'Infosec

4 Comments

  1. JBL

    Effectivement, cela peut être problématique. Je partage également ton analyse sur le fait qu’il faut protéger ces flux s’ils sont exposés aux Sniffs ou aux MATM. Toutefois ces cas sont rares, et les seuls que j’ai rencontrés était effectivement des serveurs d’université à dispo des étudiants, qui y faisait souvent n’importe quoi, et dont le SSL n’était de toutes façon pas activé 🙂
    Par ailleurs, il y a effectivement un gros biais si on envoie les sauvegardes des bases sur des serveurs FTP tout pourris. Ça c’est un point faible souvent laissé de côté !

  2. Der Joker

    Salut,
    Super article ! très intéressant. Pourrais tu publier ton script en python pour mysql ? Je suis pentesteur et ce genre de chose pourrait me faciliter la vie…. Je te remercie.

  3. SecuIP

    Pour ne pas citer un lien IPsec entre le svr web et le svr bdd ? Simple et sur !

    • Ogma_Sec

      Oui cela peut être envisagé dans les cas où l’on manage notre serveur à distance en ligne de commande (via le port 3306). Néanmoins pour une liaison serveur web – serveur base de données, il faut prendre en compte que le chiffrement/déchiffrement ralentira grandement le temps d’affichage d’une page. Mais on en a généralement moins besoin dans ce second cas. 🙂

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *