예제 #1
0
    def run(self, args):
        if args.list:
            ListSids = self.client.remote('pupwinutils.security', 'ListSids')

            sids = ListSids()

            process_table = []
            sids_table = []
            sids_dict = {}

            for (pid, process, sid, username) in sids:
                process_table.append({
                    'pid': pid,
                    'process': process,
                    'sid': sid,
                    'username': username
                })

                sids_dict[sid] = username

            for sid, username in sids_dict.iteritems():
                sids_table.append({
                    'sid': sid,
                    'username': username
                })

            self.log(MultiPart([
                Table(process_table, [
                    'pid', 'process', 'username', 'sid'
                ], caption='Process table'),

                Table(sids_table, [
                    'sid', 'username'
                ], caption='Available Sids')
            ]))

        elif args.impersonate:
            if args.migrate:
                create_proc_as_sid = self.client.remote('pupwinutils.security', 'create_proc_as_sid', False)

                proc_pid = create_proc_as_sid(args.impersonate)
                migrate(self, proc_pid, keep=True)
            else:
                impersonate_sid_long_handle = self.client.remote(
                    'pupwinutils.security', 'impersonate_sid_long_handle', False)

                self.client.impersonated_dupHandle = impersonate_sid_long_handle(args.impersonate, close=False)

            self.success('Sid {} impersonated !'.format(args.impersonate))

        elif args.rev2self:
            rev2self = self.client.remote('pupwinutils.security', 'rev2self', False)

            rev2self()
            self.client.impersonated_dupHandle = None
            self.success('rev2self called')

        else:
            self.error('no option supplied')
예제 #2
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()
예제 #3
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)
예제 #4
0
파일: pupygen.py 프로젝트: mgcfish/pupy
def pack_scriptlets(display,
                    scriptlets,
                    args_scriptlet,
                    os=None,
                    arch=None,
                    debug=False):
    sp = ScriptletsPacker(os, arch)

    for sc in args_scriptlet:
        tab = sc.split(",", 1)
        sc_args = {}
        name = tab[0]
        if len(tab) == 2:
            try:
                for x, y in [x.strip().split("=") for x in tab[1].split(",")]:
                    sc_args[x.strip()] = y.strip()
            except:
                raise ValueError(
                    "usage: pupygen ... -s %s,arg1=value,arg2=value,..." %
                    name)

        if name not in scriptlets:
            raise ValueError("unknown scriptlet %s, valid choices are : %s" %
                             (repr(name), [x for x in scriptlets.iterkeys()]))

        display(
            Success('loading scriptlet {}{}'.format(
                repr(name), 'with args {}'.format(' '.join(
                    '{}={}'.format(k, repr(v))
                    for k, v in sc_args.iteritems())) if sc_args else '')))

        try:
            sp.add_scriptlet(scriptlets[name], sc_args)

        except ScriptletArgumentError as e:
            display(
                MultiPart(
                    Error('Scriptlet {} argument error: {}'.format(
                        repr(name), str(e))), scriptlets[name].format_help()))
            raise ValueError('{}'.format(e))

    script_code = sp.pack()
    return script_code
예제 #5
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'])
                    line.append(NewLine())
                    parts.append(Line(*line))

                handler.display(MultiPart(parts))

            handler.display(NewLine())
    except Exception, e:
        handler.display(Error(e))
        return
