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
def listenv(self, args, environ): envvars = obtain(environ.data) self.log( TruncateToTerm( Table([{ 'VAR': k, 'VAL': repr(v) } for k, v in envvars.iteritems()], ['VAR', 'VAL'], legend=False)))
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)))
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)
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)
columns = ['cid', 'login', 'secret', 'resource'] 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())
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))
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')
def run(self, args): query = self.client.remote('isearch', 'query') request = [] if args.raw: request = args.raw else: request.append( 'SELECT TOP {} System.ItemUrl, System.Size, System.DateModified FROM SYSTEMINDEX' .format(args.limit)) where = [] if args.text: where.append('FREETEXT({})'.format(escape(args.text))) if args.directory: where.append('SCOPE={}'.format(escape('file:' + args.directory))) if args.path: where.append('CONTAINS(System.FileName, {})'.format( escape(args.path))) if where: request.append('WHERE') request.append('AND'.join(where)) request.append('ORDER BY System.DateModified DESC') if not request: self.error('You should specify request') return text = ' '.join(request) if args.verbose: self.info('QUERY: {}'.format(text)) idx, cidx, data, error = query(text, args.limit) if error: self.error(error) elif not data: self.warning('No data found') else: objects = [] header = [] legend = True if args.raw: legend = False for record in data: objects.append( {str(idx): v for idx, v in enumerate(record)}) header = [str(x) for x in xrange(cidx + 1)] else: header = ['File', 'Size', 'Modified'] for record in data: objects.append({ 'File': record[0][5:] if record[0].startswith('file:') else record[0], 'Size': record[1], 'Modified': datetime.fromtimestamp(record[2]) }) self.log(TruncateToTerm(Table(objects, header, legend=legend)))