Skip to content

Adjust the pre2k module#1177

Merged
NeffIsBack merged 9 commits intoPennyw0rth:mainfrom
ledrypotato:pre2k-module-adjustment
Apr 3, 2026
Merged

Adjust the pre2k module#1177
NeffIsBack merged 9 commits intoPennyw0rth:mainfrom
ledrypotato:pre2k-module-adjustment

Conversation

@ledrypotato
Copy link
Copy Markdown
Contributor

Description

On a recent engagement, using the pre2k module, multiple computer accounts were not found as having the same password as the machine name (in lowercase without the trailing $) - these are known as pre-created computer accounts. In the existing pre2k module, the LDAP filter misses out on computers that are already joined to the domain.

The userAccountControl search filter is a bit restrictive. I changed it from 4128 (32 - PASSWD_NOTREQD + 4096 - WORKSTATION_TRUST_ACCOUNT) to only 4096.

"After a computer account has joined the domain, it will just have the WORKSTATION_TRUST_ACCOUNT flag set (4096)" - https://www.trustedsec.com/blog/diving-into-pre-created-computer-accounts.

When testing with another tool (pre2k) during my engagement it successfully found valid credentials. This tool uses the filter (objectclass=computer).

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Setup guide for the review

  • I have linked relevant sources that describes the added technique (blog posts, documentation, etc)
  • I have performed a self-review of my own code (not an AI review)
  • I have commented my code, particularly in hard-to-understand areas

The userAccountControl search filter is a bit restrictive. I changed it from 4128 (32 - PASSWD_NOTREQD + 4096 - WORKSTATION_TRUST_ACCOUNT) to only 4096 since "After a computer account has joined the domain, it will just have the WORKSTATION_TRUST_ACCOUNT flag set (4096)" - https://www.trustedsec.com/blog/diving-into-pre-created-computer-accounts

Signed-off-by: ledrypotato <matt.taylor3@proton.me>
@NeffIsBack
Copy link
Copy Markdown
Member

The problem is that every domain joined computer account has this value:
image

Therefore we would request TGTs for every computer in the entire domain and that is a bit too much.

@ledrypotato
Copy link
Copy Markdown
Contributor Author

What do you suggest then? Just using the other pre2k tool by garettfoster? Seems a shame to not have the module working as intended in NetExec 😕...

@NeffIsBack
Copy link
Copy Markdown
Member

What do you suggest then? Just using the other pre2k tool by garettfoster? Seems a shame to not have the module working as intended in NetExec 😕...

We could add a module option to just request it for all computers in the domain, but I don't think that this should be the default. Garrett knows what he is doing with his tool and describes the behavior in his README file, but I think users wouldn't expect an nxc module to automatically request hundreds or even thousands of TGTs at one.

@NeffIsBack
Copy link
Copy Markdown
Member

@Marshall-Hallenbeck the PR template bot crashed again

@ledrypotato
Copy link
Copy Markdown
Contributor Author

New module option

We could add a module option to just request it for all computers in the domain

I've gone ahead and added a module option to do this:

uv run nxc ldap 10.2.10.11 -u localuser -p password -M pre2k -o ALL=true

I also slightly modified the output of the tool to indicate if a computer account or a pre-created computer account was found. Here is what it looks like:

image

Lab Setup

My lab setup to test this was:

  1. Create a pre2k computer account by checking Assign this computer account as a pre-Windows 2000 computer:
image
  1. Create another computer that doesn't have this option checked:
image
  1. Create a computer through PowerShell by setting the password manually to be equal to the hostname. By doing so the UAC is set to 4096.
New-ADComputer -Name srv01 -Path "CN=Computers,DC=ludus,DC=domain" -Enabled $true -AccountPassword (ConvertTo-SecureString "srv01" -AsPlainText -Force)

Info

  • I've ran ruff against my code

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.

Thanks for the adjustments, a few small things left to do.

Comment thread nxc/modules/pre2k.py Outdated
Comment thread nxc/modules/pre2k.py Outdated
Comment thread nxc/modules/pre2k.py Outdated
Comment thread nxc/modules/pre2k.py Outdated
@NeffIsBack NeffIsBack added enhancement New feature or request and removed waiting for response labels Apr 3, 2026
@ledrypotato
Copy link
Copy Markdown
Contributor Author

ledrypotato commented Apr 3, 2026

Ok.

  • Made the small brackets adjustments.
  • Made the output a bit cleaner (put context.log.debug() for non pre2k computer accounts and failed TGT requests).
  • Separated file writing to 2 different files for pre2k and non pre2k computer accounts.
  • Added display message to let the user know that they can try the -o ALL=true module option if they got no valid credentials with pre2k accounts.
image

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.

Fyi, made some logging adjustments, so it isn't that noisy when querying normal accounts, but still logs pre2k accounts. LGTM:
Image

@NeffIsBack NeffIsBack merged commit 1f4acea into Pennyw0rth:main Apr 3, 2026
5 checks passed
@ledrypotato
Copy link
Copy Markdown
Contributor Author

Awesome, looks good!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants