Exemplo n.º 1
0
    def check(self):

        # Server Administration
        r = Requester.get('{}/railo-context/admin/server.cfm'.format(self.url))
        if r.status_code == 200 and 'type="password"' in r.text:
            self.interface = 'railo-server-admin'
            self.interface_url = '{}/railo-context/admin/server.cfm'.format(
                self.url)
            logger.info(
                'Railo Server administration console detected: {}'.format(
                    self.interface_url))
            return True

        # Web Administration
        r = Requester.get('{}/railo-context/admin/web.cfm'.format(self.url))
        if r.status_code == 200 and 'type="password"' in r.text:
            self.interface = 'railo-server-admin'
            self.interface_url = '{}/railo-context/admin/web.cfm'.format(
                self.url)
            logger.info('Railo Web administration console detected: {}'.format(
                self.interface_url))
            return True

        logger.error('No Railo authentication interface detected')
        return False
Exemplo n.º 2
0
    def check(self):

        # Interface 1: admin-console
        r = Requester.get('{}/admin-console/login.seam'.format(self.url))
        if r.status_code == 200:
            self.interface = 'admin-console'
            self.interface_url = '{}/admin-console/login.seam'.format(self.url)
            logger.info('Jboss authentication interface detected: {}'.format(
                self.interface_url))
            return True

        # Interface 2: jmx-console
        auth_type = Requester.get_http_auth_type('{}/jmx-console/'.format(
            self.url))
        if auth_type is not AuthMode.UNKNOWN:
            self.interface = 'jmx-console'
            self.interface_url = '{}/jmx-console/'.format(self.url)
            self.http_auth_type = auth_type
            logger.info('Jboss jmx-console interface detected: {}'.format(
                self.interface_url))
            return True

        # Interface 3: web-console
        auth_type = Requester.get_http_auth_type('{}/web-console/'.format(
            self.url))
        if auth_type is not AuthMode.UNKNOWN:
            self.interface = 'web-console'
            self.interface_url = '{}/web-console/'.format(self.url)
            self.http_auth_type = auth_type
            logger.info('Jboss web-console interface detected: {}'.format(
                self.interface_url))
            return True

        # Interface 4: management
        auth_type = Requester.get_http_auth_type('{}/management/'.format(
            self.url))
        if auth_type is not AuthMode.UNKNOWN:
            self.interface = 'management'
            self.interface_url = '{}/management/'.format(self.url)
            self.http_auth_type = auth_type
            logger.info('Jboss management interface detected: {}'.format(
                self.interface_url))
            return True

        # Interface 5: management 2
        r = Requester.get('{}/console'.format(self.url))
        if r.status_code == 200:
            tmp = r.url[:r.url.rindex('/')]
            self.interface_url = '{0}/management'.format(tmp[:tmp.rindex('/')])
            auth_type = Requester.get_http_auth_type(self.interface_url)
            if auth_type is not AuthMode.UNKNOWN:
                self.interface = 'management'
                self.http_auth_type = auth_type
                logger.info('Jboss management interface detected: {}'.format(
                    self.interface_url))
                return True

        logger.error('No Jboss authentication interface detected')
        return False
Exemplo n.º 3
0
    def check(self):

        r = Requester.get('{}/CFIDE/administrator/enter.cfm'.format(self.url))
        if r.status_code == 200 and 'type="password"' in r.text.lower():
            self.interface_url = '{}/CFIDE/administrator/enter.cfm'.format(
                self.url)

            # Version 6
            if 'name="cfadminPassword"' in r.text \
                    and 'name="requestedURL"' in r.text \
                    and 'name="cfadminUserId"' not in r.text \
                    and 'name="salt"' not in r.text:
                self.interface = 'coldfusion-6-admin'
                logger.info(
                    'Coldfusion 6 administration console detected: {}'.format(
                        self.interface_url))
                return True

            # Versions 7/8/9
            elif 'name="cfadminPassword"' in r.text \
                    and 'name="requestedURL"' in r.text \
                    and 'name="cfadminUserId"' in r.text \
                    and 'name="salt"' in r.text:
                self.interface = 'coldfusion-7-8-9-admin'
                logger.info(
                    'Coldfusion 7/8/9 administration console detected: {}'.
                    format(self.interface_url))
                return True

            # Versions 10/11
            elif 'name="cfadminPassword"' in r.text \
                    and 'name="requestedURL"' in r.text \
                    and 'name="cfadminUserId"' in r.text \
                    and 'name="salt"' not in r.text:
                self.interface = 'coldfusion-10-11-admin'
                logger.info(
                    'Coldfusion 10/11 administration console detected: {}'.
                    format(self.interface_url))
                return True

        r = Requester.get('{}/CFIDE/administrator/index.cfm'.format(self.url))
        if r.status_code == 200 and 'type="password"' in r.text.lower():
            self.interface_url = '{}/CFIDE/administrator/index.cfm'.format(
                self.url)

            # Version 5
            if 'name="PasswordProvided_required"' in r.text \
                    and 'name="PasswordProvided"' in r.text:
                self.interface = 'coldfusion-5-admin'
                logger.info(
                    'Coldfusion 5 administration console detected: {}'.format(
                        self.interface_url))
                return True

        logger.error('No Coldfusion authentication interface detected')
        return False