예제 #6
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))
예제 #7
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')
예제 #8
0
파일: ad.py 프로젝트: yalpdevx/pupy
    def getinfo(self, args):
        info = self.client.remote('ad', 'info')
        desc = from_tuple_deep(info(args.realm, args.global_catalog), False)
        idesc = desc.get('info', {})

        infos = []

        versions = idesc.get('supported_ldap_versions', [])

        if not hasattr(versions, '__iter__'):
            versions = [versions]

        infos.append(
            List([
                'Bind: ' + desc.get('bind', ''), 'Root: ' +
                desc.get('root', ''), 'LDAP: ' + desc.get('ldap', ''),
                'DNS: ' + desc['dns'][4][0] if desc.get('dns', None) else '',
                'Schema: ' + idesc.get('schema_entry', ''),
                'Versions: ' + ', '.join(str(version) for version in versions),
                'SASL Mechs: ' + ', '.join(
                    mech
                    for mech in idesc.get('supported_sasl_mechanisms', []))
            ],
                 caption='Connection'))

        if desc['ldap_servers']:
            infos.append(
                Table(desc['ldap_servers'], ['address', 'port', 'priority'],
                      caption='LDAP Servers'))

        if desc['dns_servers']:
            infos.append(
                Table([{
                    'IP':
                    dns[0][4][0] + ('/tcp' if dns[0][2] == 2 else '/udp'),
                    'Delay':
                    '{:.02f}ms'.format(dns[1] * 1000),
                } for dns in desc['dns_servers']], ['IP', 'Delay'],
                      caption='DNS Servers'))

        if not idesc:
            self.log(MultiPart(infos))
            return

        if idesc['alt_servers']:
            infos.append(
                List(idesc['alt_servers'], caption='Alternate servers'))

        if idesc['naming_contexts'] and not isinstance(
                idesc['naming_contexts'], (str, unicode)):
            infos.append(
                List(idesc['naming_contexts'], caption='Naming contexts'))

        supported = []
        for table in ('supported_controls', 'supported_extensions',
                      'supported_features'):
            for oid, klass, name, vendor in idesc[table]:
                supported.append({
                    'OID': oid,
                    'Type': klass,
                    'Name': name,
                    'Vendor': vendor
                })

        if supported:
            infos.append(
                Table(supported, ['OID', 'Type', 'Name', 'Vendor'],
                      caption='Supported features and extensions'))

        if 'other' in idesc:
            infos.append(
                List(tuple('{}: {}'.format(key, value)
                           for key, value in idesc['other'].iteritems()
                           if key not in ('supportedLDAPPolicies', )),
                     caption='Other info'))

        self.log(MultiPart(infos))
예제 #9
0
파일: stat.py 프로젝트: yalpdevx/pupy
class FStat(PupyModule):
    '''Show a bit more info about file path. ACLs/Caps/Owner for now'''

    dependencies = {
        'all': ['pupyutils.basic_cmds', 'fsutils', 'fsutils_ext'],
        'windows': ['junctions', 'ntfs_streams', 'pupwinutils.security'],
        'linux': ['xattr', 'posix1e', 'prctl', '_prctl']
    }

    @classmethod
    def init_argparse(cls):
        cls.arg_parser = PupyArgumentParser(prog='stat',
                                            description=cls.__doc__)
        cls.arg_parser.add_argument(
            '-v',
            '--verbose',
            action='store_true',
            default=False,
            help='Print more information (certificates for example)')
        cls.arg_parser.add_argument('path',
                                    type=str,
                                    nargs=REMAINDER,
                                    help='path of a specific file',
                                    completer=remote_path_completer)

    def run(self, args):
        getfilesec = self.client.remote('fsutils_ext', 'getfilesec')

        path = ' '.join(args.path)

        try:
            sec = getfilesec(path)
        except Exception, e:
            self.error(' '.join(x for x in e.args
                                if type(x) in (str, unicode)))
            return

        ctime, atime, mtime, size, owner, group, header, mode, extra = sec

        owner_id, owner_name, owner_domain = owner
        group_id, group_name, group_domain = group

        default = {
            'Created':
            file_timestamp(ctime, time=True),
            'Accessed':
            file_timestamp(atime, time=True),
            'Modified':
            file_timestamp(mtime, time=True),
            'Size':
            '{} ({})'.format(size_human_readable(size), size),
            'Owner':
            '{}{} ({})'.format(owner_domain + '\\' if owner_domain else '',
                               owner_name, owner_id),
            'Group':
            '{}{} ({})'.format(group_domain + '\\' if group_domain else '',
                               group_name, group_id),
            'Mode':
            mode,
        }

        infos = []

        infos.append(
            Table([{
                'Property': p,
                'Value': default[p]
            } for p in ('Created', 'Accessed', 'Modified', 'Size', 'Owner',
                        'Group', 'Mode')], ['Property', 'Value'],
                  legend=False))

        oneliners = []

        certificates = None

        for extra, values in extra.iteritems():
            if extra == 'Certificates':
                certificates = [
                    load_cert_string(cert, FORMAT_DER).as_text()
                    for cert in values
                ]
            elif isinstance(values, dict):
                records = [{
                    'KEY':
                    k.decode('utf-8'),
                    'VALUE':
                    v.decode('utf-8') if isinstance(v, str) else str(v)
                } for k, v in values.iteritems()]

                infos.append(Table(records, ['KEY', 'VALUE'], caption=extra))
            elif isinstance(values, (list, tuple)):
                if all(
                        isinstance(value, (list, tuple)) and len(value) == 2
                        for value in values):
                    infos.append(
                        List('{}: {}'.format(key, value)
                             for key, value in values))
                else:
                    infos.append(List(values, caption=extra))
            elif isinstance(values, int):
                oneliners.append('{}: {}'.format(extra, values))
            elif '\n' in values:
                infos.append(Line(extra + ':', values))
            else:
                oneliners.append(extra + ': ' + values)

        if args.verbose:
            magic = ''
            if header:
                with Magic() as libmagic:
                    magic = libmagic.id_buffer(header)

            if magic:
                oneliners.append('Magic: {}'.format(magic))

            if certificates:
                infos.extend(certificates)

        if oneliners:
            infos.append(List(oneliners, caption='Other'))

        self.log(MultiPart(infos))
