Skip to content

Commit

Permalink
Merge pull request #46 from Ostorlab/exploit/CVE-2024-21733
Browse files Browse the repository at this point in the history
Add detection for: CVE-2024-21733
  • Loading branch information
3asm authored Feb 1, 2024
2 parents 8f9f5be + dd10df7 commit d255242
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 0 deletions.
120 changes: 120 additions & 0 deletions agent/exploits/cve_2024_21733.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
"""Agent Asteroid implementation for CVE-2024-21733"""
import re
from urllib import parse as urlparse

import requests
from ostorlab.agent.kb import kb
from ostorlab.agent.mixins import agent_report_vulnerability_mixin
from packaging import version
from requests import exceptions as requests_exceptions

from agent import definitions
from agent import exploits_registry

VULNERABILITY_TITLE = "Apache Tomcat HTTP Request Smuggling (Client- Side Desync)"
VULNERABILITY_REFERENCE = "CVE-2024-21733"
VULNERABILITY_DESCRIPTION = (
"Apache Tomcat from 8.5.7 through 8.5.63, from 9.0.0-M11 through 9.0.43 are vulnerable to client-side de-sync "
"attacks. Client-side de-sync (CSD) vulnerabilities occur when a web server fails to correctly process the "
"Content-Length of POST requests. By exploiting this behavior, an attacker can force a victim's browser to "
"de-synchronize its connection with the website, causing sensitive data to be smuggled from the server and/or "
"client connections."
)

DEFAULT_TIMEOUT = 30
ACCEPT_ENDPOINTS = [
"/docs/RELEASE-NOTES.txt",
"/manager/status",
"/manager/html",
"/docs/introduction.html",
]
CHECK_ENDPOINTS = ["/docs/RELEASE-NOTES.txt", "/404", "/"]
VERSION_PATTERN = re.compile(r"(?i)Apache Tomcat.*([0-9]\.[0-9]+\.[0-9]+)")
VULNERABLE_RANGES = [
(version.parse("8.5.7"), version.parse("8.5.63")),
(version.parse("9.0.0"), version.parse("9.0.43")),
]
MAX_REDIRECTS = 2


# TODO (BlueSquare1): Improve detection as part of request smuggling research project (os-6717).
@exploits_registry.register
class CVE202421733Exploit(definitions.Exploit):
"""
CVE-2024-21733: Apache Tomcat HTTP Request Smuggling (Client- Side Desync)
"""

def accept(self, target: definitions.Target) -> bool:
session = requests.Session()
session.max_redirects = MAX_REDIRECTS
session.verify = False
for endpoint in ACCEPT_ENDPOINTS:
try:
resp = session.get(
urlparse.urljoin(target.origin, endpoint),
timeout=DEFAULT_TIMEOUT,
)
except requests_exceptions.RequestException:
continue
if resp.status_code != 404:
return True
return False

def check(self, target: definitions.Target) -> list[definitions.Vulnerability]:
session = requests.Session()
session.max_redirects = MAX_REDIRECTS
session.verify = False
for endpoint in CHECK_ENDPOINTS:
try:
resp = session.get(
urlparse.urljoin(target.origin, endpoint),
timeout=DEFAULT_TIMEOUT,
)
except requests_exceptions.RequestException:
continue

target_version_match = VERSION_PATTERN.search(resp.text)
if target_version_match is None:
continue

target_version = version.parse(target_version_match.group(1))
for version_range in VULNERABLE_RANGES:
if version_range[0] <= target_version <= version_range[1]:
vulnerability = self._create_vulnerability(target)
return [vulnerability]

return []

def _create_vulnerability(
self, target: definitions.Target
) -> definitions.Vulnerability:
entry = kb.Entry(
title=VULNERABILITY_TITLE,
risk_rating="CRITICAL",
short_description=VULNERABILITY_DESCRIPTION,
description=VULNERABILITY_DESCRIPTION,
references={
"nvd.nist.gov": f"https://nvd.nist.gov/vuln/detail/{VULNERABILITY_REFERENCE}",
"hackerone.com": "https://hackerone.com/reports/2327341",
},
recommendation=(
"- Make sure to install the latest security patches from software vendor \n"
"- Update to the latest software version"
),
security_issue=True,
privacy_issue=False,
has_public_exploit=True,
targeted_by_malware=False,
targeted_by_ransomware=False,
targeted_by_nation_state=False,
)
technical_detail = (
f"{target.origin} is vulnerable to {VULNERABILITY_REFERENCE}, "
f"{VULNERABILITY_TITLE}"
)
vulnerability = definitions.Vulnerability(
entry=entry,
technical_detail=technical_detail,
risk_rating=agent_report_vulnerability_mixin.RiskRating.CRITICAL,
)
return vulnerability
53 changes: 53 additions & 0 deletions tests/exploits/cve_2024_21733_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""Unit tests for Agent Asteroid: CVE-2024-21733"""
import re

import requests_mock as req_mock

from agent import definitions
from agent.exploits import cve_2024_21733


def testCVE202421733_whenVulnerable_reportFinding(
requests_mock: req_mock.mocker.Mocker,
) -> None:
"""CVE-2024-21733 unit test: case when target is vulnerable."""
exploit_instance = cve_2024_21733.CVE202421733Exploit()
requests_mock.get(
re.compile("http://localhost:8085"),
text="<title>HTTP Status 403</title><h3>Apache Tomcat/9.0.43</h3>",
status_code=403,
)
target = definitions.Target("http", "localhost", 8085)

accept = exploit_instance.accept(target)
vulnerabilities = exploit_instance.check(target)

assert accept is True
vulnerability = vulnerabilities[0]
assert (
vulnerability.entry.title
== "Apache Tomcat HTTP Request Smuggling (Client- Side Desync)"
)
assert vulnerability.technical_detail == (
"http://localhost:8085 is vulnerable to CVE-2024-21733, Apache Tomcat HTTP "
"Request Smuggling (Client- Side Desync)"
)


def testCVE202421733_whenSafe_reportNothing(
requests_mock: req_mock.mocker.Mocker,
) -> None:
"""CVE-2024-21733 unit test: case when target is safe."""
exploit_instance = cve_2024_21733.CVE202421733Exploit()
requests_mock.get(
re.compile("http://localhost"),
text="<title>HTTP Status 403</title><h3>Apache Tomcat/9.0.73</h3>",
status_code=403,
)
target = definitions.Target("http", "localhost", 8089)

accept = exploit_instance.accept(target)
vulnerabilities = exploit_instance.check(target)

assert accept is True
assert len(vulnerabilities) == 0

0 comments on commit d255242

Please sign in to comment.