コード例 #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
コード例 #2
0
ファイル: Controller.py プロジェクト: shad0w008/jok3r-pocs
    def run(self):

        if self.args.list:
            self.settings.show_list_exploits()

        else:
            if self.args.target.lower().startswith('http'):
                target = Target(ip=None, port=None, url=self.args.target)
            else:
                ip, port = self.args.target.split(':', maxsplit=1)
                target = Target(ip=ip, port=port, url=None, ssl=self.args.ssl)

            exploit = self.settings.get_exploit(self.args.exploit)

            OutputUtils.title('Exploitation Attempt: {description}'.format(
                description=exploit.description))
            out = exploit.run(target)

            if out is None:
                sys.exit(1)

            if exploit.check_success():
                logger.success('{description}: Target is EXPLOITABLE !'.format(
                    description=exploit.description))
                logger.info('Exploit code available in: {directory}'.format(
                    directory=exploit.directory))

            else:
                logger.error(
                    '{description}: Target seems NOT exploitable'.format(
                        description=exploit.description))
コード例 #3
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
コード例 #4
0
    def run(self, target):
        try:
            self.command = Command(self.rawcmd, self.type)
        except CommandException as e:
            logger.error(e)
            return None

        # Build script to run
        if self.type == 'rce-blind':
            logger.warning('WARNING: This attack box must be reachable from the target !')
            logger.info('If target is vulnerable, exploit will try to ping local ' \
                'IP = {localip} from target'.format(
                    localip=NetUtils.get_local_ip_address()))

            print(self.command.get_cmdline(target))

            script = SCRIPT_RCE_BLIND.format(
                exploit_dir=self.directory,
                command=self.command.get_cmdline(target))

        elif self.type == 'rce-standard':
            script = self.command.get_cmdline(target)

        else:
            logger.error('Unsupported exploit type')
            return None

        # Run subprocess
        try:
            logger.info('Exploit will be run from directory: {directory}'.format(
                directory=self.directory))

            proc = subprocess.Popen(script, 
                                    shell=True, 
                                    stdout=subprocess.PIPE, 
                                    stderr=subprocess.STDOUT)

            # Agressivelly get the output
            while True:
                out = proc.stdout.read(1)
                # We put that inside try block to avoid utf8 decoding error
                try:
                    out = out.decode(sys.stdout.encoding)
                    sys.stdout.write(out)
                    self.output += out
                except:
                    pass

                # Break if process has finished
                if out == ''  and proc.poll() != None:
                    break

        except Exception as e:
            logger.error('Error when trying to run command: {exception}'.format(
                exception=e))
            return None

        return self.output
コード例 #5
0
ファイル: Controller.py プロジェクト: p-g-krish/jok3r-pocs
    def run(self):

        if self.args.list:
            self.settings.show_list_exploits()

        else:
            # Instantiate Target using URL or IP:PORT
            if self.args.target.lower().startswith('http'):
                target = Target(ip=None, port=None, url=self.args.target)
            else:
                ip, port = self.args.target.split(':', maxsplit=1)
                target = Target(ip=ip, port=port, url=None, ssl=self.args.ssl)

            # Get Exploit (or detection script) for selected vulnerability
            exploit = self.settings.get_exploit(self.args.vuln)

            # Check if specified mode is available for specified vuln
            if not exploit.is_mode_supported(self.args.mode):
                logger.error(
                    'Supplied mode ({mode}) is not supported for vulnerability {vuln}'
                    .format(mode=self.args.mode, vuln=self.args.vuln))
                sys.exit(1)

            # Print title and main information
            OutputUtils.title('Vulnerability: {description}'.format(
                description=exploit.description))
            logger.info(
                'Target product: {product}'.format(product=exploit.product))
            logger.info('Vulnerability type: {vuln}'.format(vuln=exploit.type))
            logger.info('Selected mode: {mode}'.format(mode=self.args.mode))
            if self.args.mode == 'exploit' and exploit.type == 'rce':
                logger.info('RCE output available: {rceoutput}'.format(
                    rceoutput='Y' if exploit.exploit_rce_output else 'N'))

            # Run exploit/detection script
            out = exploit.run(target, self.args.mode, self.args.cmd)

            if out is None:
                sys.exit(1)

            # Automatically check success when:
            # - Run in detection mode
            # - Run in exploit mode without --cmd provided (automatic exploit test)
            if self.args.mode == 'detect' or \
               (self.args.mode == 'exploit' and (not self.args.cmd or len(self.args.cmd) == 0)):
                if exploit.check_success(self.args.mode):
                    logger.success(
                        '{description}: Target is EXPLOITABLE !'.format(
                            description=exploit.description))
                    logger.info('Code available in: {directory}'.format(
                        directory=exploit.directory))
                else:
                    logger.error(
                        '{description}: Target seems NOT exploitable'.format(
                            description=exploit.description))
コード例 #6
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
コード例 #7
0
    def check(self):

        auth_type = Requester.get_http_auth_type('{}/'.format(self.url))
        if auth_type is not AuthMode.UNKNOWN:
            self.interface = 'htaccess'
            self.interface_url = '{}/'.format(self.url)
            self.http_auth_type = auth_type
            logger.info('HTTP Authentication detected: {}'.format(
                self.interface_url))
            return True

        logger.error('No HTTP authentication interface detected')
        return False
コード例 #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
コード例 #9
0
    def check(self):

        auth_type = Requester.get_http_auth_type('{}/management/domain'.format(
            self.url))
        if auth_type is not AuthMode.UNKNOWN:
            self.interface = 'glassfish-admin'
            self.interface_url = '{}/management/domain'.format(self.url)
            self.http_auth_type = auth_type
            logger.info('Glassfish admin interface detected: {}'.format(
                self.interface_url))
            return True

        logger.error('No Glassfish authentication interface detected')
        return False