예제 #10
0
    def run(self, args):
        if self.client.is_posix():
            tier1 = ('network', 'fuse', 'dm', 'block', 'vm')

            mounts = self.client.remote('mount', 'mounts')
            getuid = self.client.remote('os', 'getuid')
            getgid = self.client.remote('os', 'getgid')

            mountinfo = mounts()
            uid = getuid()
            gid = getgid()

            option_colors = {
                'rw': 'yellow',
                'nosuid': 'grey',
                'nodev': 'grey',
                'noexec': 'lightgreen',
                'uid': {
                    '0': 'green',
                    str(uid): 'red'
                },
                'gid': {
                    '0': 'green',
                    str(gid): 'red'
                },
                'ro': 'green',
                'user_id': {
                    '0': 'green',
                    str(uid): 'red'
                },
                'group_id': {
                    '0': 'green',
                    str(gid): 'red'
                },
                'allow_other': 'yellow',
                'xattr': 'yellow',
                'acl': 'yellow',
                'username': '******',
                'domain': 'red',
                'forceuid': 'yellow',
                'forcegid': 'yellow',
                'addr': 'red',
                'unix': 'red'
            }

            def colorize_option(option):
                if len(option) > 1:
                    k, v = option
                else:
                    k = option[0]
                    v = None

                color = option_colors.get(k)
                if color:
                    if type(color) == dict:
                        if v in color:
                            return colorize('='.join([x for x in [k, v] if x]),
                                            color.get(v))
                        else:
                            return '='.join([x for x in [k, v] if x])
                    else:
                        return colorize('='.join([x for x in [k, v] if x]),
                                        color)
                else:
                    return '='.join([x for x in [k, v] if x])

            output = []

            for fstype in mountinfo.iterkeys():
                if fstype in tier1:
                    continue

                output.append('{}:'.format(colorize(fstype, 'yellow')))

                dst_max = max([len(x['dst']) for x in mountinfo[fstype]])
                fsname_max = max([len(x['fsname']) for x in mountinfo[fstype]])
                free_max = max([
                    len(x['hfree']) if x['total'] else 0
                    for x in mountinfo[fstype]
                ])

                for info in mountinfo[fstype]:
                    fmt = '{{:<{}}} {{:<{}}} {{:>{}}} {{}}'.format(
                        dst_max, fsname_max,
                        (free_max + 3 + 4) if free_max else 0)

                    output.append(
                        fmt.format(
                            info['dst'], info['fsname'], (colorize(
                                ('{{:>3}}% ({{:>{}}})'.format(free_max)
                                 ).format(info['pused'], info['hfree']),
                                'white' if info['pused'] < 90 else 'yellow'))
                            if info['total'] else '', ','.join([
                                colorize_option(option)
                                for option in info['options']
                            ])))

                output.append('')

            for fstype in tier1:
                if fstype not in mountinfo:
                    continue

                src_max = max([len(x['src']) for x in mountinfo[fstype]])
                dst_max = max([len(x['dst']) for x in mountinfo[fstype]])
                fsname_max = max([len(x['fsname']) for x in mountinfo[fstype]])
                free_max = max([
                    len(x['hfree']) if x['total'] else 0
                    for x in mountinfo[fstype]
                ])

                output.append('{}:'.format(colorize(fstype, 'green')))
                for info in mountinfo[fstype]:
                    fmt = '{{:<{}}} {{:<{}}} {{:<{}}} {{:>{}}} {{}}'.format(
                        dst_max, src_max, fsname_max,
                        (free_max + 3 + 4) if free_max else 0)

                    output.append(
                        fmt.format(
                            info['dst'], info['src'], info['fsname'],
                            (colorize(
                                ('{{:>3}}% ({{:>{}}})'.format(free_max)
                                 ).format(info['pused'], info['hfree']),
                                'white' if info['pused'] < 90 else 'yellow'))
                            if info['total'] else '', ','.join([
                                colorize_option(option)
                                for option in info['options']
                            ])))

                output.append('')

            self.log('\n'.join(output))

        elif self.client.is_windows():
            list_drives = self.client.remote('pupyps', 'drives')
            EnumNetResources = self.client.remote('netresources',
                                                  'EnumNetResources')
            drives = list_drives()

            formatted_drives = []
            parts = []

            for drive in drives:
                formatted_drives.append({
                    'MP':
                    drive['mountpoint'],
                    'FS':
                    drive['fstype'],
                    'OPTS':
                    drive['opts'],
                    'USED': ('{}% ({}/{})'.format(
                        drive['percent'], size_human_readable(drive['used']),
                        size_human_readable(drive['total']))) if
                    ('used' in drive and 'total' in drive) else '?'
                })

            parts.append(Table(formatted_drives, ['MP', 'FS', 'OPTS', 'USED']))

            providers = {}

            net_resources = EnumNetResources()
            for resource in net_resources:
                if resource['provider'] not in providers:
                    providers[resource['provider']] = []

                if 'used' in resource:
                    resource['used'] = '{}% ({}/{})'.format(
                        resource['percent'],
                        size_human_readable(resource['used']),
                        size_human_readable(resource['total']))
                else:
                    resource['used'] = '?'

                providers[resource['provider']].append(
                    dict((k, v) for k, v in resource.iteritems()
                         if k not in ('usage', 'provider', 'scope')))

            for provider, records in providers.iteritems():

                parts.append(
                    Table(records, ['remote', 'local', 'type', 'used'],
                          caption=provider))

            self.log(MultiPart(parts))
