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

Refactor smb_enumusers #19095

Merged
merged 6 commits into from
Apr 25, 2024

Conversation

zeroSteiner
Copy link
Contributor

@zeroSteiner zeroSteiner commented Apr 16, 2024

This updates the existing auxiliary/scanner/smb/smb_enumusers. This should fix #19053 by using the RubySMB DCERPC methods. The output between the new and old versions should be identical, though the new one has some additional information printed as it connects to the SAMR interface as provided by the mixin. This requires the changes from rapid7/ruby_smb#266 to include the new SAMR methods for fetching the domain information for the password length and lockout policy.

There's also some overlap with #19072. Now that issue didn't request the ability to control the port in this module, but the technical limitations are the same between smb_enumusers and smb_version. With the changes in this PR landed, the pattern can be used as a precedence and copied to the other modules as necessary, starting with smb_version. The gist is that 139 and 445 are both tried with SMBDirect set as appropriate but if the user sets RPORT, only that port will be tried along with the SMBDirect setting provided through the datastore option. This is what I recommended here.

Verification

List the steps needed to make sure this thing works

This also fixes an issue where the module would fail to return results from hosts that have lots of accounts registered such as a domain controller. Now when run against a domain controller, instead of no accounts being returned, they are all returned on a single line. Neither of these outcomes are particularly great but that's probably a problem to solve in another PR.

Demo

metasploit-framework (S:0 J:0) auxiliary(scanner/smb/smb_enumusers) > run rhost=127.0.0.1 smbpass=acceptance_tests_password smbuser=acceptance_tests_user

[*] 127.0.0.1:445 - Using automatically identified domain: E74A098FA681
[+] 127.0.0.1:445 - E74A098FA681 [ acceptance_tests_user ] ( LockoutTries=0 PasswordMin=5 )
[+] 127.0.0.1:445 - Builtin [  ] ( LockoutTries=0 PasswordMin=5 )
[*] 127.0.0.1:445 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
metasploit-framework (S:0 J:0) auxiliary(scanner/smb/smb_enumusers) >

@smcintyre-r7 smcintyre-r7 added module bug rn-fix release notes fix code quality Improving code quality labels Apr 16, 2024
@zeroSteiner zeroSteiner force-pushed the fix/mod/refactor-smb-enumusers branch from b66eaa5 to 4f7eafc Compare April 22, 2024 14:58
@zeroSteiner zeroSteiner force-pushed the fix/mod/refactor-smb-enumusers branch 2 times, most recently from 4484316 to d3b5041 Compare April 22, 2024 18:01
@sjanusz-r7
Copy link
Contributor

Works as expected vs. port 445 & 139 on Docker & Windows Server 2022 VM, when targetting a session and rhost.

Testing smb_enumusers

Steps - smb_enumusers

Setting up Docker:

  1. cd test/smb
  2. docker compose build
  3. docker compose up -d --wait
  4. Boot up msfconsole
  5. repeat -n 50 run rhost=127.0.0.1 SMBPass=acceptance_tests_password SMBUser=acceptance_tests_user
  6. Confirm it works 🎉 - No broken pipes or timeouts
  7. Get a session using smb_login: run rhost=127.0.0.1 SMBPass=acceptance_tests_password SMBUser=acceptance_tests_user STOP_ON_SUCCESS=true CreateSession=true
  8. repeat -n 50 run session=-1
  9. Confirm it works 🎉 - No broken pipes or timeouts

Docker

Example output vs. Docker (RHOST) (Port 445): 🟢

msf6 auxiliary(scanner/smb/smb_enumusers) > repeat -n 50 run rhost=127.0.0.1 SMBPass=acceptance_tests_password SMBUser=acceptance_tests_user

[*] 127.0.0.1:445 - Using automatically identified domain: 39FCF914A201
[+] 127.0.0.1:445 - 39FCF914A201 [ acceptance_tests_user ] ( LockoutTries=0 PasswordMin=5 )
[+] 127.0.0.1:445 - Builtin [  ] ( LockoutTries=0 PasswordMin=5 )
[*] 127.0.0.1:445 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
...
...
[*] 127.0.0.1:445 - Using automatically identified domain: 39FCF914A201
[+] 127.0.0.1:445 - 39FCF914A201 [ acceptance_tests_user ] ( LockoutTries=0 PasswordMin=5 )
[+] 127.0.0.1:445 - Builtin [  ] ( LockoutTries=0 PasswordMin=5 )
[*] 127.0.0.1:445 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/smb/smb_enumusers) > 

Example output vs. Docker (RHOST) (Port 139): 🟢

