Skip to content

Fix DPAPI credential lookup: add lowercase username for dploot compatibility #1113

Merged
NeffIsBack merged 2 commits intoPennyw0rth:mainfrom
mverschu:fix/dpapi-username-case
Mar 11, 2026
Merged

Fix DPAPI credential lookup: add lowercase username for dploot compatibility #1113
NeffIsBack merged 2 commits intoPennyw0rth:mainfrom
mverschu:fix/dpapi-username-case

Conversation

@mverschu
Copy link
Copy Markdown
Contributor

@mverschu mverschu commented Feb 18, 2026

Description

Fixes DPAPI master key decryption when the username contains uppercase letters (e.g. Administrator).

dploot looks up credentials using user.lower() (e.g. "administrator"), but credentials were only stored under context.username (e.g. "Administrator"). Because Python dict lookups are case-sensitive, the credential lookup failed and master keys were not decrypted.

This change adds the lowercase username as an additional key in both plaintexts and nthashes so dploot can find the credentials regardless of casing.

No new dependencies.

Type of change

Insert an "x" inside the brackets for relevant items (do not delete options)

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

Setup guide for the review

Please provide guidance on what setup is needed to test the introduced changes, such as your locally running machine Python version & OS, as well as the target(s) you tested against, including software versions.
In particular:

  • Bug Fix: Run the DPAPI module against a Windows target using a username with uppercase letters (e.g. Administrator, DOMAIN\User). Before the fix, master keys for that user were not decrypted because the credential lookup failed. After the fix, credentials are found and master keys decrypt successfully.

Checklist:

Insert an "x" inside the brackets for completed and relevant items (do not delete options)

  • I have ran Ruff against my changes (via poetry: poetry run python -m ruff check . --preview, use --fix to automatically fix what it can)
  • I have added or updated the tests/e2e_commands.txt file if necessary (new modules or features are required to be added to the e2e tests)
  • 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
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation (PR here: https://github.com/Pennyw0rth/NetExec-Wiki)

…ibility

dploot looks up credentials with user.lower() (e.g. 'administrator'), but we
only stored them under context.username (e.g. 'Administrator'). Python dict
lookups are case-sensitive, so the credential wasn't found and master keys
were never decrypted.

Co-authored-by: Cursor <cursoragent@cursor.com>
@NeffIsBack
Copy link
Copy Markdown
Member

Thanks for the bug fix PR! I'll take a look at it soon.

@NeffIsBack NeffIsBack added the bug-fix This Pull Request fixes a bug label Feb 19, 2026
@NeffIsBack
Copy link
Copy Markdown
Member

NeffIsBack commented Mar 11, 2026

@mverschu any reason why you have not just added the .lower() to the original line? With that (but also your solution) i can decrypt my MasterKey file. However, it still doesn't show my saved chrome secret. @zblurx any idea why?

image

@zblurx
Copy link
Copy Markdown
Collaborator

zblurx commented Mar 11, 2026

I need to investigate on Chrome, maybe the DPAPI routine has changed again. Chances are it's not related to this issue

@zblurx
Copy link
Copy Markdown
Collaborator

zblurx commented Mar 11, 2026

I can now confirm Google Chrome has implemented a new encryption flag, which breaks Google Chrome (not the other Chromium browsers, only GC) secret decryption. Need to fix this, but it's unrelated to this issue.

@mverschu
Copy link
Copy Markdown
Contributor Author

No not a reason did not test for changing the first line. So if it both works I think its all good.

Copy link
Copy Markdown
Member

@NeffIsBack NeffIsBack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM:
Image

@NeffIsBack
Copy link
Copy Markdown
Member

I can now confirm Google Chrome has implemented a new encryption flag, which breaks Google Chrome (not the other Chromium browsers, only GC) secret decryption. Need to fix this, but it's unrelated to this issue.

Create an issue to track the missing chrome secrets: #1139

@NeffIsBack NeffIsBack merged commit e57ba1c into Pennyw0rth:main Mar 11, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug-fix This Pull Request fixes a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants