NetExec icon indicating copy to clipboard operation
NetExec copied to clipboard

Add credential manager dump feature to winrm protocol

Open tiagomanunes opened this issue 7 months ago • 22 comments

Description

This is a winrm module designed to find and unlock Credential Manager masterkeys and credentials owned by the connecting user. In a situation where smb's --dpapi cannot work due to the lack of access to the C$ share, and where a user has remote management privileges, the module automates the discovery and offline decryption of these files.

The flow is inspired by and a simplified version of dploot's triage methods for user masterkeys and credentials. Actual decryption of keys and credentials is taken and adapted from impacket-dpapi.

This is my first contribution to the project (aside from a small bugfix earlier, found in the process of writing this!), and I would appreciate any feedback :)

I'll work on the corresponding documentation on the wiki in the meantime.

Type of change

  • [ ] Bug fix (non-breaking change which fixes an issue)
  • [x] New feature (non-breaking change which adds functionality)
  • [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • [x] This change requires a documentation update
  • [ ] This requires a third party update (such as Impacket, Dploot, lsassy, etc)

Setup guide for the review

The target must have a user who is allowed to connect via WinRM, and this user should have saved credentials in Credential Manager.

There is an active HTB machine where this is easily demonstrable. There might be retired machines that allow the same, I'll research this and add as a comment below.

Screenshots:

Here's the module working on said active HTB machine: usercredman

Checklist:

  • [x] I have ran Ruff against my changes (via poetry: poetry run python -m ruff check . --preview, use --fix to automatically fix what it can)
  • [x] I have added or updated the tests/e2e_commands.txt file if necessary
  • [ ] New and existing e2e tests pass locally with my changes
  • [ ] If reliant on changes of third party dependencies, such as Impacket, dploot, lsassy, etc, I have linked the relevant PRs in those projects
  • [x] I have performed a self-review of my own code
  • [ ] I have commented my code, particularly in hard-to-understand areas
  • [x] I have made corresponding changes to the documentation (PR here: https://github.com/Pennyw0rth/NetExec-Wiki/pull/60)

tiagomanunes avatar Jul 01 '25 12:07 tiagomanunes

Interesting one, thanks for the PR! I'll take a look at this as soon as i worked on the pile of PRs that has been stacking up the past months

NeffIsBack avatar Jul 03 '25 16:07 NeffIsBack

New modules need to be added to the e2e tests

Marshall-Hallenbeck avatar Jul 13 '25 19:07 Marshall-Hallenbeck

New modules need to be added to the e2e tests

Thanks, I've now added this and took the liberty to add a line for aws-credentials, the only other winrm module currently.

It is unclear to me however what the expectation regarding running the e2e tests is. Is there an image to spin up and test against that we can use?

tiagomanunes avatar Jul 14 '25 08:07 tiagomanunes

Thanks, I've now added this and took the liberty to add a line for aws-credentials, the only other winrm module currently.

Nice, thanks!

It is unclear to me however what the expectation regarding running the e2e tests is. Is there an image to spin up and test against that we can use?

The expectation from the check is that you run the e2e tests against your target machine so you can check if you broke something with your changes, but I think @Marshall-Hallenbeck opinion and mine are split on this one.

For me it is fine if you just test your own module and make sure it works, especially as a new module won't have any impact on the rest of the code base in 99% of the time. Testing the rest of the code base is something i usually only do if there are major changes in the core of the project

NeffIsBack avatar Jul 14 '25 12:07 NeffIsBack

New modules need to be added to the e2e tests

Thanks, I've now added this and took the liberty to add a line for aws-credentials, the only other winrm module currently.

It is unclear to me however what the expectation regarding running the e2e tests is. Is there an image to spin up and test against that we can use?

Thanks!

If you are just adding a single module then you don't have to worry about e2e tests - they're there for changes that affect large portions of the code base.

Marshall-Hallenbeck avatar Jul 14 '25 13:07 Marshall-Hallenbeck

why not as a core feature of winrm ? like nxc winrm ip -u user -p pass --dpapi ?

mpgn avatar Jul 16 '25 11:07 mpgn

why not as a core feature of winrm ? like nxc winrm ip -u user -p pass --dpapi ?

If you guys think that'd be best I'll make the appropriate changes. It was in fact the first question I had :) The idea that I got from Discord was essentially that "if we use it all the time, it's a core feature; if more niche, it's a module", and I thought this was more niche than all-the-time.

tiagomanunes avatar Jul 16 '25 13:07 tiagomanunes

why not as a core feature of winrm ? like nxc winrm ip -u user -p pass --dpapi ?

If you guys think that'd be best I'll make the appropriate changes. It was in fact the first question I had :) The idea that I got from Discord was essentially that "if we use it all the time, it's a core feature; if more niche, it's a module", and I thought this was more niche than all-the-time.

