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

PASSWORD_SPRAY not working #18994

Closed
mubix opened this issue Mar 22, 2024 · 13 comments · Fixed by #19079
Closed

PASSWORD_SPRAY not working #18994

mubix opened this issue Mar 22, 2024 · 13 comments · Fixed by #19079
Labels

Comments

@mubix
Copy link
Contributor

mubix commented Mar 22, 2024

msf6 auxiliary(scanner/ldap/ldap_login) > options

Module options (auxiliary/scanner/ldap/ldap_login):

   Name              Current Setting                     Required  Description
   ----              ---------------                     --------  -----------
   ANONYMOUS_LOGIN   true                                yes       Attempt to login with a blank username and password
   BRUTEFORCE_SPEED  5                                   yes       How fast to bruteforce, from 0 to 5
   DB_ALL_CREDS      false                               no        Try each user/password couple stored in the current database
   DB_ALL_PASS       false                               no        Add all passwords in the current database to the list
   DB_ALL_USERS      false                               no        Add all users in the current database to the list
   DB_SKIP_EXISTING  none                                no        Skip existing credentials stored in the current database (Accepted: none, user, user&realm)
   DOMAIN            testdomain.com          no        The domain to authenticate to
   PASSWORD                                              no        The password to authenticate with
   PASS_FILE         /opt/rockyou.txt                    no        File containing passwords, one per line
   RHOSTS            10.1.1.100                         yes       The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
   RPORT             389                                 yes       The target port
   SSL               false                               no        Enable SSL on the LDAP connection
   STOP_ON_SUCCESS   false                               yes       Stop guessing when a credential works for a host
   THREADS           1                                   yes       The number of concurrent threads (max one per host)
   USERNAME                                              no        The username to authenticate with
   USERPASS_FILE                                         no        File containing users and passwords separated by space, one pair per line
   USER_AS_PASS      false                               no        Try the username as the password for all users
   USER_FILE         /root/users.txt  no        File containing usernames, one per line
   VERBOSE           true                                yes       Whether to print output for all attempts


   When LDAP::Auth is one of auto,plaintext:

   Name           Current Setting  Required  Description
   ----           ---------------  --------  -----------
   APPEND_DOMAIN  true             yes       Appends `@<DOMAIN> to the username for authentication`


View the full module info with the info, or info -d command.

msf6 auxiliary(scanner/ldap/ldap_login) > set PASSWORD_SPRAY
PASSWORD_SPRAY => true

Results in still hitting users

[-] 10.1.1.100:389 - LOGIN FAILED: username1:123456 (Incorrect: Bind Result: {:extended_response=>nil, :code=>34, :error_message=>"invalid DN", :matched_dn=>"", :message=>"Invalid DN Syntax"})
[-] 10.1.1.100:389 - LOGIN FAILED: username1@testdomain.com:123456 (Incorrect: Bind Result: {:extended_response=>nil, :code=>34, :error_message=>"invalid DN", :matched_dn=>"", :message=>"Invalid DN Syntax"})
[-] 10.1.1.100:389 - LOGIN FAILED: username1:12345 (Incorrect: Bind Result: {:extended_response=>nil, :code=>34, :error_message=>"invalid DN", :matched_dn=>"", :message=>"Invalid DN Syntax"})
[-] 10.1.1.100:389 - LOGIN FAILED: username1@testdomain.com:12345 (Incorrect: Bind Result: {:extended_response=>nil, :code=>34, :error_message=>"invalid DN", :matched_dn=>"", :message=>"Invalid DN Syntax"})
[-] 10.1.1.100:389 - LOGIN FAILED: username1:123456789 (Incorrect: Bind Result: {:extended_response=>nil, :code=>34, :error_message=>"invalid DN", :matched_dn=>"", :message=>"Invalid DN Syntax"})
[-] 10.1.1.100:389 - LOGIN FAILED: username1@testdomain.com:123456789 (Incorrect: Bind Result: {:extended_response=>nil, :code=>34, :error_message=>"invalid DN", :matched_dn=>"", :message=>"Invalid DN Syntax"})

@mubix
Copy link
Contributor Author

mubix commented Mar 22, 2024

What the log doesn't show is it getting to username2

@adfoster-r7
Copy link
Contributor

adfoster-r7 commented Mar 22, 2024