Exemplo n.º 4
0
    def try_auth(self, username, password):
        if self.interface == 'joomla-admin':
            r = Requester.get(self.interface_url)

            data = {
                'username': username,
                'passwd': password,
                #'lang': 'en-GB',
                'option': self.option,
                'task': 'login',
                self.token: '1',
            }
            r = Requester.post(self.interface_url,
                               data,
                               headers={
                                   'Cookie': self.cookie,
                               })

            if 'input name="passwd"' not in r.text:
                self.cookie = 'a=a'
                return True
            else:
                return False

        else:
            raise AuthException('No auth interface found during intialization')
Exemplo n.º 5
0
 def _get_salt(self, url):
     r = Requester.get(url)
     m = re.search(
         '<input name="salt" type="hidden" value="(?P<salt>\S+?)">', r.text)
     if not m:
         raise RequestException(
             'Unable to retrieve salt from {}'.format(url))
     else:
         return m.group('salt')
Exemplo n.º 6
0
    def try_auth(self, username, password):
        if self.interface == 'admin-console':
            # We need to retrieve ViewState value
            r = Requester.get(self.interface_url)
            m = re.search('<input type="hidden" name="javax\.faces\.ViewState" ' \
                'id="javax\.faces\.ViewState" value="(?P<viewstate>.*?)"', r.text)
            if not m:
                raise RequestException(
                    'Unable to retrieve ViewState from {}'.format(
                        self.interface_url))

            data = OrderedDict([
                ("login_form", "login_form"),
                ("login_form:name", username),
                ("login_form:password", password),
                ("login_form:submit", "Login"),
                ("javax.faces.ViewState", m.group('viewstate')),
            ])
            # We also need to retrieve JSESSIONID value
            m = re.search(
                r'JSESSIONID=(?P<jsessionid>.*); Path=\/admin-console',
                r.headers['Set-Cookie'])
            if not m:
                raise RequestException('Unable to retrieve JSESSIONID value ' \
                    'from {}'.format(self.interface_url))

            r = Requester.post(self.interface_url,
                               data,
                               headers={
                                   'Cookie':
                                   'JSESSIONID={}'.format(
                                       m.group('jsessionid'))
                               },
                               allow_redirects=False)

            status = ('name="login_form:password"' not in r.text \
                and 'Not logged in' not in r.text)
            return status

        elif self.interface == 'jmx-console':
            r = Requester.http_auth(self.interface_url, self.http_auth_type,
                                    username, password)
            return (r.status_code != 401)

        elif self.interface == 'management':
            r = Requester.http_auth(self.interface_url, self.http_auth_type,
                                    username, password)
            return (r.status_code != 401)

        elif self.interface == 'web-console':
            r = Requester.http_auth(self.interface_url, self.http_auth_type,
                                    username, password)
            return (r.status_code != 401)

        else:
            raise AuthException(
                'No auth interface found during initialization')
Exemplo n.º 7
0
    def check(self):

        r = Requester.get('{}/axis2/axis2-admin/login'.format(self.url))
        if r.status_code == 200 and 'name="password"' in r.text:
            self.interface = 'axis2-admin'
            self.interface_url = '{}/axis2/axis2-admin/login'.format(self.url)
            logger.info('Axis2 administration console detected: {}'.format(
                self.interface_url))
            return True

        logger.error('No Axis2 authentication interface detected')
        return False