예제 #11
0
    def run(self, args):
        close_event = threading.Event()
        result = []

        cmdargs = None
        kwargs = None

        definitions = None

        safe_exec = self.client.remote('pupyutils.safepopen', 'safe_exec',
                                       False)

        if self.client.is_linux():
            payload = open(LINUX_EXPLOIT_SUGGESTER_PATH).read()
            cmdargs = ['/bin/bash']
            kwargs = (('stdin_data', payload), )
        else:
            definitions = os.path.join(self.config.get_folder('plugins'),
                                       WES_LOCAL_FILE)

            if not os.path.isfile(definitions) or args.update:
                self.info(
                    'Updating WES defintions from {}'.format(WES_DEFINITIONS))
                try:
                    response = urlopen(WES_DEFINITIONS)
                    with open(definitions, 'w+b') as out:
                        while True:
                            block = response.read(32768)
                            if not block:
                                break

                            out.write(block)

                except Exception as e:
                    self.error('Update failed: {}'.format(e))

                    if os.path.isfile(definitions):
                        try:
                            os.unlink(definitions)
                        except (OSError, IOError):
                            pass

                    return

                self.info('Update completed ({})'.format(definitions))

            expandvars = self.client.remote('os.path', 'expandvars')
            systeminfo = expandvars(r'%WINDIR%\System32\systeminfo.exe')
            cmdargs = [systeminfo]
            kwargs = tuple()

        self.info('Execute payload ({})'.format(' '.join(cmdargs)))
        self.terminate_pipe, get_returncode = safe_exec(
            result.append, close_event.set, cmdargs, kwargs)

        close_event.wait()
        retcode = get_returncode()

        if retcode != 0:
            self.warning('Ret: {}'.format(retcode))
        else:
            self.success('Done')

        result = ''.join(result)

        if not result:
            self.error('No data')
            return

        if self.client.is_linux():
            self.log(result)
            return

        wes = imp.load_source('wes', WES_PATH)

        try:
            cves, date = wes.load_definitions(definitions)
        except BadZipfile:
            self.error('Defintions were downloaded incorrectly ({})'.format(
                definitions))
            return

        productfilter, win, mybuild, version, arch, hotfixes = \
          wes.determine_product(result)

        self.log(
            List([
                'Definitions: ' + str(date), 'Name: ' + productfilter,
                'Generation: ' + (win or 'N/A'), 'Build: ' +
                (str(mybuild) if mybuild else 'N/A'), 'Version: ' +
                (str(version) or 'N/A'), 'Architecture: ' + arch,
                'Hotfixes: ' + ', '.join(['KB%s' % kb for kb in hotfixes])
            ],
                 caption='Operating System'))

        try:
            filtered, found = wes.determine_missing_patches(
                productfilter, cves, hotfixes)
        except wes.WesException as e:
            self.error(e.msg)
            return

        if not args.no_recent_kb:
            recentkb = wes.get_most_recent_kb(found)
            if recentkb:
                recentdate = int(recentkb['DatePosted'])
                found = list(
                    filter(lambda kb: int(kb['DatePosted']) >= recentdate,
                           found))

        if 'Windows Server' in productfilter:
            self.info('Filtering duplicate vulnerabilities')
            found = wes.filter_duplicates(found)

        filtered = wes.apply_display_filters(found, args.hide, True, [], [])
        if not filtered:
            self.info('No vulnerabilities found')
            return

        results = {}
        proposed = set()

        for res in filtered:
            exploits = res['Exploits'].split(',')
            for exploit in exploits:
                exploit = exploit.strip()
                if exploit in proposed:
                    continue

                proposed.add(exploit)

                impact = ''.join(l[0] for l in res['Impact'].split())
                color = 'white'
                if impact == 'ID':
                    color = 'grey'
                elif res['Severity'] == 'Critical' or impact in ('RCE', 'EoP'):
                    color = 'lightred'
                elif res['Severity'] == 'Important':
                    color = 'lightyellow'

                title = (res['AffectedComponent'] + ' / ' + res['AffectedProduct']) \
                  if res['AffectedComponent'] else res['AffectedProduct']

                if title not in results:
                    results[title] = []

                results[title].append({
                    'CVE': Color(res['CVE'], color),
                    'Date': res['DatePosted'],
                    'Impact': impact,
                    'Exploit': exploit
                })

        tables = [NewLine()]
        for component, cves in results.iteritems():
            tables.append(
                Table(cves, ['CVE', 'Date', 'Impact', 'Exploit'], component))

        self.log(MultiPart(tables))
