skelsec / pypykatz

Mimikatz implementation in pure Python
MIT License
2.81k stars 371 forks source link

latest pypykatz and wdigest plain text password #77

Closed Papotito123 closed 3 years ago

Papotito123 commented 3 years ago

Hello: Thank you for your work. Win 1909 x64 local account with Avast disabled.

Using latest laZagne.py I installed requirements.txt and downloaded latest pypykatz(and some few others).

Now in the lazagne pypykatz block , show as this:

------------------- Pypykatz passwords -----------------

[+] Password found !!! Type: wdigest_creds Domain: DESKTOP-2GHHNFK Password: p a s s w o r d

First time I see retrieved password chars separated with a blank space between them. Chrome,Firefox,Edge(chromium),CoreFTP,WIFI logins-passwords are showing as should be.

Any info much appreciated.

skelsec commented 3 years ago

Hello! I know exactly what this is. "First time I see retrieved password chars separated with a blank space between them." << Consider yourself really lucky XD Jokes aside. The reason is that I have modified the code that converts the password bytes after decryption to text, apparently it's still not precise but this is still better than what was before (have you noticed asian text printed out in some cases?) To be precise, here is the description of the problem: Passwords/secrets (notice the secrets part) are stored encrypted in LSASS with no "encoding" information attached to them. So programmatically you can't really decide if the decrypted secret is ASCII/UTF-8/UTF-16-LE/noteventext. For this reason some guessing-logic needed to be implemented (which was changed in the recent version). Original guessing code was:

  1. Try decode as UTF-16-LE
  2. Try decode as UTF-8
  3. Try decode as ASCII
  4. If all fails: it's either just bytes or decryption failed (since there is no checksum it's hard to distinguish) Problems with original case:
  5. Byte blobs gets decoded as valid UTF-16-LE strings and you see a whole bunch of asian characters (sometimes cirillic). This is especially the case with computer passwords and passwords from the SSP module. In this case you basically loose the password since you will most likely not be able to convert the characters back.
  6. ASCII passwords get 'decoded' to either UTF16LE or UTF8. same problem as above

Updated guessing code:

  1. Try to decode as ASCII
  2. Try to decode as UTF-16
  3. UTF8
  4. ....
    • If the account name ends with '$' then just return bytes for the password as it's probably a machine account

Now what you are observing it's a problem on the other way around: ASCII for some reason decodes UTF16LE. Wonderful. What I can do here is to update the guessing code that checks if every second char is \x00 or if there are characters outside of 1-127 then skip ascii decoding entirely.
Anyhow this issue is still much less severe then the previous version's issue on the same topic. In the next update I'll probably create a new variable for all credential objects to make the password bytes available for later decoding by the user

Papotito123 commented 3 years ago

Hello: Cool. When I say that is first time I see this output string format I meant that in lazagne pypykatz output block is the first time that the password output is inserting a blank space between chars. So I suspected was related to latest pypykatz code.Every time you update pypykatz so I run lazagne and reinstall requirements to update also pypykatz module. I just wanted to inform in case you didn't hear any about this behavior.

Thanks for keep in touch.

skelsec commented 3 years ago

I have rolled back the decoding change, also now all credential objects (which have a password) have a password_raw member to access the bytes right after decryption so you can do your own decoding if needed. I hope that sorts out this issue.