Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix lsass finder #69

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 43 additions & 28 deletions pypykatz/commons/readers/local/common/live_reader_ctypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ def get_device_prefixes():
device_prefixes[QueryDosDevice(drive)] = drive
return device_prefixes

def convert_ntpath(exepath):
image_filename = str(exepath)
for win_path in DEVICE_PREFIXES:
if image_filename.startswith(win_path):
image_filename = DEVICE_PREFIXES[win_path] + image_filename[len(win_path):]
return image_filename


DEVICE_PREFIXES = get_device_prefixes()

WINDOWS_BUILD_NUMBER = getWindowsBuild()
Expand All @@ -89,33 +97,40 @@ def get_device_prefixes():
def get_process_full_imagename(pid):
_NtQuerySystemInformation = windll.ntdll.NtQuerySystemInformation
image_filename = ''
buf = ctypes.create_unicode_buffer(0x1000)
buf = ctypes.create_unicode_buffer(0x100)
process_info = SYSTEM_PROCESS_ID_INFORMATION()
process_info.ProcessId = ctypes.c_void_p(pid)
process_info.ImageName.MaximumLength = len(buf)
process_info.ImageName.Buffer = addressof(buf)
status = _NtQuerySystemInformation(
SystemProcessIdInformation,
process_info,
byref(process_info),
sizeof(process_info),
None)
if status == STATUS_INFO_LENGTH_MISMATCH:
buf = ctypes.create_unicode_buffer(MAX_PATH_UNICODE)
buf = ctypes.create_unicode_buffer(process_info.ImageName.MaximumLength)
process_info.ImageName.MaximumLength = len(buf)
process_info.ImageName.Buffer = addressof(buf)
status = _NtQuerySystemInformation(
SystemProcessIdInformation,
process_info,
byref(process_info),
sizeof(process_info),
None)
if status == 0:
image_filename = str(process_info.ImageName.Buffer)
if image_filename.startswith('\\Device\\'):
for win_path in DEVICE_PREFIXES:
if image_filename.startswith(win_path):
image_filename = DEVICE_PREFIXES[win_path] + image_filename[len(win_path):]
image_filename = convert_ntpath(image_filename)
else:
image_filename = 'N/A'
# Another method Just in case
# We only need PROCESS_QUERY_LIMITED_INFORMATION
try:
process_handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, pid)
image_filename = QueryFullProcessImageNameW(process_handle)
except Exception as e:
image_filename = 'N/A'
finally:
if process_handle:
CloseHandle(process_handle)
return image_filename

PS_PROTECTED_TYPE_STRINGS = [None,"Light","Full"]
Expand All @@ -124,30 +139,30 @@ def get_process_full_imagename(pid):
PS_PROTECTED_TYPE_OLD_OS_STRINGS = [None,"System protected process"]

#https://msdn.microsoft.com/en-us/library/windows/desktop/ms683217(v=vs.85).aspx
#def enum_process_names():
# pid_to_fullname = {}
#
# for pid in EnumProcesses():
# if pid == 0:
# continue
#
# pid_to_fullname[pid] = get_process_full_imagename(pid)
# return pid_to_fullname

def enum_process_names():
pid_to_name = {}
pid_to_fullname = {}

for pid in EnumProcesses():
if pid == 0:
continue
pid_to_name[pid] = 'Not found'
try:
process_handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, False, pid)
except Exception as e:
continue

pid_to_name[pid] = QueryFullProcessImageNameW(process_handle)
return pid_to_name

pid_to_fullname[pid] = get_process_full_imagename(pid)
return pid_to_fullname

#def enum_process_names():
# pid_to_name = {}
#
# for pid in EnumProcesses():
# if pid == 0:
# continue
# pid_to_name[pid] = 'Not found'
# try:
# process_handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, False, pid)
# except Exception as e:
# continue
#
# pid_to_name[pid] = QueryFullProcessImageNameW(process_handle)
# return pid_to_name

def get_process_extended_basic_information(pid,process_handle=None):
process_basic_info = PROCESS_EXTENDED_BASIC_INFORMATION()
Expand Down Expand Up @@ -196,7 +211,7 @@ def get_protected_process_infos(pid,process_handle=None):
def get_lsass_pid():
pid_to_name = enum_process_names()
for pid in pid_to_name:
if pid_to_name[pid].lower().endswith('lsass.exe'):
if pid_to_name[pid].lower().endswith(':\\windows\\system32\\lsass.exe'):
return pid

raise Exception('Failed to find lsass.exe')
16 changes: 8 additions & 8 deletions pypykatz/commons/readers/local/live_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,14 +344,14 @@ def setup(self):
pid = get_lsass_pid()
logging.log(1, 'Lsass.exe found at PID %d' % pid)
logging.log(1, 'Checking Lsass.exe protection status')
#proc_protection_info = get_protected_process_infos(pid)
#protection_msg = "Protection Status: No protection"
#if proc_protection_info:
# protection_msg = f"Protection Status: {proc_protection_info['type']}"
# if 'signer' in proc_protection_info:
# protection_msg += f" ({proc_protection_info['signer']})"
# raise Exception('Failed to open lsass.exe Reason: %s' % protection_msg)
#logging.log(1, protection_msg)
proc_protection_info = get_protected_process_infos(pid)
protection_msg = "Protection Status: No protection"
if proc_protection_info:
protection_msg = f"Protection Status: {proc_protection_info['type']}"
if 'signer' in proc_protection_info:
protection_msg += f" ({proc_protection_info['signer']})"
raise Exception('Failed to open lsass.exe Reason: %s' % protection_msg)
logging.log(1, protection_msg)
logging.log(1, 'Opening lsass.exe')
self.lsass_process_handle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
if self.lsass_process_handle is None:
Expand Down