예제 #12
0
class FStat(PupyModule):
    '''Show a bit more info about file path. ACLs/Caps/Owner for now'''

    dependencies = {
        'all': ['pupyutils', 'fsutils', 'fsutils_ext'],
        'windows': ['junctions', 'ntfs_streams'],
        'linux': ['xattr', 'posix1e', 'prctl', '_prctl']
    }

    @classmethod
    def init_argparse(cls):
        cls.arg_parser = PupyArgumentParser(prog='stat',
                                            description=cls.__doc__)
        cls.arg_parser.add_argument('path',
                                    type=str,
                                    nargs=REMAINDER,
                                    help='path of a specific file',
                                    completer=remote_path_completer)

    def run(self, args):
        getfilesec = self.client.remote('fsutils_ext', 'getfilesec')

        path = ' '.join(args.path)

        try:
            sec = getfilesec(path)
        except Exception, e:
            self.error(' '.join(x for x in e.args
                                if type(x) in (str, unicode)))
            return

        ctime, atime, mtime, size, owner, group, header, mode, extra = sec

        owner_id, owner_name, owner_domain = owner
        group_id, group_name, group_domain = group

        magic = ''
        if header:
            with Magic() as libmagic:
                magic = libmagic.id_buffer(header)

        default = {
            'Created':
            file_timestamp(ctime, time=True),
            'Accessed':
            file_timestamp(atime, time=True),
            'Modified':
            file_timestamp(mtime, time=True),
            'Size':
            '{} ({})'.format(size_human_readable(size), size),
            'Owner':
            '{}{} ({})'.format(owner_domain + '\\' if owner_domain else '',
                               owner_name, owner_id),
            'Group':
            '{}{} ({})'.format(group_domain + '\\' if group_domain else '',
                               group_name, group_id),
            'Mode':
            mode,
        }

        infos = []

        infos.append(
            Table([{
                'Property': p,
                'Value': default[p]
            } for p in ('Created', 'Accessed', 'Modified', 'Size', 'Owner',
                        'Group', 'Mode')], ['Property', 'Value'],
                  legend=False))

        if magic:
            infos.append('Magic: {}'.format(magic))

        for extra, values in extra.iteritems():
            if type(values) in (list, tuple):
                infos.append(List(values, caption=extra))
            else:
                infos.append(Line(extra + ':', values))

        self.log(MultiPart(infos))