What's the behavior you were expecting? 👀

msf6 auxiliary(scanner/ldap/ldap_login) > cat users.txt
[*] exec: cat users.txt

user1
vagrant
msf6 auxiliary(scanner/ldap/ldap_login) > cat pass.txt
[*] exec: cat pass.txt

pass1
pass2
pass3
vagrant
pass4
msf6 auxiliary(scanner/ldap/ldap_login) > run rhost=192.168.123.136 user_file=./users.txt pass_file=pass.txt verbose=true password_spray=true domain=demo.local stop_on_success=false

[!] No active DB -- Credential data will not be saved!
[-] 192.168.123.136:389 - LOGIN FAILED: user1:pass1 (Incorrect: Bind Result: {:extended_response=>nil, :code=>49, :error_message=>"80090308: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4f7c\u0000", :matched_dn=>"", :message=>"Invalid Credentials"})
[-] 192.168.123.136:389 - LOGIN FAILED: user1:pass2 (Incorrect: Bind Result: {:extended_response=>nil, :code=>49, :error_message=>"80090308: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4f7c\u0000", :matched_dn=>"", :message=>"Invalid Credentials"})
[-] 192.168.123.136:389 - LOGIN FAILED: user1:pass3 (Incorrect: Bind Result: {:extended_response=>nil, :code=>49, :error_message=>"80090308: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4f7c\u0000", :matched_dn=>"", :message=>"Invalid Credentials"})
[-] 192.168.123.136:389 - LOGIN FAILED: user1:vagrant (Incorrect: Bind Result: {:extended_response=>nil, :code=>49, :error_message=>"80090308: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4f7c\u0000", :matched_dn=>"", :message=>"Invalid Credentials"})
[-] 192.168.123.136:389 - LOGIN FAILED: user1:pass4 (Incorrect: Bind Result: {:extended_response=>nil, :code=>49, :error_message=>"80090308: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4f7c\u0000", :matched_dn=>"", :message=>"Invalid Credentials"})
[-] 192.168.123.136:389 - LOGIN FAILED: vagrant:pass1 (Incorrect: Bind Result: {:extended_response=>nil, :code=>49, :error_message=>"80090308: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4f7c\u0000", :matched_dn=>"", :message=>"Invalid Credentials"})
[-] 192.168.123.136:389 - LOGIN FAILED: vagrant:pass2 (Incorrect: Bind Result: {:extended_response=>nil, :code=>49, :error_message=>"80090308: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4f7c\u0000", :matched_dn=>"", :message=>"Invalid Credentials"})
[-] 192.168.123.136:389 - LOGIN FAILED: vagrant:pass3 (Incorrect: Bind Result: {:extended_response=>nil, :code=>49, :error_message=>"80090308: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4f7c\u0000", :matched_dn=>"", :message=>"Invalid Credentials"})
[+] 192.168.123.136:389 - Success: 'vagrant:vagrant'
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/ldap/ldap_login) > 

Edit: Race condition between our posts; I see a difference in my error versus yours

I'm assuming /root/users.txt is correctly new line delimited? Running locally on my setup appears to work as you intended - but let me know if I've misunderstood

@mubix
Copy link
Contributor Author

mubix commented Mar 23, 2024

Regular password brute force attack would try user1 with every password before moving on.
Password spraying would try the first password with every user before moving on.

@jmartin-tech
Copy link
Contributor

#9634 introduced this option, either ldap_login implementation did not take into account this option or there is some regression.

@nrathaus
Copy link
Contributor

nrathaus commented Apr 9, 2024