コード例 #10
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
コード例 #11
0
ファイル: Tomcat.py プロジェクト: xiaoaliha/web-brutator
    def check(self):

        auth_type = Requester.get_http_auth_type('{}/manager/html'.format(self.url))
        if auth_type is not AuthMode.UNKNOWN:
            self.interface = 'tomcat-manager'
            self.interface_url = '{}/manager/html'.format(self.url)
            self.http_auth_type = auth_type
            logger.info('Tomcat Manager interface detected: {}'.format(
                self.interface_url))
            logger.warning('Warning: By default, Tomcat has an account lockout ' \
                'feature (max 5 failures, lockout duration of 300s)')
            return True

        logger.error('No Tomcat authentication interface detected')
        return False
コード例 #12
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
コード例 #13
0
ファイル: Controller.py プロジェクト: xiaoaliha/web-brutator
    def run_bruteforcer(self, module):
        self.bruteforcer = Bruteforcer(module,
                                       self.wordlist,
                                       self.success_creds_callback,
                                       self.wrong_creds_callback,
                                       self.fatal_error_callback,
                                       self.request_error_callback,
                                       threads=self.args.threads)
        # try:
        # TODO: handle exception !!
        logger.info('Starting bruteforce with {} threads...'.format(
            self.bruteforcer.nb_threads))
        self.bruteforcer.start()
        while True:
            try:
                while not self.bruteforcer.wait(0.3):
                    continue
                break

            except (KeyboardInterrupt, SystemExit) as e:
                self.handle_interrupt()
コード例 #14
0
ファイル: Jenkins.py プロジェクト: marciopocebon/web-brutator
    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
コード例 #15
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
コード例 #16
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
コード例 #17
0
    def run(self, target, mode, rce_command=''):
        """
        :param Target targer: Target instance
        :param str mode: mode can be either "detect" or "exploit"
        :param str rce_command: RCE command to run when running exploit (requires mode=exploit)
        """
        try:
            if mode == 'detect':
                self.command = Command(self.detection_rawcmd, self.type)
            elif mode == 'exploit':
                self.command = Command(self.exploit_rawcmd, self.type, self.exploit_rce_output)
        except CommandException as e:
            logger.error(e)
            return None

        # Build script to run
        if mode == 'exploit':
            if self.type == 'rce':
                if not self.exploit_rce_output:
                    logger.warning('The exploit will attempt to execute command on remote system but no '
                        'output will be available !')
                    # For RCE exploit without command output in test mode (no rce_command provided):
                    # Use script template that check for reverse connection with ICMP ping and HTTP requests
                    if len(rce_command) == 0:
                        logger.warning('WARNING: This attack box must be reachable from the target !')
                        logger.info('No command supplied to run through RCE, automatic exploit test will be started...')
                        logger.info('If target is vulnerable, exploit will try to ping (ICMP Echo request) and '
                            'to send HTTP request to local IP = {localip} from target'.format(
                                localip=NetUtils.get_local_ip_address()))

                        cmdline = self.command.get_cmdline(target)
                        print(cmdline)

                        script = SCRIPT_RCE_BLIND.format(
                            exploit_dir=self.directory,
                            command=cmdline)
                    else:
                        cmdline = self.command.get_cmdline(target, rce_command)
                        print(cmdline)
                        script  = 'cd {exploit_dir}; '.format(exploit_dir=self.directory)
                        script += cmdline
                else:
                    if len(rce_command) == 0:
                        logger.info('No command supplied to run through RCE, automatic exploit test will be started...')
                        logger.info('If target is vulnerable, exploit will try to run an echo command on target')
                        cmdline = self.command.get_cmdline(target)
                        print(cmdline)
                        script  = 'cd {exploit_dir}; '.format(exploit_dir=self.directory)
                        script += cmdline
                    else:
                        cmdline = self.command.get_cmdline(target, rce_command)
                        print(cmdline)
                        script  = 'cd {exploit_dir}; '.format(exploit_dir=self.directory)
                        script += cmdline                        

            else:
                cmdline = self.command.get_cmdline(target)
                print(cmdline)
                script  = 'cd {exploit_dir}; '.format(exploit_dir=self.directory)
                script += cmdline
        else:
            logger.warning('The script will attempt to detect if remote system is vulnerable without '
                'actually exploiting the vulnerability.')
            logger.warning('WARNING: False Positive is possible !')
            cmdline = self.command.get_cmdline(target)
            script  = 'cd {exploit_dir}; '.format(exploit_dir=self.directory)
            script += cmdline            

        # Run subprocess
        try:
            logger.info('{script} will be run from directory: {directory}'.format(
                script='Exploit' if mode == 'exploit' else 'Detection script',
                directory=self.directory))

            proc = subprocess.Popen(script, 
                                    shell=True, 
                                    executable='/bin/bash',
                                    stdout=subprocess.PIPE, 
                                    stderr=subprocess.STDOUT)

            # Agressivelly get the output
            while True:
                out = proc.stdout.read(1)
                # We put that inside try block to avoid utf8 decoding error
                try:
                    out = out.decode(sys.stdout.encoding)
                    sys.stdout.write(out)
                    self.output += out
                except:
                    pass

                # Break if process has finished
                if out == ''  and proc.poll() != None:
                    break

        except Exception as e:
            logger.error('Error when trying to run command: {exception}'.format(
                exception=e))
            return None

        return self.output
コード例 #18
0
ファイル: Controller.py プロジェクト: xiaoaliha/web-brutator
    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 :\'(')
コード例 #19
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)