msf6 auxiliary(scanner/smb/smb_enumusers) > repeat -n 50 run rhost=127.0.0.1 SMBPass=acceptance_tests_password SMBUser=acceptance_tests_user RPORT=139

[*] 127.0.0.1:139 - Using automatically identified domain: 39FCF914A201
[+] 127.0.0.1:139 - 39FCF914A201 [ acceptance_tests_user ] ( LockoutTries=0 PasswordMin=5 )
[+] 127.0.0.1:139 - Builtin [  ] ( LockoutTries=0 PasswordMin=5 )
[*] 127.0.0.1:139 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
...
...
[*] 127.0.0.1:139 - Using automatically identified domain: 39FCF914A201
[+] 127.0.0.1:139 - 39FCF914A201 [ acceptance_tests_user ] ( LockoutTries=0 PasswordMin=5 )
[+] 127.0.0.1:139 - Builtin [  ] ( LockoutTries=0 PasswordMin=5 )
[*] 127.0.0.1:139 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/smb/smb_enumusers) > 

Example output vs. Docker (SESSION) (Port 445): 🟢

# SMB Session vs. Docker
msf6 auxiliary(scanner/smb/smb_login) > run rhost=127.0.0.1 SMBPass=acceptance_tests_password SMBUser=acceptance_tests_user CreateSession=true Stop_ON_SUCCESS=true

[*] 127.0.0.1:445         - 127.0.0.1:445 - Starting SMB login bruteforce
[+] 127.0.0.1:445         - 127.0.0.1:445 - Success: '.\acceptance_tests_user:acceptance_tests_password'
[*] SMB session 1 opened (127.0.0.1:61645 -> 127.0.0.1:445) at 2024-04-24 16:21:01 +0100
[*] 127.0.0.1:445         - Scanned 1 of 1 hosts (100% complete)
[*] 127.0.0.1:445         - Bruteforce completed, 1 credential was successful.
[*] 127.0.0.1:445         - 1 SMB session was opened successfully.
[*] Auxiliary module execution completed

# Running the module
msf6 auxiliary(scanner/smb/smb_enumusers) > repeat -n 50 run session=-1

[*] Using automatically identified domain: 39FCF914A201
[+] 39FCF914A201 [ acceptance_tests_user ] ( LockoutTries=0 PasswordMin=5 )
[+] Builtin [  ] ( LockoutTries=0 PasswordMin=5 )
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
...
...
[*] Using automatically identified domain: 39FCF914A201
[+] 39FCF914A201 [ acceptance_tests_user ] ( LockoutTries=0 PasswordMin=5 )
[+] Builtin [  ] ( LockoutTries=0 PasswordMin=5 )
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/smb/smb_enumusers) > 

Example output vs. Docker (SESSION) (Port 139): 🟢

# Getting session
msf6 auxiliary(scanner/smb/smb_login) > run rhost=127.0.0.1 SMBPass=acceptance_tests_password SMBUser=acceptance_tests_user CreateSession=true Stop_ON_SUCCESS=true RPORT=139

[*] 127.0.0.1:139         - 127.0.0.1:139 - Starting SMB login bruteforce
[+] 127.0.0.1:139         - 127.0.0.1:139 - Success: '.\acceptance_tests_user:acceptance_tests_password'
[*] SMB session 2 opened (127.0.0.1:61881 -> 127.0.0.1:139) at 2024-04-24 16:30:04 +0100
[*] 127.0.0.1:139         - Scanned 1 of 1 hosts (100% complete)
[*] 127.0.0.1:139         - Bruteforce completed, 1 credential was successful.
[*] 127.0.0.1:139         - 1 SMB session was opened successfully.
[*] Auxiliary module execution completed

# Running module
msf6 auxiliary(scanner/smb/smb_enumusers) > repeat -n 50 run session=-1

[*] Using automatically identified domain: 39FCF914A201
[+] 39FCF914A201 [ acceptance_tests_user ] ( LockoutTries=0 PasswordMin=5 )
[+] Builtin [  ] ( LockoutTries=0 PasswordMin=5 )
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
...
...
[*] Using automatically identified domain: 39FCF914A201
[+] 39FCF914A201 [ acceptance_tests_user ] ( LockoutTries=0 PasswordMin=5 )
[+] Builtin [  ] ( LockoutTries=0 PasswordMin=5 )
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/smb/smb_enumusers) > 

Windows Server 2022 x64 (Build 20348) Virtual Machine - Domain Controller

In this VM, I have not enabled SMBv1 dialect.
Example output vs. VM (RHOST) (Port 445): 🟢