I think the difference between ldap_login and owa_login (which seems to have been the target for #9634 enhancement) is that one uses each_user_pass while former does not (the latter generates its own set of user/pass sets)

@jmartin-tech what do you think?

@nrathaus
Copy link
Contributor

nrathaus commented Apr 9, 2024

Maybe all that is needed is to generate an array of user and pass using combine_users_and_passwords function which based on PASSWORD_SPRAY decides whether to do:

user1:pass2
....
user2:pass1
...

Or

user1:pass1
user2:pass1
...
user1:pass2
user2:pass2
...```

@nrathaus
Copy link
Contributor

nrathaus commented Apr 9, 2024

Maybe we can fix each_unfiltered inside lib/metasploit/framework/credential_collection.rb to do this in one centralized place

Though it doesn't seem to have access to the datastore

@nrathaus
Copy link
Contributor

@mubix try to see if this PR fixes your issue

@nrathaus
Copy link
Contributor

We might want to remove the deregister found in modules/auxiliary/scanner/ftp/ftp_login.rb

@nrathaus
Copy link
Contributor

I also tried it with pure-ftpd:

docker run --rm -d --name ftpd_server -p 21:21 -p 30000-30009:30000-30009 stilliard/pure-ftpd bash /run.sh -c 30 -C 10 -l puredb:/etc/pure-ftpd/pureftpd.pdb -E -j -R -P localhost -p 30000:30059
msf6 auxiliary(scanner/ftp/ftp_login) > set

Global
======

No entries in data store.

Module: scanner/ftp/ftp_login
=============================

  Name                     Value
  ----                     -----
  ANONYMOUS_LOGIN          false
  BLANK_PASSWORDS          false
  BRUTEFORCE_SPEED         5
  CHOST
  CPORT
  ConnectTimeout           30
  DB_ALL_CREDS             false
  DB_ALL_PASS              false
  DB_ALL_USERS             false
  DB_SKIP_EXISTING         none
  FTPDEBUG                 false
  FTPTimeout               16
  MaxGuessesPerService     0
  MaxGuessesPerUser        0
  MaxMinutesPerService     0
  PASSWORD
  PASSWORD_SPRAY           true
  PASS_FILE                /tmp/passwords.txt
  PassiveMode              false
  Proxies
  RECORD_GUEST             false
  REMOVE_PASS_FILE         false
  REMOVE_USERPASS_FILE     false
  REMOVE_USER_FILE         false
  RHOSTS                   127.0.0.1
  RPORT                    21
  SINGLE_SESSION           false
  SSL                      false
  SSLCipher
  SSLServerNameIndication
  SSLVerifyMode            PEER
  SSLVersion               Auto
  STOP_ON_SUCCESS          false
  ShowProgress             true
  ShowProgressPercent      10
  TCP::max_send_size       0
  TCP::send_delay          0
  THREADS                  1
  TRANSITION_DELAY         0
  USERNAME
  USERPASS_FILE
  USER_AS_PASS             false
  USER_FILE                /tmp/users.txt
  VERBOSE                  true
  WORKSPACE

msf6 auxiliary(scanner/ftp/ftp_login) > run

[*] 127.0.0.1:21          - 127.0.0.1:21 - Starting FTP login sweep
[!] 127.0.0.1:21          - No active DB -- Credential data will not be saved!
[-] 127.0.0.1:21          - 127.0.0.1:21 - LOGIN FAILED: user1:password1 (Incorrect: )
[-] 127.0.0.1:21          - 127.0.0.1:21 - LOGIN FAILED: user2:password1 (Incorrect: )
[-] 127.0.0.1:21          - 127.0.0.1:21 - LOGIN FAILED: user3:password1 (Incorrect: )
[-] 127.0.0.1:21          - 127.0.0.1:21 - LOGIN FAILED: user1:password2 (Incorrect: )
[-] 127.0.0.1:21          - 127.0.0.1:21 - LOGIN FAILED: user2:password2 (Incorrect: )
[-] 127.0.0.1:21          - 127.0.0.1:21 - LOGIN FAILED: user3:password2 (Incorrect: )
[-] 127.0.0.1:21          - 127.0.0.1:21 - LOGIN FAILED: user1:password3 (Incorrect: )
[-] 127.0.0.1:21          - 127.0.0.1:21 - LOGIN FAILED: user2:password3 (Incorrect: )
[-] 127.0.0.1:21          - 127.0.0.1:21 - LOGIN FAILED: user3:password3 (Incorrect: )
[*] 127.0.0.1:21          - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

@nrathaus
Copy link
Contributor

@mubix there is a PR in the works, can you look into it? and see if it is what you expected?

@mubix
Copy link
Contributor Author

mubix commented Apr 21, 2024

@nrathaus Fix worked for me thanks!

@adfoster-r7
Copy link
Contributor

adfoster-r7 commented May 3, 2024

This is wired up now for the other modules - not just ldap, extra PRs: #19158 and #19156 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Archived in project
4 participants