From c510aa1da58409e0d3098f86d311c964805399e2 Mon Sep 17 00:00:00 2001 From: pirahnasa Date: Wed, 18 Dec 2024 10:45:50 +0100 Subject: [PATCH 1/2] Add version detection for cleo cve-2024-55956 --- agent/exploits/cve_2024_55956.py | 43 ++++++++++++++++ tests/exploits/cve_2024_55956_test.py | 73 +++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 agent/exploits/cve_2024_55956.py create mode 100644 tests/exploits/cve_2024_55956_test.py diff --git a/agent/exploits/cve_2024_55956.py b/agent/exploits/cve_2024_55956.py new file mode 100644 index 0000000..aa2ee97 --- /dev/null +++ b/agent/exploits/cve_2024_55956.py @@ -0,0 +1,43 @@ +"""Agent Asteroid implementation for CVE-2024-55956""" + +import re + +from packaging import version + +from agent import definitions +from agent import exploits_registry +from agent.exploits import webexploit + +VERSION_PATTERN = re.compile( + r"(?:VLTrader|Harmony|LexiCom)/((?:[0-4](?:\.\d+){0,3})|5(?:\.[0-7](?:\.\d{1,2}){0,2})?|5\.8(?:\.0(?:\.(?:0|[1-9]|1[0-9]|2[0-3]))?)?)\s*\(" +) +MAX_VULNERABLE_VERSION = version.parse("5.8.0.23") +MIN_VULNERABLE_VERSION = version.parse("0.0.0") +VULNERABILITY_TITLE = ( + "Cleo Harmony, VLTrader, and LexiCom - Arbitrary Command Execution via Autorun Directory" +) +VULNERABILITY_REFERENCE = "CVE-2024-55956" +VULNERABILITY_DESCRIPTION = ( + "In Cleo Harmony before 5.8.0.24, VLTrader before 5.8.0.24, and LexiCom before " + "5.8.0.24, an unauthenticated user can import and execute arbitrary Bash or PowerShell " + "commands on the host system by leveraging the default settings of the Autorun directory." +) +RISK_RATING = "CRITICAL" + + +@exploits_registry.register +class CVE202455956Exploit(webexploit.WebExploit): + accept_request = definitions.Request(method="GET", path="/") + check_request = definitions.Request(method="GET", path="/") + accept_pattern = [re.compile(r"Cleo (VLTrader|Harmony|LexiCom)/[\d.]+")] + version_pattern = VERSION_PATTERN + vuln_ranges = [ + definitions.VulnRange(MIN_VULNERABLE_VERSION, MAX_VULNERABLE_VERSION) + ] + + metadata = definitions.VulnerabilityMetadata( + title=VULNERABILITY_TITLE, + description=VULNERABILITY_DESCRIPTION, + reference=VULNERABILITY_REFERENCE, + risk_rating=RISK_RATING, + ) diff --git a/tests/exploits/cve_2024_55956_test.py b/tests/exploits/cve_2024_55956_test.py new file mode 100644 index 0000000..f120e4d --- /dev/null +++ b/tests/exploits/cve_2024_55956_test.py @@ -0,0 +1,73 @@ +"""Unit tests for Agent Asteroid: CVE-2024-55956""" + +import requests_mock as req_mock +from ostorlab.agent.mixins import agent_report_vulnerability_mixin as vuln_mixin + +from agent import definitions +from agent.exploits import cve_2024_55956 + +def testCVE202455956_whenVulnerable_reportFinding( + requests_mock: req_mock.mocker.Mocker, +) -> None: + """CVE-2024-55956 unit test: case when target is vulnerable.""" + requests_mock.get( + "http://localhost:80/", + text="Cleo VLTrader/5.8.0.22 (Build 12345)", + status_code=200, + ) + exploit_instance = cve_2024_55956.CVE202455956Exploit() + target = definitions.Target("http", "localhost", 80) + + accept = exploit_instance.accept(target) + vulnerabilities = exploit_instance.check(target) + + assert accept is True + assert len(vulnerabilities) > 0 + vulnerability = vulnerabilities[0] + assert ( + vulnerability.entry.title + == "Cleo Harmony, VLTrader, and LexiCom - Arbitrary Command Execution via Autorun Directory" + ) + assert vulnerability.technical_detail == ( + "http://localhost:80 is vulnerable to CVE-2024-55956, Cleo Harmony, VLTrader, and LexiCom -" + " Arbitrary Command Execution via Autorun Directory" + ) + assert vulnerability.risk_rating == vuln_mixin.RiskRating.CRITICAL + + +def testCVE202455956_whenSafe_reportNothing( + requests_mock: req_mock.mocker.Mocker, +) -> None: + """CVE-2024-55956 unit test: case when target is safe.""" + requests_mock.get( + "http://localhost:80/", + text="Cleo VLTrader/5.8.0.24 (Build 12345)", + status_code=200, + ) + exploit_instance = cve_2024_55956.CVE202455956Exploit() + target = definitions.Target("http", "localhost", 80) + + accept = exploit_instance.accept(target) + vulnerabilities = exploit_instance.check(target) + + assert accept is True + assert len(vulnerabilities) == 0 + + +def testCVE202455956_whenTargetNotCleoProduct_reportNothing( + requests_mock: req_mock.mocker.Mocker, +) -> None: + """CVE-2024-55956 unit test: case when target is not a Cleo product.""" + requests_mock.get( + "http://localhost:80/", + text="Not Found", + status_code=404, + ) + exploit_instance = cve_2024_55956.CVE202455956Exploit() + target = definitions.Target("http", "localhost", 80) + + accept = exploit_instance.accept(target) + vulnerabilities = exploit_instance.check(target) + + assert accept is False + assert len(vulnerabilities) == 0 From 3985c2b78e650452e41fd1bea1ef8ca39d90cd35 Mon Sep 17 00:00:00 2001 From: pirahnasa Date: Wed, 18 Dec 2024 10:48:07 +0100 Subject: [PATCH 2/2] Add version detection for cleo cve-2024-55956 --- agent/exploits/cve_2024_55956.py | 4 +--- tests/exploits/cve_2024_55956_test.py | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/agent/exploits/cve_2024_55956.py b/agent/exploits/cve_2024_55956.py index aa2ee97..ebfbe84 100644 --- a/agent/exploits/cve_2024_55956.py +++ b/agent/exploits/cve_2024_55956.py @@ -13,9 +13,7 @@ ) MAX_VULNERABLE_VERSION = version.parse("5.8.0.23") MIN_VULNERABLE_VERSION = version.parse("0.0.0") -VULNERABILITY_TITLE = ( - "Cleo Harmony, VLTrader, and LexiCom - Arbitrary Command Execution via Autorun Directory" -) +VULNERABILITY_TITLE = "Cleo Harmony, VLTrader, and LexiCom - Arbitrary Command Execution via Autorun Directory" VULNERABILITY_REFERENCE = "CVE-2024-55956" VULNERABILITY_DESCRIPTION = ( "In Cleo Harmony before 5.8.0.24, VLTrader before 5.8.0.24, and LexiCom before " diff --git a/tests/exploits/cve_2024_55956_test.py b/tests/exploits/cve_2024_55956_test.py index f120e4d..7b28640 100644 --- a/tests/exploits/cve_2024_55956_test.py +++ b/tests/exploits/cve_2024_55956_test.py @@ -6,6 +6,7 @@ from agent import definitions from agent.exploits import cve_2024_55956 + def testCVE202455956_whenVulnerable_reportFinding( requests_mock: req_mock.mocker.Mocker, ) -> None: