Closed sealmove closed 2 years ago
This is a bug caused by the change of crypto library in the recent month and the lack of tests on the DPAPI module.
@skelsec I'll check it out and probably make a PR, thanks!
Don't sweat it, modifying these 2 lines solve the problem:
cleartext = unpad(cipher.decrypt(self.data), ALGORITHMS_DATA[self.crypto_algorithm][3])
hash_block_size = ALGORITHMS_DATA[self.hash_algorithm][4]
Looks good, thanks. I get another error though, might be or might not be related.
I am pretty sure my input is correct. It's an encrypted chrome aes key. I stripped the "DPAPI" prefix.
base64 -d encrypted_key.b64 | cut -c 6- | hexdump -ve '1/1 "%02x"' | tee key.blob
pypykatz dpapi blob masterkey key.blob
(...)
ValueError: Input is not padded or padding is corrupt
Which version should I try with?
$ pip show pypykatz
Name: pypykatz
Version: 0.5.7
Summary: Python implementation of Mimikatz
Home-page: https://github.com/skelsec/pypykatz
Author: Tamas Jos
Author-email: info@skelsecprojects.com
License: UNKNOWN
Location: /home/sealmove/.local/lib/python3.10/site-packages
Requires: aesedb, aiosmb, aiowinreg, minidump, minikerberos, msldap, unicrypto, winacl
Required-by:
$ pypykatz dpapi blob masterkey key.blob
Error! non-hexadecimal number found in fromhex() arg at position 0
Traceback (most recent call last):
File "/home/sealmove/.local/lib/python3.10/site-packages/pypykatz/dpapi/cmdhelper.py", line 230, in run
bytes.fromhex(args.blob)
ValueError: non-hexadecimal number found in fromhex() arg at position 0
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/sealmove/.local/bin/pypykatz", line 8, in <module>
sys.exit(main())
File "/home/sealmove/.local/lib/python3.10/site-packages/pypykatz/__main__.py", line 89, in main
helper.execute(args)
File "/home/sealmove/.local/lib/python3.10/site-packages/pypykatz/dpapi/cmdhelper.py", line 121, in execute
self.run(args)
File "/home/sealmove/.local/lib/python3.10/site-packages/pypykatz/dpapi/cmdhelper.py", line 233, in run
dec_sec = dpapi.decrypt_securestring_file(args.blob)
File "/home/sealmove/.local/lib/python3.10/site-packages/pypykatz/dpapi/dpapi.py", line 541, in decrypt_securestring_file
return self.decrypt_securestring_hex(data)
File "/home/sealmove/.local/lib/python3.10/site-packages/pypykatz/dpapi/dpapi.py", line 536, in decrypt_securestring_hex
return self.decrypt_securestring_bytes(bytes.fromhex(hex_str))
File "/home/sealmove/.local/lib/python3.10/site-packages/pypykatz/dpapi/dpapi.py", line 533, in decrypt_securestring_bytes
return self.decrypt_blob_bytes(data)
File "/home/sealmove/.local/lib/python3.10/site-packages/pypykatz/dpapi/dpapi.py", line 449, in decrypt_blob_bytes
return self.decrypt_blob(blob, key = key)
File "/home/sealmove/.local/lib/python3.10/site-packages/pypykatz/dpapi/dpapi.py", line 434, in decrypt_blob
return dpapi_blob.decrypt(key)
File "/home/sealmove/.local/lib/python3.10/site-packages/pypykatz/dpapi/structures/blob.py", line 109, in decrypt
cleartext = unpad(cipher.decrypt(self.data), ALGORITHMS_DATA[self.crypto_algorithm][3])
File "/home/sealmove/.local/lib/python3.10/site-packages/unicrypto/backends/pure/padding/pkcs7.py", line 11, in unpad
raise ValueError('Input is not padded or padding is corrupt')
ValueError: Input is not padded or padding is corrupt
Tested on a clean environment. I get the same error with v0.5.2.
$ pypykatz dpapi blob masterkey key.blob
Error! non-hexadecimal number found in fromhex() arg at position 0
Traceback (most recent call last):
File "/home/remnux/.local/lib/python3.8/site-packages/pypykatz/dpapi/cmdhelper.py", line 230, in run
bytes.fromhex(args.blob)
ValueError: non-hexadecimal number found in fromhex() arg at position 0
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/bin/pypykatz", line 33, in <module>
sys.exit(load_entry_point('pypykatz==0.5.7', 'console_scripts', 'pypykatz')())
File "/home/remnux/.local/lib/python3.8/site-packages/pypykatz/__main__.py", line 84, in main
helper.execute(args)
File "/home/remnux/.local/lib/python3.8/site-packages/pypykatz/dpapi/cmdhelper.py", line 121, in execute
self.run(args)
File "/home/remnux/.local/lib/python3.8/site-packages/pypykatz/dpapi/cmdhelper.py", line 233, in run
dec_sec = dpapi.decrypt_securestring_file(args.blob)
File "/home/remnux/.local/lib/python3.8/site-packages/pypykatz/dpapi/dpapi.py", line 542, in decrypt_securestring_file
return self.decrypt_securestring_hex(data)
File "/home/remnux/.local/lib/python3.8/site-packages/pypykatz/dpapi/dpapi.py", line 537, in decrypt_securestring_hex
return self.decrypt_securestring_bytes(bytes.fromhex(hex_str))
File "/home/remnux/.local/lib/python3.8/site-packages/pypykatz/dpapi/dpapi.py", line 534, in decrypt_securestring_bytes
return self.decrypt_blob_bytes(data)
File "/home/remnux/.local/lib/python3.8/site-packages/pypykatz/dpapi/dpapi.py", line 450, in decrypt_blob_bytes
return self.decrypt_blob(blob, key = key)
File "/home/remnux/.local/lib/python3.8/site-packages/pypykatz/dpapi/dpapi.py", line 435, in decrypt_blob
return dpapi_blob.decrypt(key)
File "/home/remnux/.local/lib/python3.8/site-packages/pypykatz/dpapi/structures/blob.py", line 109, in decrypt
cleartext = unpad(cipher.decrypt(self.data), cipher.block_size)
File "/home/remnux/.local/lib/python3.8/site-packages/pypykatz/crypto/unified/pkcs7.py", line 11, in unpad
raise ValueError('Input is not padded or padding is corrupt')
ValueError: Input is not padded or padding is corrupt
in that case I believe the error could be that the masterkeys you have do not match the one which was used to encrypt the blob OR the decryption code is buggy.
you can check the masterkey GUID required by the blob by parsing the blob (no decryption) and the GUID of the header should match one of the GUIDS of the masterkeys you have.
EDIT: The GUIDs seem to match. Looks like there is a slight difference in the GUIDs. Could it be a version incompatibility?
$ pypykatz dpapi masterkey 865be7a6-863c-4d73-ac9f-233f8734089d prekeys
[GUID] 865be7a6-863c-4d73-ac9f-233f8734089d [MASTERKEY] 138f089556f32b87e53c5337c47f5f34746162db7fe9ef47f13a92c74897bf67e890bcf9c6a1d1f4cc5454f13fcecc1f9f910afb8e2441d8d3dbc3997794c630
cat encrypted_key.blob
01000000d08c9ddf0115d1118c7a00c04fc297eb01000000a6e75b863c86734dac9f233f8734089d00000000020000000000106600000001000020000000273b46c4c77da6aec6b84106322aaa686ba6ee18801ba89ef3674ba9b01e1e3a000000000e8000000002000020000000bfdc532d088604106c3adcf8abceaacafe54242c77d414c19382d2ff7ad877f43000000041c108468a6b567d2736ac03bc294c72393e3782260a547129b2ecb7ca9df129d2a3d8423a7e71c083a1c2400000003a4218497890c65b8514dbafd35f7ab87338602e4bb38ea5c581e1fe08776b4cb8e42bdd2f684a5725eadbc38d5ea8561296ca2e42ca41a3fe51d0761e5f6f790a
EDIT: If my comparison is correct then (after applying correct byte ordering):
masterkey GUID: a6e75b863c86734dac9f233f8734089d
masterkey GUID used to encrypt blob: a6e75b863c86734dac9f233f8734089d
@skelsec could you please try decrypting this blob with this masterkey?
I can verify that decryption fails, thank you for providing the data.
At first glance it looks like either the encrypted.blob is corrupted at the end OR the parser code is incorrect somehow, as the end of the encrypted blob reports an impossibly large signature_length
I can verify the blob is not corrupted. Let me also provide the original source of the information, in case I did something wrong when extracting it:
AppData/Local/Google/Chrome/User Data/Local State
"os_crypt": {
"encrypted_key": "RFBBUEkBAAAA0Iyd3wEV0RGMegDAT8KX6wEAAACm51uGPIZzTayfIz+HNAidAAAAAAIAAAAAABBmAAAAAQAAIAAAACc7RsTHfaauxrhBBjIqqmhrpu4YgBuonvNnS6mwHh46AAAAAA6AAAAAAgAAIAAAAL/cUy0IhgQQbDrc+KvOqsr+VCQsd9QUwZOC0v962Hf0MAAAAEHBCEaKa1Z9JzasA7wpTHI5PjeCJgrNbSTeklRxKbLst8qd8SnSo9hCOn5xwIOhwkAAAAA6QhhJeJDGW4UU26/TX3q4czhgLkuzjqXFgeH+CHdrTLjkK90vaEpXJerbw41eqFYSlsouQspBo/5R0HYeX295"
}
@skelsec
Hmm, after decoding this base64 string, I removed the first 5 bytes ("DPAPI" prefix) manually using a hex editor. Previously I was using the command cut -c 6-
to achieve this. The two methods of removing the prefix yield different result! So you were right, cut -c 6-
somehow corrupts the information. It seems to decrypt it just fine. Sorry for the confusion!
P.S.: The output could be improved:
Error! non-hexadecimal number found in fromhex() arg at position 0
HEX: 46befddb52a607c5e775b7a930b6b6c4f3a35e7c1c30aaa4ce0d2277fbca6c19
Traceback (most recent call last):
File "/home/sealmove/.local/bin/pypykatz", line 8, in <module>
sys.exit(main())
File "/home/sealmove/.local/lib/python3.10/site-packages/pypykatz/__main__.py", line 89, in main
helper.execute(args)
File "/home/sealmove/.local/lib/python3.10/site-packages/pypykatz/dpapi/cmdhelper.py", line 121, in execute
self.run(args)
File "/home/sealmove/.local/lib/python3.10/site-packages/pypykatz/dpapi/cmdhelper.py", line 238, in run
print('STR: %s' % dec_sec.decode('utf-16-le'))
File "/usr/lib/python3.10/encodings/utf_16_le.py", line 16, in decode
return codecs.utf_16_le_decode(input, errors, True)
UnicodeDecodeError: 'utf-16-le' codec can't decode bytes in position 2-3: illegal UTF-16 surrogate
The decrypted information is not necessarily utf-16. Maybe the output could be more friendly instead of a stack trace in this case.
The reason you get that message is that I like stack traces, don't kink shame me.
You are using the incorrect decrypt function for chrome. Not your fault as I forgot to push the code for that part tho.
Please wait till I push the new code because it fixes another error which came in -again- because of the unicrypto
lib.
Which step is wrong? The command pypykatz dpapi blob masterkey encrypted_key.blob
? Ok, standing by =)
That command is okay, but I guess you want to see the actual logindata/cookies. There is a command to do just that in the not-yet-uploaded version
Try now with a clean environment, cloning master (new version uploaded)
There will be a new command for chrome like:
pypykatz dpapi chrome masterkey Local\ State --logindata Login\ Data
Thank you very much for the release! Works like a charm =)
I am getting an AttributeError when trying to decode blobs using master key. I installed pypykatz using pip. It looks like a problem with dependencies. Do I need to install any additional package(s) with pip?