예제 #13
0
파일: netmon.py 프로젝트: yalpdevx/pupy
    def render_diff(self, diff):
        if not diff:
            return

        listeners = []
        ingress = []
        egress = []
        parts = []

        for record in diff:
            new_listeners_tcp, new_listeners_udp, \
                new_ingress_tcp, new_ingress_udp, \
                new_egress_tcp, new_egress_udp = record

            for new_listeners in (new_listeners_tcp, new_listeners_udp):
                if not new_listeners:
                    continue

                for listener in new_listeners:
                    program, ip, port = listener
                    listeners.append({
                        'PRT':
                        'TCP' if id(new_listeners) == id(new_listeners_tcp)
                        else 'UDP',
                        'EXE':
                        program,
                        'HOST':
                        ip,
                        'PORT':
                        port
                    })

            for new_ingress in (new_ingress_tcp, new_ingress_udp):
                if not new_ingress:
                    continue

                for record in new_ingress:
                    program, (ip, port), remote_ip = record
                    ingress.append({
                        'PRT':
                        'TCP'
                        if id(new_ingress) == id(new_ingress_tcp) else 'UDP',
                        'EXE':
                        program,
                        'LADDR':
                        ip,
                        'LPORT':
                        port,
                        'RADDR':
                        remote_ip
                    })

            for new_egress in (new_egress_tcp, new_egress_udp):
                if not new_egress:
                    continue

                for record in new_egress:
                    program, (ip, port) = record
                    egress.append({
                        'PRT':
                        'TCP'
                        if id(new_egress) == id(new_egress_tcp) else 'UDP',
                        'EXE':
                        program,
                        'ADDR':
                        ip,
                        'PORT':
                        port,
                    })

        if listeners:
            parts.append(
                Table(listeners, ['PRT', 'HOST', 'PORT', 'EXE'], 'Listeners'))

        if ingress:
            parts.append(
                Table(ingress, ['PRT', 'LADDR', 'LPORT', 'RADDR', 'EXE'],
                      'Ingress'))

        if egress:
            parts.append(
                Table(egress, ['PRT', 'ADDR', 'PORT', 'EXE'], 'Egress'))

        self.log(MultiPart(parts))