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

Optionally store enumerated SMB usernames in DB #12929

Merged
merged 1 commit into from
Mar 3, 2020

Conversation

0x44434241
Copy link
Contributor

This responds to issue #12359, where it was noted that enumerated usernames from this module were not being stored in the database. Since they are not a credential pair of user:pass, I have made it an optional feature with 'DB_ALL_USERS', which is consistent with other scanning modules.

Verification

Default functionality (unchanged):

msf5 > creds -d
Credentials
===========

host  origin  service  public  private  realm  private_type  JtR Format
----  ------  -------  ------  -------  -----  ------------  ----------

msf5 > use auxiliary/scanner/smb/smb_enumusers
msf5 auxiliary(scanner/smb/smb_enumusers) > set RHOSTS 192.168.56.110
RHOSTS => 192.168.56.110
msf5 auxiliary(scanner/smb/smb_enumusers) > run

[+] 192.168.56.110:445    - USER-E74BC7C1A0 [ Administrator, Guest, SUPPORT_388945a0 ] ( LockoutTries=0 PasswordMin=0 )
[*] 192.168.56.110:       - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/smb/smb_enumusers) > creds
Credentials
===========

host  origin  service  public  private  realm  private_type  JtR Format
----  ------  -------  ------  -------  -----  ------------  ----------

msf5 auxiliary(scanner/smb/smb_enumusers) >

Set DB_ALL_USERS to true in order to save the usernames in the database:

msf5 auxiliary(scanner/smb/smb_enumusers) > show options

Module options (auxiliary/scanner/smb/smb_enumusers):

   Name          Current Setting  Required  Description
   ----          ---------------  --------  -----------
   DB_ALL_USERS  false            no        Add all enumerated usernames to the database
   RHOSTS        192.168.56.110   yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   SMBDomain     .                no        The Windows domain to use for authentication
   SMBPass                        no        The password for the specified username
   SMBUser                        no        The username to authenticate as
   THREADS       1                yes       The number of concurrent threads (max one per host)

msf5 auxiliary(scanner/smb/smb_enumusers) > set DB_ALL_USERS true
DB_ALL_USERS => true
msf5 auxiliary(scanner/smb/smb_enumusers) > run

[+] 192.168.56.110:445    - USER-E74BC7C1A0 [ Administrator, Guest, SUPPORT_388945a0 ] ( LockoutTries=0 PasswordMin=0 )
[*] 192.168.56.110:       - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/smb/smb_enumusers) > creds
Credentials
===========

host            origin          service        public            private  realm            private_type  JtR Format
----            ------          -------        ------            -------  -----            ------------  ----------
192.168.56.110  192.168.56.110  445/tcp (smb)  SUPPORT_388945a0           USER-E74BC7C1A0
192.168.56.110  192.168.56.110  445/tcp (smb)  Guest                      USER-E74BC7C1A0
192.168.56.110  192.168.56.110  445/tcp (smb)  Administrator              USER-E74BC7C1A0

msf5 auxiliary(scanner/smb/smb_enumusers) > 

Possible Bug?

Now, I would expect that I should be able to use these enumerated usernames in auxiliary/scanner/smb/smb_login in the same fashion I can with the SSH equivalents. However, this is what currently happens:

msf5 auxiliary(scanner/smb/smb_enumusers) > use auxiliary/scanner/smb/smb_login
msf5 auxiliary(scanner/smb/smb_login) > set DB_ALL_CREDS true
DB_ALL_CREDS => true
msf5 auxiliary(scanner/smb/smb_login) > set RHOSTS 192.168.56.110
RHOSTS => 192.168.56.110
msf5 auxiliary(scanner/smb/smb_login) > run

[*] 192.168.56.110:445    - 192.168.56.110:445 - Starting SMB login bruteforce
[*] 192.168.56.110:445    - Error: 192.168.56.110: Metasploit::Framework::LoginScanner::Invalid Cred details can't be blank, Cred details can't be blank (Metasploit::Framework::LoginScanner::SMB)
[*] 192.168.56.110:445    - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/smb/smb_login) > set SMBPass test
SMBPass => test
msf5 auxiliary(scanner/smb/smb_login) > set USER_AS_PASS true
USER_AS_PASS => true
msf5 auxiliary(scanner/smb/smb_login) > set BLANK_PASSWORDS true
BLANK_PASSWORDS => true
msf5 auxiliary(scanner/smb/smb_login) > run