Exemplo n.º 8
0
    def check(self):

        r = Requester.get('{}/ibm/console/logon.jsp'.format(self.url))
        if 'name="j_password"' in r.text:
            self.interface = 'websphere-admin'
            self.interface_url = '{}/ibm/console/logon.jsp'.format(self.url)
            self.action_url = '{}/ibm/console/j_security_check'.format(self.url)
            logger.info('Websphere administration console detected: {}'.format(
                self.interface_url))
            return True

        logger.error('No Websphere authentication interface detected')
        return False
Exemplo n.º 9
0
    def check(self):

        r = Requester.get('{}/console/j_security_check'.format(self.url))
        if 'name="j_password"' in r.text:
            self.interface = 'weblogic-admin'
            self.interface_url = '{}/console/j_security_check'.format(self.url)
            logger.info('Weblogic administration console detected: {}'.format(
                self.interface_url))
            logger.warning('Warning: By default, Weblogic has an account lockout ' \
                'feature (max 5 failures per 5 minutes, lockout duration of 30min)')
            return True

        logger.error('No Weblogic authentication interface detected')
        return False
Exemplo n.º 10
0
    def check(self):
        """
        <form method="post" name="login" action="j_acegi_security_check" style="text-size:smaller">
        <table><tr><td>User:</td><td><input type="text" name="j_username" id="j_username" autocorrect="off" autocapitalize="off" />
        </td></tr><tr><td>Password:</td><td><input type="password" name="j_password" /></td></tr><tr><td align="right">
        <input id="remember_me" type="checkbox" name="remember_me" /></td><td><label for="remember_me">Remember me on this computer</label>
        </td></tr></table><input name="from" type="hidden" value="/" />
        <input name="Submit" type="submit" value="log in" class="submit-button primary" /><script>
        $('j_username').focus();
        </script></form>
        """
        r = Requester.get('{}/login'.format(self.url))
        if r.status_code == 200 and 'name="j_password"' in r.text:
            self.interface = 'jenkins-admin'
            self.interface_url = '{}/login'.format(self.url)
            self.action_url = '{}/j_acegi_security_check'.format(self.url)
            logger.info('Jenkins administration console detected: {}'.format(
                self.interface_url))
            return True

        logger.error('No Jenkins authentication interface detected')
        return False
Exemplo n.º 11
0
    def check(self):

        r = Requester.get('{}/administrator/index.php'.format(self.url))
        #print(r.headers)
        if 'form action="/administrator/index.php"' in r.text:
            self.interface = 'joomla-admin'
            self.interface_url = '{}/administrator/index.php'.format(self.url)
            logger.info('Joomla administration page detected: {}'.format(
                self.interface_url))

            # Extract session cookie
            try:
                self.cookie = r.headers['Set-Cookie'].split(';')[0]
                logger.info('Extracted session cookie: {}'.format(self.cookie))
            except:
                logger.error('Unable to extract session cookie')
                return False

            # Extract token
            m = re.search('type="hidden" name="(.*)" value="1"', r.text)
            try:
                self.token = m.group(1)
                logger.info('Extracted token value: {}'.format(self.token))
            except:
                logger.error('Unable to extract token from page !')
                return False

            # Extract option
            m = re.search('type="hidden" name="option" value="(.*)"', r.text)
            try:
                self.option = m.group(1)
            except:
                # Default option value
                self.option = 'com_login'

            return True

        logger.error('No Joomla administration interface detected')
        return False
