smbauth NSE Library — Nmap Scripting Engine documentation (original) (raw)

Script Arguments Functions Tables

This module takes care of the authentication used in SMB (LM, NTLM, LMv2, NTLMv2).

There is a lot to this functionality, so if you're interested in how it works, read on. In SMB authentication, there are two distinct concepts. Each will be dealt with separately. There are:

What's confusing is that the same names are used for each of those.

Stored Hashes: Windows stores two types of hashes: Lanman and NT Lanman (or NTLM). Vista and later store NTLM only. Lanman passwords are divided into two 7-character passwords and used as a key in DES, while NTLM is converted to unicode and MD4ed.

The stored hashes can be dumped in a variety of ways (pwdump6, fgdump, Metasploit'spriv module, smb-psexec.nse, etc). Generally, two hashes are dumped together (generally, Lanman:NTLM). Sometimes, Lanman is empty and only NTLM is given. Lanman is never required.

The password hashes can be given instead of passwords when supplying credentials; this is done by using the smbhash argument. Either a pair of hashes can be passed, in the form of Lanman:NTLM, or a single hash, which is assumed to be NTLM.

Authentication: There are four types of authentication. Confusingly, these have the same names as stored hashes, but only slight relationships. The four types are Lanmanv1, NTLMv1, Lanmanv2, and NTLMv2. By default, Lanmanv1 and NTLMv1 are used together in most applications. These Nmap scripts default to NTLMv1 alone, except in special cases, but it can be overridden by the user.

Lanmanv1 and NTLMv1 both use DES for their response. The DES mixes a server challenge with the hash (Lanman hash for Lanmanv1 response and NTLMv1 hash for NTLM response). The way the challenge is DESed with the hashes is identical for Lanmanv1 and NTLMv1, the only difference is the starting hash (Lanman vs NTLM).

Lanmanv2 and NTLMv2 both use HMAC-MD5 for their response. The HMAC-MD5 mixes a server challenge and a client challenge with the NTLM hash, in both cases. The difference between Lanmanv2 and NTLMv2 is the length of the client challenge; Lanmanv2 has a maximum client challenge of 8 bytes, whereas NTLMv2 doesn't limit the length of the client challenge.

The primary advantage to the 'v2' protocols is the client challenge -- by incorporating a client challenge, a malicious server can't use a precomputation attack.

In addition to hashing the passwords, messages are also signed, by default, if a v1 protocol is being used (I (Ron Bowes) couldn't get signatures to work on v2 protocols; if anybody knows how I'd love to implement it).

Source: https://svn.nmap.org/nmap/nselib/smbauth.lua

Script Arguments

smbpassword

The password to connect with. Be cautious with this, since some servers will lock accounts if the incorrect password is given. Although it's rare that the Administrator account can be locked out, in the off chance that it can, you could get yourself in trouble. To use a blank password, leave this parameter off altogether.

smbhash

A password hash to use when logging in. This is given as a single hex string (32 characters) or a pair of hex strings (both 32 characters, optionally separated by a single character). These hashes are the LanMan or NTLM hash of the user's password, and are stored on disk or in memory. They can be retrieved from memory using the fgdump or pwdump tools.

smbnoguest

Use to disable usage of the 'guest' account.

smbdomain

The domain to log in with. If you aren't in a domain environment, then anything will (should?) be accepted by the server.

smbtype

The type of SMB authentication to use. These are the possible options:

smbusername

The SMB username to log in with. The forms "DOMAIN\username" and "username@DOMAIN" are not understood. To set a domain, use the smbdomain argument.

Functions

add_account (host, username, domain, password, password_hash, hash_type, is_admin)

Writes the given account to the registry.

calculate_signature (mac_key, data)

Create an 8-byte message signature that's sent with all SMB packets.

get_account (host)

Retrieve the current set of credentials set in the registry.

get_host_info_from_security_blob (security_blob)

Gets host info from a security blob

get_password_response (ip, username, domain, password, password_hash, hash_type, challenge, is_extended)

Generate the Lanman and NTLM password hashes.

get_security_blob (security_blob, ip, username, domain, password, password_hash, hash_type, flags)

Generate an NTLMSSP security blob.

init_account (host)

Initialize the host's account table.

lm_create_mac_key (lm_hash, lm_response, is_extended)

Create the LM mac key, which is used for message signing.

lm_create_response (lanman, challenge)

Create the Lanman response to send back to the server.

lmv2_create_response (ntlm, username, domain, challenge)

Create the LMv2 response, which can be sent back to the server.

next_account (host, num)

Try the next stored account for this host

ntlm_create_hash (password)

Generate the NTLMv1 hash.

ntlm_create_mac_key (ntlm_hash, ntlm_response, is_extended)

Create the NTLM mac key, which is used for message signing.

ntlm_create_response (ntlm, challenge)

Create the NTLM response to send back to the server.

ntlmv2_create_hash (ntlm, username, domain)

Create the NTLMv2 hash.

ntlmv2_create_response (ntlm, username, domain, challenge, client_challenge_length)

Create the NTLMv2 response, which can be sent back to the server.

ntlmv2_session_response (ntlm_password_hash, challenge)

Generates the ntlmv2 session response. It starts by generatng an 8 byte random client nonce, it is padded to 24 bytes. The padded value is the lanman response. A session nonce is made by concatenating the server challenge and the client nonce. The ntlm session hash is first 8 bytes of the md5 hash of the session nonce. The ntlm response is the lm response with session hash as challenge.

Tables

host_info

Host information for NTLM security

Functions

add_account (host, username, domain, password, password_hash, hash_type, is_admin)

Writes the given account to the registry.

There are several places where accounts are stored:

The final place, 'smbaccount', is reserved for the "best" account. This is an administrator account, if one's found; otherwise, it's the first account discovered that isn't guest.

This has to be called while no SMB connections are made, since it potentially makes its own connection.

Parameters

host

The host object.

username

The username to add.

domain

The domain to add.

password

The password to add.

password_hash

The password hash to add.

hash_type

The hash type to use.

is_admin

[optional] Set to 'true' the account is known to be an administrator.

calculate_signature (mac_key, data)

Create an 8-byte message signature that's sent with all SMB packets.

Parameters

mac_key

The key used for authentication. It's the concatenation of the session key and the response hash.

data

The packet to generate the signature for. This should be the packet that's about to be sent, except with the signature slot replaced with the sequence number.

Return value:

The 8-byte signature. The signature is equal to the first eight bytes of md5(mac_key .. smb_data)

get_account (host)

Retrieve the current set of credentials set in the registry.

If these fail, next_account should be called.

Parameters

host

The host object.

Return values:

  1. status true or false. If false, the next return value is an error message and no other values are returned.
  2. username
  3. domain
  4. password
  5. password_hash
  6. hash_type

See also:

get_host_info_from_security_blob (security_blob)

Gets host info from a security blob

Parameters

security_blob

The NTLM security blob

Return value:

A host_info table containing the data in the blob.

See also:

get_password_response (ip, username, domain, password, password_hash, hash_type, challenge, is_extended)

Generate the Lanman and NTLM password hashes.

The password itself is taken from the function parameters, the script arguments, and the registry (in that order). If no password is set, then the password hash is used (which is read from all the usual places). If neither is set, then a blank password is used.

The output passwords are hashed based on the hash type.

Parameters

ip

The ip address of the host, used for registry lookups.

username

The username, which is used for v2 passwords.

domain

The username, which is used for v2 passwords.

password

[optional] The overriding password.

password_hash

[optional] The overriding password hash. Shouldn't be set if password is set.

hash_type

The way in which to hash the password.

challenge

The server challenge.

is_extended

Set to 'true' if extended security negotiations are being used (this has to be known for the message-signing key to be generated properly).

Return values:

  1. lm_response, to be send directly back to the server
  2. ntlm_response, to be send directly back to the server
  3. mac_key used for message signing.

get_security_blob (security_blob, ip, username, domain, password, password_hash, hash_type, flags)

Generate an NTLMSSP security blob.

Parameters

security_blob

The server's security blob, or nil if this is the first message

ip

The ip address of the host, used for registry lookups.

username

The username, which is used for v2 passwords.

domain

The username, which is used for v2 passwords.

password

[optional] The overriding password.

password_hash

[optional] The overriding password hash. Shouldn't be set if password is set.

hash_type

The way in which to hash the password.

flags

The NTLM flags as a number

init_account (host)

Initialize the host's account table.

Create the account table with the anonymous and guest users, as well as the user given in the script's arguments, if there is one.

Parameters

host

The host object.

lm_create_mac_key (lm_hash, lm_response, is_extended)

Create the LM mac key, which is used for message signing.

For basic authentication, it's the first 8 bytes of the lanman hash, followed by 8 null bytes, followed by the lanman response; for extended authentication, this is just the first 8 bytes of the lanman hash followed by 8 null bytes.

Parameters

lm_hash

The LM hash.

lm_response

The LM response.

is_extended

Should be set if extended security negotiations are being used.

Return value:

The LM mac key

lm_create_response (lanman, challenge)

Create the Lanman response to send back to the server.

To do this, the Lanman password is padded to 21 characters and split into three 7-character strings. Each of those strings is used as a key to encrypt the server challenge. The three encrypted strings are concatenated and returned.

Parameters

lanman

The LMv1 hash

challenge

The server's challenge.

Return values:

  1. true on success, or false on error
  2. The client challenge response, or an error message

lmv2_create_response (ntlm, username, domain, challenge)

Create the LMv2 response, which can be sent back to the server.

This is identical to the NTLMv2 function, except that it uses an 8-byte client challenge.

The reason for LMv2 is a long and twisted story. Well, not really. The reason is basically that the v1 hashes are always 24-bytes, and some servers expect 24 bytes, but the NTLMv2 hash is more than 24 bytes. So, the only way to keep pass-through compatibility was to have a v2-hash that was guaranteed to be 24 bytes. So LMv2 was born -- it has a 16-byte hash followed by the 8-byte client challenge, for a total of 24 bytes. And now you've learned something

Parameters

ntlm

The NVLMv1 hash.

username

The username we're using.

domain

The domain.

challenge

The server challenge.

Return values:

  1. true on success, or false on error
  2. The LMv2 response, or an error message

next_account (host, num)

Try the next stored account for this host

Parameters

host

The host table

num

If nil, the next account is chosen. If a number, the account at that index is chosen

ntlm_create_hash (password)

Generate the NTLMv1 hash.

This hash is quite a bit better than LMv1, and is far easier to generate. Basically, it's the MD4 of the Unicode password.

Parameters

password

the password to hash

Return values:

  1. true on success, or false on error
  2. The NTLMv1 hash

ntlm_create_mac_key (ntlm_hash, ntlm_response, is_extended)

Create the NTLM mac key, which is used for message signing.

For basic authentication, this is the md4 of the NTLM hash, concatenated with the response hash; for extended authentication, this is just the md4 of the NTLM hash.

Parameters

ntlm_hash

The NTLM hash.

ntlm_response

The NTLM response.

is_extended

Should be set if extended security negotiations are being used.

Return value:

The NTLM mac key

ntlm_create_response (ntlm, challenge)

Create the NTLM response to send back to the server.

This is actually done the exact same way as the Lanman hash, so I call the Lanman function.

Parameters

ntlm

The NTLMv1 hash

challenge

The server's challenge.

Return values:

  1. true on success, or false on error
  2. The client challenge response, or an error message

ntlmv2_create_hash (ntlm, username, domain)

Create the NTLMv2 hash.

The NTLMv2 hash is based on the NTLMv1 hash (for easy upgrading), the username, and the domain. Essentially, the NTLM hash is used as a HMAC-MD5 key, which is used to hash the unicode domain concatenated with the unicode username.

Parameters

ntlm

The NTLMv1 hash.

username

The username we're using.

domain

The domain.

Return values:

  1. true on success, or false on error
  2. The NTLMv2 hash or an error message

ntlmv2_create_response (ntlm, username, domain, challenge, client_challenge_length)

Create the NTLMv2 response, which can be sent back to the server.

This is done by using the HMAC-MD5 algorithm with the NTLMv2 hash as a key, and the server challenge concatenated with the client challenge for the data. The resulting hash is concatenated with the client challenge and returned.

The "proper" implementation for this uses a certain structure for the client challenge, involving the time and computer name and stuff (if you don't do this, Wireshark tells you it's a malformed packet). In my tests, however, I couldn't get Vista to recognize a client challenge longer than 24 bytes, and this structure was guaranteed to be much longer than 24 bytes. So, I just use a random string generated by OpenSSL. I've tested it on every Windows system from Windows 2000 to Windows Vista, and it has always worked.

Parameters

ntlm

The NVLMv1 hash.

username

The username we're using.

domain

The domain.

challenge

The server challenge.

client_challenge_length

number of random bytes of client challenge to use

Return values:

  1. true on success, or false on error
  2. The NTLMv2 response, or an error message

ntlmv2_session_response (ntlm_password_hash, challenge)

Generates the ntlmv2 session response. It starts by generatng an 8 byte random client nonce, it is padded to 24 bytes. The padded value is the lanman response. A session nonce is made by concatenating the server challenge and the client nonce. The ntlm session hash is first 8 bytes of the md5 hash of the session nonce. The ntlm response is the lm response with session hash as challenge.

Parameters

ntlm_password_hash

The md4 hash of the utf-16 password.

challenge

The challenge sent by the server.

Tables

host_info

Host information for NTLM security

Fields

target_realm

Target Name Data

netbios_computer_name

Server name

netbios_domain_name

Domain name

fqdn

DNS server name

dns_domain_name

DNS domain name

dns_forest_name

DNS tree name

timestamp

Timestamp