[*] 192.168.56.110:445    - 192.168.56.110:445 - Starting SMB login bruteforce
[*] 192.168.56.110:445    - Error: 192.168.56.110: Metasploit::Framework::LoginScanner::Invalid Cred details can't be blank, Cred details can't be blank (Metasploit::Framework::LoginScanner::SMB)
[*] 192.168.56.110:445    - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/smb/smb_login) >

So disclaimer, I'm a very new contributor to Metasploit and a Ruby newbie in general. Poking around at the source of the LoginScanner and AuthBrute modules kinda make me think that its more likely I'm putting the data in the database wrong, but I'm not quite sure what I'm missing - feedback or suggestions of 'go and look at this bit' are welcome. I did note that if I make the module insert a fixed string like so:

diff --git a/modules/auxiliary/scanner/smb/smb_enumusers.rb b/modules/auxiliary/scanner/smb/smb_enumusers.rb
index 4ce773cf88..05402b97fa 100644
--- a/modules/auxiliary/scanner/smb/smb_enumusers.rb
+++ b/modules/auxiliary/scanner/smb/smb_enumusers.rb
@@ -351,6 +351,8 @@ class MetasploitModule < Msf::Auxiliary
       origin_type: :service,
       module_fullname: fullname,
       username: username[1],
+      private_data: "test",
+      private_type: :password,
       realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN,
       realm_value: domain,
     }.merge(service_data)

meterpreter was pretty happy with that:

msf5 auxiliary(scanner/smb/smb_enumusers) > rexploit
[*] Reloading module...

[+] 192.168.56.110:445    - USER-E74BC7C1A0 [ Administrator, Guest, SUPPORT_388945a0 ] ( LockoutTries=0 PasswordMin=0 )
[*] 192.168.56.110:       - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/smb/smb_enumusers) > creds
Credentials
===========

host            origin          service        public            private  realm            private_type  JtR Format
----            ------          -------        ------            -------  -----            ------------  ----------
192.168.56.110  192.168.56.110  445/tcp (smb)  SUPPORT_388945a0  test     USER-E74BC7C1A0  Password
192.168.56.110  192.168.56.110  445/tcp (smb)  Guest             test     USER-E74BC7C1A0  Password
192.168.56.110  192.168.56.110  445/tcp (smb)  Administrator     test     USER-E74BC7C1A0  Password

msf5 auxiliary(scanner/smb/smb_enumusers) > use auxiliary/scanner/smb/smb_login
msf5 auxiliary(scanner/smb/smb_login) > run

[*] 192.168.56.110:445    - 192.168.56.110:445 - Starting SMB login bruteforce
[-] 192.168.56.110:445    - 192.168.56.110:445 - Failed: 'USER-E74BC7C1A0\SUPPORT_388945a0:test'
[-] 192.168.56.110:445    - 192.168.56.110:445 - Failed: 'USER-E74BC7C1A0\Guest:test',
[-] 192.168.56.110:445    - 192.168.56.110:445 - Failed: 'USER-E74BC7C1A0\Administrator:test',
[*] 192.168.56.110:445    - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

Thoughts? If you know what I might be getting wrong please point me in the right direction and I'll try and fix it up in this PR - but asking for feedback is better than not doing so. This is only my second PR, constructive feedback and suggestions welcome. Thanks!

@space-r7
Copy link
Contributor

space-r7 commented Mar 2, 2020

Currently, the user names are not getting added to the cred_collection used in smb_login.

msf5 > use auxiliary/scanner/smb/smb_enumusers
msf5 auxiliary(scanner/smb/smb_enumusers) > set rhosts 192.168.37.158
rhosts => 192.168.37.158
msf5 auxiliary(scanner/smb/smb_enumusers) > set db_all_users true
db_all_users => true
msf5 auxiliary(scanner/smb/smb_enumusers) > set smbuser administrator
smbuser => administrator
msf5 auxiliary(scanner/smb/smb_enumusers) > set smbpass password
smbpass => password
msf5 auxiliary(scanner/smb/smb_enumusers) > run

