add: regsecrets plugin.

This commit is contained in:
Ulf Frisk
2019-12-19 14:43:44 +01:00
parent 2016ae0e21
commit 39d79d8aec
5 changed files with 313 additions and 2 deletions

View File

@@ -19,4 +19,19 @@ _pypykatz_ for MemProcFS exposes mimikatz functionality in the folder `/py/secre
3) Copy the _pypykatz_ for _MemProcFS_ plugin by copying all files from [`/files/plugins/pym_pypykatz`](https://github.com/ufrisk/MemProcFS-plugins/tree/master/files/plugins/pym_pypykatz) to corresponding folder in MemProcFS - overwriting any existing files there.
4) Start MemProcFS.
#### Last updated: 2019-03-17
## pypykatz regsecrets
#### Author:
Tamas Jos ([@skelsec](https://twitter.com/SkelSec)) , info@skelsec.com , https://github.com/skelsec/
#### Overview:
_regsecrets_ for MemProcFS exposes mimikatz functionality in the folder `/py/regsecrets/` in the file system root provided that the target is a supported Windows system. Functionality includes retrieval NTLM hashes for local accounts amongst other things.
<p align="center"><img src="https://raw.githubusercontent.com/wiki/ufrisk/MemProcFS-plugins/resources/p_regsecrets_1.png" height="375"/></p>
#### Installation instructions:
1) Ensure MemProcFS supported version of 64-bit Python for Windows is on the system path (or specify in `-pythonpath` option when starting MemProcFS). NB! embedded Python will not work with _pypykatz_ and _aiowinreg_ since it requires access to Python pip installed packages.
2) Install _pypykatz_ and _aiowinreg_ pip package, in correct python environment, by running `pip install pypykatz aiowinreg`.
3) Copy the _pyregsecrets_ for _MemProcFS_ plugin by copying all files from [`/files/plugins/pym_regsecrets`](https://github.com/ufrisk/MemProcFS-plugins/tree/master/files/plugins/pym_regsecrets) to corresponding folder in MemProcFS - overwriting any existing files there.
4) Start MemProcFS.
#### Last updated: 2019-12-19

View File

@@ -0,0 +1,9 @@
from plugins.pym_regsecrets.pym_regsecrets import (
Initialize,
Notify,
)
__all__ = [
"Initialize",
"Notify",
]

View File

@@ -0,0 +1,286 @@
# pym_regsecrets.py
#
# Pypykatz RegSecrets plugin for MemProcFs
#
# https://github.com/skelsec/
# https://gist.githubusercontent.com/skelsec/617abdc40a29a60edd337177f5dce85a/raw/b11e456acc23a454bd52e649cc42081c8ddd1b32/gistfile1.txt
#
# (c) Tamas Jos, 2019
# Author: Tamas Jos (@skelsec), info@skelsec.com
#
# adaptation to MemProcFS plugin by:
# (c) Ulf Frisk, 2019
# Author: Ulf Frisk (@UlfFrisk), pcileech@frizk.net
#
from vmmpy import *
from vmmpyplugin import *
import traceback
# globals needed for FS
is_initialized = False
import_failed = None
parsing_failed = None
result_all = ''
result_sam = ''
result_security = ''
result_software = ''
import_error_text_template = """
The imports for pypykatz plugin have failed at some point.
Common causes:
1. You dont have pypykatz installed.
2. You dont have the latest versions of pypykatz and/or aiowinreg.
2. Python runtime environment used by MemProcFs is not the same as you have installed pypykatz in.
3. You are not using the correct python version.
Error traceback:
%s
"""
parsing_error_template = """
pypykatz plugin tried to parse the registry hives in the memory dump but failed.
This could be caused by multiple things:
1. The pypykatz's parser code is potato.
2. MemProcFs could not fully parse the memory, usually this happens with incorrect memory dump files.
Error traceback:
%s
"""
import_error_text = None
parsing_error_text = None
try:
from pypykatz.registry.sam.sam import *
from pypykatz.registry.security.security import *
from pypykatz.registry.system.system import *
from pypykatz.registry.software.software import *
from aiowinreg.hive import AIOWinRegHive
from aiowinreg.filestruct.hbin import NTRegistryHbin
#this needs to be the last line!
import_failed = False
except Exception as e:
import_failed = True
if VmmPyPlugin_fPrintV:
traceback.print_exc()
import_error_text = import_error_text_template % traceback.format_exc()
pass
class MemProcFS_RegReader:
"""
This class provides buffer-like reader interface which can be delegated to AIOWinreg's HIVE classes.
Emulates reading and seeking capablities of a buffer but actually calling the underlying MemProcFS API.
"""
def __init__(self, va_hive):
self.va_hive = va_hive
self.position = 0
self.firstread = True
def read(self, count = -1):
if count < 0:
raise Exception('Cant read negative count')
elif count == 0:
return None
data = VmmPy_WinReg_HiveRead(self.va_hive, self.position, count, flags = 0)
self.position += count
return data
def seek(self, count, whence = 0):
if whence == 0:
if count < 0:
raise Exception('whence 0 requires positive values or 0')
self.position = count
elif whence == 1:
self.position += count
elif whence == 2:
raise Exception('Cant seek from the end!')
def list_hives():
for x in VmmPy_WinReg_HiveList():
yield x
def get_hive_va(hive_name, hive_name_short):
for hiveinfo in list_hives():
if 'name' in hiveinfo and hiveinfo['name'].endswith(hive_name):
return hiveinfo['va_hive']
for hiveinfo in list_hives():
if 'name' in hiveinfo and hive_name_short in hiveinfo['name']:
return hiveinfo['va_hive']
return None
def create_hive(hive_name, hive_name_short):
hive_va = get_hive_va(hive_name, hive_name_short)
reader = MemProcFS_RegReader(hive_va)
hroot = NTRegistryHbin.read(reader)
reader = MemProcFS_RegReader(hive_va)
return AIOWinRegHive(reader, hroot, is_file = False)
def parse_reg():
global result_all, result_sam, result_security, result_software
sam_hive = create_hive('SAM-MACHINE_SAM', 'SAM')
security_hive = create_hive('SECURITY-MACHINE_SECURITY', 'SECURITY')
system_hive = create_hive('SYSTEM-MACHINE_SYSTEM', 'SYSTEM')
software_hive = create_hive('SOFTWARE-MACHINE_SOFTWARE', 'SOFTWARE')
if system_hive is None:
raise Exception('System hive not found! this is mandatory for extracting secrets!')
system = SYSTEM(system_hive)
bootkey = system.get_bootkey()
#input('BootKey: %s' % bootkey.hex())
if sam_hive is not None:
sam = SAM(sam_hive, bootkey)
sam.get_secrets()
else:
print('SAM hive not found!')
if security_hive is not None:
security = SECURITY(security_hive, bootkey)
security.get_secrets()
else:
print('SECURITY hive not found!')
if software_hive is not None:
software = SOFTWARE(software_hive, bootkey)
software.get_default_logon()
else:
print('SOFTWARE hive not found!')
result_sam = str(sam)
result_security = str(security)
result_software = str(software)
result_all = result_sam + result_security + result_software
def parse_reg_catch():
global parsing_failed, parsing_error_text
try:
parse_reg()
parsing_failed = False
except Exception as e:
parsing_failed = True
if VmmPyPlugin_fPrintV:
traceback.print_exc()
parsing_error_text = parsing_error_template % (traceback.format_exc())
pass
def ReadResultFile(pid, file_name, file_attr, bytes_length, bytes_offset):
"""
reads the all_results data as file on the virtual FS
"""
global result_all, result_sam, result_security, result_software
if file_name == 'all.txt':
return result_all[bytes_offset:bytes_offset+bytes_length].encode()
if file_name == 'sam.txt':
return result_sam[bytes_offset:bytes_offset+bytes_length].encode()
if file_name == 'security.txt':
return result_security[bytes_offset:bytes_offset+bytes_length].encode()
if file_name == 'software.txt':
return result_software[bytes_offset:bytes_offset+bytes_length].encode()
return None
def ReadErrors(pid, file_name, file_attr, bytes_length, bytes_offset):
try:
if file_name == 'import_error.txt':
return import_error_text.encode()[bytes_offset:bytes_offset+bytes_length]
if file_name == 'parsing_error.txt':
return parsing_error_text.encode()[bytes_offset:bytes_offset+bytes_length]
except Exception as e:
if VmmPyPlugin_fPrintV:
traceback.print_exc()
return None
def List(pid, path):
#
# List function - this module employs a dynamic list function - which makes
# it responsible for providing directory listings of its contents in a
# highly optimized way. It is very important that the List function is as
# speedy as possible - to avoid locking up the file system.
#
# First check the directory to be listed. Only the module root directory is
# allowed. If it's not the module root directory return None.
global is_initialized, import_failed, parsing_failed, import_error_text, parsing_error_text
global result_all, result_sam, result_security, result_software
try:
if path != 'regsecrets':
return None
if is_initialized == False:
parse_reg_catch()
is_initialized = True
if import_failed == True:
print(import_failed)
result = {
'import_error.txt': {'size': len(import_error_text), 'read': ReadErrors, 'write': None},
}
return result
if parsing_failed == True:
result = {
'parsing_error.txt': {'size': len(parsing_error_text), 'read': ReadErrors, 'write': None},
}
return result
if path == 'regsecrets':
result = {
'all.txt': {'size': len(result_all), 'read': ReadResultFile, 'write': None},
'sam.txt': {'size': len(result_sam), 'read': ReadResultFile, 'write': None},
'security.txt': {'size': len(result_security), 'read': ReadResultFile, 'write': None},
'software.txt': {'size': len(result_software), 'read': ReadResultFile, 'write': None},
}
return result
return None
except Exception as e:
if VmmPyPlugin_fPrintV:
traceback.print_exc()
return None
def Notify(fEvent, bytesData):
if fEvent == VMMPY_PLUGIN_EVENT_TOTALREFRESH and not import_failed and not parsing_failed:
global is_initialized
is_initialized = False
def Initialize(target_system, target_memorymodel):
# Check that the operating system is 32-bit or 64-bit Windows. If it's not
# then raise an exception to terminate loading of this module.
if target_system != VMMPY_SYSTEM_WINDOWS_X64 and target_system != VMMPY_SYSTEM_WINDOWS_X86:
raise RuntimeError("Only Windows is supported by the pym_regsecrets module.")
VmmPyPlugin_FileRegisterDirectory(None, 'regsecrets', List)

View File

@@ -0,0 +1 @@
1.0.0

View File

@@ -1,2 +1,2 @@
pluginupdater 1.0.0
pypykatz 1.1.0
regsecrets 1.0.0