Exemplo n.º 12
0
    def try_auth(self, username, password):

        # If anti-CSRF token might be present, reload the page before every attempt
        # and re-extract form fields
        if self.has_csrftoken:
            r = Requester.get(self.url)
            self.cookies = r.cookies
            soup = BeautifulSoup(r.text, 'html.parser')
            try:
                target_form = soup.find_all('form')[self.form_number]
            except:
                raise AuthException(
                    'Problem occured when reloading page. Maybe some WAF/Protection '
                    'is blocking us ?')
            self.parameters = self.__extract_form_fields(target_form)
            if self.password_field not in self.parameters.keys() \
               or (self.username_field and self.username_field not in self.parameters.keys()):
                raise AuthException(
                    'Problem occured when reloading page. Maybe some WAF/Protection '
                    'is blocking us ?')

        # Send authentication request
        if self.username_field:
            self.parameters[self.username_field] = username
        self.parameters[self.password_field] = password

        if self.method == 'GET':
            r = Requester.get(self.action_url,
                              params=self.parameters,
                              cookies=self.cookies)
        else:
            r = Requester.post(self.action_url,
                               data=self.parameters,
                               cookies=self.cookies)
        if self.verbose:
            logger.info('Raw HTTP Request/Response:')
            data = dump.dump_all(r)
            print(data.decode('utf-8'))

        # Check authentication status
        # HTTP response code check
        if r.status_code >= 400:
            return False

        # Check if response page contains password field
        soup = BeautifulSoup(r.text, 'html.parser')
        input_password = soup.find('input',
                                   attrs={'name': self.password_field})
        if input_password:
            return False

        # Heuristic check of failed attemps based on possible error messages
        if re.search(
                '(username\s+or\s+password|cannot\s+log\s*in|unauthorized'
                '|auth(entication)?\s+fail|(invalid|wrong)\s+(cred|user|login|mail|email|e-mail|pass)'
                '|error\s+during\s+(login|auth))', r.text, re.IGNORECASE):
            return False

        # Heuristic check of successful attempt based on page content
        if re.search('(log\s*out|log\s*off|deconn?e|disconn?ec)', r.text,
                     re.IGNORECASE):
            return True

        # Heuristic check of account lockout based on possible error messages
        if re.search(
                '(too\s+many\s+(failed)?\s*(attempt|try|tri)|account\s+(lock|block))',
                r.text, re.IGNORECASE):
            return False

        # Heuristic check based on source code difference with original page
        s = difflib.SequenceMatcher(None, self.page_html, r.text)
        return (s.quick_ratio() < 0.60)
Exemplo n.º 13
0
    def check(self):
        r = Requester.get(self.url)

        # Cookie potentially returned are kept to be sent in the auth request
        # because sometimes application might reject request if those cookies are not present
        self.cookies = r.cookies

        # Keep HTML source code of the page for diff calculation in heuristics checks
        # to determine if auth has failed/succeeded
        self.page_html = r.text
        soup = BeautifulSoup(r.text, 'html.parser')

        logger.warning('This module is based on heuristics and is prone to '
                       'false negatives/positives')

        # Get all <form> on the page
        forms = soup.find_all('form')
        #print(forms)
        if not forms:
            logger.error('No standard web <form> found on the page')
            return False

        # Detect form with password field
        # 1. Check for standard <input type="password" ...> field
        # 2. Otherwise, check for <input type="text" ...> field with evocative name
        target_form = None
        is_input_password_type_text = False
        i = 0
        for f in forms:
            input_password = f.find(
                'input',
                type=lambda x: x and x.lower() == 'password',
                attrs={'name': True})
            if not input_password:
                input_password = f.find(
                    'input',
                    type=lambda x: x and x.lower() == 'text',
                    attrs={
                        'name':
                        re.compile('.*(pass|pwd|pswd|pssw|pswrd).*',
                                   re.IGNORECASE)
                    })
                if input_password:
                    is_input_password_type_text = True
            if input_password:
                target_form = f
                self.password_field = input_password.attrs['name']
                self.form_number = i
                break
            i += 1

        if target_form:
            logger.info(
                'Standard web authentication <form> seems present on the page')
            logger.info('Detected password field name = {name}'.format(
                name=self.password_field))
        else:
            logger.error(
                'No standard web auth <form> with password field has been detected '
                'on the page')
            return False

        # Get action url (target) used when submitting form
        if target_form.has_attr('action'):
            form_action = target_form.attrs['action']
            # Absolute URL
            if form_action.lower().startswith('http://') \
               or form_action.lower().startswith('https://'):
                self.action_url = form_action
            # Relative path
            else:
                self.action_url = urljoin(self.url, form_action)
        else:
            self.action_url = r.url
        logger.info(
            'Detected form action URL = {url}'.format(url=self.action_url))

        # Get form method (default POST)
        try:
            self.method = target_form.attrs['method'].upper()
        except:
            self.method = 'POST'

        # Detect username field
        inputs_text = target_form.find_all('input',
                                           type=lambda x: x and x.lower() in
                                           ('text', 'email'),
                                           attrs={'name': True})
        if is_input_password_type_text:
            try:
                inputs_text.remove(
                    target_form.find('input',
                                     type=lambda x: x and x.lower() == 'text',
                                     attrs={'name': self.password_field}))
            except:
                pass
        if len(inputs_text) == 0:
            self.username_field = None
        elif len(inputs_text) == 1:
            # If only one input field type=text (except password field), take this one
            self.username_field = inputs_text[0].attrs['name']
        else:
            # Take the one with the most explicit name if found, otherwise the first one
            self.username_field = self.__find_username_field_via_name(
                inputs_text)
            if not self.username_field:
                self.username_field = inputs_text[0].attrs['name']

        # In rare case, username field can have no type
        if not self.username_field:
            inputs_no_type = target_form.find_all('input',
                                                  type=False,
                                                  attrs={'name': True})
            self.username_field = self.__find_username_field_via_name(
                inputs_no_type)

        if self.username_field:
            logger.info('Detected username field name = {name}'.format(
                name=self.username_field))
        else:
            logger.info(
                'No username field detected, probably password-only authentication'
            )

        # Heuristic check of anti-CSRF token
        self.has_csrftoken = target_form.find(
            'input', type=lambda x: x and x.lower() == 'hidden') is not None
        if self.has_csrftoken:
            logger.info(
                'Heuristic check determines form might have anti-CSRF token')

        # Get ordered list of all form parameters
        self.parameters = self.__extract_form_fields(target_form)
        return True