dpapi is by default on every user directory so core feature sounds like a good place to me and it will be consistent with dpapi from smb

mpgn avatar Jul 16 '25 22:07 mpgn

dpapi is by default on every user directory so core feature sounds like a good place to me and it will be consistent with dpapi from smb

Alright, done!

winrm dpapi

tiagomanunes avatar Jul 17 '25 11:07 tiagomanunes

@NeffIsBack I'm not sure how important it is but the label no longer applies, after turning this into a core feature

tiagomanunes avatar Jul 21 '25 11:07 tiagomanunes

Currently having an issue with dploot https://github.com/zblurx/dploot/issues/37

mpgn avatar Aug 13 '25 09:08 mpgn

Currently having an issue with dploot zblurx/dploot#37

Interesting, I'm not sure what it could be. Is Credential Guard enabled perhaps? I'll be watching the ticket.

tiagomanunes avatar Aug 13 '25 13:08 tiagomanunes

Any update here ? This feature is very cool and need to be added ! 😄

qu35t-code avatar Sep 25 '25 16:09 qu35t-code

Any update here ? This feature is very cool and need to be added ! 😄

Time is pretty short on my side at the moment, but i will give it a shot now.

NeffIsBack avatar Sep 25 '25 23:09 NeffIsBack

Not sure atm what is happening here but i get a Padding error for what it looks like is the masterkey? image image

NeffIsBack avatar Sep 25 '25 23:09 NeffIsBack

Perhaps indeed related to https://github.com/zblurx/dploot/issues/37, @zblurx do you know or have you seen that error?

NeffIsBack avatar Sep 25 '25 23:09 NeffIsBack

Any update here ? This feature is very cool and need to be added ! 😄

Time is pretty short on my side at the moment, but i will give it a shot now.

Man, you are doing an amazing job, no pressure or panic aha

qu35t-code avatar Sep 26 '25 15:09 qu35t-code

Hi! Great timing to bring this PR back up, thank you @qu35t-code! The HTB machine that "inspired" me (Puppy) was retired yesterday and is currently free to try.

I've just retried and it still works there, so I'm curious about the issue you've found @NeffIsBack, I'll have a look today.

For the record: puppy htb

tiagomanunes avatar Sep 28 '25 09:09 tiagomanunes

Took a short look at it, looks to me like something is going wrong with the decryption of the first credential file which then leads to a padding error when it tries to unpad random garbage.

@zblurx will take a look at it next week, as he has much more knowledge about dpapi than i do.

NeffIsBack avatar Sep 28 '25 15:09 NeffIsBack

Took a short look at it, looks to me like something is going wrong with the decryption of the first credential file which then leads to a padding error when it tries to unpad random garbage.

@zblurx will take a look at it next week, as he has much more knowledge about dpapi than i do.

So I think the behaviour is normal, but maybe I'm missing more credential files. I got the files from Alex on discord, two masterkeys and one credential file: files

I modified the code to ignore the files on the HTB machine and just pick them from their location. The diff: diff

The output shows the "Padding is incorrect" error when trying to decrypt the credential file with the first masterkey, but succeeding with the second: output

This is an unfortunate error message from Impacket dpapi, but it seems to be the normal result when a file cannot be decrypted with a non-matching masterkey. See this write-up from 0xdf for an example (search for "Padding is incorrect"): https://0xdf.gitlab.io/2025/04/26/htb-vintage.html .

What do you think? @zblurx do you confirm that this is normal behaviour in this case?

tiagomanunes avatar Oct 04 '25 15:10 tiagomanunes

Hey guys, sorry for the delay. So the "Padding is incorrect" error happens every time you try to decrypt a DPAPI blob (for example, Credential file) with the wrong masterkey. It's completely normal behavior, so no issue from impacket nor dploot.

In DPAPI_BLOB structure, you can find the encrypted data and some metadata regarding decryption, but also the GUID of the masterkey that you need : image

The process of selecting the correct masterkey based on the GUID written in the DPAPI BLOB is automated in dploot.

zblurx avatar Oct 07 '25 11:10 zblurx

For the record, after implementing the fix pointed out by @zblurx and still testing with the hard-coded files provided by @NeffIsBack , we now pick the right masterkey to open the credentials file (and avoid the padding error message as a side-effect): Screenshot 2025-10-08 at 18 20 27

In case we don't have the necessary masterkey for a given credentials file, we now get a better message: Screenshot 2025-10-08 at 18 20 44

tiagomanunes avatar Oct 08 '25 16:10 tiagomanunes