Esempio n. 1
0
class Exploit:

    def __init__(self, name, description, type_, rawcmd, success=''):
        self.name = name
        self.description = description
        self.type = type_
        self.rawcmd = rawcmd
        self.success = success
        self.directory = TOOL_BASEPATH + '/exploits/' + self.name.lower()
        self.output = ''


    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


    def check_success(self):
        if self.type == 'rce-blind':
            m = re.search(MATCHING_PATTERN_RCE_BLIND, self.output, re.IGNORECASE)

        elif self.type == 'rce-standard':
            m = re.search(self.success, self.output, re.IGNORECASE)

        return (m is not None)
            
Esempio n. 2
0
class Exploit:

    def __init__(self, 
                 name, 
                 product,
                 description, 
                 type_, 
                 detection_rawcmd, 
                 detection_success,
                 exploit_rawcmd,
                 exploit_rce_output,
                 exploit_success):
        self.name = name
        self.product = product
        self.description = description
        self.type = type_
        self.detection_rawcmd = detection_rawcmd
        self.detection_success = detection_success
        self.exploit_rawcmd = exploit_rawcmd
        self.exploit_rce_output = exploit_rce_output
        self.exploit_success = exploit_success
        self.directory = TOOL_BASEPATH + '/exploits/' + self.name.lower()
        self.output = ''


    def is_mode_supported(self, mode):
        """
        Check is specified mode is supported (either "detect" or "exploit")
        :param str mode: Requested mode
        """
        if mode == 'detect':
            return (self.detection_rawcmd is not None and len(self.detection_rawcmd) > 0)
        elif mode == 'exploit':
            return (self.exploit_rawcmd is not None and len(self.exploit_rawcmd) > 0)
        else:
            return False


    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


    def check_success(self, mode):
        """
        Check vuln detection success or exploit success when run in automatic test (i.e. 
        no command provided via --cmd)

        :param str mode: mode can be either "detect" or "exploit"
        """
        m = None
        if mode == 'detect':
            m = re.search(self.detection_success, self.output, re.IGNORECASE)
            if not m:
                if self.detection_success.lower() in self.output.lower():
                    m = self.detection_success
        elif mode == 'exploit':
            if self.type == 'rce':
                if self.exploit_rce_output:
                    # RCE with command output: use success match string provided in settings
                    m = re.search(self.exploit_success, self.output, re.IGNORECASE)
                    if not m:
                        if self.exploit_success.lower() in self.output.lower():
                            m = self.exploit_success
                else:
                    # RCE without command output: use built-in match strings to detect either
                    # ICMP echo reply or received HTTP request
                    m = re.search(MATCHING_PATTERN_RCE_BLIND_ICMP, self.output, re.IGNORECASE)
                    if not m:
                        m = re.search(MATCHING_PATTERN_RCE_BLIND_HTTP, self.output, re.IGNORECASE)
            else:
                # Other exploit type (e.g. sqli)
                m = re.search(self.exploit_success, self.output, re.IGNORECASE)
                if not m:
                    if self.exploit_success.lower() in self.output.lower():
                        m = self.exploit_success

        return (m is not None)