Exemplo n.º 14
0
    def run(self):

        # List supported modules
        if self.args.list:
            print('List of supported modules:')
            for mod in Utils.list_modules():
                print('- {}'.format(mod))
            return

        # Check if target is available
        logger.info(
            'Check if target {url} is reachable...'.format(url=self.args.url))
        try:
            r = Requester.get(self.args.url)
        except RequestException as e:
            logger.error('Target URL seems not reachable:')
            logger.error(e)
            sys.exit(0)
        logger.success('Connection to target OK. HTTP Status {}'.format(
            r.status_code))

        # Handle potential <meta> refresh
        meta_refresh_url = Requester.get_meta_redirect_url(
            r.text, self.args.url)
        if meta_refresh_url:
            logger.info(
                'Meta refresh mechanism has been detected. Following redirect...'
            )
            self.args.url = meta_refresh_url
            try:
                r = Requester.get(self.args.url)
            except RequestException as e:
                logger.error('Redirected URL seems not reachable:')
                logger.error(e)
                sys.exit(0)
            logger.success(
                'Connection to redirection OK. HTTP Status {}'.format(
                    r.status_code))

        # Create wordlist queue
        try:
            self.wordlist = Wordlist(self.args.username, self.args.userlist,
                                     self.args.password, self.args.passlist,
                                     self.args.combolist)
            logger.info('Number of creds that will be tested: {}'.format(
                self.wordlist.length))
        except Exception as e:
            logger.error(e)
            sys.exit(0)

        # Initialize module
        try:
            mod = importlib.import_module('lib.modules.{}'.format(
                self.args.type.capitalize()))
        except Exception as e:
            logger.error('Error while importing module lib.modules.{}'.format(
                self.args.type.capitalize()))
            traceback.print_exc()
            return
        module = getattr(mod, self.args.type.capitalize())(
            self.args.url, verbose=self.args.verbose)

        # Detect authentication interface
        try:
            if not module.check():
                return
        except RequestException as e:
            logger.warning(e)

        # Run bruteforce
        self.run_bruteforcer(module)
        self.output.newline('')

        logger.info('Bruteforce finished !')
        if self.args.verbose:
            if len(self.creds_found) > 0:
                logger.success('{} valid credentials found:'.format(
                    len(self.creds_found)))
                for username, password in self.creds_found:
                    logger.success('{}:{}'.format(username, password))
            else:
                logger.error('No valid credentials found :\'(')