Script ldap-brute

Script types: portrule
Categories: intrusive, brute
Download: https://svn.nmap.org/nmap/scripts/ldap-brute.nse

Script Summary

Attempts to brute-force LDAP authentication. By default it uses the built-in username and password lists. In order to use your own lists use the userdb and passdb script arguments.

This script does not make any attempt to prevent account lockout! If the number of passwords in the dictionary exceed the amount of allowed tries, accounts will be locked out. This usually happens very quickly.

Authenticating against Active Directory using LDAP does not use the Windows user name but the user accounts distinguished name. LDAP on Windows 2003 allows authentication using a simple user name rather than using the fully distinguished name. E.g., "Patrik Karlsson" vs. "cn=Patrik Karlsson,cn=Users,dc=cqure,dc=net" This type of authentication is not supported on e.g. OpenLDAP.

This script uses some AD-specific support and optimizations:

  • LDAP on Windows 2003/2008 reports different error messages depending on whether an account exists or not. If the script receives an error indicating that the username does not exist it simply stops guessing passwords for this account and moves on to the next.
  • The script attempts to authenticate with the username only if no LDAP base is specified. The benefit of authenticating this way is that the LDAP path of each account does not need to be known in advance as it's looked up by the server. This technique will only find a match if the account Display Name matches the username being attempted.

Script Arguments

ldap.upnsuffix

If set, the script will append this suffix value to the username to create a User Principle Name (UPN). For example if the ldap.upnsuffix value were 'mycompany.com' and the username being tested was 'pete' then this script would attempt to login as 'pete@mycompany.com'. This setting should only have value when running the script against a Microsoft Active Directory LDAP implementation. When the UPN is known using this setting should provide more reliable results against domains that have been organized into various OUs or child domains. If both ldap.base and ldap.upnsuffix are unset the user list must either contain the distinguished name of each user or the server must support authentication using a simple user name. See the AD discussion in the description. DO NOT use ldap.upnsuffix in conjunction with ldap.base as attempts to login will fail.

ldap.saveprefix

If set, the script will save the output to a file beginning with the specified path and name. The file suffix will automatically be added based on the output type selected.

ldap.savetype

If set, the script will save the passwords in the specified format. The current formats are CSV, verbose and plain. In both verbose and plain records are separated by colons. The difference between the two is that verbose includes the credential state. When ldap.savetype is used without ldap.saveprefix then ldap-brute will be prefixed to all output filenames.

ldap.base

If set, the script will use it as a base for the password guessing attempts. If both ldap.base and ldap.upnsuffix are unset the user list must either contain the distinguished name of each user or the server must support authentication using a simple user name. See the AD discussion in the description. DO NOT use ldap.upnsuffix in conjunction with ldap.base as attempts to login will fail.

passdb, unpwdb.passlimit, unpwdb.timelimit, unpwdb.userlimit, userdb

See the documentation for the unpwdb library.

creds.[service], creds.global

See the documentation for the creds library.

Example Usage

nmap -p 389 --script ldap-brute --script-args ldap.base='"cn=users,dc=cqure,dc=net"' <host>

Script Output

389/tcp open  ldap
| ldap-brute:
|_  ldaptest:ldaptest => Valid credentials
|   restrict.ws:restricted1 => Valid credentials, account cannot log in from current host
|   restrict.time:restricted1 => Valid credentials, account cannot log in at current time
|   valid.user:valid1 => Valid credentials
|   expired.user:expired1 => Valid credentials, account expired
|   disabled.user:disabled1 => Valid credentials, account disabled
|_  must.change:need2change => Valid credentials, password must be changed at next logon

Requires


Author:

  • Patrik Karlsson

License: Same as Nmap--See https://nmap.org/book/man-legal.html