[+] 192.168.37.158:445    - WIN-FS4V2V58LEJ [ Administrator, Guest, printer_user, Shelby Pace ] ( LockoutTries=0 PasswordMin=0 )
[*] 192.168.37.158:       - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/smb/smb_enumusers) > creds
Credentials
===========

host            origin          service        public         private  realm            private_type  JtR Format
----            ------          -------        ------         -------  -----            ------------  ----------
192.168.37.158  192.168.37.158  445/tcp (smb)  Administrator           WIN-FS4V2V58LEJ                
192.168.37.158  192.168.37.158  445/tcp (smb)  Guest                   WIN-FS4V2V58LEJ                
192.168.37.158  192.168.37.158  445/tcp (smb)  printer_user            WIN-FS4V2V58LEJ                
192.168.37.158  192.168.37.158  445/tcp (smb)  Shelby Pace             WIN-FS4V2V58LEJ                

msf5 auxiliary(scanner/smb/smb_enumusers) > use smb_login

Matching Modules
================

   #  Name                             Disclosure Date  Rank    Check  Description
   -  ----                             ---------------  ----    -----  -----------
   0  auxiliary/scanner/smb/smb_login                   normal  No     SMB Login Check Scanner


[*] Using auxiliary/scanner/smb/smb_login
msf5 auxiliary(scanner/smb/smb_login) > set rhosts 192.168.37.158
rhosts => 192.168.37.158
msf5 auxiliary(scanner/smb/smb_login) > set smbpass password
smbpass => password
msf5 auxiliary(scanner/smb/smb_login) > set db_all_creds true
db_all_creds => true
msf5 auxiliary(scanner/smb/smb_login) > run

[*] 192.168.37.158:445    - 192.168.37.158:445 - Starting SMB login bruteforce

From: /Users/space/metasploit-framework/modules/auxiliary/scanner/smb/smb_login.rb @ line 116 Msf::Modules::Auxiliary__Scanner__Smb__Smb_login::MetasploitModule#run_host:

    111:     )
    112: 
    113:     cred_collection = prepend_db_passwords(cred_collection)
    114:     cred_collection = prepend_db_hashes(cred_collection)
    115: 
 => 116:     require 'pry';binding.pry
    117: 
    118:     @scanner.cred_details = cred_collection
    119: 
    120:     @scanner.scan! do |result|
    121:       case result.status