msf6 auxiliary(scanner/smb/smb_enumusers) > repeat -n 50 run SMBUser=Administrator SMBPass=ad-admin1 rhost=192.168.112.3

[*] 192.168.112.3:445 - Using automatically identified domain: SJ
[+] 192.168.112.3:445 - SJ [ Administrator, Guest, krbtgt ] ( LockoutTries=0 PasswordMin=7 )
[+] 192.168.112.3:445 - Builtin [  ] ( LockoutTries=0 PasswordMin=0 )
[*] 192.168.112.3:445 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
...
...
[*] 192.168.112.3:445 - Using automatically identified domain: SJ
[+] 192.168.112.3:445 - SJ [ Administrator, Guest, krbtgt ] ( LockoutTries=0 PasswordMin=7 )
[+] 192.168.112.3:445 - Builtin [  ] ( LockoutTries=0 PasswordMin=0 )
[*] 192.168.112.3:445 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/smb/smb_enumusers) > 

Example output vs. VM (SESSION) (Port 445): 🟢

# Session setup
msf6 auxiliary(scanner/smb/smb_login) > run rhost=192.168.112.3 SMBUser=Administrator SMBPass=ad-admin1 CreateSession=true STOP_ON_SUCCESS=true

[*] 192.168.112.3:445     - 192.168.112.3:445 - Starting SMB login bruteforce
[+] 192.168.112.3:445     - 192.168.112.3:445 - Success: '.\Administrator:ad-admin1' Administrator
[*] SMB session 3 opened (192.168.112.1:61909 -> 192.168.112.3:445) at 2024-04-24 16:33:02 +0100
[*] 192.168.112.3:445     - Scanned 1 of 1 hosts (100% complete)
[*] 192.168.112.3:445     - Bruteforce completed, 1 credential was successful.
[*] 192.168.112.3:445     - 1 SMB session was opened successfully.
[*] Auxiliary module execution completed

# Module run
msf6 auxiliary(scanner/smb/smb_enumusers) > repeat -n 50 run session=-1

[*] Using automatically identified domain: SJ
[+] SJ [ Administrator, Guest, krbtgt ] ( LockoutTries=0 PasswordMin=7 )
[+] Builtin [  ] ( LockoutTries=0 PasswordMin=0 )
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
...
...
[*] Using automatically identified domain: SJ
[+] SJ [ Administrator, Guest, krbtgt ] ( LockoutTries=0 PasswordMin=7 )
[+] Builtin [  ] ( LockoutTries=0 PasswordMin=0 )
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/smb/smb_enumusers) > 

Testing samr_computer

Steps - samr_computer

You will need to change the COMPUTER_NAME option to whatever the output of the hostname command is on the VM; my output was DC1, and the $ character has to be added at the end as it's a part of the name.
For this module test, I used the LOOKUP_COMPUTER action.

  1. repeat -n 50 run rhost=192.168.112.3 SMBUser=Administrator SMBPass=ad-admin1 COMPUTER_NAME=DC1$
  2. Confirm it works without issues 🎉
  3. Get an SMB session
  4. repeat -n 50 run session=-1 COMPUTER_NAME=DC1$
  5. Confirm it works without issues 🎉

Example output vs. VM (RHOST) (Port 445): 🟢

msf6 auxiliary(admin/dcerpc/samr_computer) > repeat -n 50 run rhost=192.168.112.3 SMBUser=Administrator SMBPass=ad-admin1 COMPUTER_NAME=DC1$
[*] Running module against 192.168.112.3

[*] 192.168.112.3:445 - Using automatically identified domain: SJ
[+] 192.168.112.3:445 - Found SJ\DC1$ (SID: S-1-5-21-2181772609-2124839192-2039643012-1000)
[*] Auxiliary module execution completed
...
...

Example output vs. VM (SESSION) (Port 445): 🟢

msf6 auxiliary(admin/dcerpc/samr_computer) > repeat -n 50 run session=-1 COMPUTER_NAME=DC1$

[*] Using existing session 3
[*] Using automatically identified domain: SJ
[+] Found SJ\DC1$ (SID: S-1-5-21-2181772609-2124839192-2039643012-1000)
[*] Auxiliary module execution completed
...
...

This pulls in the changes from rapid7/ruby_smb#266 which adds
SamrQueryInformationDomain support.
@sjanusz-r7 sjanusz-r7 merged commit 76d7fe8 into rapid7:master Apr 25, 2024
63 checks passed
@sjanusz-r7
Copy link
Contributor

Release Notes

Updates the smb_enumusers module to use an updated SMB implementation from RubySMB which fixes an issue where the module could sometimes time out or return an unexpected error when targeting Samba.

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