Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix failure in secrets dump edge case #19665

Closed
wants to merge 1 commit into from

Conversation

smashery
Copy link
Contributor

This fixes an issue in the windows_secrets_dump module, wherein it fails after certain password change APIs.

To reproduce this issue (and verify the fix):

  • Force a password reset with impacket to force Kerberos keys to be removed:

changepasswd.py -reset -newpass Pass123123$ domain/[email protected] -altuser administrator -altpass Password1!

  • Run the windows_secrets_dump module with appropriate credentials:
msf6 auxiliary(gather/windows_secrets_dump) > run
[*] Running module against 192.168.1.1

[*] 192.168.1.1:445 - Service RemoteRegistry is already running
[*] 192.168.1.1:445 - Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] 192.168.1.1:445 - Using the DRSUAPI method to get NTDS.DIT secrets
[*] 192.168.1.1:445 - SID enumeration progress - 0 / 9 ( 0.00%)
[*] 192.168.1.1:445 - SID enumeration progress - 9 / 9 (  100%)
[*] 192.168.1.1:445 - Cleaning up...
[-] 192.168.1.1:445 - Auxiliary failed: IOError data truncated
[-] 192.168.1.1:445 - Call stack:
[-] 192.168.1.1:445 -   /home/smash/.rbenv/versions/3.2.5/lib/ruby/gems/3.2.0/gems/bindata-2.4.15/lib/bindata/io.rb:317:in `read'
[-] 192.168.1.1:445 -   /home/smash/.rbenv/versions/3.2.5/lib/ruby/gems/3.2.0/gems/bindata-2.4.15/lib/bindata/io.rb:278:in `readbytes'
[-] 192.168.1.1:445 -   (eval):23:in `read_and_return_value'
[-] 192.168.1.1:445 -   /home/smash/.rbenv/versions/3.2.5/lib/ruby/gems/3.2.0/gems/bindata-2.4.15/lib/bindata/base_primitive.rb:129:in `do_read'
[-] 192.168.1.1:445 -   /home/smash/.rbenv/versions/3.2.5/lib/ruby/gems/3.2.0/gems/bindata-2.4.15/lib/bindata/struct.rb:140:in `block in do_read'
[-] 192.168.1.1:445 -   /home/smash/.rbenv/versions/3.2.5/lib/ruby/gems/3.2.0/gems/bindata-2.4.15/lib/bindata/struct.rb:140:in `each'
[-] 192.168.1.1:445 -   /home/smash/.rbenv/versions/3.2.5/lib/ruby/gems/3.2.0/gems/bindata-2.4.15/lib/bindata/struct.rb:140:in `do_read'
[-] 192.168.1.1:445 -   /home/smash/.rbenv/versions/3.2.5/lib/ruby/gems/3.2.0/gems/bindata-2.4.15/lib/bindata/base.rb:147:in `block in read'
[-] 192.168.1.1:445 -   /home/smash/.rbenv/versions/3.2.5/lib/ruby/gems/3.2.0/gems/bindata-2.4.15/lib/bindata/base.rb:253:in `start_read'
[-] 192.168.1.1:445 -   /home/smash/.rbenv/versions/3.2.5/lib/ruby/gems/3.2.0/gems/bindata-2.4.15/lib/bindata/base.rb:145:in `read'
[-] 192.168.1.1:445 -   /home/smash/.rbenv/versions/3.2.5/lib/ruby/gems/3.2.0/gems/bindata-2.4.15/lib/bindata/base.rb:21:in `read'
[-] 192.168.1.1:445 -   /opt/shared/git/metasploit-framework/modules/auxiliary/gather/windows_secrets_dump.rb:723:in `decrypt_supplemental_info'
[-] 192.168.1.1:445 -   /opt/shared/git/metasploit-framework/modules/auxiliary/gather/windows_secrets_dump.rb:837:in `block in parse_user_record'
[-] 192.168.1.1:445 -   /home/smash/.rbenv/versions/3.2.5/lib/ruby/gems/3.2.0/gems/bindata-2.4.15/lib/bindata/array.rb:220:in `block in each'
[-] 192.168.1.1:445 -   /home/smash/.rbenv/versions/3.2.5/lib/ruby/gems/3.2.0/gems/bindata-2.4.15/lib/bindata/array.rb:220:in `each'
[-] 192.168.1.1:445 -   /home/smash/.rbenv/versions/3.2.5/lib/ruby/gems/3.2.0/gems/bindata-2.4.15/lib/bindata/array.rb:220:in `each'
[-] 192.168.1.1:445 -   /opt/shared/git/metasploit-framework/modules/auxiliary/gather/windows_secrets_dump.rb:782:in `parse_user_record'
[-] 192.168.1.1:445 -   /opt/shared/git/metasploit-framework/modules/auxiliary/gather/windows_secrets_dump.rb:928:in `block (2 levels) in dump_ntds_hashes'
[-] 192.168.1.1:445 -   /opt/shared/git/metasploit-framework/modules/auxiliary/gather/windows_secrets_dump.rb:922:in `each'
[-] 192.168.1.1:445 -   /opt/shared/git/metasploit-framework/modules/auxiliary/gather/windows_secrets_dump.rb:922:in `block in dump_ntds_hashes'
[-] 192.168.1.1:445 -   /home/smash/.rbenv/versions/3.2.5/lib/ruby/3.2.0/set.rb:511:in `each_key'
[-] 192.168.1.1:445 -   /home/smash/.rbenv/versions/3.2.5/lib/ruby/3.2.0/set.rb:511:in `each'
[-] 192.168.1.1:445 -   /opt/shared/git/metasploit-framework/modules/auxiliary/gather/windows_secrets_dump.rb:920:in `dump_ntds_hashes'
[-] 192.168.1.1:445 -   /opt/shared/git/metasploit-framework/modules/auxiliary/gather/windows_secrets_dump.rb:1269:in `run'
[*] Auxiliary module execution completed

This occurs because the particular API being used there clears the Kerberos keys. Then, when it tries to parse the UserProperties object, it's not of the right structure. The value we receive in the supplementalCredentials lookup is something like: b'\x00\x00\x00\x00b\x00\x00\x00\x00\x00\x00\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00P\x00\x00'. I have no idea what this is. MSDN doesn't seem to help us either - the docs (https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/0705f888-62e1-4a4c-bac0-b4d427f396f8) don't mention anything about alternative structures.

Impacket's secretsdump.py just catches a parse exception and moves on with its life: https://github.com/fortra/impacket/blob/835e17550b57606ee3c681ae1c3f0edea096ec19/impacket/examples/secretsdump.py#L2275-L2278

With this fix, I do similar - catch the parse error, add a verbose warning message.

@smcintyre-r7
Copy link
Contributor

So I looked into this and I think the root cause is actually that our definition for the structure is incorrect because it doesn't take the following into account:

When there are zero USER_PROPERTY elements in the UserProperties field, this field MUST be omitted; the resultant USER_PROPERTIES structure has a constant size of 0x6F bytes.

I proposed a fix for this in rapid7/ruby_smb#280. I think with that in place, the array will just be empty and the IOError should no longer be raised.

@smashery
Copy link
Contributor Author

Yeah, that's a much cleaner solution I think - closing this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug module rn-fix release notes fix
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

2 participants