[1] pry(#<Msf::Modules::Auxiliary__Scanner__Smb__Smb_login::MetasploitModule>)> cred_collection
=> #<Metasploit::Framework::CredentialCollection:0x00007fb82b8a2510
 @additional_privates=[],
 @additional_publics=[],
 @blank_passwords=false,
 @pass_file=nil,
 @password="password",
 @prepended_creds=[],
 @realm=".",
 @user_as_pass=false,
 @user_file=nil,
 @username="",
 @userpass_file=nil>

I submitted a PR to fix that particular issue. Hopefully, once those changes are in master, you can update your branch and test against the changes. If you don't get the error, then I'll go ahead and land. Thanks for taking this issue on!

@space-r7
Copy link
Contributor

space-r7 commented Mar 2, 2020

Hey @0x44434241, my changes have been landed, so when you get the chance, could you pull in the new changes and test them with your changes? Thanks!

@0x44434241
Copy link
Contributor Author

Sure, I'll test them today. Thanks for sharing what some of the contributing factors were, I'll take a look at the details of your PR and see what I was missing!

@0x44434241
Copy link
Contributor Author

Rebased against upstream/master, looks like it works to me:

msf5 > use auxiliary/scanner/smb/smb_enumusers
msf5 auxiliary(scanner/smb/smb_enumusers) > set RHOSTS 192.168.56.110
RHOSTS => 192.168.56.110
msf5 auxiliary(scanner/smb/smb_enumusers) > creds
Credentials
===========

host  origin  service  public  private  realm  private_type  JtR Format
----  ------  -------  ------  -------  -----  ------------  ----------

msf5 auxiliary(scanner/smb/smb_enumusers) > set DB_ALL_USERS true
DB_ALL_USERS => true
msf5 auxiliary(scanner/smb/smb_enumusers) > run

[+] 192.168.56.110:445    - USER-E74BC7C1A0 [ Administrator, Guest, nopassworduser, secret, SUPPORT_388945a0, user ] ( LockoutTries=0 PasswordMin=0 )
[*] 192.168.56.110:       - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed


msf5 auxiliary(scanner/smb/smb_enumusers) > use auxiliary/scanner/smb/smb_login
msf5 auxiliary(scanner/smb/smb_login) > set RHOSTS 192.168.56.110
RHOSTS => 192.168.56.110
msf5 auxiliary(scanner/smb/smb_login) > set DB_ALL_CREDS true
DB_ALL_CREDS => true
msf5 auxiliary(scanner/smb/smb_login) > run

[*] 192.168.56.110:445    - 192.168.56.110:445 - Starting SMB login bruteforce
[-] 192.168.56.110:445    - 192.168.56.110:445 - Failed: 'USER-E74BC7C1A0\Administrator:'
[-] 192.168.56.110:445    - 192.168.56.110:445 - Failed: 'USER-E74BC7C1A0\Guest:'
[-] 192.168.56.110:445    - 192.168.56.110:445 - Failed: 'USER-E74BC7C1A0\SUPPORT_388945a0:'
[-] 192.168.56.110:445    - 192.168.56.110:445 - Failed: 'USER-E74BC7C1A0\user:',
[-] 192.168.56.110:445    - 192.168.56.110:445 - Failed: 'USER-E74BC7C1A0\secret:',
[+] 192.168.56.110:445    - 192.168.56.110:445 - Success: 'USER-E74BC7C1A0\nopassworduser:'
[*] 192.168.56.110:445    - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

Unfortunately the smb_login module won't try each database credential object with the provided SMBPass, but that's probably out of scope for this PR/issue? It makes sense that it does not, that is how DB_ALL_CREDS works.

msf5 auxiliary(scanner/smb/smb_login) > set SMBPass TestPassword   
SMBPass => TestPassword                                            
msf5 auxiliary(scanner/smb/smb_login) > run                        

[*] 192.168.56.110:445    - 192.168.56.110:445 - Starting SMB login bruteforce
[-] 192.168.56.110:445    - 192.168.56.110:445 - Failed: 'USER-E74BC7C1A0\Administrator:'
[-] 192.168.56.110:445    - 192.168.56.110:445 - Failed: 'USER-E74BC7C1A0\Guest:'
[-] 192.168.56.110:445    - 192.168.56.110:445 - Failed: 'USER-E74BC7C1A0\SUPPORT_388945a0:'
[-] 192.168.56.110:445    - 192.168.56.110:445 - Failed: 'USER-E74BC7C1A0\user:',
[-] 192.168.56.110:445    - 192.168.56.110:445 - Failed: 'USER-E74BC7C1A0\secret:',
[+] 192.168.56.110:445    - 192.168.56.110:445 - Success: 'USER-E74BC7C1A0\nopassworduser:'
[*] 192.168.56.110:445    - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

This responds to issue rapid7#12359, where it was noted that enumerated
usernames from this module were not being stored in the database. Since
they are not a credential pair of user:pass, I have made it an optional
feature with 'DB_ALL_USERS', which is consistent with other scanning
modules.
@space-r7
Copy link
Contributor

space-r7 commented Mar 3, 2020

The commit history got a little messed up, so I went ahead and force-pushed to your branch.

Unfortunately the smb_login module won't try each database credential object with the provided SMBPass, but that's probably out of scope for this PR/issue? It makes sense that it does not, that is how DB_ALL_CREDS works.

I think that's expected. I've been testing with DB_ALL_USERS set so that all of the collected user names get matched with whatever password(s) I'm using.

@space-r7
Copy link
Contributor

space-r7 commented Mar 3, 2020

Testing the new option:

msf5 > use auxiliary/scanner/smb/smb_enumusers
msf5 auxiliary(scanner/smb/smb_enumusers) > set rhosts 192.168.37.165
rhosts => 192.168.37.165
msf5 auxiliary(scanner/smb/smb_enumusers) > options

Module options (auxiliary/scanner/smb/smb_enumusers):

   Name          Current Setting  Required  Description
   ----          ---------------  --------  -----------
   DB_ALL_USERS  false            no        Add all enumerated usernames to the database
   RHOSTS        192.168.37.165   yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   SMBDomain     .                no        The Windows domain to use for authentication
   SMBPass                        no        The password for the specified username
   SMBUser                        no        The username to authenticate as
   THREADS       1                yes       The number of concurrent threads (max one per host)

msf5 auxiliary(scanner/smb/smb_enumusers) > set db_all_users true
db_all_users => true
msf5 auxiliary(scanner/smb/smb_enumusers) > set smbuser administrator
smbuser => administrator
msf5 auxiliary(scanner/smb/smb_enumusers) > set smbpass password
smbpass => password
msf5 auxiliary(scanner/smb/smb_enumusers) > run

[+] 192.168.37.165:445    - WIN-FS4V2V58LEJ [ Administrator, Guest, printer_user, Shelby Pace ] ( LockoutTries=0 PasswordMin=0 )
[*] 192.168.37.165:       - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/smb/smb_enumusers) > creds
Credentials
===========

host            origin          service        public         private  realm            private_type  JtR Format
----            ------          -------        ------         -------  -----            ------------  ----------
192.168.37.165  192.168.37.165  445/tcp (smb)  printer_user            WIN-FS4V2V58LEJ                
192.168.37.165  192.168.37.165  445/tcp (smb)  Guest                   WIN-FS4V2V58LEJ                
192.168.37.165  192.168.37.165  445/tcp (smb)  Administrator           WIN-FS4V2V58LEJ                
192.168.37.165  192.168.37.165  445/tcp (smb)  Shelby Pace             WIN-FS4V2V58LEJ                

msf5 auxiliary(scanner/smb/smb_enumusers) > use smb_login

Matching Modules
================

   #  Name                             Disclosure Date  Rank    Check  Description
   -  ----                             ---------------  ----    -----  -----------
   0  auxiliary/scanner/smb/smb_login                   normal  No     SMB Login Check Scanner


[*] Using auxiliary/scanner/smb/smb_login
msf5 auxiliary(scanner/smb/smb_login) > set rhosts 192.168.37.165
rhosts => 192.168.37.165
msf5 auxiliary(scanner/smb/smb_login) > set db_all_users true
db_all_users => true
msf5 auxiliary(scanner/smb/smb_login) > set smbpass password
smbpass => password
msf5 auxiliary(scanner/smb/smb_login) > run

[*] 192.168.37.165:445    - 192.168.37.165:445 - Starting SMB login bruteforce
[+] 192.168.37.165:445    - 192.168.37.165:445 - Success: '.\printer_user:password'
[-] 192.168.37.165:445    - 192.168.37.165:445 - Failed: '.\Guest:password',
[+] 192.168.37.165:445    - 192.168.37.165:445 - Success: '.\Administrator:password' Administrator
[+] 192.168.37.165:445    - 192.168.37.165:445 - Success: '.\Shelby Pace:password'
[*] 192.168.37.165:445    - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

@space-r7 space-r7 merged commit 29dcd0f into rapid7:master Mar 3, 2020
@space-r7
Copy link
Contributor

space-r7 commented Mar 3, 2020

Release Notes

This adds the DB_ALL_USERS option to auxiliary/scanner/smb/smb_enumusers, which allows users to store enumerated user names in the database.

@0x44434241
Copy link
Contributor Author

The commit history got a little messed up, so I went ahead and force-pushed to your branch.

No problem, clearly I messed up the rebase somehow? Will look into it. Thanks for catching my error.

Thanks for merging!

@tperry-r7 tperry-r7 added the rn-enhancement release notes enhancement label Mar 16, 2020
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants